OpenGL: Phong'a göre aydınlatma çalışmamıza devam ediyoruz. OpenGL'de Aydınlatma Aynasal ışık

Cepheler için boya çeşitleri

Bu eğitimde 3D modellerimizi nasıl vurgulayıp gölgelendireceğimizi öğreneceğiz. Öğreneceklerimizin listesi aşağıdadır:

  • Bir ışık kaynağına yakın olan bir nesnenin daha parlak görünmesi nasıl sağlanır?
  • Bir nesnenin üzerinde yansıyan ışık gördüğümüzde yansımalar nasıl yapılır (aynasal aydınlatma)
  • Işık doğrudan nesnenin üzerine düşmediğinde bir nesnenin hafif gölgeli görünmesi nasıl sağlanır (yaygın aydınlatma)
  • Ortam ışıklandırması
  • Gölgeler. Bu konu ayrı bir dersi (veya kitap değilse de dersleri) hak ediyor.
  • Ayna yansıma (örneğin, su)
  • Yer altısaçılma (örneğin, balmumu gibi)
  • Anizotropik malzemeler (boyalıörneğin metal)
  • Gerçekliği daha da iyi simüle etmek için fiziksel süreçlere dayalı gölgelendirme.
  • Işık engelleme (Ortam Tıkanması, eğer bir şey ışığı engellerse, karanlık olur)
  • Rengin yansıması (kırmızı halı beyaz tavanın hafif kırmızımsı görünmesine neden olur)
  • Şeffaflık
  • Küresel aydınlatma (prensip olarak yukarıda belirttiğimiz her şeye bu terim denilebilir)

Başka bir deyişle, çok basit bir aydınlatma ve gölgeleme.

Normaller

Son derste normallerle çalıştık ama onlara neden ihtiyaç duyulduğunu pek anlamadık.

Üçgen Normalleri

Bir düzlemin normali, o düzleme dik olan birim vektördür.

Bir üçgenin normali, üçgene dik olan birim vektördür. Normal, bir üçgenin iki tarafının çapraz çarpımı kullanılarak çok basit bir şekilde hesaplanır (hatırlarsanız, iki vektörün çapraz çarpımı bize her ikisine de dik bir vektör verir) ve normalleştirilir: uzunluğu bire ayarlanır.

Normali hesaplamak için kullanılan sözde kod:

üçgen(v1, v2, v3)
taraf1 = v2-v1
taraf2 = v3-v1
üçgen.normal = vectProduct(yan1, yan2).normalize()

Köşe Normal

Bu, hesaplama kolaylığı için tanıtılan normal bir durumdur. Bu, bu köşeyi çevreleyen üçgenlerin normallerinin birleştirilmiş normalidir. Bu çok kullanışlıdır, çünkü köşe gölgelendiricilerinde üçgenlerle değil köşelerle uğraşıyoruz. Her durumda, OpenGL'de neredeyse hiç üçgenlerle uğraşmıyoruz.

köşe v1, v2, v3, ....
üçgen tr1, tr2, tr3 // hepsi v1 köşesini kullanıyor
v1.normal = normalleştir(tr1.normal + tr2.normal + tr3.normal)

OpenGL'de Vertex Normallerini Kullanmak

OpenGL'de normalleri kullanmak çok kolaydır. Normal, tıpkı konum, renk veya UV koordinatları gibi, bir tepe noktasının yalnızca bir özelliğidir... Yani yeni bir şey öğrenmenize gerek yoktur... basit loadOBJ fonksiyonumuz bile zaten normalleri yüklüyor.

GLuint normal tampon;
glGenBuffers(1, &normalbuffer);

glBufferData(GL_ARRAY_BUFFER, normals.size() * sizeof(glm::vec3), &normals, GL_STATIC_DRAW);

// Üçüncü özellik tamponu: normaller
glEnableVertexAttribArray(2);

glBindBuffer(GL_ARRAY_BUFFER, normalbuffer);
glVertexAttribPointer(
2, // bağlanmak
3, // boyut
GL_FLOAT, //tip
GL_FALSE // normalleştirilmiş mi?
0, // adım
(geçersiz*)0 // arabellek ofseti
);

Ve başlamak için bu yeterli:


Yaygın aydınlatma

Yüzey normalinin önemi

Bir ışık demeti bir yüzeye çarptığında büyük bir kısmı her yöne yansır. Buna "yaygın bileşen" denir. Geri kalan bileşenlere biraz sonra bakacağız.

Işın düştükten sonra yüzey, ışının yüzeye çarptığı açıya bağlı olarak ışığı farklı şekilde yansıtır. Işın yüzeye dik düşerse küçük bir alanda yoğunlaşır, teğetsel ise çok daha büyük bir yüzeye dağılır:


Bilgisayar grafikleri açısından bakıldığında, bir pikselin rengi büyük ölçüde ışık yönü açıları ile yüzey normali arasındaki farka bağlıdır.


//
//
float cosTheta = nokta(n,l);

Bu kodda "n" normaldir ve "l" yüzeyden ışık kaynağına giden birim vektördür (bu durum kafa karıştırıcı görünse de tam tersi değildir)

İşarete dikkat edin

Bazen formülümüz işe yaramayabilir. Örneğin ışık üçgenin arkasında olduğunda n ve l zıt olacak, dolayısıyla n.l negatif olacaktır. Ve sonuç olarak, bir tür negatif renge ve sonuç olarak bir tür saçmalığa sahip olacağız. Bu nedenle kelepçe fonksiyonunu kullanarak tüm negatif sayıları 0'a indireceğiz.

// Normal ile ışığın yönü arasındaki açının kosinüsü
// 1 - ışık üçgene dik ise
// 0 - ışık üçgene paralelse
// 0 — ışık üçgenin arkasındaysa
float cosTheta = kelepçe(nokta(n,l), 0,1);
renk = AçıkRenk * cosTheta;

Malzeme rengi

Tabii ki, öğenin rengi büyük ölçüde malzemenin rengine bağlı olmalıdır. Beyaz ışık üç bileşenden oluşur: kırmızı, mavi ve yeşil. Işık kırmızı bir yüzeye çarptığında yeşil ve mavi bileşenler emilir ve kırmızı bileşen yansıtılır.



Bunu basit çarpma işlemiyle modelleyebiliriz:

renk = MalzemeDiffuseColor * LightColor * cosTheta;

Işık modelleme

Mum gibi her yöne ışık yayan bir nokta ışık kaynağımız olduğunu varsayalım.

Böyle bir ışık kaynağıyla yüzey aydınlatma düzeyi, ışık kaynağına olan mesafeye bağlı olacaktır: ne kadar uzak olursa o kadar karanlık olur. Bu bağımlılık şu şekilde hesaplanır:

renk = MalzemeDiffuseColor * LightColor * cosTheta / (mesafe*mesafe);

Yakında ışık yoğunluğu seviyesini kontrol etmek için başka bir parametreye ihtiyacımız olacak - ışığın rengi, ancak şimdilik belirli bir güce sahip (örneğin 60 watt) beyaz bir ampulümüz olduğunu varsayalım.

renk = MaterialDiffuseColor * LightColor * LightPower * cosTheta / (mesafe*mesafe);

Hepsini bir araya koy

Bu kodun çalışması için belirli bir dizi parametreye (renk ve güç) ve biraz ek koda ihtiyacımız var.

MaterialDiffuseColor - doğrudan dokudan alabiliriz.

LightColor ve LightPower'ın gölgelendiricide GLSL üniforması kullanılarak ayarlanması gerekecektir.

CosTheta n ve l vektörlerine bağlı olacaktır. Herhangi bir alan için hesaplanabilir, açı aynı olacaktır. Işık kaynağının konumunu hesaplamak çok kolay olduğundan kamera alanını kullanacağız:

