Зеркальные огни на кубе в opengl es

В некоторых уроках, где вводится освещение, люди начинают с примера сферы, освещенной всеми тремя типами источников света: рассеянным, рассеянным и зеркальным. Тогда можно легко увидеть, например, путем выключения отдельных источников света, окружающий свет отвечает за равномерное освещение объекта, рассеянный исходит из определенного направления, и благодаря зеркальному свету мы можем наблюдать яркое пятно на поверхности.

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

Однако я мог получить только равномерно освещенные лица, а не яркое пятно. Итак, мой вопрос: действительно ли возможно это получить? Забыл упомянуть, что я использовал простейшую триангуляцию - 2 треугольника на грань. Другое дело, я использую OpenGL ES 1.1, поэтому шейдеров нет.


person user3211670    schedule 19.01.2014    source источник
comment
Разместите свой соответствующий код.   -  person Mark    schedule 19.01.2014
comment
Код здесь не помогает, а изучает явления, которые следует смоделировать.   -  person Jens Piegsa    schedule 21.01.2014
comment
Большое спасибо всем !, извините за такой долгий перерыв. После некоторого тестирования я обнаружил, что обе подсказки, которые я здесь получил, были правильными: во-первых, зеркальный свет был расположен слишком далеко от поверхности моих объектов, а во-вторых, моя мозаика была слишком грубой.   -  person user3211670    schedule 06.04.2014


Ответы (3)


Расчет освещения в OpenGL вычисляется для каждой вершины, а затем результат линейно интерполируется (возможно, с коррекцией перспективы) по пикселям каждой грани.

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

Чтобы аппроксимировать попиксельную молнию, вам нужно разделить грани на множество маленьких треугольников ... или вам нужно использовать другие методы: например, используя «пиксельные / фрагментные шейдеры» для вычисления попиксельных трюков молнии или наложения текстуры. подражать тому же.

Для объяснения фрагментных шейдеров в OpenGL ES см. http://www.learnopengles.com/android-lesson-three-moving-to-per-fragment-lighting/

Используя уловки наложения текстуры (обычно называемые подходом «наложения окружения»), легко даже имитировать убедительные блестящие объекты, которые могут отражать окружающую среду, а не только источники света на попиксельной основе.

http://raksy.dyndns.org/torus.html - это демонстрация веб-холста, в которой блестящее отражение действительно вычисляется с помощью уловки наложения текстуры. На самом деле этот код вообще не зависит от какой-либо поддержки 3D и рисует треугольники, используя только 2-мерные матрицы преобразования, которые предоставляет объект холста html5.

Как вы можете заметить, геометрия объекта очень грубая (каждое пятно на торе имеет всего 9 вершин), но отражение источника света определено, и вы даже можете увидеть искаженное отражение плиточного пола.

трюк с отображением среды

person 6502    schedule 19.01.2014

В вашем примере есть некоторые проблемы.

Вам нужно различать точечный свет и направленный свет. В своем вопросе вы явно не указали, что используете (РЕДАКТИРОВАТЬ: вы получаете направленный свет, если ваша 4-я координата света равна 0, иначе вы получите точечный свет)

Есть красивая картинка, показывающая разницу в этом вопросе

http://i.stack.imgur.com/3udUJ.gif(с сайта okino.com)

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

Если вы используете точечный свет, то столкнетесь с проблемами из-за OpenGL (ES) - фиксированной модели освещения трубопровода. Он рассчитывал освещение для каждой вершины. Поскольку вы используете только 5 разных вершин на каждую сторону куба, вы снова получаете небольшие различия в освещении. Вы можете обойти это, используя шейдер освещения на каждый пиксель или разбив куб на более мелкие треугольники.

Конечно, есть также ряд мелких "ловушек", вам нужно убедиться, что ваши разные источники света (источники и типы) не излучают слишком много света при объединении, это испортит ваше освещение. Также убедитесь, что нормали установлены правильно.

person user1781290    schedule 19.01.2014

Освещение сильно зависит от количества вершин на каждой стороне вашего куба. Поскольку вы не используете шейдеры, освещение рассчитывается по вершинам. Но расчет зависит от нормали к поверхности, которая ориентирована перпендикулярно грани и рассчитывается для каждой грани, что означает 3 вершины. Нормали одинаковы для каждой вершины грани, поэтому интенсивность света для каждой вершины также одинакова, так что вы не видите никаких световых эффектов. Если вы правильно рассчитали нормали, вы должны увидеть разницу в цвете разных сторон куба. Чтобы получить какое-то пятно на одной стороне, вам нужно увеличить разрешение сетки для каждой стороны куба, и вы должны применить соответствующий угол для конуса прожектора, или вы минимизируете расстояние прожектора до куба.

            n1         n2
           /          /
          /          /
        v1 ---------- v2
         |         / 
         |       /
         |  n3 /    
         | / /
         |//
         |
        v3            v4

Взгляните на этот красивый учебник. Он очень понятно объясняет основной механизм: http://www.opengl-tutorial.org/beginners-tutorials/tutorial-8-basic-shading/

person Diversity    schedule 19.01.2014