Punkta gaismas avots opengl. Mēs turpinām OpenGL izpēti: apgaismojums saskaņā ar Phong. Saliekot to visu kopā

OpenGL ES apgaismojums ir noderīga funkcija, kas 3D spēlēm var pievienot jauku pieskārienu. Lai izmantotu šādu funkcionalitāti, mums vispirms ir jāsaprot OpenGL ES apgaismojuma modelis.

Kā darbojas apgaismojums

Padomāsim par to, kā darbojas apgaismojums. Vispirms mums ir nepieciešams gaismas avots, kas izstaro gaismu. Jums būs nepieciešams arī apgaismots objekts. Visbeidzot, mums ir nepieciešams arī sensors, piemēram, acs vai kamera, kas uztver fotonus, ko sūta gaismas avots un atstaro objekts. Apgaismojums maina objekta uztverto krāsu atkarībā no: gaismas avota veida; gaismas avota krāsa vai intensitāte; gaismas avota novietojums un virziens attiecībā pret apgaismoto objektu; objekta materiāls un faktūra.

Intensitāte, ar kādu objekts atstaro gaismu, ir atkarīga no daudziem faktoriem. Vissvarīgākais faktors, ko mēs skatāmies, ir leņķis, kādā gaismas stars skar virsmu. Jo tuvāk šis leņķis ir pareizajam leņķim, jo ​​lielāka intensitāte, ar kādu gaisma tiks atstarota no objekta. Tas ir parādīts attēlā. 11.1.

Tiklīdz gaismas stars saskaras ar virsmu, tas tiks atspoguļots divos dažādos virzienos. Lielākā daļa gaismas tiks atspoguļota izkliedēti. Tas nozīmē, ka atstarotie gaismas stari ir nevienmērīgi un nejauši izkliedēti pa objekta virsmu. Daži stari tiek atspoguļoti spoži. Tas nozīmē, ka gaismas stari tiks atstaroti atpakaļ tā, it kā tie atspēkotu perfektu spoguli. Attēlā 11.2. attēlā parādīta atšķirība starp difūzajiem un spoguļatspīdumiem.

Rīsi. 11.1. Jo tuvāk leņķis ir pareizajam leņķim, jo ​​lielāka ir atstarotās gaismas intensitāte

Rīsi. 11.2. Izkliedēti un spoži atspīdumi

Spoguļattēli parādīsies kā izcēlumi uz objektiem. Tas, vai gaisma spoži atstarojas no objekta, ir atkarīgs no materiāla, no kura tas ir izgatavots. Objektiem ar nelīdzenu vai raupju virsmu, piemēram, ādai, visdrīzāk nebūs spožu izgaismojumu. Objektos, kuriem ir gluda virsma, piemēram, stikls vai marmors, būs redzami šie gaišie artefakti. Protams, stikls vai marmors nav ideāli gludi, bet, salīdzinot ar koku vai cilvēka ādu, tie ir.

Kad gaisma saskaras ar virsmu, tās atstarojums arī maina krāsu atkarībā no ķīmiskais sastāvs apgaismots objekts. Objekti, kas mums šķiet sarkani, atspoguļo tikai sarkanās gaismas daļas un absorbē visas pārējās frekvences. Melns objekts ir tāds, kas absorbē gandrīz visu gaismu, kas uz tā krīt.

OpenGL ES ļauj simulēt uzvedību reālajā pasaulē, definējot gaismas avotus un objektu materiālus.

Gaismas avoti

Mūs ieskauj daudz dažādu apgaismojuma avotu. Saule nepārtraukti raida savus fotonus. Monitori izstaro gaismu, kas mūs ieskauj ar patīkamu spīdumu naktī. Spuldzes un priekšējie lukturi palīdz mums tumsā izvairīties no sadursmēm ar dažādiem objektiem. OpenGL ES ļauj izveidot četru veidu gaismas avotus.

Fona apgaismojums. Tas nav gaismas avots pats par sevi, bet gan citu gaismas avotu fotonu parādīšanās rezultāts. Kopā šie nejaušie fotoni rada pastāvīgu apgaismojuma līmeni, kam nav virziena un kas vienādi apgaismo visus objektus.

Punkta gaismas avoti. Viņiem ir pozīcija telpā un tie izstaro gaismu visos virzienos. Piemēram, punktveida gaismas avots ir spuldze.

Virziena apgaismojuma avoti. Izteikts kā norādījumi OpenGL ES. Tiek pieņemts, ka tie atrodas bezgalīgi tālu. Ideālā gadījumā Saule varētu būt šāds avots. Var pieņemt, ka visi gaismas stari, kas nāk no Saules, ietriecas Zemē vienā leņķī attāluma starp Zemi un Sauli dēļ.

Par lampām. Šīs gaismas ir līdzīgas punktveida gaismām, jo ​​tām ir noteikta pozīcija telpā. Turklāt tiem ir virziens, kurā tie izstaro gaismas starus. Tie rada gaismas konusu, kas ierobežots līdz noteiktam rādiusam. Šāda gaismas avota piemērs ir ielu lampa.

Mēs apsvērsim tikai fona apgaismojumu, kā arī punktveida un virziena gaismas avotus. Gaismas bieži ir grūti izmantot Android ierīcēs ar ierobežotu GPU, jo OpenGL ES aprēķina apgaismojumu. Drīz jūs sapratīsit, kāpēc tas tā ir.

Papildus gaismas avota novietojumam un virzienam OpenGL ES ļauj noteikt gaismas krāsu vai intensitāti. Šīs īpašības ir izteiktas, izmantojot RGBA krāsu. Tomēr OpenGL ES katram avotam ir jādefinē četras dažādas krāsas, nevis tikai viena.

Izcelt — intensitāte/krāsa, kas veicina objekta ēnojumu. Objekts tiks izgaismots vienādi no visām pusēm neatkarīgi no tā stāvokļa vai orientācijas attiecībā pret gaismas avotu.

Difūzā – gaismas intensitāte/krāsa, kas apgaismos objektu pēc izkliedētā atstarošanas aprēķināšanas. Objekta malas, kas nav vērstas pret gaismas avotu, netiks izgaismotas, tāpat kā dzīvē.

Specular – intensitāte/krāsa līdzīga difūzajai krāsai. Tomēr tas ietekmē tikai tos objekta punktus, kuriem ir noteikta orientācija attiecībā pret gaismas avotu un sensoru.

Emissīvs ir ļoti sarežģīts krāsu aprēķins, ko reālās pasaules fizikas lietojumprogrammās var izmantot ļoti ierobežoti, tāpēc mēs to neaptveram.

Visbiežāk mēs izmantosim gaismas avota izkliedētās un spožās intensitātes, un piešķirsim pārējās divas noklusējuma vērtības. Turklāt lielāko daļu laika mēs izmantosim vienu un to pašu RGBA krāsu gan difūzajai, gan spoguļajai intensitātei.

Materiāli

Visi objekti mūsu pasaulē sastāv no kāda veida materiāla. Katrs materiāls nosaka, kā uz objektu krītošā gaisma tiks atspoguļota un maina atstarotās gaismas krāsu. OpenGL ES ļauj materiālam definēt tās pašas četras RGBA krāsas kā gaismas avotam.

Fona apgaismojums ir krāsa, kas apvienojas ar jebkura gaismas avota fona krāsu ainā.

Difūzā ir krāsa, kas apvienojas ar jebkura gaismas avota izkliedēto krāsu.

Specular ir krāsa, kas apvienojas ar jebkura gaismas avota spoguļkrāsu. To izmanto, lai objekta virsmā izveidotu izcēlumus.

Izstarojošs - mēs turpinām ignorēt šāda veida krāsas, jo mūsu kontekstā to praktiski neizmanto.

11.3. attēlā ir parādīti pirmie trīs materiālu/gaismas avota īpašību veidi: fona apgaismojums, izkliedētais un spoguļais.

