Функция, которая будет формировать коорди наты GL_SPHERE_MAP в соответствии со спецификацией OpenGL, приведена в листинге 9,20.
Листинг 9.20. Вычисление GL_SPHERE_MAP
vee2 SphereMapdn vec3 ecPosition3. in vec3 normal)
{
float m: vec3 r, u:
u “ normalize(ecPos1tiori3): r - ref1ect(u. normal):
m = 2.0 * sqrt(r.x * r.x + r.y * r.y + (r.z + 1.0) * (r.z + 1.0)): return vec2 (r.x / m + 0-5. r.y / m + 0.5);
}
Функция для GL_REFLECTI0N_MAP выглядит почти так же, как предыдущая, за исключением того, что возвращает вектор отражения (листинг 9.21).
Листинг 9.21. Вычисление GL_REFLECTION_MAP
vec3 ReflectionMapdn vec3 ecPosition3, in vec3 normal)
{
float NdotU. m: vec3 u:
взять кальян в аренду в Москве.
u = normalize(ecPosition3); return (reflect(u. normal)):
}
Выбор нужного метода формирования текстурных координат и вычисление окончательных значений показаны в листинге 9.22.
Листинг 9.22. Вычисление текстурных координат
// Вычислить координаты сферического отображения при необходимости if (TexGenSphere)
sphereMap - SphereMap(ecposition3. normal): П Вычислить координаты отражения при необходимости if (TexGenReflection)
reflection = ReflectionMap(ecposition3, normal);
/./ Вычислить текстурные координаты для каждого активного текстурного модуля for (i - 0; i < NumEnabledTextureLJnits; i++)
{
if (TexGenGbject)
{
gl_TexCoord[i].s = dottgl_Vertex, gl_ObjectPlaneS[i]); gl_TexCoord[i].t = dot(gl Vertex. gl_ObjectPlaneT[i]): gl_TexCoord[i].p = dot(gl_Vertex, gl_ObjectPlaneR[i]); gl_TexCoord[i].q = dot(gl_Vertex. gl_ObjecrtPlaneQ[i]):
}
if (TexGenEye)
{
gl_TexCoord[i].s = dottecPosition. g1_EyePlaneS[i]); gl_TexCoord[i],t = dot(ecPosition, gl_EyePlaneT[i]): gl_TexCoord[i].p = dot(ecPosition. gl_EyePlaneR[i]); gl_TexCoord[i].q = dottecPosition. gl_EyePlaneQ[i]);
}
if (TexGenSphere)
gl_TexCoord['i] = vec4(sphereMap, 0.0. 1.0);
if (TexGenReflection)
gl_TexCoord[i] = vec4(reflection. 1.0):
if (TexGenNorma1)
gl_TexCoord[i] = vec4(normal. 1.0): Предполагается, что каждый текстурный модуль этого кода имеет номер меньший, чем NumEnabl edTexturellnits. Если это значение равно 0, цикл по модулям будет пропущен, В противном случае все необходимые текстурные координаты будут вычислены внутри цикла.
Так как вычисления сферического отображения и отражения не зависят от состояния заданного текстурного модуля, их можно выполнять отдельно, арезуль-тат будет использоваться для всех текстурных модулей. Для способов, реализуемых с использованием GL_0BJ ECT_L IN EAR и GL_EYE_LINEAR, существует уравнение плоскости для каждого компонента каждого набора текстурных координат. В первом примере компоненты gl_TexCoord[0] формируются умножением коэффициентов уравнения плоскости для указанного компонента на входные вершинные координаты, Во втором примере компоненты g 1 _ТexCoord С О J вычисляются умножением коэффициентов уравнения плоскости на координаты вершины в пространстве координат обзора. В зависимости от типа обращения к текстуре на этапе обработки фрагментов вычислять t,p'vi q не обязательно.
9.8. Произвольное отсечение
В OpenGL, чтобы применять произвольное отсечение (оно остается стандартной функциональностью между вершинным и фрагментным шейдерами), вершинный шейдер должен преобразовать входные вершинные координаты в то же самое пространство координат, в котором определены плоскости отсечения. Обычно они определены в пространстве обзора, и код шейдера, приведенный в листинге 9.23, используется для преобразования координат вершин.