Opengl ішіндегі нүктелік жарық көзі. Біз OpenGL зерттеуімізді жалғастырамыз: Phong бойынша жарықтандыру. Барлығын біріктіру

OpenGL ES жүйесіндегі жарықтандыру 3D ойындарына жағымды әсер қосатын пайдалы мүмкіндік болып табылады. Осындай функционалдылықты пайдалану үшін алдымен OpenGL ES жарықтандыру моделін түсінуіміз керек.

Жарықтандыру қалай жұмыс істейді

Жарықтандыру қалай жұмыс істейтіні туралы ойланайық. Алдымен бізге жарық шығаратын жарық көзі қажет. Сондай-ақ сізге жарықтандырылған нысан қажет болады. Соңында, бізге жарық көзі жіберетін және объект шағылысқан фотондарды қабылдайтын көз немесе камера сияқты сенсор қажет. Жарықтандыру заттың қабылданатын түсін өзгертеді: жарық көзінің түріне; жарық көзінің түсі немесе қарқындылығы; жарық көзінің орны және оның жарықтандырылған объектіге қатысты бағыты; объектінің материалы мен құрылымы.

Жарықтың объектінің шағылысу қарқындылығы көптеген факторларға байланысты. Біз қарастыратын ең маңызды фактор - жарық сәулесінің бетке түсетін бұрышы. Бұл бұрыш тік бұрышқа неғұрлым жақын болса, жарықтың объектіден шағылысу қарқындылығы соғұрлым жоғары болады. Бұл суретте көрсетілген. 11.1.

Жарық сәулесі бетке түскенде, ол екі түрлі бағытта шағылысады. Жарықтың көп бөлігі диффузиялық түрде шағылысатын болады. Бұл шағылған жарық сәулелерінің объектінің бетінде біркелкі емес және кездейсоқ шашырағанын білдіреді. Кейбір сәулелер айнымалы түрде шағылысады. Бұл жарық сәулелері тамаша айнаға түскендей кері шағылысатынын білдіреді. Суретте. 11.2-суретте диффузиялық және спекулярлық шағылысулардың айырмашылығы көрсетілген.

Күріш. 11.1. Бұрыш тік бұрышқа неғұрлым жақын болса, шағылған жарықтың қарқындылығы соғұрлым жоғары болады

Күріш. 11.2. Шашыраңқы және спекулярлық шағылыстар

Айналымдық шағылыстар нысандарда бөлектеу ретінде пайда болады. Жарықтың объектіден шағылысуы оның жасалған материалына байланысты. Тері сияқты беті біркелкі емес немесе кедір-бұдырлы нысандарда ерекше ерекшеліктер болмайды. Шыны немесе мәрмәр сияқты тегіс беті бар нысандар бұл жеңіл артефактілерді көрсетеді. Әрине, шыны немесе мәрмәр мінсіз тегіс емес, бірақ ағаш немесе адам терісімен салыстырғанда, олар.

Жарық бетке түскенде оның шағылысуы да түске байланысты өзгереді химиялық құрамыжарықтандырылған нысан. Бізге қызыл болып көрінетін нысандар жарықтың тек қызыл бөліктерін көрсетеді және барлық басқа жиіліктерді жұтады. Қара зат – өзіне түскен жарықтың барлығын дерлік жұтып алатын зат.

OpenGL ES жарық көздері мен объектілік материалдарды анықтау арқылы нақты дүниедегі мінез-құлықты модельдеуге мүмкіндік береді.

Жарық көздері

Бізді әртүрлі жарық көздері қоршап тұр. Күн үнемі өзінің фотондарын жібереді. Мониторлар түнде бізді жағымды жарқылмен қоршап тұрған жарық шығарады. Шамдар мен фаралар қараңғыда әртүрлі заттармен соқтығысудан аулақ болуға көмектеседі. OpenGL ES жарық көздерінің төрт түрін жасауға мүмкіндік береді.

Артқы жарық. Ол өздігінен жарық көзі емес, басқа жарық көздерінен фотондардың пайда болуының нәтижесі. Бұл кездейсоқ фотондар бірігіп, бағыты жоқ және барлық нысандарды бірдей жарықтандыратын тұрақты жарық деңгейін жасайды.

Нүктелік жарық көздері. Олардың кеңістікте орны бар және барлық бағытта жарық шығарады. Мысалы, жарықтың нүктелік көзі - электр шамы.

Бағытты жарықтандыру көздері. OpenGL ES нұсқаулығы ретінде көрсетілген. Олар шексіз алыс деп есептеледі. Ең дұрысы, Күн мұндай көз болуы мүмкін. Күннен келетін барлық жарық сәулелері Жер мен Күннің арақашықтығына байланысты Жерге бір бұрышта түседі деп болжауға болады.

Шамдар туралы. Бұл шамдар нүктелік шамдарға ұқсас, өйткені олардың кеңістікте белгілі бір орны бар. Сонымен қатар, олардың жарық сәулелерін шығаратын бағыты бар. Олар белгілі бір радиуспен шектелген жеңіл конус жасайды. Мұндай жарық көзінің мысалы - көше шамы.

Біз тек артқы жарықтандыруды, сондай-ақ нүктелік және бағытталған жарық көздерін қарастырамыз. OpenGL ES жарықтандыруды есептеу әдісіне байланысты GPU шектелген Android құрылғыларында шамдарды пайдалану жиі қиын. Неліктен бұлай екенін көп ұзамай түсінесіз.

Жарық көзінің орны мен бағытына қосымша, OpenGL ES жарықтың түсін немесе қарқындылығын анықтауға мүмкіндік береді. Бұл сипаттамалар RGBA түсі арқылы көрсетіледі. Дегенмен, OpenGL ES бір көзге бір емес, төрт түрлі түсті анықтауды талап етеді.

Бөлектеу - нысанның көлеңкеленуіне ықпал ететін қарқындылық/түс. Нысан жарық көзіне қатысты орналасуына немесе бағдарына қарамастан барлық жағынан бірдей жарықтандырылады.

Диффузиялық – диффузиялық шағылуды есептегеннен кейін объектіні жарықтандыратын жарықтың қарқындылығы/түсі. Нысанның жарық көзіне қарамайтын шеттері нақты өмірдегідей жарықтанбайды.

Айналым – диффузиялық түске ұқсас қарқындылық/түс. Дегенмен, ол жарық көзіне және сенсорға қатысты белгілі бір бағдары бар объектінің нүктелеріне ғана әсер етеді.

Эмиссивті - бұл нақты әлемдегі физика қолданбаларында өте шектеулі қолданылатын өте күрделі түсті есептеу, сондықтан біз оны қарастырмаймыз.

Көбінесе біз жарық көзінің диффузиялық және спекулярлық қарқындылығын қолданамыз және қалған екі әдепкі мәнді береміз. Сондай-ақ, көп жағдайда біз диффузиялық және спекулярлық қарқындылық үшін бірдей RGBA түсін қолданамыз.

Материалдар

Біздің әлемдегі барлық объектілер қандай да бір материалдан тұрады. Әрбір материал затқа түсетін жарықтың қалай шағылатынын және шағылған жарықтың түсін өзгертетінін анықтайды. OpenGL ES сізге жарық көзі сияқты материал үшін бірдей төрт RGBA түсін анықтауға мүмкіндік береді.

Артқы жарық – көріністегі кез келген жарық көзінің фон түсімен үйлесетін түс.

Диффузиялық - кез келген жарық көзінің диффузиялық түсімен үйлесетін түс.

Specular - бұл кез келген жарық көзінің спекулярлық түсімен үйлесетін түс. Ол нысанның бетінде бөлектеулерді жасау үшін қолданылады.

Эмиссивті - біз түстердің бұл түрін елемейміз, өйткені ол біздің контексте іс жүзінде қолданылмайды.