// Kamera alanında normal parça
vec3 n = normalize(Normal_cameraspace);
// Işık yönü (parçadan ışık kaynağına)
vec3 l = normalize(LightDirection_cameraspace);

Normal_cameraspace ve LightDirection_cameraspace köşe gölgelendiricide sayılır ve daha sonraki işlemler için parça gölgelendiriciye aktarılır:

// Tepe noktasının kamera uzayındaki konumu: MVP * konumu
gl_Pozisyon = MVP * vec4(vertexPosition_modelspace,1);
// Tepe noktasının dünya uzayındaki konumu: M * konum
Position_worldspace = (M * vec4(vertexPosition_modelspace,1)).xyz;
// Köşeden gelen vektörkamera alanındaki kamera
// Kamera uzayında kamera (0,0,0) konumunda bulunuyor
vek 3 köşe konumu _ kamera alanı = ( V * M * vek 4( köşe konumu _ model alanı ,1)). xyz ;
EyeDirection_cameraspace = vec3(0,0,0) - vertexPosition_cameraspace;
// Kamera uzayında tepe noktasından ışık kaynağına giden vektör.
//Matris M bu alanda tek olduğu için atlandı.
vec3 LightPosition_cameraspace = (V * vec4(LightPosition_worldspace,1)).xyz;
LightDirection_cameraspace = LightPosition_cameraspace +
EyeDirection_cameraspace;
// Normal zirveler V uzay kameralar
Normal_kamera alanı = (V * M * vec4(vertexNormal_modelspace,0)).xyz; // İrade sadece V hacim dava , Ne zaman matris modeller Olumsuz Hileler o boyut .

İlk bakışta kod oldukça karmaşık ve kafa karıştırıcı görünebilir, ancak aslında burada 3. derste olmayan yeni hiçbir şey yoktur: Matrisler. Burada neyin, nasıl olduğunu anlamanız kolay olsun diye her değişkene anlamlı isimler vermeye çalıştım.

Mutlaka deneyin!!!

M ve V, gölgelendiriciye eski güzel MVP'mizle aynı şekilde aktarılan Model ve Görünüm matrisleridir.

Test zamanı

Dağınık aydınlatma oluşturmak için yapmanız gereken her şeyi size anlattım. Devam edin, deneyin.

Sonuç

Sadece tek bir dağınık bileşenle şunun gibi bir resim elde ediyoruz (çirkin dokular için beni bağışlayın).



Eskisinden daha iyi gibi görünüyor ama hala çok şey eksik. Sorun özellikle aydınlatılmamış parçalarda fark edilir. Sevgili maymunumuz Suzanne'ın kafasının arkası tamamen siyahtır (biz kelepçe kullandık()).

Ortam ışıklandırması

Ortam aydınlatması tamamen hiledir.

Suzanne'in kafasının arkası tamamen siyah olmamalıdır, çünkü gerçek hayatta lambadan gelen ışığın duvara, zemine, tavana düşmesi, kısmen yansıtılması ve nesnenin gölge kısmını aydınlatması gerekir.

Ancak bu, gerçek zamanlı olarak gerçekleştirilemeyecek kadar hesaplama açısından pahalıdır. İşte bu yüzden bazı sabit bileşenler ekleyeceğiz. Sanki nesnenin kendisi tamamen siyah olmamak için biraz ışık yayıyormuş gibi.

vec3 MaterialAmbientColor = vec3(0,1,0,1,0,1) * MaterialDiffuseColor;
renk =
// Ortam aydınlatma : numara yapmak dolaylı aydınlatma
MalzemeOrtamRenk +
// Yaygın : " renk " nesnenin kendisi
MalzemeDiffuseColor * LightColor * LightPower * cosTheta /
(mesafe*mesafe);

Sonuç

Bu şekilde biraz daha iyi olacaktır. Daha iyi bir sonuç elde etmek için oranlarla (0,1, 0,1, 0,1) oynayabilirsiniz.



Speküler ışık

Işığın yansıtılan kısmı esas olarak yüzeye doğru yansıyan ışına doğru yansıtılır.



Şekilde görüldüğü gibi yansıyan ışık bir ışık noktası oluşturur. Bazı durumlarda, dağınık bileşen sıfır olduğunda, bu ışık noktası çok çok dar olur (ışık tamamen tek yönde yansıtılır) ve bir ayna elde ederiz.

(ancak, bir ayna elde etmek için parametreleri değiştirebilseniz de, bizim durumumuzda bu yalnızca ışık kaynağımızın yansımasını hesaba katacaktır. Yani tuhaf bir ayna olacaktır)


// vektöre bak (kameraya doğru)
vec3 E = normalleştir(EyeDirection_cameraspace);
//Üçgenin ışığı yansıttığı yön
vek 3 R = yansıtmak (- ben , N );
// Bakış vektörü ile yansıma vektörü arasındaki açının kosinüsü gerekirse çiz
// - Doğrudan yansımaya bakın -> 1
// -Diğer yöne bakın ->< 1
float cosAlpha = kelepçe(nokta(E,R), 0,1);
renk =
// Ortam Aydınlatması: Dolaylı Aydınlatmayı Simüle Edin
MalzemeOrtamRenk +
// Yaygın : " renk " nesnenin kendisi
MalzemeDiffuseColor * LightColor * LightPower * cosTheta /
(mesafe*mesafe) ;
// Yansıyan: ayna gibi yansıyan yansımalar
MaterialSpecularColor * LightColor * LightPower * pow(cosAlpha,5) /

Bir sonraki derste VBO'muzun oluşturulmasını nasıl hızlandırabileceğimize bakacağız.

Bölüm 1. Hazırlık

Aydınlatmayı incelemek için ihtiyacınız olan:

  • OpenGL;
  • fazlalık;
  • IDE kullanabilirsiniz ancak gedit veya Kod Blokları;
  • derleyici, örneğin, gcc Linux için ve mingw pencereler için;
Bölüm 2. Basit bir program örneği

Aydınlatmayı kullanan örnek bir programa bakalım.

Kod:

/*http://site, isaer*/ #include #katmak #katmak void init() ( glClearColor(0.3, 0.3, 0.3, 1.0); glEnable(GL_LIGHTING); glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE); glEnable(GL_NORMALIZE); ) void reshape(int genişlik, int yükseklik) ( glViewport(0, 0, genişlik, yükseklik); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(-1.2, 1.2, -1.2, 1.2, -1, 1); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); ) void init_l() ( float light0_diffuse = (0,4, 0,7, 0,2); float light0_direction = (0,0, 0,0, 1,0, 0,0); glEnable(GL_LIGHT0); glLightfv(GL_LIGHT0, GL_DIFFUSE, light0_diffuse); glLightfv(GL_LIGHT0, GL_POSITION, light0_direction); ) void display() ( glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); init_l(); GLfloat x, y; glBegin(GL_QUADS); glNormal3f(0,0, 0,0, -1,0); for (x = -1,0; x< 1.0; x += 0.005) { for (y = -1.0; y < 1.0; y += 0.005) { glVertex3f(x, y, 0.0); glVertex3f(x, y + 0.005, 0.0); glVertex3f(x + 0.005, y + 0.005, 0.0); glVertex3f(x + 0.005, y, 0.0); } } glEnd(); glDisable(GL_LIGHT0); glutSwapBuffers(); } int main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); glutInitWindowPosition(50, 100); glutInitWindowSize(500, 500); glutCreateWindow("Light"); init(); glutDisplayFunc(display); glutReshapeFunc(reshape); glutMainLoop(); }

Bölüm 3. Örnekteki kodun ayrıştırılması

