Punktvalgusallikas opengl. Jätkame OpenGL-i uurimist: valgustus Phongi järgi. Kõike kokku panema

OpenGL ES-i valgustus on kasulik funktsioon, mis võib 3D-mängudele kena lihvi lisada. Sellise funktsiooni kasutamiseks peame kõigepealt mõistma OpenGL ES-i valgustusmudelit.

Kuidas valgustus töötab

Mõelgem, kuidas valgustus töötab. Kõigepealt vajame valgusallikat, mis kiirgab valgust. Teil on vaja ka valgustatud objekti. Lõpuks vajame ka andurit, nagu silm või kaamera, mis võtab vastu valgusallika poolt saadetud ja objektilt peegelduvad footonid. Valgustus muudab objekti tajutavat värvi sõltuvalt: valgusallika tüübist; valgusallika värvus või intensiivsus; valgusallika asukoht ja suund valgustatud objekti suhtes; objekti materjal ja tekstuur.

Valguse peegeldumise intensiivsus objektilt sõltub paljudest teguritest. Kõige olulisem tegur, mida me vaatame, on nurk, mille all valguskiir pinda tabab. Mida lähemal on see nurk õigele nurgale, seda suurema intensiivsusega valgus objektilt peegeldub. Seda illustreerib joonis fig. 11.1.

Kui valguskiir puudutab pinda, peegeldub see kahes erinevas suunas. Enamik valgust peegeldub hajusalt. See tähendab, et peegeldunud valguskiired hajuvad ebaühtlaselt ja juhuslikult üle objekti pinna. Mõned kiired peegelduvad spekulaarselt. See tähendab, et valguskiired peegelduvad tagasi nii, nagu lööksid nad täiuslikku peeglit. Joonisel fig. Joonisel 11.2 on kujutatud difuusse ja peegelduva peegelduse erinevus.

Riis. 11.1. Mida lähemal on nurk õigele nurgale, seda suurem on peegeldunud valguse intensiivsus

Riis. 11.2. Hajutatud ja peegeldused

Spekulaarsed peegeldused ilmuvad objektide esiletõstudena. See, kas valgus objektilt peegeldub, sõltub materjalist, millest see on valmistatud. Objektidel, mille pind on ebaühtlane või kare, nagu nahk, ei ole suure tõenäosusega silmatorkavaid esiletõstmisi. Objektidel, millel on sile pind, nagu klaas või marmor, on need heledad esemed. Muidugi ei ole klaas või marmor ideaalselt siledad, kuid võrreldes puidu või inimese nahaga siiski.

Kui valgus tabab pinda, muudab selle peegeldus ka värvi sõltuvalt keemiline koostis valgustatud objekt. Objektid, mis tunduvad meile punased, peegeldavad ainult punaseid valguse osi ja neelavad kõik muud sagedused. Must objekt on selline, mis neelab peaaegu kogu sellele langeva valguse.

OpenGL ES võimaldab teil simuleerida tegelikku käitumist, määratledes valgusallikad ja objekti materjalid.

Valgusallikad

Oleme ümbritsetud paljudest erinevatest valgusallikatest. Päike saadab pidevalt oma footoneid välja. Monitorid kiirgavad valgust, mis ümbritseb meid öösel meeldiva säraga. Lambipirnid ja esituled aitavad meil pimedas vältida kokkupõrkeid erinevate objektidega. OpenGL ES võimaldab luua nelja tüüpi valgusallikaid.

Taustvalgus. See ei ole iseenesest valgusallikas, vaid teistest valgusallikatest pärit footonite ilmumise tulemus. Need juhuslikud footonid koos loovad pideva valgustuse taseme, millel pole suunda ja mis valgustab kõiki objekte võrdselt.

Punktvalgusallikad. Neil on ruumis positsioon ja nad kiirgavad valgust igas suunas. Näiteks punktvalgusallikaks on lambipirn.

Suunatud valgusallikad. Väljendatakse juhistena OpenGL ES-is. Eeldatakse, et nad asuvad lõpmatult kaugel. Ideaalis võiks selliseks allikaks olla Päike. Võib eeldada, et kõik Päikeselt tulevad valguskiired tabavad Maad sama nurga all Maa ja Päikese vahelise kauguse tõttu.

Lampide kohta. Need tuled on sarnased punkttuledega selle poolest, et neil on ruumis kindel asukoht. Lisaks on neil suund, milles nad kiirgavad valguskiiri. Nad loovad teatud raadiusega piiratud valguskoonuse. Sellise valgusallika näiteks on tänavavalgusti.

Arvestame ainult taustvalgustusega, samuti punkt- ja suunavalgusallikatega. Tulesid on GPU-ga piiratud Android-seadmetes sageli keeruline kasutada, kuna OpenGL ES arvutab valgustuse. Peagi saate aru, miks see nii on.

Lisaks valgusallika asukohale ja suunale võimaldab OpenGL ES määrata valguse värvi või intensiivsuse. Neid omadusi väljendatakse RGBA värviga. OpenGL ES nõuab aga ühe allika kohta nelja erineva värvi määramist ühe asemel.

Esiletõst – intensiivsus/värv, mis aitab kaasa objekti varjutamisele. Objekti valgustatakse kõikidest külgedest võrdselt, olenemata selle asukohast või orientatsioonist valgusallika suhtes.

Hajus – valguse intensiivsus/värvus, mis valgustab objekti pärast hajutatud peegelduse arvutamist. Objekti servad, mis ei ole suunatud valgusallika poole, ei valgustata, nagu päriselus.

Spekulaarne – intensiivsus/värv, mis sarnaneb hajutatud värviga. See mõjutab aga ainult neid objekti punkte, millel on valgusallika ja anduri suhtes teatud orientatsioon.

Emissiiv on väga keeruline värviarvutus, mida kasutatakse reaalmaailma füüsikarakendustes äärmiselt vähe, seega me seda ei käsitle.

Kõige sagedamini kasutame valgusallika hajutatud ja peegeldavat intensiivsust ning anname ülejäänud kaks vaikeväärtust. Samuti kasutame enamasti sama RGBA värvi nii hajutatud kui ka peegeldava intensiivsuse jaoks.

Materjalid

Kõik meie maailma objektid koosnevad mingist materjalist. Iga materjal määrab, kuidas objektile langev valgus peegeldub ja muudab peegeldunud valguse värvi. OpenGL ES võimaldab materjali jaoks määratleda samad neli RGBA värvi kui valgusallika jaoks.

Taustvalgus on värv, mis kombineeritakse stseeni mis tahes valgusallika taustavärviga.

Hajus on värv, mis kombineerib mis tahes valgusallika hajutatud värviga.

Spekulaarne on värv, mis kombineerib mis tahes valgusallika spekulaarse värviga. Seda kasutatakse objekti pinnale esiletõstude loomiseks.

Emissiivne - me ignoreerime seda tüüpi värve jätkuvalt, kuna seda meie kontekstis praktiliselt ei kasutata.