11.3-сурет материал/жарық көзі қасиеттерінің алғашқы үш түрін көрсетеді: артқы жарық, диффузиялық және айнымалы.

Күріш. 11.3. Материалдардың/жарық көздерінің әртүрлі түрлері: тек артқы жарық (сол жақта), тек диффузиялық (ортаңғы), артқы жарық және ерекше жарықтандырулары бар диффузиялық түс (оң жақта)

Суретте. 11.3-суретте материалдар мен жарық көздерінің әртүрлі қасиеттерінің түске әсері көрсетілген. Артқы жарық өлшемді біркелкі жарықтандырады. Жарық сәулелерінің объектіге түсу бұрышына қарай шашыраңқы жарық шағылысатын болады; Жарық көзіне тікелей қараған аумақтар жарықтандырылады, ал жарық жетпейтін жерлер қараңғы болады. Оң жақтағы суретте сіз артқы жарық, диффузиялық және спекулярлық жарықтың комбинациясын көре аласыз. Айналмалы жарық сферада ақ нүктелер ретінде пайда болады.

OpenGL ES жарықтандыруды қалай есептейді: шыңның нормасы

Нысаннан шағылған жарықтың қарқындылығы оның объектіге түсу бұрышына байланысты екенін білесіз. OpenGL ES бұл фактіні жарықтандыруды есептеу үшін пайдаланады. Ол үшін текстура координаттары немесе шыңдарының түстері сияқты кодта анықталуы керек шыңның қалыпты мәндерін пайдаланады. Суретте. 11.4-суретте шар және оның төбесінің нормальдары көрсетілген.

Күріш. 11.4. Шар және оның шыңының нормальдары

Қалыптылар - беттің бұрылу бағытын көрсететін бірлік векторлар. Біздің жағдайда беті үшбұрыш болып табылады. Нормал бетті анықтаудың орнына нормаль шыңын анықтаймыз. Бұл нормалдардың арасындағы айырмашылық нормаль шыңы беттің нормаль бағытымен бірдей бағытты көрсетпеуі мүмкін. Бұл суретте анық көрінеді. 11.4, мұндағы әрбір төбе нормасы төбесі жататын барлық үшбұрыштардың орташаланған нормальы болып табылады. Бұл орташалау нысанның тегіс көлеңкесін жасау үшін орындалады.

Жарықтандыруды және шыңның нормасын пайдаланып нысанды көрсету кезінде OpenGL ES әрбір шың мен жарық көзі арасындағы бұрышты анықтайды. Егер ол осы бұрышты білсе, материалдың қасиеттеріне сүйене отырып, төбенің түсін есептей алады. Ақырғы нәтиже әрбір төбенің түсі болып табылады, содан кейін ол әр үшбұрышқа басқа шыңдардың есептелген түстерімен үйлесімде қолданылады. Пайдаланылған бұл түс нысанға қолданатын кез келген құрылымдық түрлендірулермен біріктіріледі.

Бұл өте қорқынышты естіледі, бірақ іс жүзінде бұл жаман емес. Біз жарықтандыруды қосып, жарық көздерін, өңделетін материалды және шыңның нормасын анықтауымыз керек (орын немесе текстура координаттары сияқты біз әдетте анықтайтын шың параметрлеріне қосымша). Мұны OpenGL ES көмегімен қалай жүзеге асыруға болатынын қарастырайық.

Іс жүзінде

Енді OpenGL ES көмегімен жарықтандырумен жұмыс істеуге қажетті барлық қадамдарды орындайық. Жарық көздерімен жұмыс істеуді жеңілдететін бірнеше шағын көмекші сыныптарды жасап, оларды com.badlogi with.androi dgames.framework.gl бумасына орналастырайық.

Жарықтандыруға рұқсат беру және тыйым салу

Басқа OpenGL ES күйлері сияқты, алдымен аталған функцияны қосу керек. Мұны келесідей жасауға болады:

Осыдан кейін жарықтандыру барлық көрсетілген нысандарға қолданылады. Нәтижеге қол жеткізу үшін жарық көздері мен материалдарды, сондай-ақ шыңдардың нормасын анықтау керек. Барлық қажетті нысандарды салуды аяқтағаннан кейін, жарықтандыруды өшіруге болады:

Жарық көздерін анықтау

OpenGL ES жарық көздерінің 4 түрін қамтамасыз етеді: артқы жарық, нүктелік, бағытталған және жарықтандыру. Алғашқы үштікті қалай анықтау керектігін қарастырайық. Шамдар тиімді және жақсы көрінуі үшін әр модель көптеген үшбұрыштардан тұруы керек. Бұл қазіргі көптеген мобильді құрылғылар үшін мүмкін емес.

OpenGL ES бір уақытта ең көбі 8 жарық көзін, сондай-ақ бір ғаламдық жарық көзін анықтауға мүмкіндік береді. 8 жарық көзінің әрқайсысында GL10.GL LIGHT0-ден GL10.GL LIGHT7-ге дейінгі идентификатор бар. Осы шамдардың біреуінің қасиеттерін өзгерту қажет болса, оны сәйкес идентификаторды анықтау арқылы жасауға болады.

Келесі синтаксисті пайдаланып шамдарды пайдалануды қосуға болады:

Әрі қарай, OpenGL ES осы жарық көзінің қасиеттерін алады және оларды барлық көрсетілген нысандарға қолданады. Жарық көзін пайдалануды өшіру қажет болса, біз мұны келесі мәлімдеме арқылы жасай аламыз:

Бөлектеу ерекше жағдай, себебі оның идентификаторы жоқ. OpenGL ES көрінісінде тек бір бөлектеу болуы мүмкін. Осы жарықтандыру көзін толығырақ қарастырайық.

Артқы жарық

Артқы жарықтандыру - жарықтандырудың ерекше түрі. Оның орны немесе бағыты жоқ, тек барлық жарықтандырылған нысандарға бірдей қолданылатын түс. OpenGL ES жаһандық бөлектеуді келесідей анықтауға мүмкіндік береді:

ambi entCol немесе массив 0-ден 1-ге дейінгі өзгермелі нүкте сандары ретінде ұсынылған артқы жарық түсінің RGBA мәндерін қамтиды. gl LightModel fv әдісі өзінің бірінші параметрі ретінде фондық жарықтың түсін орнатқымыз келетінін көрсететін тұрақты мәнді алады. көз, бастапқы түсті қамтитын өзгермелі нүкте сандарының жиымы және әдіс RGBA мәндерін оқи бастайтын қалқымалы массивтің ығысуы. Бұл мәселені шешетін кодты шағын сыныпқа орналастырайық. Оның коды 11.2 листингте көрсетілген.

Листинг 11.2. AmbientLight.java класы. қарапайым ғаламдық жарықтандыру абстракциясы ODenGL ES

Біз тек қана бөлектеу түсін қалқымалы массивте сақтаймыз және екі әдісті қамтамасыз етеміз: біреуі түсті орнату үшін, екіншісі OpenGL ES-ке осы түсті пайдалануды айту үшін қолданылады. Әдепкі түс - сұр.

Нүктелік жарықтандыру көздері

Нүкте шамдарының позициясы, сондай-ақ өңі, диффузиялық және спекулярлық түсі/қарқындылығы бар (біз эмиссиялық түс/қарқындылықты қарастырмаймыз). Анықтаңыз әртүрлі түрлерітүстер келесідей:

Бірінші параметр - жарық көзінің идентификаторы. Бұл жағдайда біз төртінші көзді пайдаланамыз. Келесі параметр өзгерткіміз келетін төлсипатты көрсетеді. Үшінші параметр RGBA мәндерін қамтитын өзгермелі нүктелі сандар массиві, ал соңғысы осы массивтегі ығысу болып табылады. Көздің орнын анықтау оңай:

Біз өзгерткіміз келетін атрибутты (бұл жағдайда позиция) тағы да анықтаймыз, құрылып жатқан әлемдегі жарық көзінің x-, y- және z-координатасын қамтитын төрт элементті массив. Жарық көзінің позициясы болса, массивтің төртінші элементі біреуге тең болуы керек екенін ескеріңіз. Мұны көмекші сыныпқа орналастырайық. Оның коды 11.3 листингте қамтылған.

Листинг 11.3. Point.Light.java класы, OpenGL ES нүкте шамдарының қарапайым абстракциясы

Біздің көмекші сыныпта жарықтың фондық, диффузиялық және нақты түсті құрамдас бөліктері, сондай-ақ позиция бар (төртінші элемент - біреу). Сонымен қатар, біз берілген көз үшін пайдаланылған соңғы идентификаторды сақтаймыз, сондықтан қажет болған жағдайда жарықты өшіретін disableO әдісін жасауға болады. Бізде GL10 класының данасын және жарық көзі идентификаторын қабылдайтын enableO әдісі де бар (мысалы, GL10.GL LIGHT6). Ол жарықтандыруды пайдалануға мүмкіндік береді, оның атрибуттарын орнатады және пайдаланылған идентификаторды сақтайды. disableO әдісі қосу әдісіндегі 1ast.Ligh.tId сынып мүшесі жиынын пайдаланып жарықтандыруды пайдалануды жай ғана өшіреді.

Сынып мүшелерінің массивтерін инициализациялау кезінде фондық, диффузиялық және нақты түстер үшін қолайлы әдепкі мәндерді қолданамыз. Жарық ақ болады және ешқандай жарқырауды тудырмайды, өйткені оның нақты құрамдас бөлігі қара.

Бағытталған жарық көздері

Бағытталған жарық көздері нүктелік шамдармен дерлік бірдей. Жалғыз айырмашылығы - оларда позицияның орнына бағыт бар. Бағытты білдіру тәсілі біршама түсініксіз. Бағытты көрсету үшін векторды пайдаланудың орнына, OpenGL ES бізден бір нүктені анықтауды күтеді. Содан кейін бағыт осы нүкте мен координаторды қосатын вектор арқылы анықталады. Келесі үзінді әлемнің оң жағынан келетін бағытталған жарық көзін жасауға мүмкіндік береді:

Оны векторға түрлендіруге болады:

Фон немесе диффузиялық түс сияқты басқа атрибуттар нүктелік жарықтың атрибуттарымен бірдей. 11.4 листинг бағыттағы шамдарды жасау үшін пайдаланылатын шағын көмекші сыныптың кодын көрсетеді.

Листинг 11.4. Directi onLi класы ght.java, OpenGL ES жүйесіндегі бағытталған жарық көздерінің қарапайым абстракциясы

Бұл көмекші класс PointLight сыныбымен дерлік бірдей. Жалғыз айырмашылық - массивтегі Directi-де төртінші элемент бір. Сонымен қатар, setPosition әдісінің орнына setDirecti on әдісі пайда болды. Ол бағытты анықтауға мүмкіндік береді, мысалы: (-1; 0; 0), бұл жағдайда жарық оң жақтан түседі. Әдістің ішінде вектордың барлық компоненттері таңбасын өзгертеді, сондықтан бағытты OpenGL ES күткен форматқа түрлендіреміз.

Материалдарды анықтау

Материал бірнеше атрибуттармен анықталады. Кез келген басқа OpenGL ES нысанындағы сияқты материал - біз оны қайтадан өзгерткенше немесе OpenGL ES мәтінмәні жоғалмайынша белсенді болып қалатын күй. Ағымдағы материал атрибуттарын орнату үшін келесі әрекеттерді орындауға болады:

Әдеттегідей, біз фондық, диффузиялық және нақты RGBA түстерін анықтауымыз керек. Мұны бұрынғыдай - төрт элементтен тұратын өзгермелі нүктелі сандар массивтерін пайдалану арқылы жасауға болады.

Бұл әрекеттерді бір көмекші сыныпқа біріктіру өте қарапайым. Нәтижені 11.5 листингтен көре аласыз.

Листинг 11.5. Материалдық Java класы, OpenGL ES материалдарының қарапайым абстракциясы

Мұнда да таң қаларлық ештеңе жоқ. Біз жай ғана материалды сипаттайтын үш құрамдас бөлікті сақтаймыз, сонымен қатар олардың мәндерін орнату функцияларын және оларды OpenGL ES жүйесіне беретін қосу әдісін қамтамасыз етеміз.

OpenGL ES-тің материалдарға қатысты тағы бір мүмкіндігі бар. Ол әдетте glMaterialfvO әдісінің орнына материалдық түс деп аталатын нәрсені пайдаланады. Бұл glMateri al fv әдісімен анықталатын фон және диффузиялық түстердің орнына OpenGL ES материалдың фон және диффузиялық түстері ретінде біздің үлгілеріміздің шыңдарының түсін қабылдайтынын білдіреді. Бұл мүмкіндікті қосу үшін сіз жай ғана қоңырау шалыңыз:

Мен әдетте осылай істеймін, себебі фон және диффузиялық түстер жиі бірдей. Ойындарымның және демонстрацияларымның көпшілігінде ерекше көріністерді қолданбайтындықтан, мен бұл әдісті оңай пайдалана аламын және glMaterial fv әдісін мүлде шақырмаймын. Оны қандай жолмен қолдануды өзіңіз шешесіз.

Нормаларды анықтау

OpenGL ES жүйесінде жарықтандыру жұмыс істеуі үшін үлгідегі әрбір шың үшін шың нормасын анықтау керек. Шыңның нормальы төбе жататын беттің бұрылу бағытын көрсететін (әдетте) бірлік вектор болуы керек. Суретте. 11.5-суретте текшенің шыңы нормальдары көрсетілген.

Күріш. 11.5. Біздің текшенің әрбір шыңы үшін шың нормасы

Қалыпты шыңы - позиция немесе түс сияқты шыңның басқа атрибуты. Шың нормасының артықшылығын пайдалану үшін Verti ces3 сыныбын қайтадан өзгерту керек. OpenGL ES-ке әрбір шың үшін норманы қайдан таба алатынын айту үшін, біз gl VertexPointer немесе gl Col немесе Pointer әдістерін пайдаланғанымыздай, gl Normal PointerO әдісін қолданамыз. 11.6 листинг Vertices3 класының соңғы нұсқасын көрсетеді.

Листинг 11.6. Vertices3.Java класы, қалыптыларды қолдайтын соңғы нұсқасы

Сыныпта шыңдардың қалыпты мәндері бар-жоғын қадағалайтын жаңа hasNormal.s мүшесі бар.

Конструктор енді hasNormals параметрін де қабылдайды. Мүмкіндігінше әрбір шыңға үш қалқымалы мәнді қосу арқылы vertexSize мүшесінің есебін әлі де өзгертуіміз керек.

Көріп отырғаныңыздай, setVertices және setlndices әдістері өзгеріссіз қалады.

Біз жаңа ғана көрсеткен bindO әдісінде біз бұрынғыдай ByteBuffer-мен бірдей әдістерді қолданамыз, бірақ бұл жолы қалыпты мәндерді gl Қалыпты көрсеткіш әдісі арқылы қосамыз. Қалыпты көрсеткіштің ығысуын есептеу үшін текстура мен түс координаталары көрсетілгенін ескеру қажет.

Көріп отырғаныңыздай, ұтыс әдісі де өзгерген жоқ; барлық әрекет O байлау әдісінде орындалады.

Соңында unbindO әдісін аздап өзгертеміз. Біз қалыпты көрсеткіштерді пайдалануды өшіреміз, егер бар болса, OpenGL ES күйін сәйкесінше тазартамыз.

Өзгертілген Verti ces3 сыныбын қолдану бұрынғыдай оңай. Шағын мысалды қарастырайық:

Біз үш шыңды сақтау үшін өзгермелі нүкте массивін жасаймыз, олардың әрқайсысында позиция (әр жолдағы алғашқы үш сан) және қалыпты (әр жолда соңғы үш сан) бар. Бұл жағдайда xy жазықтығында оның нормальдары z осінің оң бөлігінің бағытын көрсететін үшбұрышты анықтаймыз.

Бізге тек Vertices3 класының данасын жасау және шыңдардың мәндерін орнату жеткілікті. Өте оңай, солай емес пе?

Барлық байланыстыру, сызу және жабу жұмыстары сыныптың алдыңғы нұсқасындағыдай орындалады. Бұрынғыдай, біз шыңдардың түстері мен текстура координаттарын қоса аламыз.

Барлығын біріктіру

Барлығын біріктірейік. Бізге ғаламдық жарықтандыру, нүктелік және бағытталған жарық көздері бар көріністі салу керек. Олар бастапқыда орналасқан текшені жарықтандырады. Біз сондай-ақ gl uLookAt әдісін шақыруымыз керек. камераны орналастыру үшін. Суретте. 11.6 көрсетілген сыртқы түріБіздің әлем.

Барлық басқа мысалдар сияқты, GLGame сыныбын әдеттегідей кеңейте отырып, LightTest деп аталатын сыныпты жасайық. Ол getStartScreenO әдісін пайдаланып LightScreen класының данасын қайтарады. LightScreen класы GLScreen сыныбынан мұраланады (11.7 тізімі).

Күріш. 11.6. Біздің алғашқы жарық сахнамыз

Листинг 11.7. LightTest.java сыныбының фрагменттері. OpenGL ES көмегімен жарықтандыруды жасау

Сыныптың бірнеше мүшелерін сипаттаудан бастайық. Бұрыш мүшесі текшенің y осінің айналасындағы ағымдағы айналу бұрышы туралы ақпаратты сақтайды. Verti ces3 мүшесі біз жақын арада анықтайтын текше үлгісінің шыңдарын сақтайды. Бұған қоса, бізде AmbientLight, PointLight және Directional Light сыныптарының даналары, сондай-ақ Material класының данасы бар.

Содан кейін конструктор келеді. Мұнда текше үлгісінің шыңдары жасалып, қораптың текстурасы жүктеледі. Біз сондай-ақ шамдар мен материалдарды инициализациялаймыз. Артқы жарық түсі ашық жасыл. Бағытталған көз қызыл түсті және біздің әлемнің (3; 3; 0) нүктесінде орналасқан. Бағытталған жарық көзінің көк түсті диффузиялық түсі бар, жарық сол жақтан түседі. Материал үшін біз әдепкі мәндерді қолданамыз (біршама фон, диффузиялық компонент үшін ақ және айнымалы құрамдас үшін қара).

Резюме әдісінде контекст жоғалса, текстурамыздың (қайта) жүктелетініне көз жеткіземіз.

createCube әдісі алдыңғы мысалдардан айтарлықтай өзгермейді. Дегенмен, бұл жолы біз суретте көрсетілгендей әрбір шыңға нормальдарды қосамыз. 11.5. Одан басқа бәрі бұрынғыдай.

Жаңарту әдісінде текшенің айналу бұрышын көбейтеміз.

Бұл жерде қызықтырақ болады. Алғашқы бірнеше жолдар түс пен тереңдік буферін тазалауға, тереңдікті тексеруді қосуға және аумақты орнатуға арналған қазандық коды болып табылады.

Әрі қарай, біз gl uPerspecti ve әдісі арқылы проекциялық матрицаны перспективалық проекциялық матрицаға тең етіп орнатамыз, сонымен қатар модельді қарау матрицасы үшін gl uLookAt әдісін қолданамыз, соның арқасында камера суреттегідей жұмыс істейді. 11.6.

Содан кейін біз жарықтандыруды пайдалануға рұқсат етеміз. Осы сәтте шамдар әлі анықталған жоқ, сондықтан біз шамдар мен материалдар бойынша әдісті шақыру арқылы келесі бірнеше жолдарда анықтаймыз.

Әдеттегідей, біз текстураны қосамыз және қорап текстурасын байланыстырамыз. Соңында, текшені айналдыру үшін gl RotatefC) әдісін шақырамыз, содан кейін Verti ces3 сыныбының данасына жақсы орналастырылған қоңырауларды пайдаланып оның шыңдарын сызамыз.

Әдістің соңында біз нүктелік және бағытталған шамдарды (есіңізде болсын, артқы жарықтандыру жаһандық күй), сондай-ақ текстураны және тереңдікті сынауды өшіреміз. Бұл OpenGL ES жүйесінде жарықтандыруға арналған.

Сыныптың қалған бөлігі бос; үзіліс жағдайында ешқандай әрекетті орындаудың қажеті жоқ. Суретте. 11.7-суретте бағдарламаның нәтижесі көрсетілген.

Күріш. 11.7. Суретте көрсетілген көрініс. 11.6, OpenGL ES көмегімен жасалған

OpenGL ES жүйесіндегі жарықтандыру туралы бірнеше ескертулер

Жарықтандыруды пайдалану ойыныңызға дәм қосуы мүмкін, бірақ оның шектеулері мен тұзақтары бар. Сіз білуіңіз керек бірнеше нәрсе бар.

Жарықтандыруды пайдалану тым көп ресурстарды тұтынады, әсіресе баяу құрылғыларда байқалады. Жарықты мұқият пайдаланыңыз. Сіз неғұрлым көп жарық көздерін сипаттасаңыз, көріністі көрсету үшін соғұрлым көп есептеулер қажет болады.

Нүктелік/бағыттық жарық көздерінің орны/бағыты камера матрицалары жүктелгеннен кейін және нысандарды жылжыту және айналдыру үшін үлгі көрінісі матрицасын кез келген басқа матрицаларға көбейту алдында анықталуы керек. Бұл сыни. Егер бұл нұсқаулар орындалмаса, түсініксіз жарық артефактілері пайда болуы мүмкін.

Үлгінің өлшемін өзгерту үшін gl Seal ef әдісін пайдаланған кезде оның қалыптылары да масштабталады. Бұл нашар, өйткені OpenGL ES қалыптылардың берілген бірліктерде параметрлері болуын күтеді. Бұл мәселені шешу үшін glEnable(GL10.GL NORMALIZE) пәрменін немесе кейбір жағдайларда gl Enable (GL10 .GL CALE N0RMAL) пәрменін пайдалануға болады. Менің ойымша, бірінші пәрменді пайдалану керек, өйткені екіншісін пайдаланудың шектеулері мен тұзақтары бар. Мәселе мынада, қалыпты мәндерді қалыпқа келтіру немесе қайта масштабтау көп өңдеу қуатын қажет етеді. Өнімділік тұрғысынан ең жақсы шешім - жарықтандырылған нысандарды масштабтатпау.

Ал, мырзалар. Соңғы уақытта біз OpenGL туралы біраз нәрсе білдік, соның ішінде қалай істеу керек камераны басқару , текстурамен жұмыс, сонымен қатар бірге модельдер. Әлдеқайда қызықты нәрсе, атап айтқанда жарықтандыру туралы сөйлесетін кез келді. Бұл тақырып қызықты, өйткені OpenGL-де жарықпен жұмыс істеуге дайын ештеңе жоқ, барлығын шейдерлерді пайдаланып дербес жазу керек. Бұл мақалада біз Phong жарықтандыруын қарастырамыз. Бұл өте үлкен тақырып, сондықтан біз тек осы туралы сөйлесетін боламыз жарықтандыру. Олардың қалай жасалғанында көлеңкелер, біз оны басқа уақытта анықтауымыз керек.

Қалыптыларды сақтау және пайдалану

