Лабораторна робота № 6. Освітлення.
Мета роботи.
Знайомство з можливостями бібліотеки OPENGL для завдання параметрів освітлення сцени; аналіз різних варіантів освітлення.
Порядок виконання роботи.
Перед виконанням завдань даної лабораторної роботи необхідно повторити відомості, що відносяться до колірної моделі RGB ([7] – лекція 4), вивчити теоретичний матеріал, пов'язаний з різними рівнями візуалізації ([7] – лекція 15), з урахуванням властивостей матеріалу об'єктів при їх зображенні; відмінності методів Гуро і Фонга ([7] – лекція 16).
Необхідні теоретичні відомості.
OPENGL обчислює колір кожного пікселя в результуючій, сцені, що відображується, міститься в буфері кадру. Частка цього розрахунку залежить від того, яке освітлення використовується в сцені, і як об'єкти сцени відображають і поглинають світло. Як приклад цьому пригадаєте, що океан (або море, або річка – взагалі кажучи, будь-яке водоймище) має різний колір в сонячний або в хмарний день. Присутність світла або хмар визначає, чи буде вода виглядати яскраво сині або брудно зеленою. По правді кажучи, більшість об'єктів взагалі не виглядають тривимірними, якщо вони не освітлені. Скажімо, неосвітлена сфера нічим не відрізняється від двовимірного круга. Освітлення будь-якого об'єкту залежить від двох чинників. Перший - це матеріал, з якого зроблений об'єкт. Другий - це світло, яким він освітлений.
Модель освітлення.
OPENGL розраховує світло і освітлення так, як ніби світло може бути роздільний на червоний, зелений і синій компоненти. Таким чином, джерело світла характеризується кількістю червоного, зеленого і синього світла, яку він випромінює, а матеріал поверхні характеризується долями червоного, зеленого і синього компонентів, які він відображає в різних напрямах. Рівняння освітленості в OPENGL є всього лише апроксимаціями, та зате вони працюють досить добре і можуть бути обчислені відносно швидко.
У моделі освітлення OPENGL світло виходить від декількох джерел, які можуть включатися і вимикатися індивідуально. Частина світу зазвичай виходить з якого-небудь певного напряму або позиції, частка розподілена по всій сцені. Наприклад, якщо ви включите лампочку в кімнаті, велика частина світу виходитиме від неї, але частина світу падає на поверхні предметів в кімнаті після того, як він відбився від однієї, два, три або більш за стени. Вважається, що це багато разів відбите світло (званий фоновим світлом) розподілене настільки сильно, що не існує ніякого способу визначити його початковий напрям, проте він зникає при виключенні певного джерела світла.
Нарешті, в сцені може бути також присутнім загальне фонове світло, у якого немає ніякого конкретного джерела, неначе він був відбитий стільки раз і розподілений так сильно, що його оригінальне джерело встановити неможливо.
У моделі OPENGL ефект від джерела світла присутній тільки якщо є поверхні що поглинають або відображають світло. Вважається, що кожна поверхня складається з матеріалу з декількома властивостями. Матеріал може випромінювати своє власне світло (наприклад, фара автомобіля), він може розподіляти деяку кількість вхідного світла на всіх напрямках, також він може відображати частину світу в певному напрямі (наприклад, дзеркало або інша блискуча поверхня).
У моделі освітлення OPENGL передбачається, що освітлення може бути розділене на 4 компоненти: фонове (ambient), дифузне (diffuse), дзеркальне (specular) і витікаюче (емісійне – emissive). Все 4 компоненти розраховуються незалежно і тільки тоді підсумовуються.
Фонове, дифузне, дзеркальне і витікаюче світло.
Фонове випромінювання – це світло, яке настільки розподілене середою (предметами, стінами і так далі), що його напрям визначити неможливо – здається, що він виходитиме звідусіль. Лампа денного світла має великий фоновий компонент, оскільки велика частина світу, досягаючого вашого ока, спочатку відбивається від безлічі поверхонь. Вуличний ліхтар має маленький фоновий компонент: велика частина його світу йде в одному напрямі, крім того, оскільки він знаходиться на вулиці, дуже невелика частина світу потрапляє вам в око після того, як відіб'ється від інших об'єктів. Коли фонове світло падає на поверхню, він однаково розподіляється на всіх напрямках.
Дифузний компонент – це світло, що йде з одного напряму, таким чином, він виглядає яскравішим, якщо падає на поверхню під прямим кутом, і виглядає тьмяним, якщо стосується її всього лише побіжно. Проте, коли він падає на поверхню, він розподіляється однаково на всіх напрямках, тобто його яскравість однакова незалежно від того, з якого боку ви дивитеся на поверхню. Ймовірно, будь-яке світло, витікаюче з певного напряму або позиції, має дифузний компонент.
Дзеркальне світло виходить з певного напряму і відбивається від поверхні в певному напрямі. При віддзеркаленні добре сфокусованого лазерного променя від якісного дзеркала походить майже 100 процентне дзеркальне відзеркалення. Блискучий метав або пластик має високий дзеркальний компонент, а шматок килима або плюшева іграшка – ні. Ви можете думати про дзеркальність як про те, наскільки блискучим виглядає матеріал.
Окрім фонового, дифузного і дзеркального кольорів, матеріали можуть також мати витікаючий колір, що імітує світло, витікаюче від самого об'єкту. У моделі освітлення OpenGLвихідне світло поверхні додає об'єкту інтенсивності, але на нього не впливають ніякі джерела світла, і він не проводить додаткового світла для сцени в цілому.
Хоча джерело світла випромінює єдиний розподіл частот, фоновий, дифузний і дзеркальний компоненти можуть бути різні. Наприклад, якщо у вашій кімнаті червоні стіни і білий світ, то це світло, відбиваючись від стенів буде швидше червоним, чим білим (не дивлячись на те, що падаюче на стіну світло – білий). OPENGL дозволяє встановлювати значення червоного, зеленого і синього незалежно для кожного компоненту світла.
Колір матеріалу і світла.
Модель освітлення OPENGL робить допущення про те, що колір матеріалу залежить від доль падаючого червоного, зеленого і синього світла, які він відображає. Наприклад, максимально червону кулю відображає все червоне світло, яке на нього падає і поглинає весь зелений і синій. Якщо ви подивитеся на такий м'яч під білим світом (що складається з однакової кількості червоної, зеленої і синьої), все червоне світло відіб'ється, і ви побачите червоний м'яч. Якщо дивитися на м'яч при червоному світлі, він також виглядатиме червоним. Якщо, проте, подивитися на нього під зеленим світлом, він виглядатиме чорним (все зелене світло поглинеться, а червоного немає, тобто ніяке світло відбитий не буде).
Також як і світло, матеріали мають різні фоновий, дифузний і дзеркальний кольори, які задають реакцію матеріалу на фоновий, дифузний і дзеркальний компоненти світла. Фоновий колір матеріалу комбінується з фоновим компонентом всіх джерел світла, дифузний колір з дифузним компонентом, а дзеркальний з дзеркальним. Фоновий і дифузний кольори задають видимий колір матеріалу, вони зазвичай близькі, якщо не еквівалентні. Дзеркальний колір зазвичай білий або сірий. Він зачеплений колір відблиску на об'єкті (тобто він може збігатися з дзеркальним компонентом джерела світла).
Колірні компоненти, що задаються для джерел світла, означають зовсім не те ж саме, що для матеріалів. Для джерела світла числом є відсоток від повної інтенсивності кожного кольору. Якщо R, G і B – величини кольору джерела світла всі дорівнюють 1.0, світло буде максимально білим. Якщо величини дорівнюватимуть 0.5, світло все одно залишиться білим, але лише з половиною інтенсивності (він здаватиметься сірим). Якщо R=G=1 і B=0 (повний червоний, повний зелений, відсутність синю), світло буде жовтим.
Для матеріалів числа відповідають відбитим пропорціям цих квітів. Отже, якщо для матеріалу R=1, G=0.5 і B=0, цей матеріал відображає все червоне світло, половину зеленого і зовсім не відображає синього. Іншими словами, якщо позначити компоненти джерела світла як (LR, LG, LB), а компоненти матеріалу як і проігнорувати решту всіх взаємодій, то світло, яке поступить в око можна визначити як (LR–MR, LG–MG, LB–MB).
Схожим чином, якщо два джерела світла з характеристиками (R1, G1, B1) і (R2, G2, B2) направлені в око, OPENGL складе компоненти: (R1+R2, G1+G2, B1+B2). Якщо яка-небудь з сум буде більше 1 (відповідаючи кольору, який не можна відображувати), компонент буде урізаний до 1.
Увімкнення фонового освітлення.
За умовчанням освітлення вимкнуте. Вмикається воно командою glEnable(GL_LIGHTING). Без освітлення працювати практично неможливо. Сфера завжди показуватиметься як круг, а конус - як круг або трикутник. Якщо монотонне тіло у рівномірно освітлено, то побачити його рельєф неможливо. Тому необхідно використовувати джерела світла.
Коли освітлення розсіяне, то можна встановлювати фонову освітленість. За умовчанням, значення фонової освітленості рівне (0.2, 0.2, 0.2, 1). Фонове освітлення встановлюється за допомогою функції glLightModel. Якщо підвищити фонове освітлення (1,1,1,1), тобто до максимуму, то включати джерела світла не знадобиться. Їх дія просто не буде помітна, оскільки об'єкт вже максимально освітлений
Додавання у функцію main виклик наступної функції дозволить встановити фонове освітлення.
float ambient[4]= {0.5, 0.5, 0.5, 1};
...
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient);
Завдання параметрів матеріалу.
Матеріал може розсіювати, відображати і випромінювати світло. Властивості матеріалу встановлюються за допомогою функції
glMaterialfv(GLenum face, GLenum pname, GLtype* params)
Перший параметр визначає грань, для якої встановлюються властивості. Він може приймати одне з наступних значень:
GL_BACK задня грань
GL_FONT передня грань
GL_FRONT_AND_BACK обидві грані
Другий параметр функції glMaterialfv визначає властивість матеріалу, яка буде встановлено, і може набувати наступних значень.
GL_AMBIENT розсіяне світло
GL_DIFFUSE теж розсіяне світло, пояснення дивися нижче
GL_SPECULAR відбите світло
GL_EMISSION випромінюване світло
GL_SHININESS ступінь відбитого світла
GL_AMBIENT_AND_DIFFUSE обидва розсіяне світло
Ambient і diffuse перекладаються на украінську як "розсіяний". Різниця між ними не дуже зрозуміла. Я використовую тільки GL_DIFFUSE. Третій параметр визначає колір відповідного світла, окрім випадку GL_SHININESS. Колір задається у вигляді масиву з чотирьох елементів - RGBA. В разі GL_SHININESS params указує на число типа float, яке має бути в діапазоні від 0 до 128.
Створення, позиціювання і включення одне або більш за джерела світла.
У розмовній мові джерела світла часто іменуються просто лампами. Всі параметри лампи задаються за допомогою функції glLight, яка має наступний прототип:
void glLight[if][v](
GLenum light
GLenum pname
GLfloat param)
Буква v в назві функції визначає, чи використовується векторна версія команди.
Перший аргумент визначає номер лампи. Його можна задавати двома способами. Перший - явно вказати GL_LIHGTi, де GL_LIGHTi зумовлене у файлі gl.h таким чином:
/* LightName */
#define GL_LIGHT0 0x4000
#define GL_LIGHT1 0x4001
#define GL_LIGHT2 0x4002
#define GL_LIGHT3 0x4003
#define GL_LIGHT4 0x4004
#define GL_LIGHT5 0x4005
#define GL_LIGHT6 0x4006
#define GL_LIGHT7 0x4007
Другий спосіб - GL_LIGHT0 + i, де i номер лампи. Такий спосіб використовується, коли існує необхідність в циклі змінювати параметри ламп. Другий аргумент визначає ім'я параметра, а третій його значення. За допомогою наступних функцій вирішуємо освітлення і включаємо нульову лампу.
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
Масиви pos і dir містять координати місця розташування лампи і напряму, куди вона світить. Масив dir містить три координати - x,y,z. Масив pos - чотири, призначення четвертого мені не дуже ясно. Якщо його значення відрізняється від нуля, то зображення цілком логічне виходить. Якщо ж він нуль, то виходить щось непотрібне. За умовчанням колір всіх джерел світла окрім GL_LIGHT0 – чорний.
glLightfv(GL_LIGHT0, GL_POSITION, pos);
glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, dir);
Після налаштування параметрів джерела світла його потрібно активувати командою glEnable().
Параметри джерела світла.
У аргументі param задається значення або значення, в які слід встановити характеристику pname. Якщо використовується векторна версія команди, param є вектором величин, а якщо невекторна, то param – одне єдине значення. Невекторна версія команди може використовуватися тільки для вказівки параметрів, чиє значення виражається одним числом.
Значення параметрів за умовчанням.
Імена параметрів
Значення за умовчанням
Сенс

