gl_Position = ftransformO; Единственное различие между ними в следующем: второй способ гарантирует, что преобразование координат выполнялось точно таким же способом, как это делает стандартная функциональность. Некоторые реализации могут иметь собственные аппаратные усовершенствования, которые будут обусловливать небольшие различия в таких преобразованиях. Это может создавать проблемы при использовании многопроходных алгоритмов, где один и тот же алгоритм используется для рисования одних и тех же фигур более одного раза. В таких случаях предпочтительно применять второй метод, поскольку он работает точно так же, как стандартная функциональность.

Координаты источника освещения преобразуются с помощью матрицы моде-ли-вида при передаче их в OpenGL. Это значит, что сохраняются они в координатах обзора. Зачастую удобнее рассчитывать освещение в системе координат обзора, так что бывает необходимо сделать соответствующие преобразования (листинг 9.1).

Листинг 9.1. Вычисление координат точки обзора

vec4 ecPosition:

vec3 ecPosition3: // in 3 space

// Преобразование координат вершины в систему координат обзора

if (NeedEyePosition)

{

ecPosition = gl_Mode1Vi ewMatri x * gl_Vertex: ecPosition3 = (vec3 (ecPosition)) / ecPosition.w:

}

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

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

Листинг 9,2. Преобразования нормали

normal = gl NormalMatrix * gl_Normal: Во многих случаях приложение может и не знать ничего о характеристиках нормалей поверхности. Чтобы убедиться в том, что освещение вычислено правильно, нужно нормализовать каждую входящую нормаль до единичной длины. В стандартной функциональности OpenGL нормализация - это параметр, который можно контролировать с помощью передачи символической константы GL_NORMALIZE в функции glEnable или glDisable. В шейдере OpenGL необходимая нормализация делается так, как в листинге 9.3.

Листинг 9.3. Нормализация нормали

normal = normalize(normal); Иногда приложение знает, что всегда будет посылать нормали в единичном виде, а матрица модели-вида будет применяться для масштабирования. В этом случае можно изменять масштаб, чтобы избежать «дорогой» операции извлечения квадратного корня. Коэффициенты масштабирования должны быть предоставлены приложением, и нормали могут быть масштабированы так, как показано в листинге 9.4.

Листинг 9.4. Масштабирование нормали

normal = normal * gl_NormalScale; Коэффициенты масштабирования сохраняются как состояние OpenGL, и к ним можно обращаться из шейдера, используя встроенную uniform-переменную gl _Norma 1 Seal е.

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


⇐ вернуться назад | | далее ⇒