Yorumlar sembol aracılığıyla verilir // - "yırtmaç".

Kod:


Aydınlatmanın başlatıldığı yer burasıdır

Kod:


Tüm çizimin gerçekleştiği yer burasıdır.

Kod:


Bölüm 4. Aydınlatmanın incelenmesi

Öncelikle aydınlatma hesaplamasını şu komutla açalım. glEtkinleştir(GL_LIGHTING). Daha sonra ışık kaynağının kilidini şu komutla açmanız gerekir: glEtkinleştir(GL_LIGHT). GL_LIGHT yalnızca 8 değer alabilir (en azından OpenGL 2.1'de), yani. GL_LIGHT0..GL_LIGHT7.

Şimdi bir ışık kaynağı oluşturmamız gerekiyor. Her ışık kaynağının kendi varsayılan parametreleri vardır; örneğin, 2 ışık kaynağı GL_LIGHT0 ve GL_LIGHT1'in kilidini açarsanız, varsayılan parametreleri diğerlerinden farklı olduğundan yalnızca 0 görünür olacaktır (bunlar diğerleri için aynıdır).

Işık kaynaklarının çeşitli parametreleri vardır: renk, konum ve yön.

Tüm ışık parametrelerini belirtmek için kullanılan komut: glIşık*(). Üç bağımsız değişken alır: ışık kaynağı tanımlayıcısı, özellik adı ve bunun için istenen değer.

Kod:


Değilse, o zaman tek anlamı budur.

Örneğin:

Kod:

/*http://site, isaer*/ glLightf(GL_LIGHT0, GL_GL_SPOT_CUTOFF, 180);

İşte değerlerin bir listesi Glenum adı.

Şöyle okunur: İlk satır parametrenin adıdır, ikincisi varsayılan değerdir ve üçüncüsü bir açıklamadır. (1.0,1.0,1.0,1.0) veya (0.0,0.0,0.0,1.0) gibi bir şey görürseniz, bu, ilk braketin boş kaynak için varsayılan olduğu ve ikinci braketin geri kalanı için varsayılan olduğu anlamına gelir:

Kod:


Aydınlatma kullanımına örnek:

Kod:

/*http://site, isaer*/ float light_ambient = (0.0,0.0,0.0,1.0); float light_diffuse = (1.0,1.0,1.0,1.0); float light_specular = (1.0,1.0,1.0,1.0); float light_position = (1.0,1.0,1.0,0.0); glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient); glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse); glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular); glLightfv(GL_LIGHT0, GL_POSITION, light_position);

Bölüm 5. Işık parametrelerinin incelenmesi

1. Renk

Yaygın

GL_DIFFUSE parametresi muhtemelen "açık renk" olarak adlandırdığınız şeye en yakın olanıdır. Bireysel bir ışık kaynağının sahneye eklediği dağınık ışığın RGBA rengini tanımlar.

Ortam

GL_AMBIENT parametresi nesne üzerindeki aynasal vurgunun rengini etkiler. Gerçek dünyada, cam şişe gibi nesneler, ışığın rengiyle (genellikle beyaz) eşleşen aynasal bir vurguya sahiptir.

Aynasal

GL_SPECULAR parametresi nesneler üzerindeki aynasal vurguların yoğunluğunu etkiler.

2. Pozisyon

Parametre GL_POSITION(x, y, z, w) 3 adet konum değeri ve biri hangi ışık kaynağının kullanılacağını belirten değere sahiptir.

İlk 3 (x, y, z) parametre açıklayıcı olup, 4. (w) parametresi sonsuz ışık mı yoksa nokta ışık mı kullanılacağını belirtir. Eğer değer w = 0 o zaman ışık kaynağı sonsuz derecede uzaktadır (güneş gibi bir şey). Eğer w = 1, o zaman bu ışık kaynağı bir noktadır (ampul gibi bir şey).

Eğer w = 0, bu durumda ilk 3 parametre koordinat sisteminin merkezinden (0,0,0) bir vektördür.

3. Gündem

GL_SPOT_DIRECTION- spot ışığının yönü.

GL_SPOT_EXPONENT- ışık ışınının konsantrasyonu.

GL_SPOT_CUTOFF- ışık ışınının açısal genişliği.

Açıklığa kavuşturulması gereken tek şey, pozisyonun şu şekilde olması gerektiğidir: w = 1.

4. Zayıflama

Işık yoğunluğunu merkezden zayıflatmanız gerekiyorsa (yani merkezden uzaklaştıkça dimmer), parametreleri ayarlamanız gerekir: GL_CONSTANT_ATTENUATION, GL_LINEAR_ATTENUATION, GL_QUADRATIC_ATTENUATION.

Ancak bu pek uygun olmadığından şu formülü kullanabilirsiniz:

Kod:


Yarıçap merkezden uca doğru ayarlanır.

Genel yoğunluğu azaltmanız gerekiyorsa parametreyi değiştirebilirsiniz. atıf.

Bölüm 6. Aydınlatma modelinin seçilmesi

Bir aydınlatma modelinin OpenGL konsepti 4 bileşene ayrılmıştır:

  • küresel arka plan ışığı yoğunluğu;
  • gözlem noktasının konumunun olay yerine yerel olarak mı yoksa sonsuz derecede uzak olarak mı değerlendirildiği;
  • nesnelerin ön ve arka yüzleri için aydınlatma farklı mı hesaplanmalıdır;
  • Tekstüre işlemlerinden sonra aynasal rengin arka plandan ayrılıp dağılması ve nesneye uygulanması gerekip gerekmediği.
glLightModel*() aydınlatma modelinin tüm parametrelerini ayarlamak için kullanılan bir komuttur. İki argüman alabilir: Aydınlatma modeli parametresinin sabit olarak adı ve bu parametrenin değeri.

Kod:


Artık harika ışık kaynakları oluşturabilirsiniz.

OpenGL ES'de aydınlatma, 3D oyunlara hoş bir dokunuş katabilecek kullanışlı bir özelliktir. Bu gibi işlevleri kullanabilmek için öncelikle OpenGL ES aydınlatma modelini anlamamız gerekiyor.

Aydınlatma nasıl çalışır?

Aydınlatmanın nasıl çalıştığını düşünelim. Öncelikle ışık yayan bir ışık kaynağına ihtiyacımız var. Ayrıca aydınlatılmış bir nesneye de ihtiyacınız olacak. Son olarak ışık kaynağından gönderilen ve nesneden yansıyan fotonları alan göz veya kamera gibi bir sensöre de ihtiyacımız var. Aydınlatma, bir nesnenin algılanan rengini aşağıdakilere bağlı olarak değiştirir: ışık kaynağının türü; ışık kaynağının rengi veya yoğunluğu; ışık kaynağının konumu ve aydınlatılan nesneye göre yönü; Nesne malzemesi ve dokusu.

Işığın bir nesne tarafından yansıtılma yoğunluğu birçok faktöre bağlıdır. Baktığımız en önemli faktör ışık ışınının yüzeye çarpma açısıdır. Bu açı dik açıya ne kadar yakınsa ışığın nesneden yansıyacağı yoğunluk da o kadar büyük olur. Bu, Şekil 2'de gösterilmektedir. 11.1.

Bir ışık demeti bir yüzeye çarptığında iki farklı yönde yansır. Işığın büyük bir kısmı dağınık olarak yansıtılacaktır. Bu, yansıyan ışık ışınlarının nesnenin yüzeyi boyunca eşit olmayan ve rastgele dağıldığı anlamına gelir. Bazı ışınlar aynasal olarak yansıtılır. Bu, ışık ışınlarının sanki mükemmel bir aynaya çarpıyormuşçasına geri yansıyacağı anlamına gelir. İncirde. Şekil 11.2 dağınık ve aynasal yansımalar arasındaki farkı göstermektedir.