Тікелей жарықтандыруға көшпес бұрын, бізге қалыпты сияқты нәрсе қажет.

Модельдердің осы шыңдарға сәйкес келетін төбелері мен УК координаталары бар екенін біз қазірдің өзінде білеміз. Жарықтандыруды жасау үшін бізге үлгілер, атап айтқанда қалыптылар туралы қосымша ақпарат қажет. Нормальды - төбеге сәйкес келетін бірлік векторы (немесе, балама ретінде, көпбұрыш, бірақ бұл біздің жағдайымыз емес). Төменде жарықтандыруды жүзеге асыруда қалыптылардың қандай рөл атқаратынын нақты анықтаймыз. Әзірге қалыпты жағдайдың өте маңызды екенін айту жеткілікті. Мысалы, олардың арқасында беттер тегіс болып көрінеді және допты икосаэдр сияқты кәдімгі дөңес көп қырлыдан ажыратуға болады. Қалыпты мәндер өте маңызды болғандықтан, біз Blender үлгілерін өз пішімімізге түрлендіру кезінде оларды қалай сақтау керектігін үйренуіміз керек.

Сәйкес өзгерістер өте тривиальды. Нормаларды шыңның координаталары мен УК координаталары сияқты аламыз:

// importedModelCreate процедура денесінің бөлігі

үшін (таңбасыз int j = 0 ; j< face.mNumIndices ; ++ j) {
unsigned int index = face.mIndices[ j] ;
aiVector3D pos = mesh->mVertices[индекс] ;
aiVector3D uv = mesh-> mTextureCoords[ 0 ] [индекс] ;
aiVector3D қалыпты = mesh-> mNormals[ индекс] ;

VerticesBuffer[ verticesBufferIndex++ ] = pos.x ;
verticesBuffer[ verticesBufferIndex++ ] = pos.y ;
verticesBuffer[ verticesBufferIndex++ ] = pos.z ;
verticesBuffer[ verticesBufferIndex++ ] = normal.x ;
verticesBuffer[ verticesBufferIndex++ ] = normal.y ;
verticesBuffer[ verticesBufferIndex++ ] = normal.z ;
verticesBuffer[ verticesBufferIndex++ ] = uv.x ;
verticesBuffer[ verticesBufferIndex++ ] = 1.0f - uv.y ;
}

Модельді оңтайландыру процедурасы да осылай өзгереді. Ал modelLoad процедурасында екі атрибут массивінің орнына бізге үш қажет:

// modelLoad процедурасының денесінің бөлігі

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

GlBindBuffer(GL_ARRAY_BUFFER, modelVBO) ;
glBufferData(GL_ARRAY_BUFFER, тақырып- > verticesDataSize, verticesPtr,
GL_STATIC_DRAW);

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

Сонымен қатар бізге M матрицасы бар біркелкі айнымалы қажет:

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

// ...

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

... шыңы шейдердегі кеңістіктегі нормалды дұрыс бұру үшін:

#330 ядросының нұсқасы

vec3 vertexPos ішіндегі орналасу(орын = 0 );
vec3 vertexNorm ішіндегі орналасу(орын = 1 );
vec2 vertexUV ішіндегі орналасу(орын = 2 );

біркелкі mat4 MVP;
біркелкі мат4 M;

vec2 фрагменті UV;
out vec3 fragmentNormal;
vec3 fragmentPos;

void main() (
фрагментUV = шыңыUV;
fragmentNormal = (M * vec4 (vertexNorm, 0 ) ) . xyz;
fragmentPos = (M * vec4 (vertexPos, 1 ) ). xyz;

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

Соңында, фрагмент шейдері үш шың бойынша қалыпты интерполяцияны қабылдайды:

// ...

void main() (

// ...
}

Осы қарапайым жолмен біз қалыпты мәндерді аламыз фрагменттері.

Phong жарықтандыру дегеніміз не?

Жоғарыда айтылғандай, OpenGL-де жарықтандыруды бағдарламашының өзі шейдерлерде жазады. Бұл жарықтандыруды жүзеге асырудың бірнеше жолы бар екені анық, олардың әрқайсысының өзіндік шынайылық дәрежесі мен ресурс талаптары бар. Және әрбір әдіс әлі де сансыз нақты іске асыруға ие болуы мүмкін. Менің түсінуімше, нақты уақыттағы тиімді және шынайы жарықтандыру әлі де белсенді зерттеу саласы болып табылады. Бұл пост үшін біз Phong жарықтандыруын қарастырамыз, ол өте шынайы және оңай жүзеге асырылады.

Келесі ұғымдар арасындағы айырмашылықты түсіну маңызды:

  • Гура көлеңкесі - бұл әрбір шыңның жарықтандыруын есептегенде және олардың арасындағы фрагменттердің жарықтандыруы интерполяцияланады;
  • Фонг көлеңкесі - жарықтандыру әрбір фрагмент үшін бөлек есептелген кезде;
  • Фонг жарықтандыру немесе Фонг шағылыстыру моделі - осы мақалада талқыланатын және Гурада да, Фонг көлеңкесінде де қолдануға болатын арнайы жарықтандыру әдісі;

Таңқаларлық емес, Phong көлеңкесі мен Phong жарықтандыруы жиі шатастырылады, және кейбір оқулықтарда сіз «Фонг көлеңкесі идеясы үш компонентті пайдалану болып табылады ...» сияқты мағынасыз сөздерді оқи аласыз, бұл сізді бірден автордың беделіне қатты күмәндануға мәжбүр етеді. осы оқулықты жазған адам.

Менің түсінуімше, заманауи қолданбаларда Gouraud көлеңкесі қолданылмайды, оның орнына Phong көлеңкесі артықшылық береді. Бұл постта біз Phong көлеңкесін де қолданамыз, яғни жарықтандыру әр фрагмент үшін бөлек есептеледі. Біз қолданатын арнайы жарықтандыру әдісі - Phong жарықтандыру. Бұл әдіс келесідей.

Жарықтандырудың үш құрамдас бөлігі әртүрлі формулалар арқылы есептеледі:

  • Қоршаған ортаның жарықтандыруы – басқа заттардан шағылысқаннан кейін берілген нүктеге жеткен жарыққа еліктеу. Фондық жарықтандыруды есептеу кезінде қалыптылар да, камераның ағымдағы орны да ескерілмейді;
  • Диффузиялық жарық - бұл белгілі бір нүктеге тигеннен кейін шашыраңқы көзден түсетін жарық. Жарықтың түсу бұрышына байланысты жарықтандыру күшейеді немесе әлсіз болады. Бұл қалыпты жағдайларды ескереді, бірақ камераның орнын емес;
  • Айналымдық жарықтандыру - бұл белгілі бір нүктеге тигеннен кейін шағылысатын көзден түсетін жарық. Шағылысқан жарық камераға түссе, көрінеді. Сондықтан мұнда қалыпты жағдай да, камераның орны да ескеріледі;

Содан кейін жалпы жарықтандыруды беру үшін нәтижелер жинақталады.

Істі одан да қызықты ету үшін әртүрлі жарық көздері бар. Сырттағы күн мен қараңғыдағы фонарь көріністі басқаша жарықтандыратыны анық. Біріншіден, біз ең қарапайым көзді - бағытталған жарықты қарастырамыз.

Бағытталған жарық

Бағытталған жарық дегеніміз - шексіз қашықтықтағы жарық көзіне еліктеу. Мысалы, Күнді алайық. Күн жерден өте алыс. Сондықтан Жер бетінде Күннен түсетін барлық жарық сәулелерін үлкен дәлдікпен параллель деп санауға болады. Бағытталған жарық оның бағытымен, түсімен, сондай-ақ төменде қажет болатын кейбір коэффициенттермен сипатталады:

struct DirectionalLight(
vec3 бағыты;

vec3 түсі;
float ambientintensity;
float diffuseIntensity;
float specularIntensity;
} ;

Фрагмент шейдер кодында біз келесідей пайдаланылатын calcDirectionalLight процедурасын анықтаймыз:

vec3 fragmentPos ішінде;
біркелкі vec3 cameraPos;
біркелкі DirectionalLight DirectionalLight;

// ...

void main() (
// интерполяциядан кейін қалыпты түзету керек
vec3 қалыпты = қалыпқа келтіру (фрагментҚалыпты) ;


бағытты жарық);

// ...
}

