intensity = clamp(dot(HVector. normal), 0.0, 1.0); intensity = pow(intensity. SpecularColor.a): surfColor += SpecularColor * intensity:

Как видно на цветном рис. 17, б, зеркальное освещение идеально. Так как нормаль поверхности вычисляется очень точно для каждого фрагмента, здесь нет эффекта мозаики, который обычно наблюдается. На последнем шаге значение записывается в gl_FragColor и посылается для окончательной обработки перед тем, как отправиться в буфер кадров.

11.2. Игрушечный шар

gl_FragColar = vec4 (surfColor, 1.0):

Вот и все, игрушечный шар создан. Полностью код фрагментного шейдера приведен в листинге 11.5.

Листинг 11.5. Фрагментный шейдер для рисования игрушечного шара

varying vec4 Exposition; // Координаты поверхности в пространстве обзора varying vec4 ECballCenter; // Центр шара в пространстве обзора

uniform vec4 LightDir; // направление освещения, нужна нормализация

uniform vec4 HVector: // вектор отражения для освещения

uniform vec4 SpecularColor: uniform vec4 Red. Yellow. Blue;

uniform vec4 HalfSpaceO; // полупространства, определяющие звезду uniform vec4 HalfSpacel: uniform vec4 HalfSpace2; uniform vec4 НаШрасеЗ; uniform vec4 HalfSpace4;

uniform float InOrOutlnit: // = -3 uniform float StripeWidth; // = 0.4 uniform float FWidth; // = TBD
void main(void) {

vec4 normal: // Аналитически вычисленная нормаль

vec4 p; //Точка

vec4 surfColor: // Вычисленный цвет поверхности

float intensity: // Вычисленная интенсивность освещения

vec4 distance; // Вычисленные значения расстояния

float inorout; // Счетчик для вычисления звезды

p.xyz = norraalize(ECposition.xyz - ECbal1 Center.xyz); p.w =* 1.0;

inorout - InOrOutlnit: // инициализация inorout в -3

distancefO] = dot(p, HalfSpaceO):
distanced] = dotCp. HalfSpacel):
distanced] = dot (p. HalfSpace2);
distance[3] = dot(p. HalfSpace3):
distance = smoothstep(-FWidth, FWidth. distance);
inorout +- dot(distance. vec4(1.0));
distance.x = dot(p. HalfSpace4);

⇐ Предыдущая| |Следующая ⇒