Pirinç. 11.1. Açı dik açıya ne kadar yakınsa yansıyan ışığın yoğunluğu o kadar büyük olur

Pirinç. 11.2. Dağınık ve aynasal yansımalar

Aynasal yansımalar nesneler üzerinde vurgular olarak görünecektir. Işığın bir nesneden aynasal olarak yansıyıp yansımayacağı, yapıldığı malzemeye bağlıdır. Deri gibi düzgün olmayan veya pürüzlü bir yüzeye sahip nesnelerde büyük olasılıkla aynasal vurgular olmayacaktır. Cam veya mermer gibi pürüzsüz bir yüzeye sahip nesneler bu ışık eserlerini sergileyecektir. Elbette cam veya mermer tamamen pürüzsüz değildir, ancak ahşap veya insan derisiyle karşılaştırıldığında öyledir.

Işık bir yüzeye çarptığında yansıması da aydınlatılan nesnenin kimyasal bileşimine bağlı olarak renk değiştirir. Bize kırmızı görünen nesneler ışığın yalnızca kırmızı kısımlarını yansıtır ve diğer tüm frekansları emer. Siyah bir nesne, üzerine düşen ışığın neredeyse tamamını emen bir nesnedir.

OpenGL ES, ışık kaynaklarını ve nesne malzemelerini tanımlayarak gerçek dünyadaki davranışı simüle etmenize olanak tanır.

Işık kaynakları

Etrafımız birçok farklı ışık kaynağıyla çevrilidir. Güneş sürekli olarak fotonlarını göndermektedir. Monitörler geceleri hoş bir ışıltıyla etrafımızı saran ışık yayar. Ampuller ve farlar karanlıkta çeşitli nesnelerle çarpışmayı önlememize yardımcı olur. OpenGL ES dört tür ışık kaynağı oluşturmanıza olanak tanır.

Arka ışık. Kendi başına bir ışık kaynağı değil, diğer ışık kaynaklarından gelen fotonların ortaya çıkmasının sonucudur. Bu rastgele fotonlar hep birlikte, yönü olmayan ve tüm nesneleri eşit şekilde aydınlatan sabit bir aydınlatma düzeyi oluşturur.

Noktasal ışık kaynakları. Uzayda bir konumları vardır ve her yöne ışık yayarlar. Örneğin noktasal ışık kaynağı bir ampuldür.

Yönlendirilmiş aydınlatma kaynakları. OpenGL ES'de yön olarak ifade edilir. Sonsuz uzakta oldukları varsayılır. İdeal durumda Güneş böyle bir kaynak olabilir. Dünya ile Güneş arasındaki mesafe nedeniyle, Güneş'ten gelen tüm ışık ışınlarının Dünya'ya aynı açıyla çarptığını varsayabiliriz.

Lambalar Hakkında. Bu ışıklar, uzayda belirli bir konuma sahip olmaları bakımından nokta ışıklara benzer. Ayrıca ışık ışınlarını yaydıkları bir yönleri vardır. Belirli bir yarıçapla sınırlı bir ışık konisi oluştururlar. Böyle bir ışık kaynağına örnek olarak sokak lambası verilebilir.

Yalnızca arka aydınlatmanın yanı sıra noktasal ve yönlü ışık kaynaklarını da dikkate alacağız. OpenGL ES'in aydınlatmayı hesaplama şekli nedeniyle, GPU sınırlı Android cihazlarda ışıkların kullanılması genellikle zordur. Bunun neden böyle olduğunu yakında anlayacaksınız.

OpenGL ES, ışık kaynağının konumu ve yönünün yanı sıra ışığın rengini veya yoğunluğunu da belirlemenize olanak tanır. Bu özellikler RGBA rengi kullanılarak ifade edilir. Ancak OpenGL ES, kaynak başına yalnızca bir renk yerine dört farklı renk tanımlamanızı gerektirir.

Vurgu - Bir nesnenin gölgelenmesine katkıda bulunan yoğunluk/renk. Nesne, ışık kaynağına göre konumu veya yönü ne olursa olsun her taraftan eşit şekilde aydınlatılacaktır.

Yaygın – dağınık yansıma hesaplandıktan sonra nesneyi aydınlatacak ışığın yoğunluğu/rengi. Nesnenin ışık kaynağına bakmayan kenarları tıpkı gerçek hayatta olduğu gibi aydınlatılmayacaktır.

Aynasal – dağınık renge benzer yoğunluk/renk. Ancak nesnenin yalnızca ışık kaynağına ve sensöre göre belirli bir yönelime sahip olan noktalarını etkiler.

Emissive, gerçek dünyadaki fizik uygulamalarında son derece sınırlı kullanıma sahip, çok karmaşık bir renk hesaplamasıdır, bu nedenle bu konuya değinmeyeceğiz.

Çoğunlukla ışık kaynağının dağınık ve aynasal yoğunluklarını kullanacağız ve diğer iki varsayılan değeri vereceğiz. Ayrıca çoğu zaman hem dağınık hem de aynasal yoğunluk için aynı RGBA rengini kullanacağız.

Malzemeler

Dünyamızdaki tüm nesneler bir çeşit malzemeden oluşur. Her malzeme, bir cismin üzerine düşen ışığın nasıl yansıyacağını belirler ve yansıyan ışığın rengini değiştirir. OpenGL ES, bir malzeme için ışık kaynağıyla aynı dört RGBA rengini tanımlamanıza olanak tanır.

Arka ışık, sahnedeki herhangi bir ışık kaynağının arka plan rengiyle birleşen bir renktir.

Yaygın, herhangi bir ışık kaynağının dağınık rengiyle birleşen bir renktir.

Aynasal, herhangi bir ışık kaynağının aynasal rengiyle birleşen bir renktir. Bir nesnenin yüzeyinde vurgular oluşturmak için kullanılır.

Yayıcı - bağlamımızda pratik olarak kullanılmadığı için bu renk türünü görmezden gelmeye devam ediyoruz.

Şekil 11.3'te ilk üç malzeme/ışık kaynağı özelliği türü gösterilmektedir: arka ışık, dağınık ve aynasal.

Pirinç. 11.3. Farklı malzeme/ışık kaynağı türleri: yalnızca arka ışık (sol), yalnızca dağınık (orta), arka ışık ve aynasal vurgularla dağınık renk (sağ)

İncirde. Şekil 11.3, malzemelerin ve ışık kaynaklarının çeşitli özelliklerinin renk üzerindeki etkisini göstermektedir. Arka ışık boyutu eşit şekilde aydınlatır. Saçılan ışık, ışık ışınlarının nesneye çarptığı açıya bağlı olarak yansıtılacaktır; Işık kaynağına doğrudan bakan alanlar daha parlak aydınlatılacak, ışığın ulaşamadığı alanlar ise karanlık olacaktır. Sağdaki görüntüde arka ışık, dağınık ve aynasal ışığın bir kombinasyonunu görebilirsiniz. Aynasal ışık, küre üzerinde beyaz vurgular halinde görünür.

OpenGL ES aydınlatmayı nasıl hesaplar: köşe normalleri

Bir nesneden yansıyan ışığın yoğunluğunun, nesneye geliş açısına bağlı olduğunu biliyorsunuz. OpenGL ES aydınlatmayı hesaplamak için bu gerçeği kullanır. Bunun için kodda doku koordinatları veya köşe renkleriyle aynı şekilde tanımlanması gereken köşe normallerini kullanır. İncirde. Şekil 11.4 bir küreyi ve onun köşe normallerini göstermektedir.