Joonis 11.3 illustreerib kolme esimest materjali/valgusallika omaduste tüüpi: taustvalgus, hajutatud ja peegeldav.

Riis. 11.3. Erinevat tüüpi materjalid/valgusallikad: ainult taustvalgus (vasakul), ainult hajus (keskmine), taustvalgus ja hajutatud värv koos silmatorkavate esiletõstmistega (paremal)

Joonisel fig. Joonis 11.3 näitab materjalide ja valgusallikate erinevate omaduste mõju värvile. Taustvalgus valgustab suurust ühtlaselt. Hajunud valgus peegeldub sõltuvalt nurgast, mille all valguskiired objekti tabavad; Otse valgusallika poole jäävad alad valgustatakse eredamalt, alad, kuhu valgus ei ulatu, on tumedad. Paremal pildil näete taustavalguse, hajutatud ja peegelvalguse kombinatsiooni. Spekulaarne valgus ilmub sfäärile valgete esiletõstetena.

Kuidas OpenGL ES arvutab valgustuse: tipunormaalid

Teate, et objektilt peegelduva valguse intensiivsus sõltub selle langemisnurgast objektile. OpenGL ES kasutab seda fakti valgustuse arvutamiseks. Ta kasutab selleks tipunormaale, mis tuleb koodis määratleda samamoodi nagu tekstuuri koordinaadid või tipuvärvid. Joonisel fig. Joonisel 11.4 on kujutatud kera ja selle tipunormaalid.

Riis. 11.4. Kera ja selle tipunormaalid

Normaalid on ühikvektorid, mis näitavad suunda, mille poole pinda pööratakse. Meie puhul on pind kolmnurk. Pinnanormaali defineerimise asemel defineerime tipunormaali. Nende normaalide erinevus seisneb selles, et tipunormaal ei pruugi osutada pinnanormaaliga samas suunas. See on selgelt näha joonisel fig. 11.4, kus iga tipunormaal on kõigi kolmnurkade, millesse tipp kuulub, keskmistatud normaal. See keskmistamine tehakse objekti sujuva varjutuse loomiseks.

Objekti renderdamisel valgustuse ja tipunormaalide abil määrab OpenGL ES iga tipu ja valgusallika vahelise nurga. Kui ta seda nurka teab, oskab ta materjali omaduste põhjal välja arvutada tipu värvi. Lõpptulemuseks on iga tipu värv, mida seejärel rakendatakse igale kolmnurgale koos teiste tippude arvutatud värvidega. Seda kasutatud värvi kombineeritakse mis tahes tekstuuriteisendustega, mida objektile rakendame.

See kõlab üsna hirmutavalt, kuid tegelikult pole see nii hull. Peame lubama valgustuse ja määratlema valgusallikad, renderdatava materjali ja tipunormaalid (lisaks tipuparameetritele, mida me tavaliselt määratleme, näiteks asukoha või tekstuuri koordinaadid). Vaatame, kuidas seda OpenGL ES-i abil rakendada.

Praktikas

Nüüd teeme kõik sammud, mis on vajalikud OpenGL ES-i valgustusega töötamiseks. Loome mõned väikesed abiklassid, mis muudavad valgusallikatega töötamise veidi lihtsamaks, ja paigutame need paketti com.badlogi koos.androi dgames.framework.gl.

Valgustuse lubamine ja keelamine

Nagu ka teiste OpenGL ES-i olekute puhul, peate esmalt lubama nimetatud funktsiooni. Seda saab teha järgmiselt.

Pärast seda valgustatakse kõiki renderdatud objekte. Tulemuse saamiseks tuleb defineerida valgusallikad ja materjalid, samuti tipunormaalid. Kui oleme kõik vajalikud objektid joonistanud, saab valgustuse välja lülitada:

Valgusallikate määramine

OpenGL ES pakub 4 tüüpi valgusallikaid: taustvalgus, kohtvalgus, suundvalgus ja prožektor. Vaatame, kuidas määrata kolm esimest. Selleks, et valgustid oleksid tõhusad ja näeksid head välja, peab iga mudel koosnema tohutust hulgast kolmnurkadest. Paljude praeguste mobiilseadmete puhul pole see võimalik.

OpenGL ES võimaldab defineerida korraga maksimaalselt 8 valgusallikat, aga ka ühe globaalse valgusallika. Kõigil kaheksal valgusallikal on identifikaator GL10.GL LIGHT0 kuni GL10.GL LIGHT7. Kui teil on vaja mõne sellise tule omadusi muuta, saate seda teha vastava ID määratlemisega.

Tulede kasutamise saate lubada järgmise süntaksi abil:

Järgmisena saab OpenGL ES selle valgusallika omadused ja rakendab need kõikidele renderdatud objektidele. Kui meil on vaja valgusallika kasutamine keelata, saame seda teha järgmise avaldusega:

Esiletõstmine on erijuhtum, kuna sellel puudub ID. OpenGL ES-i stseenis saab olla ainult üks esiletõst. Vaatame seda valgusallikat lähemalt.

Taustvalgus

Taustvalgustus on valgustuse eriliik. Sellel pole asendit ega suunda, on ainult värv, mida rakendatakse kõigile valgustatud objektidele võrdselt. OpenGL ES võimaldab globaalset esiletõstmist määratleda järgmiselt:

ambi entCol või massiiv sisaldab taustvalgustuse värvi RGBA väärtusi, mis on esitatud ujukomaarvudena vahemikus 0 kuni 1. Meetod gl LightModel fv võtab esimese parameetrina konstanti, mis määrab, et tahame määrata taustavalguse värvi allikas, ujukomaarvude massiiv , mis sisaldab lähtevärvi ja ujukite massiivi nihet, millest meetod alustab RGBA väärtuste lugemist. Paneme selle probleemi lahendava koodi väikesesse klassi. Selle kood on näidatud nimekirjas 11.2.

Nimekiri 11.2. Klass AmbientLight.java. lihtne globaalse valgustuse abstraktsioon ODenGL ES

Kõik, mida me teeme, on salvestada esiletõstetud värv ujuva massiivi ja pakkuda kahte meetodit: ühte kasutatakse värvi määramiseks ja teist, mida kasutatakse OpenGL ES-i käsuks seda värvi kasutada. Vaikevärv on hall.

Punktvalgustusallikad

Punktvalgustitel on nii asend kui ka taust, hajus ja peegeldav värv/intensiivsus (me ei arvesta kiirgavat värvi/intensiivsust). Defineeri erinevad tüübid värvid järgmiselt:

Esimene parameeter on valgusallika identifikaator. Sel juhul kasutame neljandat allikat. Järgmine parameeter määrab atribuudi, mida soovime muuta. Kolmas parameeter on ujukomaarvude massiiv, mis sisaldab RGBA väärtusi, ja viimane on selle massiivi nihe. Allika asukoha määramine on sama lihtne:

Määratleme uuesti atribuudi, mida soovime muuta (antud juhul positsiooni), nelja elemendiga massiivi, mis sisaldab loodavas maailmas valgusallika x-, y- ja z-koordinaate. Pange tähele, et massiivi neljas element peab olema võrdne ühega, kui valgusallikal on asukoht. Paneme selle abistajate klassi. Selle kood sisaldub nimekirjas 11.3.

Nimekiri 11.3. Point.Light.java klass, OpenGL ES punkttulede lihtne abstraktsioon

Meie abiklass sisaldab valguse tausta-, hajus- ja spekulaarseid värvikomponente ning asendit (neljas element on üks). Lisaks salvestame antud allika jaoks viimati kasutatud identifikaatori, nii on võimalik luua disableO meetod, mis vajadusel valguse välja lülitab. Meil on ka meetod enableO, mis võtab GL10 klassi eksemplari ja valgusallika identifikaatori (näiteks GL10.GL LIGHT6). See võimaldab valgustust kasutada, määrab selle atribuudid ja salvestab kasutatud ID. DisableO meetod lihtsalt keelab valgustuse kasutamise, kasutades lubamismeetodis määratud klassi liiget 1ast.Ligh.tId.

Klassiliikmete massiivi lähtestamisel kasutame tausta-, hajus- ja peegeldavate värvide jaoks mõistlikke vaikeväärtusi. Valgus on valge ja ei tekita pimestamist, kuna selle peegeldav komponent on must.

Suunatud valgusallikad

Suunatud valgusallikad on peaaegu identsed punktvalgusallikatega. Ainus erinevus on see, et neil on positsiooni asemel suund. See, kuidas väljendatakse, on mõnevõrra segane. Selle asemel, et kasutada suuna näitamiseks vektorit, eeldab OpenGL ES, et määratleksime ühe punkti. Seejärel määratakse suund selle punkti ja alguspunkti ühendava vektori abil. Järgmine jupp võimaldab luua suunavalgusallika, mis tuleb maailma paremalt küljelt:

Saame selle teisendada vektoriks:

Muud atribuudid, nagu taust või hajutatud värv, on identsed punktvalgusega. Nimekiri 11.4 näitab suunatulede loomiseks kasutatava väikese abiklassi koodi.

Nimekiri 11.4. Directi onLi klass ght.java, OpenGL ES-i suunatud valgusallikate lihtne abstraktsioon

See abiklass on peaaegu identne PointLighti klassiga. Ainus erinevus seisneb selles, et massiivi Directi on neljas element üks. Lisaks on setPosition meetodi asemel ilmunud meetod setDirecti on. See võimaldab teil määrata suuna, näiteks järgmiselt: (-1; 0; 0), sel juhul tuleb valgus paremalt poolt. Meetodi sees muudavad kõik vektori komponendid oma märki, seega teisendame suuna OpenGL ES-i poolt oodatud vormingusse.

Materjalide määramine

Materjal on määratletud mitme atribuudiga. Nagu iga muu OpenGL ES-i objekti puhul, on materjal olek, mis jääb aktiivseks seni, kuni me seda uuesti muudame või OpenGL ES-i kontekst kaob. Praeguste materjaliatribuutide määramiseks saame teha järgmist.

Nagu tavaliselt, peame määratlema tausta, hajusad ja peegeldavad RGBA värvid. Seda saab teha samamoodi nagu varem – kasutades neljast elemendist koosnevaid ujukomaarvude massiive.

Nende toimingute ühendamine üheks abimeeste klassiks on väga lihtne. Tulemust näete nimekirjas 11.5.

Nimekiri 11.5. Materjal Java klass, OpenGL ES materjalide lihtne abstraktsioon

Ka siin pole midagi üllatavat. Salvestame lihtsalt kolm komponenti, mis kirjeldavad materjali, ning pakume ka funktsioone nende väärtuste määramiseks ja lubamismeetodi, mis edastab need OpenGL ES-ile.

OpenGL ES-il on materjalide osas veel üks äss. Tavaliselt kasutab see glMaterialfvO meetodi asemel midagi, mida nimetatakse materjali värviks. See tähendab, et glMateri al fv meetodil määratud tausta ja hajusvärvide asemel võtab OpenGL ES materjali taustaks meie mudelite tippude värvi ning hajusvärvid. Selle funktsiooni lubamiseks helistage sellele lihtsalt:

Tavaliselt ma teen seda, sest taust ja hajutatud värvid on sageli samad. Kuna ma ei kasuta enamikus oma mängudes ja demodes specular highlight’e, saan seda meetodit hõlpsalt kasutada ja glMaterial fv meetodit üldse mitte kutsuda. Milline viis seda kasutada, on teie otsustada.

Normaalide määratlemine

Selleks, et valgustus OpenGL ES-is töötaks, tuleb iga mudeli tipu jaoks määratleda tipunormaalid. Tipu normaal peaks olema ühikvektor, mis osutab (tavaliselt) selle pinna pööramise suunas, kuhu tipp kuulub. Joonisel fig. Joonis 11.5 illustreerib meie kuubi tipunormaale.

Riis. 11.5. Meie kuubi iga tipu tipunormaalid

Tipu normaalne on tipu teine ​​atribuut, nagu ka asend või värv. Tipunormaalide ärakasutamiseks peame Verti ces3 klassi uuesti muutma. Et anda OpenGL ES-ile teada, kust ta leiab iga tipu jaoks normaalväärtusi, kasutame meetodit gl Normal PointerO, täpselt nagu varem kasutasime meetodeid gl VertexPointer või gl Col või Pointer. Nimekiri 11.6 näitab klassi Vertices3 lõplikku versiooni.

Nimekiri 11.6. Vertices3.Java klass, lõppversioon, mis toetab normaalväärtusi

Klassil on uus liige hasNormal.s, mis jälgib, kas tippudel on normaalväärtusi.

Konstruktor aktsepteerib nüüd ka hasNormals parameetrit. Peame siiski muutma tipu suuruse liikme arvutust, lisades võimaluse korral igale tipule kolm ujuki.

Nagu näete, jäävad setVertices ja setlndices meetodid muutumatuks.

Äsja demonstreeritud bindO meetodis kasutame ByteBufferiga samu tehnikaid nagu varem, kuid seekord lisame normaalväärtused gl Normal Pointer meetodi abil. Tavalise osuti nihke arvutamiseks tuleb arvestada, kas tekstuuri ja värvi koordinaadid on määratud.

Nagu näete, pole ka loosimeetod muutunud; kogu tegevus toimub sidumismeetodil O.

Lõpuks muudame veidi unbindO meetodit. Keelame tavaliste osutite kasutamise, kui neid on, tühjendades vastavalt OpenGL ES-i oleku.

Muudetud Verti ces3 klassi rakendamine on sama lihtne kui varem. Vaatame väikest näidet:

Loome ujukoma massiivi, et salvestada kolm tippu, millest igaühel on asukoht (iga rea ​​kolm esimest numbrit) ja tavaline (iga rea ​​kolm viimast numbrit). Sel juhul defineerime xy-tasandil oleva kolmnurga, mille normaalid on suunatud z-telje positiivse osa suunas.

Peame vaid looma Vertices3 klassi eksemplari ja määrama tippude väärtused. Päris lihtne, kas pole?

Kõik köitmis-, joonistamis- ja lahtiköitmistööd tehakse täpselt samamoodi nagu klassi eelmises versioonis. Nagu varemgi, saame lisada tippude värve ja tekstuuri koordinaate.

Kõike kokku panema

Paneme kõik kokku. Peame joonistama stseeni, millel on globaalne valgustus, punkt- ja suunavalgusallikad. Need valgustavad lähtekohas asuvat kuupi. Peame kutsuma ka meetodit gl uLookAt. kaamera positsioneerimiseks. Joonisel fig. 11.6 näidatud välimus meie maailm.

Nagu kõigi teiste näidete puhul, loome klassi nimega LightTest, mis laiendab GLGame klassi nagu tavaliselt. See tagastab LightScreeni klassi eksemplari, kasutades meetodit getStartScreenO. LightScreeni klass pärineb GLScreeni klassist (loetelu 11.7).

Riis. 11.6. Meie esimene valgustatud stseen

Nimekiri 11.7. Fragmendid klassist LightTest.java. valgustuse loomine OpenGL ES-i abil

Alustuseks kirjeldame mõnda klassi liiget. Nurgaelement salvestab informatsiooni kuubi praeguse pöördenurga kohta ümber y-telje. Verti ces3 liige salvestab kuubimudeli tipud, mille me lähiajal defineerime. Lisaks on meil klasside AmbientLight, PointLight ja Directional Light eksemplarid, samuti klassi Material eksemplarid.

Edasi tuleb konstruktor. Siin luuakse kuubimudeli tipud ja laaditakse kasti tekstuur. Samuti initsialiseerime tuled ja materjalid. Taustvalgustuse värv on heleroheline. Suunatud allikas on punane ja asub meie maailma punktis (3; 3; 0). Suunatud valgusallikal on sinine hajus värv, valgus langeb vasakult. Materjali jaoks kasutame vaikeväärtusi (mõnevõrra taust, valge hajuskomponendi jaoks ja must spekulaarse komponendi jaoks).

Jätkamismeetodi puhul veendume, et konteksti kaotsimineku korral laaditakse meie tekstuur (uuesti).

Meetod createCube on eelmiste näidetega võrreldes sisuliselt muutumatu. Kuid seekord lisame igale tipule normaalväärtused, nagu on näidatud joonisel fig. 11.5. Peale selle jääb kõik samaks.

Värskendusmeetodis suurendame lihtsalt kuubi pöördenurka.

Siin läheb asi huvitavamaks. Esimesed paar rida on standardkood, et tühjendada värvi- ja sügavuspuhvrit, lubada sügavustesti ja määrata ulatus.

Järgmiseks seame projektsioonimaatriksi võrdseks perspektiivprojektsiooni maatriksiga, kasutades gl uPerspecti ve meetodit ja samuti kasutame mudel-vaate maatriksi jaoks meetodit gl uLookAt, tänu millele töötab kaamera samamoodi nagu joonisel fig. 11.6.

Seejärel lubame kasutada valgustust. Praegu pole veel ühtegi valgust määratletud, seega määratleme need järgmistel ridadel, kutsudes esile tulede ja materjalide meetodi.

Nagu tavaliselt, lubame ka tekstureerimise ja seome kasti tekstuuri. Lõpuks kutsume kuubi pööramiseks meetodit gl RotatefC) ja seejärel joonistame selle tipud, kasutades hästi paigutatud väljakutseid klassi Verti ces3 eksemplarile.

Meetodi lõpus keelame koht- ja suunatuled (pidage meeles, et taustvalgustus on globaalne olek), samuti tekstureerimise ja sügavuse testimise. See on kõik OpenGL ES-i valgustamiseks.

Ülejäänud klassiruum on tühi; me ei pea pausi korral mingeid toiminguid tegema. Joonisel fig. Joonis 11.7 näitab programmi tulemust.

Riis. 11.7. Joonisel fig. 11.6, renderdatud OpenGL ES-iga

Mõned märkused valgustuse kohta OpenGL ES-is

Kuigi valgustuse kasutamine võib teie mängule maitset lisada, on sellel oma piirangud ja lõkse. On mõned asjad, mida peaksite teadma.

Valgustuse kasutamine kulutab liiga palju ressursse, eriti aeglaste seadmete puhul. Kasutage valgustust ettevaatlikult. Mida rohkem valgusallikaid kirjeldate, seda rohkem on stseeni renderdamiseks vaja arvutusi.

Punkt-/suundvalgusallikate asukoht/suund tuleks määrata pärast kaamera maatriksite laadimist ja enne mudelivaate maatriksi korrutamist mis tahes muu maatriksiga objektide liigutamiseks ja pööramiseks. See on kriitiline. Kui neid juhiseid ei järgita, võivad ilmneda seletamatud valgusartefaktid.

Kui kasutate mudeli suuruse muutmiseks meetodit gl Seal ef, skaleeritakse ka selle normaalväärtusi. See on halb, sest OpenGL ES eeldab, et normaalarvudel on parameetrid antud ühikutes. Selle probleemi lahendamiseks võite kasutada käsku glEnable(GL10.GL NORMALIZE) või mõnel juhul käsku gl Enable(GL10 .GL RESCALE N0RMAL). Usun, et tuleks kasutada esimest käsku, kuna teise kasutamisel on piiranguid ja lõkse. Probleem on selles, et normaalsete väärtuste normaliseerimine või skaleerimine nõuab palju töötlemisvõimsust. Parim lahendus jõudluse seisukohalt on mitte skaleerida valgustatud objekte.

Noh, härrased. Oleme viimasel ajal OpenGL-i kohta üsna palju õppinud, sealhulgas seda, kuidas seda teha juhtida kaamerat , töötada tekstuuridega, ja ka koos mudelid. On aeg rääkida millestki palju huvitavamast, nimelt valgustusest. See teema on huvitav, kuna OpenGL-is pole valgusega töötamiseks midagi valmis, kõik tuleb kirjutada iseseisvalt varjundite abil. Selles postituses vaatleme Phongi valgustust. See on üsna suur teema, nii et me räägime ainult sellest valgustus. Selles, kuidas need on valmistatud varjud, peame selle teinekord välja mõtlema.

Normaalide salvestamine ja kasutamine

Enne otse valgustuse juurde liikumist on meil vaja sellist asja nagu tavaline.