Процедураның орындалуын қарастырайық.

vec4 calcDirectionalLight(vec3 қалыпты, vec3 фрагментіКамера,
Бағытты жарық шамы) (
vec4 ambientColor = vec4 (ашық. түс, 1) * ашық. ambientIntensity;

// ...
}

Біріншіден, бірінші компонент есептеледі - фондық жарықтандыру. Бұл жай ғана шығарылатын жарықтың түсі фондық жарықтың қарқындылығына көбейтілген. Әзірге бәрі қарапайым.

// ...

float diffuseFactor = max (0,0 , нүкте (қалыпты, - жарық. бағыт ) );
vec4 diffuseColor = vec4 (ашық. түс, 1) * жарық. диффузиялық қарқындылық
* диффузиялық фактор;

// ...

Диффузиялық жарықтандыру. DiffuseFactor айнымалысы фрагментке нормаль мен фрагменттен жарық көзіне бағытталған вектор арасындағы бұрыштың косинусын көрсетеді. Егер жарық бетіне перпендикуляр түссе, бұрыш нөлге тең болады. Бұл бұрыштың косинусы бірге тең және жарықтандыру максималды (Ламберт заңы туралы Википедия мақаласын қараңыз). Бұрыш өскен сайын косинус кемиді және жарық бетіне параллель болса, нөлге тең болады. Егер косинус теріс болса, онда жарық көзі бетінің артында орналасқан және ол жарықтандырылмаған, сондықтан теріс мәндерді max(0,0, ...) көмегімен нөлге айналдырамыз. Жарықтың түсу бұрышынан басқа, диффузиялық жарықтың диффузиялық интенсивтілігі де ескеріледі.

// ...
vec3 lightReflect = қалыпқа келтіру(шағылыстыру(жарық. бағыт, қалыпты));
float specularFactor = pow(
макс (0,0 , нүкте (фрагментке камера, жарық шағылыстыру) ,
MaterialSpecularFactor
) ;
vec4 specularТүс = ашық. SpecularIntensity * vec4(ашық.түс, 1)
* materialSpecularIntensity * specularFactor;
// ...

Жанама жарықтандыру. LightReflect айнымалысы шағылған жарықтың бағытын көрсететін бірлік векторы болып табылады. SpecularFactor айнымалысы diffuseFactor-қа ұқсас жолмен есептеледі, тек осы жолы жарық шағылған бағыт пен фрагменттен камераға дейінгі бағыт арасындағы бұрыштың косинусын ескереді. Егер бұл бұрыш нөлге тең болса, онда шағылысқан жарық тікелей камераға түседі және бетіндегі жарқырау максималды болады. Егер бұрыш үлкен болса, онда ешқандай жарқырау көрінбеуі керек. Мұнда materialSpecularFactor біркелкі айнымалы болып табылады. Ол неғұрлым үлкен болса, объектінің бетіндегі жарқырау ауданы соғұрлым аз болады. MaterialSpecularIntensity айнымалысы бөлектелетін жерлердің жарықтығын анықтау үшін де қолданылады. Бұл жарық емес, материалдың барлық қасиеттері екенін ескеріңіз. Мысалы, металл жарықты шағылыстырады, сондықтан жарқырайды. Бірақ ағаш жарықты көрсетпейді, содан кейін сіз ешқашан ағаштардағы жарқырауды көрмейсіз (әрине, егер беті құрғақ болса және т.б.).

Жоғарыдағы кодта жарықтың specularIntensity қасиеті бар. Бірақ ол белгілі бір жарық көзінен бөлектеулерді бөлектеу үшін ғана жөндеу мақсатында пайдаланылуы керек. Кодтың шығарылған нұсқасында бұл коэффициент не біреуге тең болуы керек, не кодтан толығымен жойылуы керек.

Соңында үш компонент қосылады және нәтиже қайтарылады:

// ...

ambientColor + diffuseColor + specularColor қайтару;
}

Соншалықты қиын емес, иә?

Нүктелік жарық көзі

Жарықтың нүктелік көзі, мысалы, жанып тұрған шам. Шамның жарығы барлық жаққа бағытталған. Сондықтан нүктелік жарық көзі жарық бағытымен сипатталмайды, бірақ көздің кеңістіктегі орнымен сипатталады:

struct PointLight(
vec3 орны;

vec3 түсі;
float ambientintensity;
float diffuseIntensity;
float specularIntensity; // жөндеу мақсаттары үшін 1.0 мәніне орнатылуы керек
} ;

Нүктелік жарық көзінен жарықтандыру бұрыннан бар calcDirectionalLight процедурасы арқылы оңай есептеледі:

vec4 calcPointLight(vec3 қалыпты, vec3 фрагментіToCamera,
PointLight жарығы) (
vec3 lightDirection = қалыпқа келтіру (фрагментПос - жарық. позиция );
қалқымалы қашықтық = ұзындық (fragmentPos - жарық. позиция );
float pointFactor = 1,0 / (1,0 + pow(қашықтық, 2));

DirectionalLight tempDirectionalLight = DirectionalLight(
жарық бағыты,
жарық. түс,
жарық. қоршаған ортаның қарқындылығы
жарық. диффузиялық қарқындылық
жарық. Айналым қарқындылығы
) ;
қайтару нүктесіFactor * calcDirectionalLight(қалыпты, fragmentToCamera,
tempDirectionalLight);
}

Фрагмент пен жарық көзінің координаталарына ие бола отырып, векторлар айырымы арқылы берілген фрагментке жарықтың бағытын оңай есептеуге болады. PointFactor көбейткіші жарықтың оның көзіне дейінгі қашықтықтың квадратымен әлсіреу фактісін көрсетеді (сфераның бетінің ауданы радиусқа тәуелділік формуласына сәйкес). Нөлге бөлу мүмкіндігін болдырмау үшін нүкте Факторын есептеу кезінде бөлгішке қосымша қосылады. Осыдан кейін бәрі бағдарланған жарық сияқты дәл осылай есептеледі.

Нүктелік жарық

Бұл жарық көзінің мысалы - фонарь. Ол нүктелік жарық көзіне ұқсас, тек оның қосымша бағыты мен әсер ету бұрышы (кесу) бар:

struct SpotLight (
vec3 бағыты;
vec3 орны;
қалқымалы үзіліс;

vec3 түсі;
float ambientintensity;
float diffuseIntensity;
float specularIntensity; // жөндеу мақсаттары үшін 1.0 мәніне орнатылуы керек
} ;

Сәйкес процедура:

vec4 calcSpotLight(vec3 қалыпты, vec3 фрагментіToCamera,
Spotlight жарығы) (
vec3 spotLightDirection = қалыпқа келтіру (fragmentPos - жарық. позиция );
float spotAngleCos = нүкте (spotLightDirection, жарық. бағыт) ;
қалқымалы әлсіреуі = (1,0 - 1,0 * (1,0 - spotAngleCos) /
(1,0 - жарық. кесу ) );
float spotFactor = float (spotAngleCos > жарық. cutoff ) * әлсіреу;

PointLight tempPointLight = PointLight(
жарық. позиция
жарық. түс,
жарық. қоршаған ортаның қарқындылығы
жарық. диффузиялық қарқындылық
жарық. қоршаған ортаның қарқындылығы
) ;
қайтару spotFactor * calcPointLight(қалыпты, fragmentToCamera,
tempPointLight);
}