Pirinç. 11.4. Küre ve köşe normalleri

Normaller, bir yüzeyin döndürüldüğü yönü gösteren birim vektörlerdir. Bizim durumumuzda yüzey bir üçgendir. Yüzey normalini tanımlamak yerine köşe normalini tanımlarız. Bu normaller arasındaki fark, köşe normalinin yüzey normaliyle aynı yöne işaret etmeyebilmesidir. Bu, Şekil 2'de açıkça görülmektedir. Şekil 11.4'te her köşe normali, tepe noktasının ait olduğu tüm üçgenlerin ortalama normalidir. Bu ortalama, nesnenin düzgün gölgelenmesini sağlamak için gerçekleştirilir.

Bir nesneyi aydınlatma ve köşe normalleri kullanarak işlerken OpenGL ES, her köşe ile ışık kaynağı arasındaki açıyı belirleyecektir. Bu açıyı biliyorsa malzemenin özelliklerine göre köşenin rengini hesaplayabilir. Nihai sonuç, her bir köşenin rengidir ve bu daha sonra diğer köşelerin hesaplanan renkleriyle birlikte her üçgene uygulanır. Kullanılan bu renk, nesneye uyguladığımız herhangi bir doku dönüşümüyle birleştirilecektir.

Bu kulağa oldukça korkutucu geliyor ama aslında o kadar da kötü değil. Aydınlatmayı etkinleştirmemiz ve ışık kaynaklarını, oluşturulabilir malzemeyi ve köşe normallerini (konum veya doku koordinatları gibi normalde tanımladığımız köşe parametrelerine ek olarak) tanımlamamız gerekir. Bunun OpenGL ES kullanılarak nasıl uygulanabileceğine bakalım.

Pratikte

Şimdi OpenGL ES kullanarak aydınlatmayla çalışmak için gerekli tüm adımları gerçekleştirelim. Işık kaynaklarıyla çalışmayı biraz daha kolaylaştıracak birkaç küçük yardımcı sınıf oluşturalım ve bunları.androi dgames.framework.gl ile com.badlogi paketine yerleştirelim.

Aydınlatmanın izni ve yasaklanması

Diğer OpenGL ES durumlarında olduğu gibi, öncelikle adlandırılmış işlevselliği etkinleştirmeniz gerekir. Bu şöyle yapılabilir:

Bundan sonra işlenen tüm nesnelere ışıklandırma uygulanacaktır. Sonucu elde etmek için ışık kaynakları ve malzemelerinin yanı sıra köşe normallerini de tanımlamanız gerekir. Gerekli tüm nesneleri çizmeyi bitirdikten sonra aydınlatma kapatılabilir:

Işık Kaynaklarının Belirlenmesi

OpenGL ES 4 tür ışık kaynağı sağlar: arka ışık, spot, yönlü ve spot ışık. İlk üçünü nasıl belirleyeceğimize bakalım. Armatürlerin etkili ve güzel görünmesi için her modelin çok sayıda üçgenden oluşması gerekir. Bu, mevcut birçok mobil cihaz için mümkün değildir.

OpenGL ES, tek bir global ışık kaynağının yanı sıra aynı anda maksimum 8 ışık kaynağını tanımlamanıza olanak tanır. 8 ışık kaynağının her birinin GL10.GL LIGHT0'dan GL10.GL LIGHT7'ye kadar bir tanımlayıcısı vardır. Bu ışıklardan birinin özelliklerini değiştirmeniz gerekiyorsa bunu ilgili ID'yi tanımlayarak yapabilirsiniz.

Aşağıdaki sözdizimini kullanarak ışıkların kullanımını etkinleştirebilirsiniz:

Daha sonra OpenGL ES bu ışık kaynağının özelliklerini alacak ve bunları oluşturulan tüm nesnelere uygulayacaktır. Bir ışık kaynağının kullanımını devre dışı bırakmamız gerekiyorsa bunu aşağıdaki ifadeyle yapabiliriz:

Vurgu, kimliği olmadığı için özel bir durumdur. OpenGL ES sahnesinde yalnızca bir vurgu mevcut olabilir. Gelin bu ışık kaynağına daha yakından bakalım.

Arka ışık

Arka aydınlatma özel bir aydınlatma türüdür. Herhangi bir konumu veya yönü yoktur; yalnızca tüm ışıklı nesnelere eşit şekilde uygulanan bir renk vardır. OpenGL ES, genel vurgulamayı aşağıdaki gibi tanımlamanıza olanak tanır:

Ambi entCol veya dizisi, 0 ile 1 arasında değişen kayan nokta sayıları olarak temsil edilen, arka ışık renginin RGBA değerlerini içerir. gl LightModel fv yöntemi, ilk parametresi olarak, arka plan ışığının rengini ayarlamak istediğimizi belirten bir sabiti alır. source, kaynak rengini içeren bir kayan nokta sayıları dizisi ve yöntemin RGBA değerlerini okumaya başlayacağı kayan nokta dizisinin uzaklığını içerir. Bu sorunu çözen kodu küçük bir sınıfa koyalım. Kodu Liste 11.2'de gösterilmektedir.

Listeleme 11.2. AmbientLight.java sınıfı. basit küresel aydınlatma soyutlaması ODenGL ES

Yaptığımız tek şey, vurgu rengini bir kayan dizide depolamak ve iki yöntem sunmaktır: biri rengi ayarlamak için kullanılır, diğeri ise OpenGL ES'e bu rengi kullanmasını söylemek için kullanılır. Varsayılan renk gridir.

Nokta aydınlatma kaynakları

Noktasal ışıkların konumu, arka planı, dağınık ve aynasal rengi/yoğunluğu vardır (yayıcı rengi/yoğunluğu dikkate almayız). Farklı çiçek türleri şu şekilde tanımlanabilir:

İlk parametre ışık kaynağı tanımlayıcısıdır. Bu durumda dördüncü kaynağı kullanıyoruz. Bir sonraki parametre değiştirmek istediğimiz özelliği belirtir. Üçüncü parametre, RGBA değerlerini içeren bir kayan nokta sayıları dizisidir ve sonuncusu, bu dizideki ofsettir. Kaynağın konumunu belirlemek de aynı derecede kolaydır:

Değiştirmek istediğimiz niteliği (bu durumda konum) yeniden tanımlıyoruz; yaratılan dünyadaki ışık kaynağının x-, y- ve z-koordinatını içeren dört öğeli bir dizi. Işık kaynağının bir konumu varsa dizinin dördüncü öğesinin bire eşit olması gerektiğini unutmayın. Bunu bir yardımcı sınıfa koyalım. Kodu Liste 11.3'te yer almaktadır.

Listeleme 11.3. Point.Light.java sınıfı, OpenGL ES nokta ışıklarının basit bir soyutlaması

Yardımcı sınıfımız ışığın arka plan, dağınık ve aynasal renk bileşenlerinin yanı sıra konumunu da içerir (dördüncü öğe birdir). Ek olarak, belirli bir kaynak için kullanılan son tanımlayıcıyı da saklıyoruz, böylece gerekirse ışığı kapatacak bir disableO yöntemi oluşturmak mümkün hale geliyor. Ayrıca GL10 sınıfının bir örneğini ve bir ışık kaynağı tanımlayıcısını (örneğin GL10.GL LIGHT6) alan activeO yöntemine de sahibiz. Aydınlatmanın kullanılmasına izin verir, niteliklerini ayarlar ve kullanılan kimliği saklar. DisableO yöntemi, etkinleştirme yöntemindeki 1ast.Ligh.tId sınıf üyesini kullanarak aydınlatma kullanımını devre dışı bırakır.