Rīsi. 11.3. Dažādu veidu materiāli/gaismas avoti: tikai fona apgaismojums (pa kreisi), tikai izkliedēts (vidējais), fona apgaismojums un izkliedēta krāsa ar spožiem izgaismojumu (pa labi)

Attēlā 11.3. attēlā parādīta dažādu materiālu un gaismas avotu īpašību ietekme uz krāsu. Fona apgaismojums vienmērīgi izgaismo izmēru. Izkliedētā gaisma tiks atspoguļota atkarībā no leņķa, kādā gaismas stari skāra objektu; Apgabali, kas ir tieši vērsti pret gaismas avotu, tiks izgaismoti spilgtāk, bet apgabali, kurus gaisma nevar sasniegt, būs tumši. Labajā attēlā var redzēt fona apgaismojuma, izkliedētās un spožās gaismas kombināciju. Spožā gaisma uz sfēras parādās kā balti izgaismoti punkti.

Kā OpenGL ES aprēķina apgaismojumu: virsotņu normālie

Jūs zināt, ka no objekta atstarotās gaismas intensitāte ir atkarīga no tās krišanas leņķa uz objektu. OpenGL ES izmanto šo faktu, lai aprēķinātu apgaismojumu. Tam tiek izmantoti virsotņu normālie, kas jādefinē kodā tāpat kā tekstūras koordinātas vai virsotņu krāsas. Attēlā 11.4. attēlā parādīta sfēra un tās virsotņu normālie.

Rīsi. 11.4. Sfēra un tās virsotnes normālie

Normālie ir vienības vektori, kas norāda virzienu, uz kuru virsma tiek pagriezta. Mūsu gadījumā virsma ir trīsstūris. Tā vietā, lai definētu virsmas normālu, mēs definējam virsotnes normālu. Atšķirība starp šiem normāliem ir tāda, ka virsotnes normāls var nenorādīt tajā pašā virzienā kā virsmas normāls. Tas ir skaidri redzams attēlā. 11.4, kur katra virsotnes norma ir visu trijstūri, kuriem virsotne pieder, vidējā norma. Šī vidējā aprēķināšana tiek veikta, lai radītu vienmērīgu objekta ēnojumu.

Renderējot objektu, izmantojot apgaismojumu un virsotņu normālus, OpenGL ES noteiks leņķi starp katru virsotni un gaismas avotu. Ja viņš zina šo leņķi, viņš var aprēķināt virsotnes krāsu, pamatojoties uz materiāla īpašībām. Gala rezultāts ir katras virsotnes krāsa, kas pēc tam tiek piemērota katram trīsstūrim kombinācijā ar citu virsotņu aprēķinātajām krāsām. Šī izmantotā krāsa tiks apvienota ar jebkādām faktūras pārveidojumiem, ko piemērosim objektam.

Tas izklausās diezgan biedējoši, bet patiesībā tas nav tik slikti. Mums ir jāiespējo apgaismojums un jādefinē gaismas avoti, renderējamais materiāls un virsotņu normālie (papildus virsotņu parametriem, ko mēs parasti definējam, piemēram, pozīcijas vai faktūras koordinātas). Apskatīsim, kā to var īstenot, izmantojot OpenGL ES.

Par praksi

Tagad veiksim visas darbības, kas nepieciešamas darbam ar apgaismojumu, izmantojot OpenGL ES. Izveidosim dažas nelielas palīgklases, kas nedaudz atvieglos darbu ar gaismas avotiem, un ievietosim tās com.badlogi pakotnē ar.androi dgames.framework.gl.

Apgaismojuma atļauja un aizliegums

Tāpat kā citos OpenGL ES stāvokļos, vispirms ir jāiespējo nosauktā funkcionalitāte. To var izdarīt šādi:

Pēc tam visiem renderētajiem objektiem tiks piemērots apgaismojums. Lai iegūtu rezultātu, ir jādefinē gaismas avoti un materiāli, kā arī virsotņu normālie. Kad esam pabeiguši visu nepieciešamo objektu zīmēšanu, apgaismojumu var izslēgt:

Gaismas avotu noteikšana

OpenGL ES nodrošina 4 veidu gaismas avotus: fona apgaismojumu, punktu, virzienu un prožektoru. Apskatīsim, kā noteikt pirmos trīs. Lai gaismekļi būtu efektīvi un labi izskatītos, katram modelim ir jāsastāv no milzīga skaita trīsstūru. Daudzām pašreizējām mobilajām ierīcēm tas nav iespējams.

OpenGL ES ļauj definēt ne vairāk kā 8 gaismas avotus vienlaicīgi, kā arī vienu globālo gaismas avotu. Katram no 8 gaismas avotiem ir identifikators, sākot no GL10.GL LIGHT0 līdz GL10.GL LIGHT7. Ja jums ir jāmaina kāda no šiem lukturiem īpašības, varat to izdarīt, definējot atbilstošo ID.

Gaismas izmantošanu var iespējot, izmantojot šādu sintaksi:

Pēc tam OpenGL ES saņems šī gaismas avota rekvizītus un lietos tos visiem renderētajiem objektiem. Ja mums ir jāatspējo gaismas avota lietošana, mēs to varam izdarīt, izmantojot šādu paziņojumu:

Izceltais ir īpašs gadījums, jo tam nav ID. OpenGL ES ainā var būt tikai viens izcēlums. Apskatīsim šo apgaismojuma avotu tuvāk.

Fona apgaismojums

Fona apgaismojums ir īpašs apgaismojuma veids. Tam nav ne pozīcijas, ne virziena, tikai krāsa, kas tiek vienādi piemērota visiem apgaismotajiem objektiem. OpenGL ES ļauj definēt globālo izcelšanu šādi:

ambi entCol vai masīvs satur fona apgaismojuma krāsas RGBA vērtības, kas attēlotas kā peldošā komata skaitļi no 0 līdz 1. Metodes gl LightModel fv pirmais parametrs ir konstante, kas norāda, ka mēs vēlamies iestatīt fona apgaismojuma krāsu. avots, peldošā komata skaitļu masīvs, kurā ir avota krāsa un peldošā masīva nobīde, no kuras metode sāks nolasīt RGBA vērtības. Ieliksim kodu, kas atrisina šo problēmu, mazā klasē. Tās kods ir parādīts sarakstā 11.2.

Uzskaitījums 11.2. Klase AmbientLight.java. vienkārša globālā apgaismojuma abstrakcija ODenGL ES

Viss, ko mēs darām, ir saglabājam izcēluma krāsu peldošā masīvā un nodrošinām divas metodes: vienu izmanto, lai iestatītu krāsu, un otru, lai norādītu OpenGL ES izmantot šo krāsu. Noklusējuma krāsa ir pelēka.

Punkta apgaismojuma avoti

Punkta gaismām ir pozīcija, kā arī fona, izkliedētā un spožā krāsa/intensitāte (mēs neuzskatām izstarojošo krāsu/intensitāti). Definējiet dažādi veidi krāsas šādi:

Pirmais parametrs ir gaismas avota identifikators. Šajā gadījumā mēs izmantojam ceturto avotu. Nākamais parametrs norāda atribūtu, kuru vēlamies mainīt. Trešais parametrs ir peldošā komata skaitļu masīvs, kas satur RGBA vērtības, un pēdējais ir šī masīva nobīde. Avota atrašanās vietas noteikšana ir tikpat vienkārša:

Mēs vēlreiz definējam atribūtu, kuru vēlamies mainīt (šajā gadījumā pozīciju), četru elementu masīvu, kas satur gaismas avota x-, y- un z-koordinātu radītajā pasaulē. Ņemiet vērā, ka masīva ceturtajam elementam jābūt vienādam ar vienu, ja gaismas avotam ir pozīcija. Ieliksim šo palīgu klasē. Tās kods ir iekļauts sarakstā 11.3.

