distance.у = StripeWidth - abs(p.z);
distance = smoothstep(-FWidth. FWidth. distance):
inorout += distance.x;
inorout - clamp(inorout, 0.0. 1.0):
surfColor = mix(Yellow, Red. inorout);
продолжение &
Процедурные текстурные шейдеры
Листинг 11.5 (продолжение)
surfColor = mix(surfColor, Blue, distance.у):
// normal - точка на поверхности сферы (0.0.0) normal = р;
// Вычисление рассеянного освещения для каждого фрагмента intensity = 0.2; // ambient
intensity += 0.8 * clamp(dot(LightDir, normal)., 0.0. 1.0); surfColor *= intensity,
// Вычисления отраженного освещения для каждого фрагмента intensity - clarap(dot(HVector, normal), 0,0. 1.0); intensity = pow(intensity. SpecularColor.a): surfColor += SpecularColor * intensity:
gl_FragColor = vec4 (surfColor, 1.0);
}
11.3. Сетка Рассмотрим своего рода хитрость. Здесь будет показано, как не рисовать объект процедурно.
В этом примере читатель увидит, как можно использовать команду discard во фрагментном шейдере, чтобы получить интересные эффекты. Команда discard означает, что фрагмент будет отброшен и не попадет в буфер кадров вообще. Используем этот прием для рисования геометрических фигур с «дырками». Вершинный шейдер будет таким же, как вершинный шейдер полосок (см. раздел 11.1.1). Фрагментный шейдер приведен в листинге 11.6.
Листинг 11.6. Фрагментный шейдер для процедурного отбрасывания частей объекта
varying vee3 DiffuseColor: varying vec3 SpecularColor;
uniform vec2 Scale; uniform vec2 Threshold; uniform vec3 SurfaceColor;
void main (void) {
float ss = fract(gl_TexCoord[0].s * Scale.s); float tt = fract(gl_TexCoord[0].t * Scale.t);
if ((ss > Threshold.s) &&. (tt > Threshold.t)) discard;
vec3 finalColor = SurfaceColor * DiffuseColor + SpecularColor; gl_FragColor = vec4 (finalColor. 1.0);
}
Отбрасываемая часть объекта определяется значениями s mt текстурных координат. Коэффициент масштаба применяется для того, чтобы определить частоту сетки. Затем вычисляется дробная часть отмасштабированного значения тек11.4. Бугристая поверхность