Sınıf üyesi dizileri başlatırken arka plan, dağınık ve aynasal renkler için makul varsayılan değerleri kullanırız. Işık beyaz olacak ve aynasal bileşeni siyah olduğundan herhangi bir parlama yaratmayacaktır.

Yönlü ışık kaynakları

Yönlü ışık kaynakları neredeyse nokta olanlarla aynıdır. Tek farkları konum yerine bir yöne sahip olmalarıdır. Yönün ifade edilme şekli biraz kafa karıştırıcıdır. OpenGL ES, bir yönü belirtmek için bir vektör kullanmak yerine tek bir nokta tanımlamamızı bekler. Daha sonra yön, bu noktayı orijine bağlayan bir vektör kullanılarak belirlenecektir. Aşağıdaki kod parçası, dünyanın sağ tarafından gelen yönlü bir ışık kaynağı oluşturmanıza olanak tanır:

Bunu bir vektöre dönüştürebiliriz:

Arka plan veya dağınık renk gibi diğer özellikler noktasal ışığın özellikleriyle aynıdır. Liste 11.4, yönsel ışıklar oluşturmak için kullanılan küçük bir yardımcı sınıfın kodunu göstermektedir.

Listeleme 11.4. Directi onLi sınıfı ght.java, OpenGL ES'deki yönlü ışık kaynaklarının basit bir soyutlaması

Bu yardımcı sınıf PointLight sınıfıyla neredeyse aynıdır. Tek fark, dizi yönündeki dördüncü elemanın bir olmasıdır. Ayrıca setPosition yöntemi yerine setDirecti on yöntemi ortaya çıkmıştır. Yönü tanımlamanıza olanak tanır, örneğin şu şekilde: (-1; 0; 0), bu durumda ışık sağ taraftan gelecektir. Yöntemin içinde vektörün tüm bileşenleri işaretlerini değiştirir, böylece yönü OpenGL ES tarafından beklenen formata dönüştürürüz.

Malzemelerin belirlenmesi

Bir malzeme çeşitli niteliklerle tanımlanır. Diğer herhangi bir OpenGL ES nesnesinde olduğu gibi, malzeme biz onu tekrar değiştirene veya OpenGL ES içeriği kaybolana kadar aktif kalacak bir durumdur. Geçerli malzeme niteliklerini ayarlamak için aşağıdakileri yapabiliriz:

Her zamanki gibi arka plan, dağınık ve aynasal RGBA renklerini tanımlamamız gerekiyor. Bu, dört öğeden oluşan kayan nokta sayıları dizileri kullanılarak öncekiyle aynı şekilde yapılabilir.

Bu eylemleri tek bir yardımcı sınıfta birleştirmek çok basittir. Sonucu Liste 11.5'te görebilirsiniz.

Liste 11.5. Material Java sınıfı, OpenGL ES materyallerinin basit bir soyutlaması

Burada da şaşırtıcı bir şey yok. Malzemeyi tanımlayan üç bileşeni saklıyoruz ve aynı zamanda değerlerini ayarlamak için işlevler ve bunları OpenGL ES'ye aktaran bir etkinleştirme yöntemi sağlıyoruz.

Malzemeler söz konusu olduğunda OpenGL ES'in elinde bir koz daha var. Genellikle glMaterialfvO yöntemi yerine malzeme rengi adı verilen bir şey kullanır. Bu, glMateri al fv yöntemiyle belirlenen arka plan ve dağınık renkler yerine OpenGL ES'nin, malzemenin arka plan ve dağınık renkleri olarak modellerimizin köşelerinin rengini alacağı anlamına gelir. Bu özelliği etkinleştirmek için şunu çağırmanız yeterlidir:

Genellikle bunu yapıyorum çünkü arka plan ve dağınık renkler genellikle aynı. Oyunlarımın ve demolarımın çoğunda aynasal vurgular kullanmadığım için bu yöntemi rahatlıkla kullanabilirim ve glMaterial fv yöntemini hiç çağırmam. Hangi yolu kullanacağınıza karar vermek size kalmış.

Normalleri tanımlama

Işıklandırmanın OpenGL ES'de çalışması için modeldeki her köşe için köşe normallerini tanımlamanız gerekir. Bir tepe noktasının normali, tepe noktasının ait olduğu yüzeyin döndürüldüğü yönü (genellikle) işaret eden bir birim vektör olmalıdır. İncirde. Şekil 11.5 küpümüz için köşe normallerini göstermektedir.

Pirinç. 11.5. Küpümüzün her köşesi için köşe normalleri

Köşe normali, tıpkı konum veya renk gibi, bir köşe noktasının başka bir özelliğidir. Köşe normallerinden yararlanmak için Verti ces3 sınıfını tekrar değiştirmemiz gerekiyor. OpenGL ES'e her köşe için normalleri nerede bulabileceğini söylemek için, tıpkı daha önce gl VertexPointer veya gl Col veya Pointer yöntemlerini kullandığımız gibi, gl Normal PointerO yöntemini kullanacağız. Liste 11.6 Vertices3 sınıfının son versiyonunu göstermektedir.

Listeleme 11.6. Vertices3.Java sınıfı, normalleri destekleyen son sürüm

Sınıfın, köşelerin normalleri olup olmadığını izleyen hasNormal.s adlı yeni bir üyesi var.

Yapıcı artık hasNormals parametresini de kabul ediyor. Mümkün olduğunda her köşeye üç kayan nokta ekleyerek vertexSize üyesinin hesaplamasını değiştirmemiz gerekiyor.

Gördüğünüz gibi setVertices ve setlndices yöntemleri değişmeden kalıyor.

Az önce gösterdiğimiz binO metodunda ByteBuffer ile aynı teknikleri kullanıyoruz ama bu sefer gl Normal Pointer metodunu kullanarak normalleri ekliyoruz. Normal işaretçinin uzaklığını hesaplamak için doku ve renk koordinatlarının belirtilip belirtilmediğini dikkate almak gerekir.

Gördüğünüz gibi çizim yöntemi de değişmedi; tüm eylem O bağlama yönteminde gerçekleşir.

Son olarak unbindO yöntemini biraz değiştiriyoruz. Varsa normal işaretçilerin kullanımını devre dışı bırakarak OpenGL ES durumunu uygun şekilde temizliyoruz.

Değiştirilen Verti ces3 sınıfını uygulamak eskisi kadar kolaydır. Küçük bir örneğe bakalım:

Her biri bir konuma (her satırdaki ilk üç sayı) ve bir normale (her satırdaki son üç sayı) sahip olan üç köşeyi depolamak için bir kayan nokta dizisi oluştururuz. Bu durumda, xy düzleminde normalleri z ekseninin pozitif kısmının yönünü gösteren bir üçgen tanımlarız.

Tek yapmamız gereken Vertices3 sınıfının bir örneğini oluşturup köşelerin değerlerini ayarlamak. Oldukça kolay, değil mi?

Tüm bağlama, çizim ve ayırma işlemleri, sınıfın önceki sürümündekiyle tamamen aynı şekilde yapılır. Daha önce olduğu gibi köşe renkleri ve doku koordinatlarını ekleyebiliriz.

Hepsini bir araya koy

Hepsini bir araya getirelim. Küresel aydınlatmaya sahip, noktasal ve yönlü ışık kaynaklarına sahip bir sahne çizmemiz gerekiyor. Başlangıç ​​noktasında bulunan küpü aydınlatacaklar. Ayrıca gl uLookAt yöntemini de çağırmamız gerekiyor. kamerayı konumlandırmak için. İncirde. Şekil 11.6 dünyamızın görünümünü göstermektedir.

