//
// 0 3D1 abs. Inc. и Hewlett-Packard. L.P.. 2003.
// опубликовано с разрешения компаний //
uniform vec3 LightPos; uniform vec3 EyeDir:
attribute vec3 Tangent; attribute vec3 Binormal:
varying float Du;
varying float Dv; t
varying float LdotN: varying vec2 TexCoord:
void main(void)
{
vec3 lightTemp: vec3 halfAngleTemp; vec3 tPrime: vec3 bPrime:
// Преобразование вершины
gl_Position = ftransfarmt):
lightTemp = normalizetLightPos - gl_Vertex.xyz):
I! Вычисление вектора половины угла halfAngleTemp = normalize(EyeDir + lightTemp): И Вычисление T' и В'
// Т' - |Т - СТ.Н)Н|
tPrime = Tangent - (halfAngleTemp * dot(Tangent, halfAngleTemp)); tPrime = normalize(tPrime);
// В' - H x T'
bPrime = crossChalfAngleTemp. tPrime);
Du = dot(lightTemp, tPrime):
Dv = dot(lightTemp, bPrime):
It Умножение половинного угла на N0ISE_FACT0R,
// чтобы избешать помех а BRDF-данных
Листинг 10.7 (продолжение)
halfAngleTemp = halfAngleTemp * 0.9:
// Hu = DptCHalfAngle, T)
// Hv = Dot(HalfAngle. B)
// Remap [-1.0..1.0] to [0.0..1.0]
TexCoord.s = dotCTangent, halfAngleTemp) * 0.5 + 0.5:
TexCoord.t = dot(Binormal, halfAngleTemp) * 0.5 + 0.5:
// "S" Text Coord3; Dot(Light. Normal);
LdotN = dotdigbtTemp, gljJormaD * 0.5 + 0.5:
}
Координаты источника освещения и направление обзора передаются в шейдер приложением как uniform-переменные. В дополнение к стандартным атрибутам вершины - координатам и нормали - приложение передает тангенс и бинормаль для каждой вершины, как описано в предыдущем разделе. Эти два. дополнительных атрибута определены с соответствующими именами в данном вершинном шейдере.
Первая строчка вершинного шейдера преобразует входные координаты с помощью проекционной матрицы модели-вида. Следующая строчка вычисляет направление освещения вычитанием координат вершины из координат источника освещения. Так как переменная LightPos - типа vec3, а встроенная переменная gl_Vertex - типа vec4, необходимо использовать компоненты . xyz, чтобы получить первые три элемента gl_Vertex перед вычитанием векторов. Результат вычитания векторов нормализуется и сохраняется как направление освещения.
Следующая строчка кода вычисляет половинный угол следующим образом: вектор обзора и вектор освещения складываются и результат нормализуется.
Следующие несколько строккода выполняют двухмерную параметризацию половинного угла и вектора приращения. Это нужно для вычисления значений для и (Du) и v (Dv), которые подставляются в биквадратное уравнение во фрагментном шейдере (так называемый метод ортонормирования Грама-Шмидта). Здесь Н (половинный угол), Т1 и В' - ортогональные оси системы координат, Т' и В' поддерживают общее выравнивание с исходными векторами Т (тангенциальный вектор) и В (вектор бинормали). В то время как Т и В лежат на плоскости треугольника, рендеринг которого выполняется, Т' и В' находятся в плоскости, перпендикулярной вектору половинного угла. Обоснование для определения системы координат через Н, Т’ и В' содержится в документе «Interactive Rendering with Arbitrary BRDFs Using Separable Approximations» (авторы Ян Куц и Майкл МакКул, 1999 г.).