Почему бы не применить матрицу представления модели к нормальному вектору в Toon Shading (учебник Lighthouse3d)? - PullRequest
1 голос
/ 20 июня 2011

Я изучаю GLSL, изучив учебник в Интернете .

В учебнике есть пример, называемый Toon Shading. Вот ссылка на Toon Shading - Версия I .

В этом примере вершинный шейдер записывается следующим образом:

 uniform vec3 lightDir;
 varying float intensity;

 void main()
 {
      intensity = dot(lightDir,gl_Normal);
      gl_Position = ftransform();
 }

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

Что касается моей заботы, то вот что говорится в руководстве:

«допустим, что направление света определено в мировом пространстве».

и

"Если на модели в приложении OpenGL не выполняется никаких поворотов или масштабов, то нормаль, определенная в мировом пространстве и предоставленная вершинному шейдеру как gl_Normal, совпадает с нормалью, определенной в локальном пространстве."

Эти объяснения дают мне несколько вопросов:

1. What are world space and local space? How are they different? (This question
   seems a little bit elementary, but I need to understand...)

2. I figure the fact that "the light’s direction is defined in world space"
   has something to do with not applying the Model View Matrix on to the
   normal vector of a vertex. But, what is that?

3. Finally, If we don't apply the Model View Matrix on the normal vector then
   wouldn't the normal be pointing to a direction different from the actual
   direction of the surface? How do we solve this problem?

Надеюсь, я прояснил свои вопросы.

Спасибо!

1 Ответ

3 голосов
/ 20 июня 2011

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

Локальное пространствоНекоторые называют его также «пространством модели». Это пространство, в котором находятся данные вашего атрибута вершины. Если ваши сетки получены от кого-то, использующего такие инструменты, как 3DS Max, Blender и т. д., то пространство этих позиций и нормалей не обязательноТо же самое, что и мировое пространство.

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

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

Учебное пособие правильно вчто если у вас есть норма в мировом пространстве и направление света в мировом пространстве (и вы делаете направленное освещение, а не точечное освещение), то вам не нужно ничего трансформировать.Цель преобразования нормали - преобразовать ее из локального пространства в то же пространство, что и направление вашего света.Здесь они просто определяют, что находятся в одном и том же пространстве.

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

Наконец, если мы не применим матрицу представления модели к вектору нормали, тогда нормаль не будет указывать в направлении, отличном от фактического направленияповерхность?

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

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

Некоторые люди освещают в локальном пространстве.Если вы выполняете рельефное отображение, вам часто нужно делать освещение в пространстве, касательном к плоскости текстуры.


Добавление:

Стандартный способ обработки нормалей(при условии, что все ваши матрицы по-прежнему поступают через стандартные матричные команды OpenGL) означает, что нормали находятся в том же пространстве, что и данные о вашем положении.Следовательно, их также необходимо преобразовать.

Однако по причинам, которые лучше объяснены здесь, (примечание: в целях полного раскрытия я написал эту страницу), вы не можете простопреобразовать нормали с матрицей, которую вы использовали бы для позиций.К счастью, OpenGL был написан с ожиданием того, что, если вы используете стандартный стек матриц OpenGL, они дают вам заранее определенную матрицу для обработки этого: gl_NormalMatrix.

Типичный сценарий освещения в GLSL будет выглядетькак это:

uniform vec3 eyeSpaceLightDir;
varying float intensity;

void main()
{
    vec3 eyeSpaceNormal = gl_NormalMatrix * gl_Normal;
    intensity = dot(eyeSpaceLightDir, eyeSpaceNormal);
    gl_Position = ftransform;
}

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

...