Diğer tüm örneklerde olduğu gibi, her zamanki gibi GLGame sınıfını genişleten LightTest adında bir sınıf oluşturalım. getStartScreenO yöntemini kullanarak LightScreen sınıfının bir örneğini döndürür. LightScreen sınıfı, GLScreen sınıfından miras alır (Liste 11.7).

Pirinç. 11.6. İlk ışıklı sahnemiz

Listeleme 11.7. LightTest.java sınıfının parçaları. OpenGL ES kullanarak aydınlatma oluşturma

Sınıfın birkaç üyesini tanımlayarak başlayalım. Açı elemanı, küpün y ekseni etrafındaki mevcut dönme açısı hakkındaki bilgileri depolar. Verti ces3 üyesi birazdan tanımlayacağımız küp modelinin köşelerini saklıyor. Ayrıca AmbientLight, PointLight ve Directional Light sınıflarının örneklerinin yanı sıra Material sınıfının bir örneğine de sahibiz.

Daha sonra yapıcı gelir. Burada küp modelinin köşeleri oluşturulur ve kutunun dokusu yüklenir. Ayrıca ışıkları ve malzemeleri de başlatıyoruz. Arka ışık rengi açık yeşildir. Yönlendirilen kaynak kırmızıdır ve dünyamızın (3; 3; 0) noktasında bulunmaktadır. Yönlü ışık kaynağı mavi dağınık bir renge sahiptir, ışık soldan düşer. Malzeme için varsayılan değerleri kullanıyoruz (bir miktar arka plan, dağınık bileşen için beyaz ve aynasal bileşen için siyah).

Devam etme yönteminde, bağlamın kaybolması durumunda dokumuzun (yeniden) yüklendiğinden emin oluruz.

createCube yöntemi esas olarak önceki örneklere göre değişmemiştir. Ancak bu sefer Şekil 2'de gösterildiği gibi her köşeye normaller ekliyoruz. 11.5. Bunun dışında her şey aynı kalıyor.

Güncelleme yönteminde basitçe küpün dönüş açısını arttırıyoruz.

İşte burası daha da ilginçleşiyor. İlk birkaç satır, renk ve derinlik arabelleğini temizlemek, derinlik testini etkinleştirmek ve kapsamı ayarlamak için standart koddur.

Daha sonra, gl uPerspective yöntemini kullanarak projeksiyon matrisini perspektif projeksiyon matrisine eşitliyoruz ve ayrıca model görünümü matrisi için gl uLookAt yöntemini kullanıyoruz, bu sayede kamera Şekil 1'deki gibi çalışıyor. 11.6.

Daha sonra aydınlatma kullanımına izin veriyoruz. Bu noktada henüz hiçbir ışık tanımlanmadığından sonraki birkaç satırda ışıklar ve malzemeler üzerine yöntemi çağırarak bunları tanımlayacağız.

Her zamanki gibi dokulandırmayı da etkinleştiriyoruz ve kutu dokusunu bağlıyoruz. Son olarak, küpü döndürmek için gl RotatefC) yöntemini çağırıyoruz ve ardından Verti ces3 sınıfının bir örneğine iyi yerleştirilmiş çağrılar kullanarak köşelerini çiziyoruz.

Yöntemin sonunda spot ve yönlü ışıkları (arkadan aydınlatmanın küresel bir durum olduğunu unutmayın) yanı sıra dokulandırma ve derinlik testini de devre dışı bırakıyoruz. OpenGL ES'deki aydınlatma bu kadar.

Sınıfın geri kalanı boş; duraklama durumunda herhangi bir işlem yapmamıza gerek yoktur. İncirde. Şekil 11.7 programın sonucunu göstermektedir.

Pirinç. 11.7. Şekil 2'de gösterilen sahne. 11.6, OpenGL ES ile oluşturuldu

OpenGL ES'de aydınlatma hakkında birkaç not

Işıklandırmayı kullanmak oyununuza lezzet katsa da sınırlamaları ve tuzakları vardır. Bilmeniz gereken birkaç şey var.

Aydınlatmanın kullanılması çok fazla kaynak tüketir, özellikle yavaş cihazlarda fark edilir. Aydınlatmayı dikkatli kullanın. Ne kadar çok ışık kaynağı tanımlarsanız, sahneyi oluşturmak için o kadar çok hesaplama gerekecektir.

Noktasal/yönlü ışık kaynaklarının konumu/yönleri, kamera matrisleri yüklendikten sonra ve model-görüntü matrisi nesneleri hareket ettirmek ve döndürmek için diğer matrislerle çarpılmadan önce belirlenmelidir. Bu çok kritik. Bu talimatlara uyulmadığı takdirde açıklanamayan ışık oluşumları meydana gelebilir.

Modeli yeniden boyutlandırmak için gl Seal ef yöntemini kullandığınızda normalleri de ölçeklenecektir. Bu kötüdür çünkü OpenGL ES normallerin verilen birimlerde parametrelere sahip olmasını bekler. Bu soruna geçici bir çözüm bulmak için glEnable(GL10.GL NORMALIZE) komutunu veya bazı durumlarda gl Enable(GL10 .GL RESCALE N0RMAL) komutunu kullanabilirsiniz. İkinci komutun kullanımının sınırlamaları ve tuzakları olduğundan ilk komutun kullanılması gerektiğine inanıyorum. Sorun, normalleştirmenin veya normalleri yeniden ölçeklendirmenin çok fazla işlem gücü gerektirmesidir. Performans açısından en iyi çözüm aydınlatılmış nesneleri ölçeklendirmemektir.

Gördüğünüz gibi ek bir normal matris ekledik, nesnenin normallerini nesnenin yerel koordinat sisteminden dünya koordinat sistemine aktarmak için gereklidir, dünya koordinat sisteminde aydınlatmayı hesaplamak için bu gereklidir.

FFP OpenGL kullanırken aydınlatmanın dünya koordinat sisteminde değil, görünüm koordinat sisteminde hesaplandığını belirtmekte fayda var. Bana göre bu pek uygun değil çünkü... Görünüm koordinat sistemi kameraya bağlanır ve aydınlatma kaynaklarının dünya koordinat sistemine ayarlanması uygundur ve hesaplamanın tamamı burada yapılır.

Aydınlatma hesaplaması

Bu eğitimdeki aydınlatma hesaplamaları Phong gölgeleme modelini kullanır. Modelin ana fikri, bir nesnenin son aydınlatmasının üç bileşenden oluşmasıdır:

  • Arka plan ışığı (ortam)
  • Dağınık ışık (yaygın)
  • Speküler ışık

Bu parametrelere ek olarak, malzemenin kendi parıltısını (emisyon) ekleyeceğiz, bu parametre, herhangi bir ışık kaynağı tarafından aydınlatılmasa bile bir nesneyi vurgulamanıza olanak tanır.

Buna göre bileşenlerin her biri, ışık kaynağının parametreleri ve nesnenin malzemesi dikkate alınarak hesaplanır. Bu aydınlatma modeli hakkında daha detaylı bilgiye bu yazımızdan ulaşabilirsiniz.

Aydınlatma hesaplamaları köşe başına aydınlatma veya piksel başına aydınlatma olabilir. Bu dersimizde piksel piksel aydınlatmaya bakacağız; bu, çokgen modellerin yetersiz ayrıntılarını düzeltmenize ve nesnenin her noktasındaki aydınlatmayı daha doğru hesaplamanıza olanak tanır. Piksel başına aydınlatmanın ana hesaplaması parça gölgelendiricide gerçekleşir.