Teame juba, et mudelitel on neile tippudele vastavad tipud ja UV-koordinaadid. Valgustuse loomiseks vajame mudelite, nimelt tavaliste kohta rohkem teavet. Normaalne on tipule vastav ühikvektor (või alternatiivselt hulknurgale, kuid see pole meie juhtum). Millist rolli mängivad valgustuse rakendamisel normaalsed täpselt, saame teada allpool. Praegu piisab, kui öelda, et normaalsed on tõepoolest väga olulised. Näiteks näevad pinnad tänu neile välja siledamad ja palli saab eristada tavalisest kumerast hulktahukast nagu ikosaeedrist. Ja kuna normaalsed on nii olulised, peame õppima, kuidas neid Blenderi mudelite oma vormingusse teisendamisel säilitada.

Vastavad muudatused on üsna triviaalsed. Normaalid saame samamoodi nagu tipukoordinaadid ja UV-koordinaadid:

// osa protseduuri kehast importedModelCreate

jaoks (märgita int j = 0 ; j< face.mNumIndices ; ++ j) {
märgita int indeks = nägu.mIndeksid[ j] ;
aiVector3D pos = mesh->mTipud[ indeks] ;
aiVector3D uv = mesh-> mTextureCoords[ 0 ] [ indeks] ;
aiVector3D normaalne = võrk-> mNormaalid[ indeks] ;

VerticesBuffer[ tipudBufferIndex++ ] = pos.x ;
tipudBuffer[ tipudPuhvriindeks++ ] = pos.y ;
tipudBuffer[ tipudPuhvriindeks++ ] = pos.z ;
tipudBuffer[ tipudPuhvriindeks++ ] = normaalne.x ;
tipudBuffer[ tipudPuhvriindeks++ ] = normaalne.y ;
tipudBuffer[ tipudPuhvriindeks++ ] = normaalne.z ;
tipudpuhver[ tipudPuhvriindeks++ ] = uv.x ;
tipudpuhver[ tipudPuhvriindeks++ ] = 1.0f - uv.y ;
}

Mudeli optimeerimise protseduur muutub sarnaselt. Ja protseduuri modelLoad puhul vajame kahe atribuudimassiivi asemel nüüd kolme:

// mudeli Laadimisprotseduuri kehaosa

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

GlBindBuffer(GL_ARRAY_BUFFER, mudelVBO) ;
glBufferData(GL_ARRAY_BUFFER, header- > tipudDataSize, tipudPtr,
GL_STATIC_DRAW) ;

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

Lisaks vajame ühtset muutujat maatriksiga M:

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

// ...

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

... normaalse ruumi õigeks pööramiseks tipuvarjutajas:

#versioon 330 tuum

Paigutus(asukoht = 0 ) in vec3 vertexPos;
paigutus(asukoht = 1 ) vec3 tipusNorm;
paigutus(asukoht = 2 ) vektor2 tipusUV;

ühtne mat4 MVP;
vormimatt4 M;

välja vec2 fragmentUV;
välja vec3 fragment Normaalne;
välja vec3 fragmentPos;

void main() (
fragmentUV = tippUV;
fragmentNormaalne = (M * vec4 (tippNorm, 0 ) ) . xyz;
fragmentPos = (M * vec4 (vertexPos, 1 ) ) . xyz;

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

Lõpuks võtab fragmentide varjutaja normaalse interpolatsiooni kolme tipu vahel:

// ...

void main() (

// ...
}

Sel lihtsal viisil saame normaalsed väärtused killud.

Mis on Phongi valgustus?

Nagu märgitud, kirjutab OpenGL-i valgustuse varjunditesse programmeerija ise. On selge, et selle valgustuse rakendamiseks on rohkem kui üks viis, millest igaühel on oma realistlikkus ja ressursivajadus. Ja igal meetodil võib siiski olla lugematu arv konkreetseid rakendusi. Minu arusaamist mööda on tõhus ja realistlik reaalajas valgustus endiselt aktiivse uurimistöö valdkond. Selle postituse jaoks vaatleme Phongi valgustust, mis on nii üsna realistlik kui ka hõlpsasti rakendatav.

Oluline on mõista erinevust järgmiste mõistete vahel:

  • Gouraud varjutus on siis, kui arvutate iga tipu valgustatuse ja nendevaheliste fragmentide valgustus on interpoleeritud;
  • Phongi varjutus - kui valgustus arvutatakse iga fragmendi jaoks eraldi;
  • Phong-valgustus või Phongi peegeldusmudel on selles artiklis käsitletav spetsiifiline valgustusmeetod, mida saab kasutada nii Gouraud kui ka Phongi varjus;

Pole üllatav, et Phong-varjutus ja Phongi valgustus aetakse sageli segamini ning mõnest õpetusest võib lugeda jama nagu "Phong-varjutuse idee on kasutada kolme komponenti...", mis paneb teid kohe tugevalt kahtlema selle autoriteedis. isik, kes selle õpetuse kirjutas.

Nii palju kui mina aru sain, siis tänapäevastes rakendustes Gouraud varjutust peaaegu ei kasutata, selle asemel eelistatakse Phong-varjutust. Selles postituses kasutame ka Phong-varjutust ehk valgustust arvestatakse iga fragmendi jaoks eraldi. Spetsiifiline valgustusmeetod, mida me kasutame, on Phongi valgustus. See meetod on järgmine.

Erinevate valemite abil arvutatakse kolm valgustuskomponenti:

  • Ümbritsev valgustus on valguse imitatsioon, mis on pärast teistelt objektidelt peegeldumist jõudnud teatud punkti. Taustavalgustuse arvutamisel ei võeta arvesse ei normaalväärtusi ega kaamera hetkeasendit;
  • Hajusvalgustus on valgusallikast, mis hajub pärast antud punkti tabamist. Sõltuvalt valguse langemise nurgast muutub valgustus tugevamaks või nõrgemaks. See võtab arvesse tavalisi, kuid mitte kaamera asendit;
  • Spekulaarne valgustus on valgusallikast, mis peegeldub pärast antud punkti tabamist. Peegeldunud valgus on nähtav, kui see kaamerasse siseneb. Seetõttu võetakse siin arvesse nii normaalväärtusi kui ka kaamera asendit;

Seejärel summeeritakse tulemused, et saada kogu valgustus.

Et asi veelgi huvitavam oleks, on olemas erinevad valgusallikad. Ilmselgelt valgustavad päike õues ja taskulamp pimedas stseeni väga erinevalt. Esiteks vaatleme kõige lihtsamat allikat - suunavalgust.

Suunavalgus

Suunavalgus on lõpmata kaugel asuva valgusallika imitatsioon. Võtame näiteks Päikese. Päike on maast väga kaugel. Seetõttu võib Maa pinnal kõiki Päikesest lähtuvaid valguskiiri pidada suure täpsusega paralleelseks. Suunavalgust iseloomustavad selle suund, värv ja mõned koefitsiendid, mida me allpool vajame:

struct DirectionalLight(
vec3 suund;

vec3 värv;
float ambientIntensity;
ujuki hajusIntensiivsus;
float specularIntensiivsus;
} ;

Fragmendi varjutaja koodis defineerime calcDirectionalLight protseduuri, mida kasutatakse midagi sellist:

vektor3 fragmendis Pos;
ühtne vec3 cameraPos;
ühtlane SuundValgus suundValgus;

// ...

void main() (
// normaalne tuleks pärast interpoleerimist parandada
vec3 normaalne = normaliseerida (fragmentNormal) ;


suundvalgus) ;

// ...
}

