Пытаясь понять свет на 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. Вы можете испечь эмбиентную окклюзию к вершинам вашей модели в программном обеспечении для трехмерного моделирования или использовать 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 specular по умолчанию равен 1.0, но материал specular по умолчанию равен 0.0. Так что измените glLightfv (GL_LIGHT0, GL_SPECULAR, specLight0); в glMaterialfv (GL_FRONT, GL_SPECULAR, specLight0); Также хорошо установить glLightModeli (GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE); или зеркальное отражение может быть неправильно рассчитано при вращении камеры.
msell

1
@Nazgulled Для вторичного света, установите ambient и specular на ноль и небольшое значение, например 0.2, для diffuse. Вы также можете установить окружающее освещение всех источников на ноль и использовать вместо него глобальное окружающее с GL_LIGHT_MODEL_AMBIENT.
msell

2

Окружающее освещение OpenGL - один цвет, но окружающее освещение в реальном мире обычно ярче сверху и темнее снизу. Вы можете приблизить это в OpenGL, установив окружающий свет очень темно-синим и добавив темно-синий направленный свет, направленный вниз. Это, плюс яркий белый направленный свет, идущий от того места, где солнце, может очень хорошо приближаться к освещению на открытом воздухе.

Что вы действительно должны сделать, это написать шейдер, который рассчитывает свет на пиксель, но чтобы добраться туда, где вы находитесь, потребуется немного времени.


Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.