Uzskaitījums 11.3. Point.Light.java klase, vienkārša OpenGL ES punktu gaismas abstrakcija

Mūsu palīgu klasē ir gaismas fona, izkliedētās un spožās krāsas komponentes, kā arī pozīcija (ceturtais elements ir viens). Turklāt mēs saglabājam pēdējo konkrētajam avotam izmantoto identifikatoru, tāpēc kļūst iespējams izveidot disableO metodi, kas nepieciešamības gadījumā izslēgs gaismu. Mums ir arī metode enableO, kas izmanto GL10 klases gadījumu un gaismas avota identifikatoru (piemēram, GL10.GL LIGHT6). Tas ļauj izmantot apgaismojumu, iestata tā atribūtus un saglabā izmantoto ID. DisableO metode vienkārši atspējo apgaismojuma izmantošanu, izmantojot 1ast.Ligh.tId klases locekli, kas iestatīts iespējošanas metodē.

Inicializējot klases dalībnieku masīvus, mēs izmantojam saprātīgas noklusējuma vērtības fona, izkliedētajām un spožajām krāsām. Gaisma būs balta un neradīs atspīdumu, jo tā spožā sastāvdaļa ir melna.

Virziena gaismas avoti

Virziena gaismas avoti ir gandrīz identiski punktveida gaismas avotiem. Vienīgā atšķirība ir tā, ka tiem ir virziens, nevis pozīcija. Veids, kādā virzienā tiek izteikts, ir nedaudz mulsinošs. Tā vietā, lai izmantotu vektoru, lai norādītu virzienu, OpenGL ES sagaida, ka mēs definēsim vienu punktu. Virziens tiks noteikts, izmantojot vektoru, kas savieno šo punktu un sākumpunktu. Šis fragments ļauj izveidot virziena gaismas avotu, kas nāk no pasaules labās puses:

Mēs to varam pārvērst vektorā:

Citi atribūti, piemēram, fons vai izkliedētā krāsa, ir identiski punktveida gaismas atribūti. 11.4. sarakstā ir parādīts kods mazai palīgu klasei, ko izmanto, lai izveidotu virziena gaismas.

Uzskaitījums 11.4. Directi onLi klase ght.java, vienkārša virziena gaismas avotu abstrakcija programmā OpenGL ES

Šī palīgu klase ir gandrīz identiska PointLight klasei. Vienīgā atšķirība ir tā, ka masīva virzienā ceturtais elements ir viens. Turklāt setPosition metodes vietā ir parādījusies metode setDirecti on. Tas ļauj definēt virzienu, piemēram, šādi: (-1; 0; 0), tādā gadījumā gaisma nāks no labās puses. Metodes iekšpusē visi vektora komponenti maina savu zīmi, tāpēc virzienu pārvēršam formātā, ko sagaida OpenGL ES.

Materiālu noteikšana

Materiālu nosaka vairāki atribūti. Tāpat kā ar jebkuru citu OpenGL ES objektu, materiāls ir stāvoklis, kas paliks aktīvs, līdz mēs to atkal mainīsim vai OpenGL ES konteksts tiek zaudēts. Lai iestatītu pašreizējos materiāla atribūtus, mēs varam rīkoties šādi:

Kā parasti, mums ir jādefinē fons, izkliedētās un spožās RGBA krāsas. To var izdarīt tāpat kā iepriekš – izmantojot peldošā komata skaitļu masīvus, kas sastāv no četriem elementiem.

Šo darbību apvienošana vienā palīgu klasē ir ļoti vienkārša. Rezultātu var redzēt sarakstā 11.5.

Uzskaitījums 11.5. Materiāls Java klase, vienkārša OpenGL ES materiālu abstrakcija

Arī šeit nav nekā pārsteidzoša. Mēs vienkārši saglabājam trīs komponentus, kas apraksta materiālu, kā arī nodrošinām funkcijas to vērtību iestatīšanai un iespējošanas metodi, kas tās nodod OpenGL ES.

OpenGL ES ir vēl viens dūzis, kad runa ir par materiāliem. Tas parasti izmanto kaut ko, ko sauc par materiāla krāsu, nevis glMaterialfvO metodi. Tas nozīmē, ka ar glMateri al fv metodi noteikto fona un izkliedēto krāsu vietā OpenGL ES izmantos mūsu modeļu virsotņu krāsu kā materiāla fona un difūzās krāsas. Lai iespējotu šo funkciju, vienkārši izsauciet to:

Parasti to es daru, jo fons un izkliedētās krāsas bieži vien ir vienādas. Tā kā lielākajā daļā spēļu un demonstrāciju es neizmantoju spožus izcēlumus, es varu viegli izmantot šo metodi un vispār neizsaukt glMaterial fv metodi. Kā to izmantot, ir jāizlemj jums.

Normālu definēšana

Lai apgaismojums darbotos OpenGL ES, jums ir jādefinē virsotņu normāli katrai virsotnei modelī. Virsotnes normālajam jābūt vienības vektoram, kas norāda (parasti) virzienā, kurā tiek pagriezta virsma, kurai pieder virsotne. Attēlā 11.5. attēlā parādīti mūsu kuba virsotņu normālie.

Rīsi. 11.5. Virsotnes normālie katrai mūsu kuba virsotnei

Virsotnes normāls ir vēl viens virsotnes atribūts, tāpat kā pozīcija vai krāsa. Lai izmantotu virsotņu normāļu priekšrocības, mums atkal jāmaina Verti ces3 klase. Lai norādītu OpenGL ES, kur tā var atrast katras virsotnes normas, mēs izmantosim gl Normal PointerO metodi, tāpat kā iepriekš izmantojām gl VertexPointer vai gl Col vai Pointer metodi. Saraksts 11.6 parāda klases Vertices3 galīgo versiju.

Uzskaitījums 11.6. Vertices3.Java klase, galīgā versija atbalsta normālus

Klasei ir jauns dalībnieks hasNormal.s, kas izseko, vai virsotnēm ir normāli.

Konstruktors tagad pieņem arī parametru hasNormals. Mums joprojām ir jāmaina vertexSize locekļa aprēķins, pievienojot katrai virsotnei trīs pludiņus, ja iespējams.

Kā redzat, setVertices un setlndices metodes paliek nemainīgas.

Tikko demonstrētajā bindO metodē mēs izmantojam tos pašus paņēmienus ar ByteBuffer kā iepriekš, bet šoreiz pievienojam normālus, izmantojot gl Normal Pointer metodi. Lai aprēķinātu parastā rādītāja nobīdi, jāņem vērā, vai ir norādītas faktūras un krāsu koordinātas.

Kā redzat, arī izlozes metode nav mainījusies; visas darbības notiek saistīšanas metodē O.

Visbeidzot, mēs nedaudz modificējam unbindO metodi. Mēs atspējojam parasto rādītāju izmantošanu, ja tādi ir, attiecīgi notīrot OpenGL ES stāvokli.

Modificētās Verti ces3 klases pielietošana ir tikpat vienkārša kā iepriekš. Apskatīsim nelielu piemēru:

Mēs izveidojam peldošā komata masīvu, lai saglabātu trīs virsotnes, no kurām katrai ir pozīcija (pirmie trīs cipari katrā rindā) un parastais (pēdējie trīs skaitļi katrā rindā). Šajā gadījumā mēs definējam trīsstūri xy plaknē, kura normālie ir vērsti z ass pozitīvās daļas virzienā.

Viss, kas mums jādara, ir izveidot klases Vertices3 eksemplāru un iestatīt virsotņu vērtības. Diezgan viegli, vai ne?

Visi iesiešanas, zīmēšanas un atsaistīšanas darbi tiek veikti tieši tāpat kā iepriekšējā klases versijā. Tāpat kā iepriekš, mēs varam pievienot virsotņu krāsas un tekstūras koordinātas.

