DirectionalLigbtd, normal, amb. diff, spec); else if (gl_LightSource[i].spotCutoff == 180,0)

PointL1ght(i. eye, ecPosition3, normal, amb, diff. spec): else

SpotLight(i. eye, ecPosition3. normal, amb, diff. spec);

}

color = gl_BackLightModelProduct.sceneColor + amb * gl_BackMaterial.ambient + diff * glBackMaterial.diffuse;

if (SeparateSpecular)

gIBackSecondaryColor = vec4 (spec *gl_BackMaterial .specular, 1.0): else

color +■= spec * gl_BackMaterial .specular: gl_BackColor = color; Нет необходимости ограничивать значения gl_BackSeconeta ryCol or и gl_BackCol or, потому что это выполняется автоматически.

.5. Отсутствие освещения

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

Листинг 9.14. Установка значений цвета без освещения

1f (SecondaryColor).

gl_FrontSecondaryColor = gl_SecondaryColor;

// Для gl_FrontColor ограничение будет выполнено автоматически gl_FrontColor - gl_Color:

9.6. Эффект дымки

В OpenGL эффекты глубины и дымки (туман, а в большинстве изображений просто ухудшение видимости с удалением предметов от точки обзора) контролируются параметрами дымки. Коэффициент дымки вычисляется с помощью одного из трех уравнений, а в дальнейшем используется при вычислении плавного перехода между цветом дымки и цветом фрагмента. Значение глубины, которое используется в выражении для дымки, может быть либо координатой дымки, переданной как стандартный атрибут вершины (gl_FogCoord), либо расстоянием от точки обзора до фрагмента изображения в пространстве координат обзора. Во втором случае обычно достаточно просто аппроксимировать значение глубины, используя абсолютное значение координаты z в пространстве обзора (то есть abs(ecPosition.z)). При очень большом угле обзора такая аппроксимация может спровоцировать заметный дефект изображения (небольшую дымку у края). В этом случае можно вычислять z как расстояние от точки обзора до фрагмента (1 ength(ecPosi ti on)). (Этот метод предполагает вычисление квадратного корня, что немного ухудшит производительность.) Выбрать способ вычисления в вершинном шейдере можно так:

if (UseFogCoordinate)

gl_FogFragCoord = gl_FogCoord; е!зе

gl_FogFragCoord = abs(ecPosition.z); Листинг 9.15. Вычисления дымки no GLJJNEAR

fog = (gl_Fog.end - gl_FogFragCoord)) * gl_Fog.scale: Так как 1.0 / (gl_Fog.end - gl_Fog.start) не зависит от состояния вершины или фрагмента, это значение можно вычислить заранее и сделать доступным в виде встроенной переменной gl_Fog. scale.

Более реалистичного эффекта дымки можно достичь с помощью экспоненциальной функции. Используя отрицательное значение экспоненты, экспоненциальная функция моделирует убывание изначального цвета в зависимости от расстояния. Простая экспоненциальная функция дымки выбирается в OpenGL с помощью константы GL__EXP, Язык шейдеров OpenGL не имеет встроенной функции expCbase е), но в нем есть экспоненциальная функция с основанием 2, ехр2. Учитывая, что ехр(х) = ехр 2{х/ lqg(2)), можно получить нужный результат. Выражение l/log(2) равно 1,442695. Код шейдера OpenGL для вычисления приведенного уравнения показан в листинге Э.16.


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