// Нормализация вектора от поверхности до источника освещения VP = normalize(VP):

// Вычисление коэффициента поглощения

attenuation = 1.0 / (g1_LightSource[i].constantAttenuation + gl _LightSource[i].1inearAttenuati on * d + gl_LightSource[i],quadraticAttenuation * d * d):

// Проверка вхождения точки поверхности в конус света spotDot = dot С - VP, gl_LightSource[i].spotDire.ction):

if (spotDot < gl_LightSource[i].spotCosCutoff)

spotAttenuation = 0.0: // этот источник освещения не участвует

else

spotAttenuation =* pow(spotDot. gl_LightSource[i].spotExponent):

// Совмещение коэффициентов поглощения и расстояния

attenuation *= spotAttenuation; halfVector = normalize(VP + eye); nDotVP = max(0.0. dot(normal. VP)): nDotHV = max(0.0. dot(normal. halfVector));

if (nDotVP == 0.0) pf = 0.0: else

pf = pow(nDotHV. gl_FrontMaterial .shininess):

ambient += gl_LightSource[i],ambient:

diffuse +" gl_LightSource[i].diffuse * nDotVP * attenuation;

specular += gl_LightSourc.e[i].specular * pf * attenuation:

}

1.3. Свойства материала и освещение

Вычисление освещения в OpenGL требует знания направления обзора в системе координат обзора, чтобы вычислить элемент отражения. По умолчанию направление обзора принимается параллельным оси -г. В OpenGL есть режим, требующий определения направления обзора от начала координат в системе координат обзора. Чтобы сделать это, можно преобразовать входные координаты вершины в систему координат обзора с помощью текущей матрицы модели-вида. Координаты х,у иг точки обзора делятся на однородную координату w для получения значения vec3, которое и используется в дальнейших вычислениях. Вычисление этих координат обзора (ecPosi ti опЗ) показано в разделе 9.1. Для получения единичного вектора направления обзора нужно нормализовать и инвертировать координаты. Код шейдера, который это выполняет, показан в листинге 9.9.

Листинг 9.9. Вычисление координат наблюдателя

if (Local Vi ewer)

eye = -normalize(ecPosition3): else

eye = vec3 (0.0, 0.0. 1.0): После этого можно инициализировать переменные, которые затем будут использоваться для накопления составляющих рассеянного света, отражения и зеркального отражения от всех источников освещения. Можно использовать функции из предыдущего раздела, чтобы вычислить вклад в освещение каждого источника. В коде листинга 9.10 предполагается, что все источники освещения с номером, меньшим NumEnabl edLi ghts, включены. Источники направленного освещения имеют значение однородной координаты w равное 0 во время передачи этих координат в OpenGL (затем все переданные координаты преобразуются с помощью матрицы модели-вида, так что координата w после преобразования останется О, если последний столбец матрицы типичный (ООО 1)). У точечных источников освещения угол ограничения равен 180°.

Листинг 9.10. Цикл для вычисления суммарного освещения от всех источников

// Инициализация переменных для накопления интенсивности света arnb = vec4 (0.0):


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