Saliekot to visu kopā

Saliksim to visu kopā. Mums ir jāuzzīmē aina, kurai ir globāls apgaismojums, punktveida un virziena gaismas avoti. Tie apgaismos kubu, kas atrodas sākuma vietā. Mums ir jāizsauc arī metode gl uLookAt. lai novietotu kameru. Attēlā Parādīts 11.6 izskats mūsu pasaule.

Tāpat kā visos citos piemēros, izveidosim klasi ar nosaukumu LightTest, paplašinot GLGame klasi kā parasti. Tas atgriezīs LightScreen klases gadījumu, izmantojot metodi getStartScreenO. LightScreen klase ir mantota no GLScreen klases (saraksts 11.7).

Rīsi. 11.6. Mūsu pirmā apgaismota aina

Uzskaitījums 11.7. LightTest.java klases fragmenti. apgaismojuma izveide, izmantojot OpenGL ES

Sāksim, aprakstot dažus klases dalībniekus. Leņķa elements saglabā informāciju par pašreizējo kuba griešanās leņķi ap ​​y asi. Verti ces3 dalībnieks saglabā kuba modeļa virsotnes, kuras mēs drīzumā definēsim. Turklāt mums ir AmbientLight, PointLight un Directional Light klases gadījumi, kā arī Material klases eksemplāri.

Tālāk seko konstruktors. Šeit tiek izveidotas kuba modeļa virsotnes un tiek ielādēta kastes faktūra. Mēs arī inicializējam gaismas un materiālus. Fona apgaismojuma krāsa ir gaiši zaļa. Virzītais avots ir sarkans un atrodas mūsu pasaules punktā (3; 3; 0). Virziena gaismas avotam ir zila izkliedēta krāsa, gaisma krīt no kreisās puses. Materiālam mēs izmantojam noklusējuma vērtības (neliels fons, balts difūzajam komponentam un melns spoguļkomponentam).

Atsākšanas metodē mēs pārliecināmies, ka mūsu tekstūra tiek (atkārtoti) ielādēta, ja konteksts tiek zaudēts.

Metode createCube būtībā nav mainīta salīdzinājumā ar iepriekšējiem piemēriem. Tomēr šoreiz katrai virsotnei pievienojam normālus, kā parādīts attēlā. 11.5. Izņemot to, viss paliek pa vecam.

Atjaunināšanas metodē mēs vienkārši palielinām kuba griešanās leņķi.

Šeit tas kļūst interesantāk. Dažas pirmās rindas ir standarta kods, lai notīrītu krāsu un dziļuma buferi, iespējotu dziļuma pārbaudi un iestatītu darbības jomu.

Tālāk mēs iestatām projekcijas matricu vienādu ar perspektīvās projekcijas matricu, izmantojot gl uPerspecti ve metodi, kā arī izmantojam gl uLookAt metodi modeļa skata matricai, pateicoties kurai kamera darbojas tāpat kā attēlā. 11.6.

Tad ļaujam izmantot apgaismojumu. Šobrīd vēl nav definētas gaismas, tāpēc mēs tās definējam nākamajās rindiņās, izsaucot metodi gaismām un materiāliem.

Kā parasti, mēs arī iespējojam teksturēšanu un saistām kastes tekstūru. Visbeidzot, mēs izsaucam gl RotatefC) metodi, lai pagrieztu kubu un pēc tam uzzīmētu tā virsotnes, izmantojot labi izvietotus izsaukumus uz Verti ces3 klases gadījumu.

Metodes beigās mēs atspējojam punktveida un virziena gaismas (atcerieties, fona apgaismojums ir globāls stāvoklis), kā arī tekstūras un dziļuma pārbaudi. Tas ir viss apgaismojumam OpenGL ES.

Pārējā klase ir tukša; mums nav jāveic nekādas darbības pauzes gadījumā. Attēlā 11.7. attēlā parādīts programmas rezultāts.

Rīsi. 11.7. Attēlā redzamā aina. 11.6, renderēts ar OpenGL ES

Dažas piezīmes par apgaismojumu OpenGL ES

Lai gan apgaismojuma izmantošana var pievienot jūsu spēlei garšu, tai ir savi ierobežojumi un nepilnības. Ir dažas lietas, kas jums jāzina.

Apgaismojuma izmantošana patērē pārāk daudz resursu, īpaši pamanāmi lēnās ierīcēs. Rūpīgi izmantojiet apgaismojumu. Jo vairāk gaismas avotu aprakstīsit, jo vairāk aprēķinu būs nepieciešams, lai atveidotu ainu.

Punkta/virziena gaismas avotu pozīcija/virziens jānosaka pēc kameras matricu ielādes un pirms modeļa skata matricas reizināšanas ar citām matricām, lai pārvietotu un pagrieztu objektus. Tas ir ļoti svarīgi. Ja šie norādījumi netiek ievēroti, var rasties neizskaidrojami gaismas artefakti.

Izmantojot metodi gl Seal ef, lai mainītu modeļa izmēru, tiks mērogoti arī tā normālie lielumi. Tas ir slikti, jo OpenGL ES sagaida, ka normāliem parametriem ir parametri dotajās vienībās. Lai novērstu šo problēmu, varat izmantot komandu glEnable(GL10.GL NORMALIZE) vai dažos gadījumos komandu gl Enable(GL10 .GL RESCALE N0RMAL). Es uzskatu, ka ir jāizmanto pirmā komanda, jo otrās komandas lietošanai ir ierobežojumi un nepilnības. Problēma ir tāda, ka normālu vērtību normalizēšanai vai mērogošanas maiņai ir nepieciešams daudz apstrādes jaudas. Labākais risinājums no veiktspējas viedokļa ir izgaismotu objektu mērogošana.

Nu, kungi. Pēdējā laikā esam uzzinājuši diezgan daudz par OpenGL, tostarp, kā to izdarīt kontrolēt kameru , strādāt ar tekstūrām, un arī ar modeļiem. Ir pienācis laiks runāt par kaut ko daudz interesantāku, proti, apgaismojumu. Šī tēma ir interesanta, jo nav nekā gatava darbam ar gaismu OpenGL, viss ir jāraksta neatkarīgi, izmantojot ēnotājus. Šajā amatā mēs apskatīsim Phong apgaismojumu. Šī ir diezgan liela tēma, tāpēc mēs runāsim tikai par to apgaismojums. Tajā, kā tie tiek izgatavoti ēnas, mums tas būs jāizdomā citreiz.

Normālu saglabāšana un izmantošana

Pirms mēs pārejam tieši uz apgaismojumu, mums ir vajadzīga tāda lieta kā parastie.

Mēs jau zinām, ka modeļiem ir virsotnes un UV koordinātas, kas atbilst šīm virsotnēm. Lai izveidotu apgaismojumu, mums ir nepieciešama papildu informācija par modeļiem, proti, parastajiem. Normāls ir vienības vektors, kas atbilst virsotnei (vai, alternatīvi, daudzstūrim, bet tas nav mūsu gadījums). Kādu lomu apgaismojuma ieviešanā spēlē normālie, mēs uzzināsim tālāk. Pagaidām pietiek pateikt, ka normāli ir patiešām ļoti svarīgi. Piemēram, pateicoties tiem, virsmas izskatās gludākas un jūs varat atšķirt lodi no parasta izliekta daudzskaldņa, piemēram, ikosaedra. Un tā kā parastie ir tik svarīgi, mums ir jāiemācās tos saglabāt, pārveidojot Blender modeļus savā formātā.

Attiecīgās izmaiņas ir diezgan triviālas. Mēs iegūstam normālus tādā pašā veidā, kā ieguvām virsotņu koordinātas un UV koordinātas:

// daļa no procedūras korpusa importedModelCreate