Mõelgem menetluse rakendamisele.

vec4 calcDirectionalLight(vec3 normaalne, vec3 fragmentToCamera,
Suunavalgus) (
vec4 ambientColor = vec4 (hele. värv, 1) * hele. ambientIntensity ;

// ...
}

Esiteks arvutatakse esimene komponent - taustvalgustus. See on lihtsalt kiiratava valguse värvus, mis on korrutatud taustavalguse intensiivsusega. Siiani on kõik lihtne.

// ...

float difuuseFactor = max (0,0 , punkt (tavaline, - valgus. suund ) ) ;
vec4 hajusVärv = vec4 (hele. värv, 1) * hele. hajusIntensiivsus
* difuussetegur;

// ...

Hajutatud valgustus. DiffuseFactor muutuja tähistab fragmendi normaalnurga ja fragmendilt valgusallikani suunatud vektori vahelise nurga koosinust. Kui valgus langeb pinnaga risti, on nurk null. Selle nurga koosinus on võrdne ühega ja valgustus on maksimaalne (vt Vikipeedia artiklit Lamberti seaduse kohta). Nurga suurenedes koosinus väheneb ja muutub võrdseks nulliga, kui valgus on pinnaga paralleelne. Kui koosinus on negatiivne, siis on valgusallikas kuskil pinna taga ja see ei ole valgustatud, seega muudame negatiivsed väärtused nulliks, kasutades max(0,0, ...) . Lisaks valguse langemise nurgale võetakse arvesse ka hajutatud valguse intensiivsust.

// ...
vec3 valgusReflect = normaliseerima(peegelda(valgus. suund, normaalne));
float specular Factor = pow(
max (0,0 , punkt (fragmentToCamera, lightReflect) ,
materjali Spekulaartegur
) ;
vec4 specularColor = valgus. specularIntensity * vec4 (hele.värv, 1)
* materjalSpecularIntensity * specularFactor;
// ...

Kaudne valgustus. Muutuja lightReflect on ühikvektor, mis määrab peegeldunud valguse suuna. SpecularFactori muutuja arvutatakse sarnaselt diffuseFactorile, ainult seekord võtab see arvesse valguse peegeldussuuna ja fragmendist kaamerasse suunduva suuna vahelise nurga koosinust. Kui see nurk on null, siis peegelduv valgus lendab otse kaamerasse ja peegeldus pinnal on maksimaalne. Kui nurk on suur, ei tohiks pimestamist näha. Siin on materialSpecularFactor ühtlane muutuja. Mida suurem see on, seda väiksem on pimestamise ala objekti pinnal. Muutujat materialSpecularIntensity kasutatakse ka esiletõstude heleduse määramiseks. Pange tähele, et need on kõik materjali omadused, mitte valgus. Näiteks metall peegeldab valgust ja seetõttu on sellel pimestav. Kuid puit ei peegelda valgust ja siis ei näe puudel kunagi pimestamist (muidugi, kui pind on kuiv jne).

Ülaltoodud koodis on valgusel specularIntensity omadus. Kuid seda tuleks kasutada ainult silumiseks, et esile tõsta konkreetse valgusallika esiletõstmisi. Koodi väljalaskeversioonis peaks see koefitsient olema võrdne ühega või olema koodist täielikult eemaldatud.

Lõpuks lisatakse kolm komponenti ja tulemus tagastatakse:

// ...

return ambientColor + difuusneColor + specularColor;
}

Pole nii raske, eks?

Punktvalgusallikas

Punktvalgusallikaks on näiteks põlev lambipirn. Lambipirni valgus on suunatud igas suunas. Seetõttu ei iseloomusta punktvalgusallikat valguse suund, vaid seda iseloomustab allika asukoht ruumis:

struct PointLight(
vec3 asend;

vec3 värv;
float ambientIntensity;
ujuki hajusIntensiivsus;
float specularIntensiivsus; // silumise eesmärgil tuleks seada väärtusele 1.0
} ;

Punktvalgusallika valgustust on lihtne arvutada juba olemasoleva calcDirectionalLight protseduuri abil:

vec4 calcPointLight(vec3 normaalne, vec3 fragmentToCamera,
PointLighti tuli) (
vec3 lightDirection = normaliseerima (fragmentPos - light. position ) ;
ujuki kaugus = pikkus (fragmentPos - valgus. asend ) ;
ujuvpunktitegur = 1,0 / (1,0 + pow(kaugus, 2));

DirectionalLight tempDirectionalLight = Suunavalgus(
valguse suund,
valgus. värv,
valgus. ambientIntensity
valgus. hajusIntensiivsus
valgus. specularIntensiivsus
) ;
tagastuspunktitegur * calcDirectionalLight(tavaline, fragmentToCamera,
tempDirectionalLight) ;
}

Omades fragmendi ja valgusallika koordinaate, saate vektorite erinevuse kaudu hõlpsasti arvutada valguse suuna antud fragmendile. Punktfaktori kordaja peegeldab asjaolu, et valgus nõrgeneb selle allika kauguse ruuduga (vastavalt sfääri pindala raadiusest sõltuvuse valemile). PunktFactori arvutamisel lisatakse jagajale veel üks, et vältida nulliga jagamise võimalust. Pärast seda arvutatakse kõik täpselt samamoodi nagu suunavalguse puhul.

Kohtvalgus

Selle valgusallika näiteks on taskulamp. See sarnaneb punktvalgusallikaga, ainult sellel on lisaks suund ja mõjunurk (katkestus):

struct SpotLight (
vec3 suund;
vec3 asend;
ujuki väljalõige;

vec3 värv;
float ambientIntensity;
ujuki hajusIntensiivsus;
float specularIntensiivsus; // silumise eesmärgil tuleks seada väärtusele 1.0
} ;

Vastav protseduur:

vec4 calcSpotLight(vec3 normaalne, vec3 fragmentToCamera,
Kohtvalgusti) (
vec3 spotLightDirection = normaliseerima (fragmentPos - light. position ) ;
float spotAngleCos = punkt (spotLightDirection, light. direction) ;
ujuki sumbumine = (1,0–1,0 * (1,0 – spotAngleCos) /
(1,0 - hele. cutoff ) ;
float spotFactor = float (spotAngleCos > light. cutoff ) * sumbumine;

PointLight tempPointLight = PointLight(
valgus. positsiooni
valgus. värv,
valgus. ambientIntensity
valgus. hajusIntensiivsus
valgus. ambientIntensity
) ;
return spotFactor * calcPointLight(tavaline, fragmentToCamera,
tempPointLight);
}

Valguse suund arvutatakse samamoodi nagu punktallika puhul. Seejärel arvutatakse selle suuna ja valgusallika enda omadustes määratud suuna vahelise nurga koosinus. Kasutades väljendit float(spotAngleCos > light.cutoff) valgus on jäigalt kinnitatud määratud nurga alla. Sumbumise kordaja lisab sile valguse sumbumine, kui killud eemalduvad allika omadustes määratud valguse suunast. Pärast seda taandatakse kõik arvutused punktvalgusallika arvutusteks.

Gamma korrektsioon

Kogu fragmendivarjutaja põhiprotseduur näeb välja järgmine:

void main() (
// normaalne tuleks pärast interpoleerimist parandada
vec3 normaalne = normaliseerida (fragmentNormal) ;
vec3 fragmentToCamera = normaliseerima(kaameraPos - fragmentPos) ;

vec4 directColor = calcDirectionalLight(tavaline, fragmentToCamera,
suundvalgus) ;
vec4 pointColor = calcPointLight(tavaline, fragmentToCamera,
pointLight);
vec4 spotColor = calcSpotLight(normaalne, fragmentToCamera, spotlight) ;
vec4 linearColor = tekstuur(tekstuurinäidis, fragmentUV) *
(vec4(materjalEmission, 1) + DirectColor +
pointColor + spotColor);

vec4 gamma = vec4 (vec3 (1,0/2,2), 1);
värv = pow(lineaarneVärv, gamma); // gammakorrigeeritud värv
}

Ärge pöörake palju tähelepanu materjalileEmissioon. See on lihtsalt veel üks materjali omadus, mis lisab oma sära. Paljud objektid helendavad iseenesest. Võtke samad lambipirnid, mis toimivad valgusallikana teistele objektidele. Me peaksime nägema neid täielikus pimeduses, isegi kui pirne ei valgusta ükski muu valgusallikas, eks?

Tõepoolest väärib tähelepanu gammakorrektsioon, mis seisneb kõigi valguskomponentide tõstmises 1/2,2 astmeni. Seni oleme töötanud lineaarses värviruumis, eeldades, et intensiivsusega 1,0 värv on kaks korda heledam kui intensiivsusega 0,5 värv. Probleem on selles, et inimsilm ei taju heledust lineaarselt. Seetõttu on realistliku valgustuse saamiseks vaja pärast kõiki lineaarruumi arvutusi teha gammakorrektsioon.

Arvestada tuleks sellega, et pildi salvestamisel teostavad tänapäevased graafilised redaktorid ka gammakorrektsiooni. Seetõttu peate enne tekstuuride kasutamist selle gammakorrektsiooni tühistama. Õnneks pole see raske.

Piisab, kui asendada kõik konstandid tekstuuri laadimiskoodis:

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

… vastavalt. See näitab, et pildile on rakendatud gammaparandus ja see tuleb tagasi võtta. OpenGL hoolitseb ülejäänu eest.

Reaalsetes rakendustes on gamma parameeter (meil gamma = 2,2) paremini paigutatud programmi seadistustesse, et kasutaja saaks seda soovi korral oma monitorile veidi kohandada.

Järeldus

On aeg pilte vaadata!

Siin näeme erinevaid valgustuskomponente. Vasakult paremale, ülalt alla: taust, hajus, peegeldunud, kõik kolm koos. Nagu näha, on sündmuskohale lisatud toruse mudel. Normaalide keeruka paigutuse tõttu on see mudel soovitatav valgustuse testimiseks.

Erinevad valgusallikad. Vasakult paremale, ülalt alla: valge kohtvalgusti, punane kohtvalgusti, sinine prožektor, kõik kolm koos.

Lubage mul veel kord märkida, et samal valgustusmeetodil võivad olla erinevad teostused. Näiteks saate määrata materjali omadusteks ümbritseva, hajutatud ja peegeldava värvi, mis võimaldab teil joonistada punaseid objekte, mis hajuvad roheliselt ja millel on sinine esiletõstmine. Mõnes Phongi valgustusrakenduses olen näinud, et taustavalgustust arvutatakse üks kord, mitte iga valguse jaoks. Nägin ka teostusi, kus punktallika valgus tuhmus mitte lihtsalt võrdeliselt selle kauguse ruuduga (d * d), vaid üldisema valemi järgi (stiilis A + B*d + C* d*d). Keegi muudab ümbritseva intensiivsuse ja hajutatud intensiivsuse mitte ainult valgusallika, vaid ka materjali omaduseks. Kuid ma pole kindel, kui palju see kõik on seotud realistliku valgustusega. Seda kõike saab aga kodutööna mängida.

Aastate teosed. Vološin Maximilian. POEEDI VÄÄRSUS. 1. Redigeerige luuletust nagu välismaale saadetud teksti: kuivus, selgus, surve – iga sõna on valvel.

Kõval ja kitsal kivil täht-tähe haaval lõikamine: Mida hõredamad on sõnad, seda intensiivsem on nende jõud. Mõtte tahtlik laeng võrdub vaikivate stroofidega.

Kustutage sõnastikust sõnad "Ilu", "Inspiratsioon" - riimide alatu žargoon. Luuletajale - arusaamad: Tõde, kujundus, plaan, samaväärsus, kokkuvõtlikkus ja täpsus. Kaines ja raskes töös on luuletaja inspiratsioon ja au: teravdada transtsendentaalset valvsust kurttummas aines. Voloshin M.A. Raamatukogu: nime saanud Oryoli piirkondlik teaduslik universaalne avalik raamatukogu. I.A. Bunina. - M., ; Valitud teosed: 2 köites.

M., ; Punane suits: lood. - M., ; Gladõšev luurefirmast: lood. - M., ; Ešelon; Paratamatus: romaanid. Ta tegi palju tõlkeid mari ja udmurdi luuletajaid. Aeg-ajalt proovisin kätt ka proosas. Op. Maximilian Aleksandrovitš Vološin () on 20. sajandi esimese kolmandiku üks suurimaid luuletajaid. Ta on andekas kunstnik, mitmekülgne lüürik, kes on läbinud tee sümbolistlikest, esoteerilistest luuletustest kodanikuajakirjandusliku ja teadusfilosoofilise luuleni, antroposoofiliste eelsoodumuste kaudu – “Jumala linna ideaalini”.

Kavandatav väljaanne annab lugejale võimaluse tutvuda mitte ainult Vološini parimate poeetiliste teostega, vaid ka tema kõige huvitavamate esteetikateostega, memuaariproosaga, ajakirjandusega ja kirjadega, mis on seotud dramaatiliste sündmustega riikide elus. Autor. Vološin Maximilian. Kõik autori luuletused. Töö. Luuletaja vaprus. 2. Tähed. Looge autorite ja luuletuste lemmikkogusid!

Vestelge mõttekaaslastega! Kirjutage arvustusi, osalege luuleduellidel ja -võistlustel! Liituge parimatega! Täname Luuleraamatuga liitumise eest! Sinu meilile on saadetud kiri konto juurdepääsuandmetega!

Peate sisse logima 24 tunni jooksul. Vastasel juhul konto kustutatakse! Registreeritud kasutajad saavad palju eeliseid: avaldage luulet – realiseerige oma talent! Looge autorite ja luuletuste lemmikkogusid! Vestelge mõttekaaslastega! Kirjutage arvustusi, osalege luuleduellidel ja -võistlustel!. Maximilian Vološin. Kirjeldus. Maximilian Aleksandrovitš Vološin on 20. sajandi esimese kolmandiku üks suurimaid luuletajaid.

Ta on andekas kunstnik, mitmekülgne lüürik, kes on läbinud tee sümbolistlikust, esoteerilisest luuletusest kodanikuajakirjandusliku ja teadusfilosoofilise luuleni, läbi antroposoofiliste eelsoodumuste – “Jumala linna ideaalini”. Kavandatav väljaanne annab lugejale võimaluse tutvuda mitte ainult Vološini parimate poeetiliste teostega, vaid ka tema kõige huvitavamate esteetikateostega, memuaariproosa, ajakirjanduse ja draamaga seotud kirjadega.

Valitud teosed ja kirjad. M. A. Vološin. Hind. hõõruda. Maximilian Aleksandrovitš Vološin on 20. sajandi esimese kolmandiku üks suurimaid luuletajaid. Ta on andekas kunstnik, mitmekülgne lüürik, kes on läbinud tee sümbolistlikust, esoteerilisest luuletusest kodanikuajakirjandusliku ja teadusfilosoofilise luuleni, läbi antroposoofiliste eelsoodumuste – “Jumala linna ideaalini”.

Voloshin M.A., Poeedi vaprus: valitud teosed ja kirjad. sari: Uus vene klassika raamatukogu: nõutav eksemplar Paraad, linn, leht, Raamatu kirjeldus. Maximilian Aleksandrovitš Vološin () on 20. sajandi esimese kolmandiku üks suurimaid luuletajaid. Ta on andekas kunstnik, mitmetahuline lüürik, kes on läbinud tee sümbolistlikust, esoteerilisest luuletusest kodanikuajakirjandusliku ja teadusfilosoofilise luuleni, läbi antroposoofiliste eelsoodumuste – “Jumala linna ideaalini”.

Kategooriad Postituse navigeerimine

Ilma valgusallikata pole pilti näha. Allika lähtestamiseks ja protsessori lubamiseks allika mõju objektidele arvutamiseks täitke lihtsalt käsud: glEnable(gl_lighting); // lubage valgustuse analüüsi režiim

GlEnable(gl_light0); // kaasama stseeni konkreetse (null)allika koos selle tunnustega

Allika keelamiseks kasutage funktsiooni Disable(). Vaikimisi asub valgusallikas koordinaatidega (0,0,∞) ruumis. Saate luua valgusallika kõikjal pildiruumis.

OpenGl teek toetab nelja tüüpi valgusallikaid:

  • taustvalgustus (ümbritsev valgustus),
  • punktallikad,
  • prožektorid,
  • kaugvalgusallikad (kaugvalgus).
Igal valgusallikal on oma omadused.
Valgusallika omadused vastavad Phongi mudeli parameetritele.
Vektoriparameetrite määramiseks kasutage funktsiooni glLightfv(), millel on järgmine vorming:

glLightfv(allikas, parameeter, pointer_to_masse);

On neli vektori parameetrit, mis määravad allikakiirte asukoha ja suuna ning selle komponentide värvikompositsiooni – taust, hajus ja spekkulaarne.
Skalaarsete parameetrite määramiseks OpenGL-is kasutage funktsiooni glLightf():

glLightf(allikas, parameeter, väärtus);

Olgu näiteks, et soovite stseenis kaasata allika GL_LIGHT0, mis peaks asuma punktis (1.0, 2.0, 3.0). Lähtekoht salvestatakse programmi ühtsete koordinaatidega punktina:

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

Kui selle punkti neljas komponent on null, muutub punktallikas kaugallikaks, mille jaoks on oluline ainult kiirte suund:

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

Järgmisena määratakse allika tausta, difusiooni ja spekulaarkomponentide värvikompositsioon. Kui vaadeldavas näites on allikal valget värvi spekulaarne komponent ning taust- ja difusioonikomponendid peaksid olema punased, siis allika moodustav programmifragment näeb välja selline:

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_VALGUS0, GL_POSITION, valgus0_pos);