GL_AMBIENT
(0.0,0.0,0.0,1.0)
Інтенсивність фонового світла

GL_DIFFUSE
(1.0,1.0,1.0,1.0)или(0.0,0.0,0.0,1.0)
Інтенсивність дифузного світла (значення за умовчанням для 0-го джерела - білий світ, для останніх - чорний)

GL_SPECULAR
(1.0,1.0,1.0,1.0)или(0.0,0.0,0.0,1.0)
Інтенсивність дзеркального світла (значення за умовчанням для 0-го джерела - білий світ, для останніх - чорний)

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_ATTENUATION
1.0
Постійний чинник ослаблення

GL_LINEAR_ATTENUATION
0.0
Лінійний чинник ослаблення

GL_QUADRATIC_ATTENUATION
0.0
Квадратичний чинник ослаблення


Значення за умовчанням для GL_DIFFUSEи GL_SPECULAR в таблиці розрізняються для GL_LIGHT0 і інших джерел світла (GL_LIGHT1, GL_LIGHT2 ...). Для параметрів GL_DIFFUSEи GL_SPECULAR джерела світла GL_LIGHT0 значення за умовчанням – (1.0, 1.0, 1.0, 1.0). Для інших джерел світла значення тих же параметрів за умовчанням – (0.0, 0.0, 0.0, 1.0).
Колір.
OPENGL дозволяє асоціювати з кожним джерелом світла три різні параметри, пов'язаних з кольором: GL_AMBIENT, GL_DIFFUSE і GL_SPECULAR. Параметр GL_AMBIENT задає RGBA інтенсивність фонового світла, яке кожне окреме джерело світла додає до сцени.
Glfloat light_ambient[]={0.0,0.0,1.0,1.0};glLightfv(GL_LIGHT0,GL_AMBIENT,light_ambient);
Параметр GL_DIFFUSE напевно найточніше збігається з тим, що ви звиклися називати «кольором світла». Він визначає RGBA колір дифузного світла, яке окреме джерело світла додає до сцени. За умовчанням для GL_LIGHT0 параметр GL_DIFFUSE рівний (1.0, 1.0, 1.0, 1.0), що відповідає яскравому білому світу. Значення за умовчанням для решти всіх джерел світла (GL_LIGHT1, GL_LIGHT2 ..., GL_LIGHT7) рівне (0.0, 0.0, 0.0, 0.0).
Параметр GL_AMBIENT впливає на колір дзеркального відблиску на об'єкті. На реальному світі на об'єктах на зразок скляної пляшки є дзеркальний відблиск відповідного освітленню кольору (часто білого). Для створення ефекту реалістичності потрібно встановити GL_SPECULAR в те ж значення, що і GL_DIFFUSE. За умовчанням GL_SPECULAR рівне (1.0, 1.0, 1.0, 1.0) для GL_LIGHT0 і (0.0, 0.0, 0.0, 0.0) для решти джерел.
Позиція і ослаблення.
Можна вибрати, чи слід вважати джерело світла за розташоване нескінченно далеко від сцени або близько до неї. На джерела світла першого типа посилаються як на направлених (directional): ефект від нескінченно далекого розташування джерела полягає в тому, що всі промені його світла можуть вважатися за паралельних до моменту досягнення об'єкту. Прикладом реального направленого джерела світла може служити сонце. Джерела другого типа називаються позиційними (positional), оскільки їх точне положення на сцені визначає їх ефект і, зокрема, направлення з якого йдуть промені. Прикладом позиційного джерела світла є настільна лампа.
Направлене джерело:
Glfloat light_position[]={1.0,1.0,1.0,0.0};glLightfv(GL_LIGHT0, GL_POSITION, light_position);
Як видно, для параметра GL_POSITION задається вектор з чотирьох величин (x, у, z, w). Якщо остання величина w дорівнює 0, відповідне джерело світла вважається за направлене, і величини (x, у, z) визначають його напрям. Цей напрям перетвориться видовою матрицею. За замовчанням параметру GL_POSITION відповідають значення (0, 0, 1, 0), що задає світло, направлене уздовж негативного напряму осі z. (Відмітьте, що ніхто не забороняє вам створити світло, направлене в (0, 0, 0), проте таке світло не дасть належного ефекту).
Якщо значення w не дорівнює 0, світло є позиційним, і величини (x, у, z) задають місце розташування джерела світла в однорідних об'єктних координатах. Це положення перетвориться видовою матрицею і зберігається у видових координатах. Крім того, за замовченням позиційне світло випромінюється на всіх напрямках, але ви можете обмежити розповсюдження світла, створивши конус випромінювання, що визначає прожектор.
Завдання лабораторній роботі.
Завдання 1. Побудувати 2 сфери з координатами і радіусом, заданими в таблиці 1 для кожного варіанту.
Завдання 2. Задати фонове освітлення з параметрами, заданими в таблиці 1 для кожного варіанту.
Завдання 3. Задати параметри матеріалу для сфер. Одна з сфер повинна мати властивість GL_DIFFUSE, а друга GL_SHININESS. Колір і ступінь блиску задані в таблиці 1.
Завдання 4. Створити джерела світла, кількість яких різна для кожного варіанту. Параметри джерел світла задаються довільно, проте вони мають бути різні для різних ламп.
Варіанти до завдання лабораторної роботи.