for (neparakstīts int j = 0 ; j< face.mNumIndices ; ++ j) {
neparakstīts int indekss = face.mIndeksi[ j] ;
aiVector3D poz = mesh->mVertices[ indekss] ;
aiVector3D uv = mesh-> mTextureCoords[ 0 ] [ indekss] ;
aiVector3D normāls = mesh-> mNormals[ indekss] ;

VerticesBuffer[ virsotnesBufferIndex++ ] = poz.x ;
virsotnesBuferis[ virsotnesBufferIndex++ ] = poz.y ;
virsotnesBuferis[ virsotnesBufferIndex++ ] = poz.z ;
virsotnesBuffer[ virsotnesBufferIndex++ ] = normal.x ;
virsotnesBuffer[ virsotnesBufferIndex++ ] = normal.y ;
virsotnesBuffer[ virsotnesBufferIndex++ ] = normal.z ;
virsotnesBuferis[ virsotnesBufferIndex++ ] = uv.x ;
virsotnesBuferis[ virsotnesBufferIndex++ ] = 1.0f - uv.y ;
}

Modeļa optimizācijas procedūra mainās līdzīgi. Un modelLoad procedūrā divu atribūtu masīvu vietā tagad ir nepieciešami trīs:

// modeļa Ielādēšanas procedūras daļa

GlBindVertexArray(modelisVAO) ;
glEnableVertexAttribArray(0 ) ;
glEnableVertexAttribArray(1) ;
glEnableVertexAttribArray(2) ;

GlBindBuffer(GL_ARRAY_BUFFER, modelisVBO) ;
glBufferData(GL_ARRAY_BUFFER, galvene-> virsotnesDataSize, virsotnesPtr,
GL_STATIC_DRAW) ;

GLsizei solis = 8 * sizeof(GLfloat) ;
glVertexAttribPointer(0 , 3 , GL_FLOAT, GL_FALSE, solis, nullptr) ;
glVertexAttribPointer(1 , 3 , GL_FLOAT, GL_FALSE, solis,
(const void * ) (3 * sizeof (GLfloat) ) );
glVertexAttribPointer(2 , 2 , GL_FLOAT, GL_FALSE, solis,
(const void * ) (6 * sizeof (GLfloat) ) );

Mums papildus nepieciešams arī vienots mainīgais ar matricu M:

GLint uniformM = getUniformLocation(programId, "M") ;

// ...

GlUniformMatrix4fv(uniformM, 1, GL_FALSE, & towerM[ 0 ] [ 0 ] ) ;

... lai pareizi pagrieztu normālu telpā virsotņu ēnotājā:

#versija 330 kodols

Izkārtojums(vieta = 0 ) vec3 virsotnēPos;
izkārtojums(vieta = 1 ) vec3 virsotnēNorm;
izkārtojums(atrašanās vieta = 2 ) vec2 virsotnēUV;

uniforma mat4 MVP;
formas paklājiņš4 M;

out vec2 fragmentUV;
out vec3 fragmentsNormāls;
out vec3 fragmentPos;

Void main() (
fragmentUV = virsotneUV;
fragmentsNormāls = (M * vec4 (virsotneNorm, 0 ) ) . xyz;
fragmentPos = (M * vec4 (virsotnePos, 1 ) ) . xyz;

gl_Position = MVP * vec4 (virsotnePos, 1 );
}

Visbeidzot, fragmentu ēnotājs izmanto normālu interpolāciju trīs virsotnēs:

// ...

Void main() (

// ...
}

Šādā vienkāršā veidā mēs iegūstam normālos rādītājus fragmenti.

Kas ir fongas apgaismojums?

Kā minēts, apgaismojumu OpenGL ēnojumos raksta pats programmētājs. Ir skaidrs, ka ir vairāk nekā viens veids, kā ieviest šo apgaismojumu, katrs ar savu reālisma pakāpi un resursu prasībām. Un katrai metodei joprojām var būt neskaitāmas īpašas ieviešanas iespējas. Cik es saprotu, efektīvs un reālistisks reāllaika apgaismojums joprojām ir aktīvas pētniecības joma. Šajā ziņā mēs apskatīsim Phong apgaismojumu, kas ir gan diezgan reālistisks, gan viegli īstenojams.

Ir svarīgi saprast atšķirību starp šādiem jēdzieniem:

  • Gouraud ēnojums ir tad, kad aprēķina katras virsotnes apgaismojumu un starp tām esošo fragmentu apgaismojumu interpolē;
  • Fong ēnojums - kad apgaismojums tiek aprēķināts atsevišķi katram fragmentam;
  • Fonga apgaismojums vai fongas atstarošanas modelis ir īpaša apgaismojuma metode, kas aplūkota šajā rakstā un ko var izmantot gan Gouraud, gan Phong ēnošanā;

Nav pārsteidzoši, ka fonu ēnojums un fonu apgaismojums bieži tiek sajaukti, un dažās pamācībās var lasīt tādas muļķības kā "Phong ēnošanas ideja ir izmantot trīs komponentus...", kas nekavējoties liek jums stipri šaubīties par šīs ierīces autoritāti. persona, kas uzrakstīja šo pamācību.

Cik nopratu, mūsdienu aplikācijās Gouraud ēnojumu tikpat kā neizmanto, tā vietā priekšroka tiek dota Phong ēnojumam. Šajā ierakstā mēs izmantosim arī Phong ēnojumu, tas ir, apgaismojums tiks aprēķināts katram fragmentam atsevišķi. Īpašā apgaismojuma metode, ko izmantosim, ir Phong apgaismojums. Šī metode ir šāda.

Trīs apgaismojuma sastāvdaļas tiek aprēķinātas, izmantojot dažādas formulas:

  • Apkārtējais apgaismojums ir gaismas imitācija, kas ir sasniegusi noteiktu punktu pēc atstarošanas no citiem objektiem. Aprēķinot fona apgaismojumu, netiek ņemti vērā ne normālie, ne pašreizējā kameras pozīcija;
  • Izkliedētais apgaismojums ir gaisma no avota, kas tiek izkliedēta pēc trāpījuma noteiktā punktā. Atkarībā no leņķa, kurā gaisma krīt, apgaismojums kļūst stiprāks vai vājāks. Tas ņem vērā normālus, bet ne kameras stāvokli;
  • Spekulārais apgaismojums ir gaisma no avota, kas tiek atstarots pēc tam, kad ir sasniegts noteikts punkts. Atstarotā gaisma ir redzama, ja tā nonāk kamerā. Tāpēc šeit tiek ņemtas vērā gan normas, gan kameras pozīcija;

Pēc tam rezultāti tiek summēti, lai iegūtu kopējo apgaismojumu.

Lai padarītu lietas vēl interesantākas, ir dažādi gaismas avoti. Acīmredzot, saule ārā un lukturītis tumsā izgaismo ainu ļoti atšķirīgi. Pirmkārt, mēs apskatīsim vienkāršāko avotu - virziena gaismu.

Virziena gaisma

Virziena gaisma ir bezgalīgi attāla gaismas avota imitācija. Ņemsim, piemēram, Sauli. Saule ir ļoti tālu no zemes. Tāpēc uz Zemes virsmas visus Saules gaismas starus var uzskatīt par paralēliem ar lielu precizitāti. Virziena gaismu raksturo tā virziens, krāsa, kā arī daži koeficienti, kas mums būs nepieciešami tālāk:

struct DirectionalLight(
vec3 virziens;

vec3 krāsa;
float ambientIntensity;
pludiņa difūzsIntensitāte;
peldēt spoguļattēlsIntensitāte;
} ;

Fragmentu ēnotāja kodā mēs definēsim calcDirectionalLight procedūru, kas tiks izmantota apmēram šādi:

vec3 fragmentāPos;
vienota vec3 cameraPos;
vienota VirzienaGaismas virzienaGaisma;