GlLightfv(GL_LIGHT0, GL_AMBIENT, ambient0);

GlLightfv(GL_VALGUS0, GL_DIFFUSE, hajus0);

GlLightfv(GL_VALGUS0, GL_SPECULAR, specular0);

Saate lisada stseenile ka globaalse taustvalgustuse, mis ei ole seotud ühegi üksiku valgusallikaga. Kui soovite näiteks kõik stseeni objektid valgega hämaralt esile tõsta, peaksite programmi lisama järgmise koodilõigu:

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

GlLightModelfv(GL_LIGHT_MODEL_AMBIENT, globaalne_ambient);

Valgustusmudelis on allika kaugust arvestav termin järgmine:

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

Ja konstantsed, lineaarsed ja ruutkomponendid. Iga allika vastavad koefitsiendid määratakse individuaalselt, kasutades skalaarsete parameetrite seadistusfunktsiooni, näiteks:

GlLightf(GL_LIGHT0, GL_CONSTANT_ATTENATION, a);

Punktallika prožektoriks teisendamiseks peate määrama prožektori kiire suuna (GL_SPOT_DIRECTION), intensiivsuse jaotusfunktsiooni indikaatori (GL_SPOT_EXPONENT) ja kiire hajumise nurga (GL_SPOT_CUTTOF). Need parameetrid määratakse funktsioonide glLightf() ja glLightfv() abil.

Valgusallikate vaikeparameetrid on näidatud tabelis 3.

Tulede vaikesätted

Tabel 3

Parameetri nimi Vaikeväärtus Sisu
GL_AMBIENT (0.0, 0.0, 0.0, 1.0) ümbritsev RGBA valguse intensiivsus
GL_DIFFUSE (1.0, 1.0, 1.0, 1.0) hajutatud RGBA valguse intensiivsus
GL_SPECULAR (1.0, 1.0, 1.0, 1.0) Spekulaarne RGBA valguse intensiivsus
GL_POSITION (0.0, 0.0, 1.0, 0.0) (x, y, z, w) valguse asend
GL_SPOT_DIRECTION (0.0, 0.0, -1.0) (x, y, z) prožektori suund
GL_SPOT_EXPONENT 0.0 prožektori eksponent
GL_SPOT_CUTOFF 180.0 prožektorite lõikenurk
GL_CONSTANT_ATTENUATION 1.0 konstantne sumbumistegur
GL_LINEAR_ATTENUATION 0.0 lineaarne sumbumistegur
GL_QUADRATIC_ATTENUATION 0.0 ruutsummutustegur