ambient += gl_L1ghtSource[i].ambient: diffuse += gl_LightSource[i].diffuse * nDotVP: specular += gl_LightSource[i].specular * pf;
}
9.2.2. Точечные источники
Точечные источники освещения имитируют свет возле или внутри изображения, например лампы, люстры или уличные фонари. Существует два основных отличия точечных источников света от источников направленного освещения. Первое состоит в том, что направление максимальной подсветки должно быть вычислено в каждой вершине, а значение из gl_LightSource[i ] .halfVector не может быть использовано. Второе отличие - в том, что свет, полученный поверхностью, уменьшается с удалением источника освещения. Этот эффект называется поглощением. Каждый источник освещения имеет постоянный, линейный и квадратичный коэффициенты, которые используются при вычислении доли освещения от точечного источника.
Эти различия выделяются уже в первых нескольких строках функции вычисления освещения от точечного источника (листинг 9.7). Первый шаг - вычисление вектора от поверхности до источника освещения с помощью функции длины, VP нормализуется и в дальнейшем будет использоваться в операции dot при нахождении правильного значения косинуса. Коэффициент поглощения и направление максимума освещения вычисляются как обычно. Остальной код остается таким же, как и в предыдущей функции (вычисление света от источника направленного освещения), за исключением того, что отраженные и зеркальные составляющие освещения умножаются ка коэффициент поглощения.
Оптимизация, которую здесь можно выполнить, состоит в том, чтобы получить две функции для вычисления точечного освещения: одна функция учитывает коэффициент поглощения, а другая - нет. Если значения постоянного, линейного и квадратичного коэффициентов - (1, 0, 0) (значения по умолчанию), для улучшения производительности можно использовать функцию без вычисления поглощения.
Листинг 9.7. Вычисления освещения отточенного источника
void PointLight(in int i.
in vec3 eye.
in vec3 ecPositions, in vec3 normal, inout vec4 ambient, inout vec4 diffuse, inout vec4 specular)
{■
float nDotVP; U нормаль . направление освещения
float nDotHV; // нормаль . половинный вектор
float pf: // степень
float attenuation; // вычисленный коэффициент поглощения
float d; // расстояние от поверхности до источника уесЗ VP: // направление от поверхности до источника
vec3 halfVector; // направление максимального освещения
// Вычисление вектора от поверхности до источника VP = vec3 (gl_LightSource[i].position) - ecPosition3;
// Вычисление расстояния между поверхностью и источником d = length(VP):
// Нормализация вектора от поверхности до источника VP = normalize(VP):
// Вычисление поглощения
attenuation = 1.0/( g1_LightSource[i].cohstantAttenuation + gl_LightSource[i].linearAttenuation * d + gl_LightSource[i].quadraticAttenuation * d * d);