// ...

Void main() (
// normāls jālabo pēc interpolācijas
vec3 normāls = normalizēt (fragmentNormal) ;


virzienaGaisma) ;

// ...
}

Apsvērsim procedūras īstenošanu.

vec4 calcDirectionalLight(vec3 normāls, vec3 fragmentsToCamera,
Virziena gaismas gaisma) (
vec4 ambientColor = vec4 (gaiša. krāsa, 1) * gaiša. ambientIntensity ;

// ...
}

Pirmkārt, tiek aprēķināta pirmā sastāvdaļa - fona apgaismojums. Tā ir vienkārši izstarotās gaismas krāsa, kas reizināta ar fona gaismas intensitāti. Pagaidām viss ir vienkārši.

// ...

pludiņa difūzaFactor = max (0.0 , punkts (normāls, - gaismas. virziens ) ) ;
vec4 diffuseColor = vec4 (gaiša. krāsa, 1) * gaiša. difūzsIntensitāte
* difūzaFactor;

// ...

Izkliedēts apgaismojums. DiffuseFactor mainīgais attēlo kosinusu leņķim starp normālu pret fragmentu un vektoru, kas vērsts no fragmenta uz gaismas avotu. Ja gaisma krīt perpendikulāri virsmai, leņķis ir nulle. Šī leņķa kosinuss ir vienāds ar vienu un apgaismojums ir maksimāls (skat. Wikipedia rakstu par Lamberta likumu). Palielinoties leņķim, kosinuss samazinās un kļūst vienāds ar nulli, ja gaisma ir paralēla virsmai. Ja kosinuss ir negatīvs, tad gaismas avots atrodas kaut kur aiz virsmas un tas nav izgaismots, tāpēc negatīvās vērtības pagriežam uz nulli, izmantojot max(0,0, ...) . Papildus leņķim, kurā gaisma krīt, tiek ņemta vērā arī izkliedētās gaismas intensitāte.

// ...
vec3 lightReflect = normalizēt(atspoguļot(gaismas. virziens, normāls));
peldēt specularFactor = pow(
maks. (0,0 , punkts (fragmentToCamera, lightReflect) ,
materiālsSpekulārais faktors
) ;
vec4 specularColor = gaišs. specularIntensity * vec4(gaisma.krāsa, 1)
* materiālsSpecularIntensity * specularFactor;
// ...

Netiešais apgaismojums. LightReflect mainīgais ir vienības vektors, kas norāda atstarotās gaismas virzienu. SpecularFactor mainīgais tiek aprēķināts līdzīgi kā diffuseFactor, tikai šoreiz tiek ņemts vērā leņķa kosinuss starp virzienu, kurā gaisma tika atstarots, un virzienu no fragmenta uz kameru. Ja šis leņķis ir nulle, tad atstarotā gaisma lido tieši kamerā un atspīdums uz virsmas ir maksimāls. Ja leņķis ir liels, tad nedrīkst būt redzams atspīdums. Šeit materiālsSpecularFactor ir vienots mainīgais. Jo lielāks tas ir, jo mazāks ir atspīduma laukums uz objekta virsmas. Mainīgais materiālsSpecularIntensity tiek izmantots arī, lai noteiktu izcelto vietu spilgtumu. Ņemiet vērā, ka tās visas ir materiāla īpašības, nevis gaisma. Piemēram, metāls atstaro gaismu un tāpēc tam ir atspīdums. Bet koks neatspoguļo gaismu, un tad jūs nekad neredzat atspīdumu uz kokiem (protams, ja virsma ir sausa utt.).

Iepriekš minētajā kodā gaismai ir specularIntensity īpašība. Taču to vajadzētu izmantot tikai atkļūdošanas nolūkos, lai izceltu konkrēta gaismas avota spilgtākos objektus. Koda izlaišanas versijā šim koeficientam ir jābūt vienādam ar vienu vai arī tas ir pilnībā jānoņem no koda.

Visbeidzot, tiek pievienoti trīs komponenti un tiek atgriezts rezultāts:

// ...

return ambientColor + diffuseColor + specularColor;
}

Nav tik grūti, vai ne?

Punkta gaismas avots

Punkta gaismas avots ir, piemēram, degoša spuldze. Gaisma no spuldzes tiek virzīta visos virzienos. Tāpēc punktveida gaismas avotu raksturo nevis gaismas virziens, bet gan avota novietojums telpā:

struct PointLight(
vec3 pozīcija;

vec3 krāsa;
float ambientIntensity;
pludiņa difūzsIntensitāte;
peldēt spoguļattēlsIntensitāte; // atkļūdošanas nolūkos jāiestata uz 1.0
} ;

Apgaismojumu no punktveida gaismas avota var viegli aprēķināt, izmantojot jau esošo calcDirectionalLight procedūru:

vec4 calcPointLight(vec3 normāls, vec3 fragmentsToCamera,
PointLight gaisma) (
vec3 lightDirection = normalizēt (fragmentPos - light. position ) ;
peldēšanas attālums = garums (fragmentPos - light. position ) ;
peldošā punkta koeficients = 1,0 / (1,0 + pow(attālums, 2));

DirectionalLight tempDirectionalLight = DirectionalLight(
gaismas virziens,
gaisma. krāsa,
gaisma. ambientIntensity
gaisma. difūzsIntensitāte
gaisma. spožaIntensitāte
) ;
atgriešanās punkta koeficients * calcDirectionalLight(normāls, fragmentsuz kameru,
tempDirectionalLight) ;
}

Izmantojot fragmenta un gaismas avota koordinātas, jūs varat viegli aprēķināt gaismas virzienu uz noteiktu fragmentu, izmantojot vektoru starpību. PointFactor reizinātājs atspoguļo faktu, ka gaisma vājina ar attāluma līdz tās avotam kvadrātu (saskaņā ar formulu sfēras virsmas laukuma atkarībai no rādiusa). Aprēķinot pointFactor, dalītājam tiek pievienots papildu viens, lai novērstu iespēju dalīt ar nulli. Pēc tam viss tiek aprēķināts tieši tāpat kā virziena gaismai.

Vietas gaisma

Šī gaismas avota piemērs ir lukturītis. Tas ir līdzīgs punktveida gaismas avotam, tikai tam ir papildus virziens un ietekmes leņķis (griezums):

strukturēt SpotLight (
vec3 virziens;
vec3 pozīcija;
pludiņa nogriešana;

vec3 krāsa;
float ambientIntensity;
pludiņa difūzsIntensitāte;
peldēt spoguļattēlsIntensitāte; // atkļūdošanas nolūkos jāiestata uz 1.0
} ;

Attiecīgā procedūra:

vec4 calcSpotLight(vec3 normāls, vec3 fragmentsToCamera,
SpotLight gaisma) (
vec3 spotLightDirection = normalizēt (fragmentPos - light. position ) ;
float spotAngleCos = punkts (spotLightDirection, light. direction) ;
peldošā vājināšanās = (1,0 - 1,0 * (1,0 - spotAngleCos) /
(1.0 - gaisma. nogrieznis ) ;
float spotFactor = peldēt (spotAngleCos > light. cutoff ) * vājināšanās;

PointLight tempPointLight = PointLight(
gaisma. pozīciju
gaisma. krāsa,
gaisma. ambientIntensity
gaisma. difūzsIntensitāte
gaisma. ambientIntensity
) ;
atgriezties spotFactor * calcPointLight(normāls, fragmentsToCamera,
tempPointLight);
}

Gaismas virzienu aprēķina tāpat kā punktveida avotam. Pēc tam tiek aprēķināts leņķa kosinuss starp šo virzienu un virzienu, kas norādīts paša gaismas avota īpašībās. Izmantojot izteiksmi peldēt(spotAngleCos > light.cutoff) gaisma ir stingri nosprausta norādītajā leņķī. Vājināšanās reizinātājs pievieno gluda gaismas vājināšanās, fragmentiem attālinoties no avota īpašībās norādītā gaismas virziena. Pēc tam visi aprēķini tiek samazināti līdz punktveida gaismas avota aprēķiniem.

Gamma korekcija

Visa galvenā procedūra fragmentu ēnotājā izskatās šādi:

Void main() (
// normāls jālabo pēc interpolācijas
vec3 normāls = normalizēt (fragmentNormal) ;
vec3 fragmentsToCamera = normalize(cameraPos - fragmentPos) ;

vec4 DirectColor = calcDirectionalLight(normāls, fragmentsToCamera,
virzienaGaisma) ;
vec4 pointColor = calcPointLight(normāls, fragmentsToCamera,
pointLight);
vec4 spotColor = calcSpotLight(normāls, fragmentsToCamera, spotlight) ;
vec4 linearColor = tekstūra(textureSampler, fragmentUV) *
(vec4(materialEmission, 1) + DirectColor +
pointColor + spotColor);

vec4 gamma = vec4 (vec3 (1,0 / 2,2), 1);
krāsa = pow(lineāra krāsa, gamma); // gamma koriģēta krāsa
}

Nepievērsiet lielu uzmanību materiālamEmisija. Šī ir tikai vēl viena materiāla īpašība, kas piešķir savu mirdzumu. Daudzi objekti mirdz paši. Paņemiet tās pašas spuldzes, kas kalpo kā gaismas avots citiem objektiem. Mums vajadzētu būt iespējai tos redzēt pilnīgā tumsā, pat ja spuldzes neizgaismo neviens cits gaismas avots, vai ne?

Tas, kas patiešām ir pelnījis uzmanību, ir gamma korekcija, kas sastāv no visu gaismas komponentu paaugstināšanas līdz 1/2,2. Līdz šim mēs esam strādājuši lineārā krāsu telpā, pieņemot, ka krāsa ar intensitāti 1,0 ir divreiz spilgtāka nekā krāsa ar intensitāti 0,5. Problēma ir tā, ka cilvēka acs spilgtumu neuztver lineāri. Tāpēc, lai iegūtu reālistisku apgaismojumu, pēc visiem aprēķiniem lineārajā telpā ir jāveic gamma korekcija.

Jāņem vērā, ka saglabājot attēlu, mūsdienu grafiskie redaktori veic arī gamma korekciju. Tāpēc pirms tekstūru izmantošanas šī gamma korekcija ir jāatceļ. Par laimi, tas nav grūti.

Pietiek aizstāt visas konstantes tekstūras ielādes kodā:

GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
GL_COMPRESSED_RGBA_S3TC_DXT5_EXT

GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT
GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT
GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT

… attiecīgi. Tas norāda, ka attēlam ir piemērota gamma korekcija un tā ir jāatsauc. OpenGL parūpēsies par pārējo.

Reālās lietojumprogrammās gamma parametrs (mums ir gamma = 2,2) ir labāk novietots programmas iestatījumos, lai lietotājs, ja vēlas, varētu to nedaudz pielāgot savam monitoram.

Secinājums

Ir pienācis laiks apskatīt bildes!

Šeit mēs redzam dažādus apgaismojuma komponentus. No kreisās uz labo, no augšas uz leju: fons, izkliedēts, atspoguļots, visi trīs kopā. Kā redzat, ainai ir pievienots tora modelis. Normālu sarežģītā izvietojuma dēļ šis modelis ir ieteicams apgaismojuma testēšanai.

Dažādi gaismas avoti. No kreisās puses uz labo, no augšas uz leju: balts prožektors, sarkans prožektors, zils prožektors, visi trīs kopā.

Ļaujiet man vēlreiz atzīmēt, ka vienai un tai pašai apgaismojuma metodei var būt dažādas realizācijas. Piemēram, materiāla īpašībām varat iestatīt apkārtējās, izkliedētās un spožās krāsas, kas ļaus zīmēt sarkanus objektus, kas izkliedē zaļo krāsu un kuriem ir zilas krāsas. Dažās Phong apgaismojuma ieviesumos esmu redzējis, ka fona apgaismojums tiek aprēķināts vienreiz, nevis katrai gaismai. Es redzēju arī implementācijas, kurās gaisma no punktveida avota izbalēja nevis vienkārši proporcionāli attāluma līdz tam kvadrātam (d * d), bet pēc vispārīgākas formulas (stilā A + B*d + C* d*d). Kāds padara apkārtējās vides intensitāti un izkliedēto intensitāti ne tikai gaismas avota, bet arī materiāla īpašību. Tomēr es neesmu pārliecināts, cik daudz tam visam ir sakars ar reālistisku apgaismojumu. Bet jūs varat spēlēt ar to visu kā mājasdarbu.

Gadu darbi. Vološins Maksimiliāns. DZEJNIEKA VALORS. 1. Rediģējiet dzejoli kā ārzemju sūtījuma tekstu: Sausums, skaidrība, spiediens — katrs vārds ir modrs.

Burtu pa burtam griezt uz cieta un saspiesta akmens: Jo retāki vārdi, jo intensīvāks to spēks. Domas gribas lādiņš ir vienāds ar klusajām strofām.

Izdzēsiet no vārdnīcas vārdus "Skaistums", "Iedvesma" - rupjš rīmētāju žargons. Dzejniekam - izpratnes: Patiesība, dizains, plāns, līdzvērtība, kodolīgums un precizitāte. Atturīgā, grūtā amatā ir dzejnieka iedvesma un gods: Asināt pārpasaulīgo modrību kurlmēmā matērijā. Vološins M.A. Bibliotēka: Oriolas reģionālā zinātniskā universālā publiskā bibliotēka, kas nosaukta vārdā. I.A. Bunina. - M., ; Izvēlētie darbi: 2 sējumos.

M., ; Sarkanie dūmi: stāsti. - M., ; Gladiševs no izlūkošanas kompānijas: stāsti. - M., ; Ešelons; Neizbēgamība: romāni. Viņš daudz tulkoja mari un udmurtu dzejniekus. Ik pa laikam izmēģināju spēkus arī prozā. Op. Maksimiliāns Aleksandrovičs Vološins () ir viens no izcilākajiem 20. gadsimta pirmās trešdaļas dzejniekiem. Viņš ir talantīgs mākslinieks, daudzšķautņains tekstu autors, kurš gājis ceļu no simboliskiem, ezotēriskiem dzejoļiem līdz pilsoniski žurnālistiskai un zinātniski filozofiskai dzejai, caur antroposofiskām tieksmēm - līdz "Dieva pilsētas ideālam".

Piedāvātā publikācija sniedz lasītājam iespēju iepazīties ne tikai ar Vološina labākajiem poētiskajiem darbiem, bet arī ar interesantākajiem darbiem par estētiku, memuāru prozu, žurnālistiku un vēstulēm, kas saistītas ar dramatiskiem notikumiem valstu dzīvē. Autors. Vološins Maksimiliāns. Visi autora dzejoļi. Darbs. Dzejnieka varonība. 2. Zvaigznes. Izveidojiet iecienītākās autoru un dzejoļu kolekcijas!

Parunājiet ar līdzīgi domājošiem cilvēkiem! Raksti recenzijas, piedalies dzejas dueļos un konkursos! Pievienojieties labākajiem! Paldies, ka pievienojāties Poembook! Uz jūsu e-pastu ir nosūtīta vēstule ar konta piekļuves datiem!

Jums jāpiesakās 24 stundu laikā. Pretējā gadījumā konts tiks dzēsts! Reģistrētie lietotāji saņem daudz priekšrocību: Publicējiet dzeju - realizējiet savu talantu! Izveidojiet iecienītākās autoru un dzejoļu kolekcijas! Parunājiet ar līdzīgi domājošiem cilvēkiem! Raksti recenzijas, piedalies dzejas dueļos un konkursos!. Maksimiliāns Vološins. Apraksts. Maksimiliāns Aleksandrovičs Vološins ir viens no izcilākajiem 20. gadsimta pirmās trešdaļas dzejniekiem.

Viņš ir talantīgs mākslinieks, daudzšķautņains tekstu autors, kurš gājis ceļu no simboliskiem, ezotēriskiem dzejoļiem līdz pilsoniski žurnālistiskai un zinātniski filozofiskai dzejai, caur antroposofiskām tieksmēm - līdz "Dieva pilsētas ideālam". Piedāvātā publikācija sniedz lasītājam iespēju iepazīties ne tikai ar Vološina labākajiem poētiskajiem darbiem, bet arī ar interesantākajiem darbiem par estētiku, memuāru prozu, žurnālistiku un ar drāmu saistītām vēstulēm.

Atlasīti darbi un vēstules. M. A. Vološins. Cena. berzēt. Maksimiliāns Aleksandrovičs Vološins ir viens no izcilākajiem 20. gadsimta pirmās trešdaļas dzejniekiem. Viņš ir talantīgs mākslinieks, daudzšķautņains tekstu autors, kurš gājis ceļu no simboliskiem, ezotēriskiem dzejoļiem līdz pilsoniski žurnālistiskai un zinātniski filozofiskai dzejai, caur antroposofiskām tieksmēm - līdz "Dieva pilsētas ideālam".

Vološins M.A., Dzejnieka varonība: atlasīti darbi un vēstules. sērija: Jauna krievu klasikas bibliotēka: obligātais eksemplārs Parāde, pilsēta, lapa, Grāmatas apraksts. Maksimiliāns Aleksandrovičs Vološins () ir viens no izcilākajiem 20. gadsimta pirmās trešdaļas dzejniekiem. Viņš ir talantīgs mākslinieks, daudzšķautņains liriķis, kurš ir gājis ceļu no simboliskiem, ezotēriskiem dzejoļiem līdz pilsoniski žurnālistiskai un zinātniski filozofiskai dzejai, caur antroposofiskām tieksmēm - līdz "Dieva pilsētas ideālam".

Kategorijas Ziņu navigācija

Bez gaismas avota attēls nav redzams. Lai inicializētu avotu un iespējotu procesoru, lai aprēķinātu avota ietekmi uz objektiem, vienkārši izpildiet komandas: glEnable(gl_lighting); // iespējojiet apgaismojuma analīzes režīmu

GlEnable(gl_light0); // iekļaujiet ainā konkrētu (nulles) avotu ar tā īpašībām

Lai atspējotu avotu, izmantojiet funkciju Disable(). Pēc noklusējuma gaismas avots atrodas telpā ar koordinātām (0,0,∞). Jūs varat izveidot gaismas avotu jebkurā attēla telpā.

OpenGl bibliotēka atbalsta četru veidu gaismas avotus:

  • fona apgaismojums (apkārtējais apgaismojums),
  • punktveida avoti,
  • prožektori,
  • attāli gaismas avoti (tālā gaisma).
Katram gaismas avotam ir savs raksturlielumu kopums.
Gaismas avota raksturlielumi atbilst Phong modeļa parametriem.
Lai iestatītu vektora parametrus, izmantojiet funkciju glLightfv(), kurai ir šāds formāts:

glLightfv(avots, parametrs, rādītājs_masīvam);

Ir četri vektora parametri, kas nosaka avota staru pozīciju un virzienu un tā komponentu krāsu sastāvu - fona, difūzo un spoguļattēlu.
Lai iestatītu skalāros parametrus OpenGL, izmantojiet funkciju glLightf():

glLightf(avots, parametrs, vērtība);

Ļaujiet, piemēram, ainā iekļaut avotu GL_LIGHT0, kam jāatrodas punktā (1.0, 2.0, 3.0). Avota pozīcija programmā tiek saglabāta kā punkts vienādās koordinātēs:

GLfloat light0_pos=(1.0, 2.0, 3.0, 1.0);

Ja šī punkta ceturtā sastāvdaļa ir nulle, tad punktveida avots pārvēršas par attālu avotu, kuram svarīgs ir tikai staru virziens:

GLfloat light0_dir=(1,0, 2,0, 3,0, 0,0);

Tālāk tiek noteikts avota fona krāsu sastāvs, difūzija un spoguļkomponenti. Ja aplūkojamajā piemērā avotam ir baltas krāsas spoguļkomponents un fona un difūzijas komponentiem jābūt sarkaniem, programmas fragments, kas veido avotu, izskatās šādi:

GLfloat diffise0= (1,0, 0,0, 0,0, 1,0);

GLfloat ambient0=(1,0, 0,0, 0,0, 1,0);

GLfloat specular0=(1,0, 1,0, 1,0, 1,0);

GlEnable(GL_LIGHTING);

GlEnable(GL_LIGHT0);

GlLightfv(GL_GAISMA0, GL_POSITION, light0_pos);

GlLightfv(GL_LIGHT0, GL_AMBIENT, ambient0);

GlLightfv(GL_LIGHT0, GL_DIFFUSE, difūzs0);

GlLightfv(GL_LIGHT0, GL_SPECULAR, specular0);

Varat arī savā ainā iekļaut globālu fona apgaismojumu, kas nav saistīts ar nevienu atsevišķu gaismas avotu. Ja, piemēram, vēlaties vāji izcelt visus ainas objektus ar baltu krāsu, programmā jāiekļauj šāda koda daļa:

GLfloat global_ambient=(0,1, 0,1, 0,1, 1,0);

GlLightModelfv(GL_LIGHT_MODEL_AMBIENT, globālais_ambients);

Apgaismojuma modelī terminam, kas ņem vērā attālumu līdz avotam, ir šāda forma:

K= 1/(a+ b*d+ c*d^2)

Un nemainīgas, lineāras un kvadrātiskās sastāvdaļas. Katram avotam atbilstošie koeficienti tiek iestatīti atsevišķi, izmantojot skalāro parametru iestatīšanas funkciju, piemēram:

GlLightf(GL_LIGHT0, GL_CONSTANT_ATTENATION, a);

Lai punktveida avotu pārvērstu par prožektoru, jānorāda prožektora staru kūļa virziens (GL_SPOT_DIRECTION), intensitātes sadalījuma funkcijas indikators (GL_SPOT_EXPONENT) un staru kūļa izkliedes leņķis (GL_SPOT_CUTTOF). Šie parametri tiek iestatīti, izmantojot funkcijas glLightf() un glLightfv().

Gaismas avotu noklusējuma parametri ir parādīti 3. tabulā.

Gaismas noklusējuma iestatījumi

3. tabula

Parametra nosaukums Noklusējuma vērtība Saturs
GL_AMBIENT (0.0, 0.0, 0.0, 1.0) apkārtējā RGBA gaismas intensitāte
GL_DIFFUSE (1.0, 1.0, 1.0, 1.0) izkliedētā RGBA gaismas intensitāte
GL_SPEKULĀRS (1.0, 1.0, 1.0, 1.0) spožā RGBA gaismas intensitāte
GL_POSITION (0.0, 0.0, 1.0, 0.0) (x, y, z, w) gaismas novietojums
GL_SPOT_DIRECTION (0.0, 0.0, -1.0) (x, y, z) prožektoru virziens
GL_SPOT_EXPONENT 0.0 prožektoru eksponents
GL_SPOT_CUTOFF 180.0 prožektoru nogriešanas leņķis
GL_CONSTANT_ATTENUATION 1.0 pastāvīgs vājinājuma koeficients
GL_LINEAR_ATTENUATION 0.0 lineārais vājinājuma koeficients
GL_QUADRATIC_ATTENUATION 0.0 kvadrātiskā vājinājuma koeficients