Отдельное освещение OpenGL ES 2.0 для нетекстурированной сгенерированной геометрии

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

Я успешно реализовал затенение Гуро (для каждой вершины) и теперь хочу реализовать затенение Фонга (для каждого фрагмента / пикселя).

Я просмотрел соответствующие учебные пособия в Интернете, и есть два лагеря: один предлагает простую перестановку кода шейдера по Гуро на Фонга, которая, хотя и предлагает улучшенное освещение, на самом деле не попиксельная. Второй делает все правильно, используя карты нормалей, встроенные в текстуры, но они создаются в наборе инструментов моделирования, таком как RenderMonkey.

Мои вопросы:

  1. Как мне программно генерировать нормали для моей сгенерированной геометрии, считая ее набором вершин? Другими словами, нужно ли будет вручную вычислять интерполированные нормали для заданного набора дискретных многоугольных точек?

  2. Должен ли я хранить сгенерированные нормали в текстуре, как показано в Интернете, и если да, то как мне сделать это в коде, а не с помощью программного обеспечения для моделирования?


person KomodoDave    schedule 02.09.2011    source источник


Ответы (2)


Вычисление освещения во фрагментном шейдере на интерполированных нормалях для каждой вершины определенно даст лучшие результаты (при условии, что вы правильно повторно нормализуете интерполированные нормали во фрагментном шейдере), и это действительно на пиксель. Хотя сила различия может сильно зависеть от мозаики модели и вариации освещения. Вы только что попробовали?

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

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

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

  2. Вы должны сначала попробовать простое попиксельное освещение, прежде чем углубляться в такие методы, как отображение нормалей. Если у вас не очень мелкая мозаичная геометрия или очень блестящие поверхности, вы наверняка заметите разницу с простым освещением по вершинам. Затем, когда это сработает, вы можете попробовать обычные методы отображения, но для того, чтобы они сработали, вам, безусловно, нужно сначала понять значение попиксельного освещения и затенения Фонга в отличие от затенения Гуро.

person Christian Rau    schedule 02.09.2011
comment
Прекрасная деталь, как всегда, Кристиан. Мои нормали не сильно меняются, но я хотел выполнить работу должным образом, поэтому пришлось проверить; книга ввела меня в заблуждение цитатой, которую я разместил в комментарии к персику ниже. Я только что реализовал Фонга, и теперь освещение выглядит фантастически :) Большое спасибо. - person KomodoDave; 03.09.2011

Карты нормалей не необходимы для попиксельного освещения.

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

Карты нормалей могут либо предоставлять полные данные нормалей (карты rgb), либо просто модулировать сохраненные нормали вершин (карты du / dv, отображаются красным / синим). Последняя форма, возможно, более распространена и зависит от нормалей вершин для работы.

Создание нормалей зависит от вашего кода и геометрии. Как правило, вы используете точечные произведения и окружающие грани или вершины для сглаживания нормалей или просто создаете единичный вектор, указывающий на то, что "не" для вашей геометрии.

person ssube    schedule 02.09.2011
comment
Последняя форма, возможно, более распространена. Возможно, вы думаете о форме нормального сжатия, когда нормали касательного пространства хранятся в двух компонентах. Третья реконструируется во фрагментном шейдере с помощью простого квадратного корня, поскольку нормаль, как известно, имеет единичную длину, а координата Z (отброшенная) всегда положительна в касательном пространстве. - person Nicol Bolas; 02.09.2011
comment
@peachy: Это не требование само по себе, но определенно полезно, отсюда и мой вопрос. Цитата из Руководства по программированию OpenGL ES 2.0: Простейший способ сделать освещение для каждого фрагмента - использовать интерполированную нормаль вершины во фрагментном шейдере, а затем перенести вычисления освещения во фрагментный шейдер. Тем не менее, для диффузного элемента это действительно не даст гораздо лучших результатов, чем освещение для каждой вершины. Чтобы действительно воспользоваться преимуществом ... использование карты нормалей для хранения нормалей на тексель может обеспечить значительно больше деталей. - person KomodoDave; 02.09.2011
comment
@KomodoDave Вы путаете два разных понятия. Добавление карт нормалей предназначено для обеспечения большей детализации при использовании попиксельного освещения, однако попиксельное освещение работает должным образом и без него; вы просто не получите никаких деталей, кроме того, что дано в геометрии. - person ssube; 02.09.2011