Жарық бағыты нүктелік көздегідей есептеледі. Содан кейін осы бағыт пен жарық көзінің қасиеттерінде көрсетілген бағыт арасындағы бұрыштың косинусы есептеледі. Өрнекті қолдану float(spotAngleCos > light.cutoff)жарық белгіленген бұрышқа қатаң түрде кесіледі. Өсіру мультипликаторы қосылады тегісжарықтың әлсіреуі, өйткені үзінділер көздің қасиеттерінде көрсетілген жарық бағытынан алыстайды. Осыдан кейін барлық есептеулер нүктелік жарық көзі үшін есептеулерге дейін қысқарады.

Гамма түзету

Фрагмент шейдеріндегі барлық негізгі процедура келесідей:

void main() (
// интерполяциядан кейін қалыпты түзету керек
vec3 қалыпты = қалыпқа келтіру (фрагментҚалыпты) ;
vec3 fragmentToCamera = қалыпқа келтіру(cameraPos - fragmentPos) ;

vec4 directColor = calcDirectionalLight(қалыпты, fragmentToCamera,
бағытты жарық);
vec4 pointColor = calcPointLight(қалыпты, fragmentToCamera,
нүктелік жарық);
vec4 spotColor = calcSpotLight(қалыпты, fragmentToCamera, spotLight) ;
vec4 linearColor = текстура (текстураSampler, fragmentUV) *
(vec4(материал шығару, 1) + directColor +
pointColor + нүкте түсі);

vec4 гамма = vec4 (vec3 (1,0 / 2,2), 1);
color = pow(linearColor, гамма); // гамма-түзетілген түс
}

Материал шығаруға көп көңіл бөлмеңіз. Бұл материалдың өзіндік жарқырауын қосатын тағы бір қасиеті. Көптеген нысандар өздігінен жарқырайды. Басқа нысандар үшін жарық көзі ретінде қызмет ететін бірдей шамдарды алыңыз. Шамдар басқа жарық көзімен жарықтандырылмаса да, біз оларды толық қараңғылықта көре алуымыз керек, солай емес пе?

Шын мәнінде назар аудару керек нәрсе - барлық жарық компоненттерін 1/2,2 қуатқа дейін көтеруден тұратын гамма түзету. Осы уақытқа дейін біз интенсивтілігі 1,0 түс 0,5 қарқындылығы бар түстен екі есе ашық деген болжаммен сызықтық түс кеңістігінде жұмыс істедік. Мәселе мынада, адам көзі жарықты сызықты түрде қабылдамайды. Сондықтан шынайы жарықтандыруды алу үшін сызықтық кеңістіктегі барлық есептеулерден кейін гамма түзетуді орындау қажет.

Кескінді сақтау кезінде қазіргі графикалық редакторлар да гамма түзетуді орындайтынын ескеру қажет. Сондықтан, текстураларды қолданбас бұрын, бұл гамма түзетуден бас тарту керек. Бақытымызға орай, бұл қиын емес.

Текстураны жүктеу кодындағы барлық тұрақты мәндерді ауыстыру жеткілікті:

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

… сәйкесінше. Бұл кескінге гамма-түзету қолданылғанын және оны қайтару қажет екенін көрсетеді. Қалғанымен OpenGL айналысады.

Нақты қолданбаларда гамма параметрі (бізде гамма = 2.2) бағдарлама параметрлерінде жақсырақ орналастырылған, сондықтан пайдаланушы қаласа, оны мониторына аздап реттей алады.

Қорытынды

Суреттерді қарау уақыты келді!

Мұнда біз әртүрлі жарықтандыру компоненттерін көреміз. Солдан оңға, жоғарыдан төменге: фондық, диффузиялық, шағылысқан, үшеуі бірге. Көріп отырғаныңыздай, сахнаға торус үлгісі қосылды. Нормалардың күрделі орналасуына байланысты бұл модель жарықтандыруды сынау үшін ұсынылады.

Әртүрлі жарық көздері. Солдан оңға, жоғарыдан төменге қарай: ақ нүкте шамы, қызыл нүкте шамы, көк прожектор, үшеуі бірге.

Бір жарықтандыру әдісінің әртүрлі іске асырылуы мүмкін екенін тағы да атап өтейін. Мысалы, материалдың қасиеттерін қоршаған орта, диффузиялық және спекулярлық түске орнатуға болады, бұл жасыл түсті диффузиялық және көк жарықтары бар қызыл нысандарды салуға мүмкіндік береді. Кейбір Phong жарықтандыру нұсқаларында фондық жарықтандыру әр жарық үшін емес, бір рет есептелгенін көрдім. Мен сондай-ақ нүктелік көзден түсетін жарық оған дейінгі қашықтықтың квадратына пропорционалды түрде (d * d) ғана емес, жалпы формулаға сәйкес (A + B * d + C * стилінде) сөнетін іске асыруды көрдім. d*d). Біреу қоршаған ортаның қарқындылығын және диффузиялық қарқындылықты тек жарық көзінің ғана емес, сонымен қатар материалдың қасиетіне айналдырады. Мұның бәрі шынайы жарықтандырумен қаншалықты байланысты екенін білмеймін. Бірақ мұның бәрімен үй тапсырмасы ретінде ойнауға болады.

Жылдардың еңбектері. Волошин Максимилиан. АҚЫН ЕРЛІГІ. 1. Өлеңді шетелге жөнелтілген мәтін сияқты өңдеңіз: Құрғақтық, айқындық, қысым - әрбір сөз ескертуде.

Қатты және тар тасты әріппен әріппен кесу: Сөздер неғұрлым сирек болса, олардың күші соғұрлым күшті болады. Ойдың ерік заряды үнсіз шумақтармен тең.

«Сұлулық», «Шабыт» сөздерін сөздіктен өшіріп тастаңыз - римерлердің арам жаргоны.Ақынға - түсініктер: Ақиқат, дизайн, жоспар, теңдік, қысқалық және дәлдік. Байсалды, қатал өнерде ақынның шабыты мен намысы бар: Саңырау-мылқау материяда трансцендентальды қырағылықты қайрау. Волошин М.А. Кітапхана: Орлов атындағы облыстық ғылыми әмбебап кітапханасы. И.А. Бунина. - М., ; Таңдамалы шығармалары: 2 томдық.

М., ; Қызыл түтін: әңгімелер. - М., ; Гладышев барлау ротасынан: Әңгімелер. - М., ; эшелон; Еріксіз: романдар. Ол мари және удмурт ақындарының аудармаларын көп жасады. Ара-тұра прозада да бағымды сынап көрдім. Оп. Максимилиан Александрович Волошин () - 20 ғасырдың бірінші үштен бірінің ұлы ақындарының бірі. Ол символистік, эзотерикалық поэмалардан азаматтық-публицистикалық және ғылыми-философиялық поэзияға, антропософиялық бейімділіктер арқылы «Құдай қаласы идеалына» дейінгі жолды басып өткен дарынды суретші, көп қырлы лирик.

Ұсынылған басылым оқырманға Волошиннің ең жақсы поэтикалық шығармаларымен ғана емес, сонымен қатар оның эстетикадағы ең қызықты шығармаларымен, мемуарлық прозасымен, публицистикасымен және елдер өміріндегі драмалық оқиғаларға байланысты хаттарымен танысуға мүмкіндік береді. Автор. Волошин Максимилиан. Автордың барлық өлеңдері. Жұмыс. Ақынның ерлігі. 2. Жұлдыздар. Авторлар мен өлеңдердің сүйікті жинақтарын жасаңыз!

Пікірлес адамдармен сөйлесіңіз! Пікірлер жазыңыз, поэзиялық дуэльдер мен байқауларға қатысыңыз! Үздіктерге қосылыңыз! Poembook-қа қосылғаныңыз үшін рахмет! Электрондық поштаңызға тіркелгіге кіру деректері бар хат жіберілді!