Aydınlatmayı hesaplamaya başlamadan önce, bazı köşe parametrelerini hesaplamanız ve köşe gölgelendiriciden parça gölgelendiriciye aktarmanız gerekir:

  • Bir nesnenin köşe noktasındaki yüzeyine normal (normal)
  • Gelen ışığın tepe noktasından ışık kaynağına yönü (ışık yönü)
  • Tepe noktasından gözlemciye bakış yönü (görünüm yönü)
  • Bir nokta ışık kaynağından tepe noktasına olan mesafe (mesafe)

Nesnenin yüzeyine normal ve gelen ışığın yönü, dağınık ve aynasal ışığı hesaplamak için kullanılır, ancak yansıyan ışığı hesaplamak için ayrıca gözlemcinin görüş yönünü de bilmeniz gerekir. Genel zayıflama katsayısının hesaplanması için tepe noktasından ışık kaynağına olan mesafe gereklidir. Köşe gölgelendiricisi şöyle görünecek:

#versiyon 330 çekirdeği #define VERT_POSITION 0 #define VERT_TEXCOORD 1 #define VERT_NORMAL 2 düzeni (konum = VERT_POSITION) vec3 konumunda; vec2 texcoord'daki düzen(konum = VERT_TEXCOORD); vec3 normalinde düzen(konum = VERT_NORMAL); // dönüşüm parametreleri düzgün yapı Dönüşümü ( mat4 modeli; mat4 viewProjection; mat3 normal; vec3 viewPosition; ) dönüşümü; // nokta ışık kaynağının parametreleri tekdüze yapı PointLight ( vec4 konumu; vec4 ortam; vec4 yaygın; vec4 aynasal; vec3 zayıflama; ) ışık; // parça gölgelendiricinin parametreleri out Vertex ( vec2 texcoord; vec3 normal; vec3 lightDir; vec3 viewDir; float uzaklığı; ) Vert; geçersiz ana (geçersiz) ( // köşenin koordinatlarını dünya koordinat sistemine dönüştürün vec4 köşe = transform.model * vec4(konum, 1 .0 ) ; // dünya koordinat sisteminde tepe noktasından ışık kaynağına yön vec4 lightDir = ışık.konum - tepe noktası; // bazı parametreleri parça gölgelendiriciye ilet // doku koordinatlarını aktar Vert.texcoord = texcoord; // dünya koordinat sisteminde normali geç Dikey.normal = transform.normal * normal; // yönü ışık kaynağına ilet Vert.lightDir = vec3(lightDir) ; // dünya koordinat sistemindeki yönü köşeden gözlemciye ilet Vert.viewDir = transform.viewPosition - vec3(vertex) ; // tepe noktasından ışık kaynağına olan mesafeyi ilet Dikey.mesafe = uzunluk(ışıkDir) ; // köşenin koordinatlarını homojen olanlara dönüştürün gl_Position = transform.viewProjection * vertex; )

Yılların eserleri. Voloshin Maximilian. BİR ŞAİRİN DEĞERLİĞİ. 1. Şiiri denizaşırı bir gönderinin metni gibi düzenleyin: Kuruluk, netlik, baskı - her kelime tetikte.

Sert ve sıkışık bir taş üzerinde harf harf kesmek: Kelimeler ne kadar seyrekse, güçleri de o kadar yoğun olur. Düşüncenin istemli yükü sessiz kıtalara eşittir.

Sözlükten "Güzellik", "İlham" kelimelerini silin - kafiyelilerin aşağılık jargonu Şair için - anlayışlar: Gerçek, tasarım, plan, eşdeğerlik, özlülük ve doğruluk. Ciddi, zorlu bir zanaatta bir şairin ilhamı ve onuru vardır: Sağır-dilsiz meselede aşkın uyanıklığı keskinleştirmek. Voloshin M.A. Kütüphane: Oryol Bölge Bilimsel Evrensel Halk Kütüphanesi adını almıştır. I.A. Bunina. - M., ; Seçilmiş eserler: 2 cilt halinde.

M., ; Kırmızı Duman: Hikayeler. - M., ; Keşif şirketinden Gladyshev: Hikayeler. - M., ; Echelon; Kaçınılmazlık: Romanlar. Mari ve Udmurt şairlerinin pek çok çevirisini yaptı. Zaman zaman düzyazıda da şansımı denedim. Op. Maximilian Aleksandrovich Voloshin (), 20. yüzyılın ilk üçte birinin en büyük şairlerinden biridir. O, sembolist, ezoterik şiirlerden sivil-gazeteci ve bilimsel-felsefi şiire, antroposofik tercihler yoluyla "Tanrı Şehri idealine" giden yolu kat etmiş, yetenekli bir sanatçı, çok yönlü bir söz yazarıdır.

Önerilen yayın, okuyucuya yalnızca Voloshin'in en iyi şiirsel eserleriyle değil, aynı zamanda estetik, anı düzyazı, gazetecilik ve ülkelerin yaşamındaki dramatik olaylarla ilgili mektuplar üzerine en ilginç eserleriyle de tanışma fırsatı veriyor. Yazar. Voloshin Maximilian. Yazarın tüm şiirleri. İş. Şairin yiğitliği. 2. Yıldızlar. Favori yazar ve şiir koleksiyonlarını oluşturun!

Benzer düşünen insanlarla sohbet edin! İnceleme yazın, şiir düellolarına ve yarışmalara katılın! En iyiye katılın! Poembook'a katıldığınız için teşekkürler! Hesap erişim verilerini içeren bir mektup e-postanıza gönderildi!

24 saat içerisinde giriş yapmalısınız. Aksi takdirde hesap silinecektir! Kayıtlı kullanıcılar birçok avantajdan yararlanır: Şiir yayınlayın - yeteneğinizin farkına varın! Favori yazar ve şiir koleksiyonlarını oluşturun! Benzer düşünen insanlarla sohbet edin! Eleştiriler yazın, şiir düellolarına ve yarışmalara katılın!. Maximilian Voloshin. Tanım. Maximilian Aleksandrovich Voloshin, 20. yüzyılın ilk üçte birinin en büyük şairlerinden biridir.

O, sembolist, ezoterik şiirlerden sivil-gazeteci ve bilimsel-felsefi şiire, antroposofik tercihler yoluyla "Tanrı Şehri idealine" giden yolu kat etmiş, yetenekli bir sanatçı, çok yönlü bir söz yazarıdır. Önerilen yayın, okuyucuya yalnızca Voloshin'in en iyi şiirsel eserleriyle değil, aynı zamanda estetik, anı düzyazı, gazetecilik ve drama ile ilgili mektuplar üzerine en ilginç eserleriyle de tanışma fırsatı veriyor.

Seçilmiş eserler ve mektuplar. M. A. Voloshin. Fiyat. ovmak. Maximilian Aleksandrovich Voloshin, 20. yüzyılın ilk üçte birinin en büyük şairlerinden biridir. O, sembolist, ezoterik şiirlerden sivil-gazeteci ve bilimsel-felsefi şiire, antroposofik tercihler yoluyla "Tanrı Şehri idealine" giden yolu kat etmiş, yetenekli bir sanatçı, çok yönlü bir söz yazarıdır.

Voloshin M.A., Şairin Cesareti: Seçilmiş Eserler ve Mektuplar. dizi: Yeni Rus Klasikleri Kütüphanesi: gerekli kopya Geçit Töreni, şehir, sayfa, Kitabın Açıklaması. Maximilian Aleksandrovich Voloshin (), 20. yüzyılın ilk üçte birinin en büyük şairlerinden biridir. O, sembolist, ezoterik şiirlerden sivil-gazeteci ve bilimsel-felsefi şiire, antroposofik tercihler yoluyla "Tanrı Şehri idealine" giden yolu kat etmiş, yetenekli bir sanatçı, çok yönlü bir söz yazarıdır.

Kategoriler navigasyon gönderisi