Координати центру сфери
Радіус сфери
Параметри фонового освітлення
Колір, ступінь блиску
К-ть ламп

1
1,0,4
3
0.2,0.2,0.3,1
червоний, 45
2

2
2,7,9
5
0.1,0.4,0.1,1
синій, 79
3

3
9,4,10
2.9
0.5,0.3,0.5,1
жовтий, 93
1

4
-15,9,2.2
6
0.3,0.6,0.2,1
зелений, 39
2

5
8,3.8,-1.7
3.4
0.2,0.7,0.1,1
рожевий, 122
1

Додаткові завдання.
У встановленому графічному вікні побудувати куб, задати для різних його граней різні параметри матеріалу: GL_AMBIENT, GL_DIFFUSE, GL_SPECULAR, GL_EMISSION, GL_SHININESS, GL_AMBIENT_AND_DIFFUSE.
Встановити дифузне джерело світла, освітлююче білу неблискучу сферу. По натисненню клавіші на клавіатури лампа повинна змінювати свій колір від червоного до фіолетового в порядку проходження квітів в спектрі.
Встановити дифузне джерело світла, освітлююче білу неблискучу сферу. При натисненні клавіш курсора лампа повинна пересуватися у вказаному напрямі.
Побудувати піраміду, що освітлюється двома джерелами світла. Червоним і зеленим. При натисненні клавіші “G” або “R” інтенсивність відповідно зеленого або червоного джерела світла збільшується на 10%. Досягши інтенсивності в 100%, вона повинна автоматично падати до 10%.
Побудувати куб, освітлений джерелом світла, що обертається навколо нього. При натисненні клавіші «вправо» джерело світла починає рухати з більшою швидкістю. При натисненні клавіші «вліво», швидкість руху лампи повинна зменшуватися.
Контрольні питання.
Яка модель освітлення використовується в OPENGL?
Які види освітлення можна встановити в програмі OPENGL?
Чим визначається колір поверхні об'єкту?
Які команди використовуються для установки джерела освітлення?
Скільки джерел освітлення можна визначити в програмі OPENGL?
Як впливають властивості матеріалу на видимий колір об'єкту?
У чому полягають відмінності між направленими і позиційними джерелами освітлення?
У чому полягає ефект ослаблення?