Намагаючись зрозуміти світло на Opengl, як імітувати реалістичне сонячне світло?


13

Я не знаю, чи роблю щось не так, чи щось не вистачаю, але я хочу імітувати сонячне світло, як у сонячний день.

Коли об’єкт стикається із спрямованим світлом, він добре освітлюється і там немає проблем. Якщо я обходжу об’єкт і дивлюся на його назад, темно. Це не надто темно, тому що я використовую, GL_AMBIENTале все ще занадто темно для сонячного дня. Якщо я збільшить значення, воно ніколи не буде виглядати краще, оскільки сторона предмета, спрямована до світла, буде занадто яскравою.

І є ще одна набридлива проблема з навколишнім світлом, коли дивлячись на задню сторону об'єкта, я не бачу жодної форми, лише звичайного кольору. Важко пояснити, ось деякі фотографії:

Передня панель
об'єкта: http://i.stack.imgur.com/YW53X.png Назад об’єкта: http://i.stack.imgur.com/Qufha.png

Як ви легко бачите, передня сторона виглядає красиво, ви можете побачити форму тієї червоної речі. На зворотному боці це просто, ви не можете побачити однакову форму.

Тепер я знаю, що я дивлюся на задню частину предмета і дивлюсь у напрямку світла, і він повинен бути темніше, ніж лицьова сторона. Але це не повинно виглядати так просто. Це не те, що ми бачимо, йдучи проти сонячного світла, дивлячись на якийсь предмет, ми бачимо, що предмети утворюють певну форму.

Як я можу мати такий же (або подібний) ефект на OpenGL?

Наразі моє світло визначається так:

float posLight0[4] = {-1.0f, 1.0f, 1.0f, 0.0f};
float ambLight0[4] = {0.5f, 0.5f, 0.5f, 0.5f};

glLightfv(GL_LIGHT0, GL_POSITION, posLight0);
glLightfv(GL_LIGHT0, GL_AMBIENT, ambLight0);

Я пропоную вам розглянути можливість використання шейдерів, якщо це можливо. У конвеєрі OpenGL з фіксованою функцією використовується досить проста модель освітлення, тоді як шейдери забезпечують повний контроль над математикою.
Невірний чернець

Відповіді:


11

При навколишньому світлі ваші об'єкти виглядають занадто яскравими, оскільки дифузне світло додається до навколишнього світла, а дифузне світло - за 1,0 Це додає до 1,5, і все вище 1,0 затискається. Встановіть дифузне світло на 0,5:

float difLight0[4] = {0.5f, 0.5f, 0.5f, 1.0f};
glLightfv(GL_LIGHT0, GL_DIFFUSE, difLight0);

Другу проблему вирішити важче. Ви можете спробувати додати на поверхню якісь дрібні деталі, такі як текстура чи карта. У OpenGL навколишнє світло є постійним, але в реальному світі це ніколи не буває. Для імітації реального світу потрібна певна форма глобального освітлення . Оклюзія навколишнього середовища тут дуже багато допомагає, але важче здійснити, ніж просто встановити стани OpenGL. Ви можете розкрити оклюзію навколишнього середовища до вершин своєї моделі у вашому програмному забезпеченні для 3D-моделювання або використовувати SSAO , але я не збираюся докладно.

Що ви можете легко зробити, це додати ще одне тьмяне джерело світла з якогось іншого напрямку (наприклад, протилежного напрямку). Це не буде реалістично, але принаймні це додасть певної форми і задній стороні ваших предметів.

Також розгляньте можливість додавати яскраві моменти до своєї програми. Це зробить предмети блискучими.

float specLight0[4] = {0.5f, 0.5f, 0.5f, 1.0f};
glLightfv(GL_LIGHT0, GL_SPECULAR, specLight0);
glMaterialfv(GL_FRONT, GL_SHININESS, 10.0f); // Shininess between 0 and 128

Ви також можете вказати кольори світлого та матеріального кольору окремо, особливо якщо значення за замовчуванням не підходять для вас.


Тож немає простого і прямого способу зробити те, що я хочу в OpengGL ... Шкода. Можливо, я спробую додати інше джерело світла, але як саме вказати інтенсивність світла?
rfgamaral

GL_SPECULARІ , GL_SHININESSздається, не виробляють ніякого ефекту , хоча ... Я зробив зміни , glMaterialfvщоб , glMaterialiбо не компіляції. А також спробував більшу величину, як 128. На мене це виглядає так само ... Можливо, проблема в моїй завантаженій моделі (obj / mtl), доведеться подивитися.
rfgamaral

1
@Nazgulled Просто перевірив, що значення за замовчуванням light0 за замовчуванням до 1,0, а значення за замовчуванням для матеріалу - 0,0. Так змінити glLightfv (GL_LIGHT0, GL_SPECULAR, specLight0); to glMaterialfv (GL_FRONT, GL_SPECULAR, specLight0); Також добре встановити glLightModeli (GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE); або окуляр може бути обчислений неправильно при обертанні камери.
msell

1
@Nazgulled Для вторинного світла встановіть навколишнє середовище та окуляр на нуль і деяке невелике значення, як 0,2 для дифузного. Ви також можете встановити навколишнє середовище всіх вогнів на нуль і використовувати глобальний навколишній світ за допомогою GL_LIGHT_MODEL_AMBIENT.
msell

2

Навколишнє світло OpenGL - це одноколірне, але навколишнє світло в реальному світі зазвичай яскравіше згори і темніше знизу. Ви можете наблизити це у OpenGL, встановивши навколишнє світло на дуже темно-синій і додавши темно-синій спрямований світло вниз. Це, плюс яскраве біле спрямоване світло, яке виходить звідки б не було сонце, може досить добре наближати світло на вулиці.

Що ви насправді повинні зробити, це написати шейдер, який обчислює світло на піксель, але дістатися туди, де ви збираєтеся, знадобиться небагато часу.


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.