Сіз 24 сағат ішінде жүйеге кіруіңіз керек. Әйтпесе, есептік жазба жойылады! Тіркелген пайдаланушылар көптеген артықшылықтарға ие болады: Поэзияны жариялаңыз - талантыңызды іске асырыңыз! Авторлар мен өлеңдердің сүйікті жинақтарын жасаңыз! Пікірлес адамдармен сөйлесіңіз! Пікірлер жазыңыз, поэзиялық дуэльдер мен байқауларға қатысыңыз! Максимилиан Волошин. Сипаттама. Максимилиан Александрович Волошин - 20 ғасырдың бірінші үштен бірінің ұлы ақындарының бірі.

Ол символистік, эзотерикалық поэмалардан азаматтық-публицистикалық және ғылыми-философиялық поэзияға, антропософиялық бейімділіктер арқылы «Құдай қаласы идеалына» дейінгі жолды басып өткен дарынды суретші, көп қырлы лирик. Ұсынылған басылым оқырманға Волошиннің ең жақсы поэтикалық шығармаларымен ғана емес, сонымен қатар оның эстетикадағы ең қызықты шығармаларымен, мемуарлық прозасымен, публицистикасымен және драматургияға қатысты хаттарымен танысуға мүмкіндік береді.

Таңдамалы шығармалар мен хаттар. М.А.Волошин. Бағасы. ысқылау. Максимилиан Александрович Волошин - 20 ғасырдың бірінші үштен бірінің ұлы ақындарының бірі. Ол символистік, эзотерикалық поэмалардан азаматтық-публицистикалық және ғылыми-философиялық поэзияға, антропософиялық бейімділіктер арқылы «Құдай қаласы идеалына» дейінгі жолды басып өткен дарынды суретші, көп қырлы лирик.

Волошин М.А., Ақынның ерлігі: таңдамалы шығармалар мен хаттар. серия: Орыс классикасының жаңа кітапханасы: қажетті көшірме Парад, қала, бет, Кітаптың сипаттамасы. Максимилиан Александрович Волошин () - 20 ғасырдың бірінші үштен бірінің ұлы ақындарының бірі. Ол символистік, эзотерикалық поэмалардан азаматтық-публицистикалық және ғылыми-философиялық поэзияға, антропософиялық бейімділіктер арқылы «Құдай қаласы идеалына» дейінгі жолды басып өткен дарынды суретші, көп қырлы лирик.

СанаттарПост навигациясы

Жарық көзі болмаса, сурет көрінбейді. Көзді инициализациялау және көздің нысандарға әсерін есептеу үшін процессорды қосу үшін жай ғана пәрмендерді орындаңыз: glEnable(gl_lighting); // жарықтандыруды талдау режимін қосу

GlEnable(gl_light0); // көрініске оның сипаттамаларымен нақты (нөлдік) көзді қосыңыз

Көзді өшіру үшін Disable() функциясын пайдаланыңыз. Әдепкі бойынша жарық көзі координаттары (0,0,∞) бар кеңістікте орналасқан. Кескін кеңістігінің кез келген жерінде жарық көзін жасауға болады.

OpenGl кітапханасы жарық көздерінің төрт түрін қолдайды:

  • фондық жарықтандыру (жарықтандыру),
  • нүктелік көздер,
  • прожекторлар,
  • қашықтағы жарық көздері (қашықтағы жарық).
Әрбір жарық көзінің өзіндік сипаттамалары бар.
Жарық көзінің сипаттамалары Phong моделінің параметрлеріне сәйкес келеді.
Векторлық параметрлерді орнату үшін келесі пішімге ие glLightfv() функциясын пайдаланыңыз:

glLightfv(көз, параметр, көрсеткіш_жиым);

Бастапқы сәулелердің орны мен бағытын және оның құрамдас бөліктерінің түстік құрамын анықтайтын төрт векторлық параметр бар - фон, диффузиялық және спекулярлық.
OpenGL жүйесінде скалярлық параметрлерді орнату үшін glLightf() функциясын пайдаланыңыз:

glLightf(көз, параметр, мән);

Мысалы, (1.0, 2.0, 3.0) нүктесінде орналасуы керек GL_LIGHT0 көзін сахнаға қосқыңыз келетін болсын. Бастапқы позиция бағдарламада біркелкі координаталардағы нүкте ретінде сақталады:

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

Егер осы нүктенің төртінші құрамдас бөлігі нөлге тең болса, онда нүкте көзі қашықтағы көзге айналады, ол үшін тек сәулелердің бағыты маңызды:

GLfloat light0_dir=(1.0, 2.0, 3.0, 0.0);

Әрі қарай, көздің фонының, диффузиясының және спекулярлық компоненттерінің түстік құрамы анықталады. Егер қарастырылып отырған мысалда көзде ақ түстің спекулярлық құрамдас бөлігі болса, ал фондық және диффузиялық компоненттер қызыл болуы керек болса, онда көзді құрайтын бағдарлама фрагменті келесідей болады:

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_LIGHT0, GL_POSITION, light0_pos);

GlLightfv(GL_LIGHT0, GL_AMBIENT, ambient0);

GlLightfv(GL_LIGHT0, GL_DIFFUSE, диффузиялық0);

GlLightfv(GL_LIGHT0, GL_SPECULAR, specular0);

Сондай-ақ, кез келген жеке жарық көзімен байланыстырмайтын көрініске жаһандық фондық жарықтандыруды қосуға болады. Мысалы, көріністегі барлық нысандарды ақ түспен күңгірттеу керек болса, бағдарламаға келесі код бөлігін қосу керек:

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

GlLightModelfv(GL_LIGHT_MODEL_AMBIENT, жаһандық_орта);

Жарықтандыру моделінде көзге дейінгі қашықтықты ескеретін термин келесі формада болады:

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

Ал тұрақты, сызықтық және квадраттық компоненттер. Әрбір көз үшін сәйкес коэффициенттер скаляр параметрді орнату функциясы арқылы жеке орнатылады, мысалы:

GlLightf(GL_LIGHT0, GL_CONSTANT_ATTENATION, a);

Нүктелік көзді прожекторға түрлендіру үшін прожектор сәулесінің бағытын (GL_SPOT_DIRECTION), қарқындылықты бөлу функциясының индикаторын (GL_SPOT_EXPONENT) және сәуленің шашырау бұрышын (GL_SPOT_CUTTOF) көрсету керек. Бұл параметрлер glLightf() және glLightfv() функциялары арқылы орнатылады.

Жарық көздерінің әдепкі параметрлері 3-кестеде көрсетілген.

Шамдарға арналған әдепкі параметрлер

3-кесте

Параметр аты Әдепкі мән Мазмұны
GL_AMBIENT (0.0, 0.0, 0.0, 1.0) қоршаған ортаның RGBA жарық қарқындылығы
GL_DIFFUSE (1.0, 1.0, 1.0, 1.0) жарықтың диффузиялық RGBA қарқындылығы
GL_SPECULAR (1.0, 1.0, 1.0, 1.0) жарықтың айналмалы RGBA қарқындылығы
GL_POSITION (0.0, 0.0, 1.0, 0.0) (x, y, z, w) жарықтың орны
GL_SPOT_DIRECTION (0.0, 0.0, -1.0) (x, y, z) прожектордың бағыты
GL_SPOT_EXPONENT 0.0 жарықтандыру көрсеткіші
GL_SPOT_CUTOFF 180.0 прожекторды кесу бұрышы
GL_CONSTANT_ALTENUATION 1.0 тұрақты әлсірету коэффициенті
GL_LINEAR_ATTENUATION 0.0 сызықтық әлсіреу коэффициенті
GL_QUADRATIC_ATTENUATION 0.0 квадраттық әлсіреу коэффициенті