Lightlntensity = DiffuseContribution *
max(dot(lightVec, tnorm). 0.0) +
SpecularContribution * spec:
Position = vec3(gl_MultiTexCoordO - 0.5) * 5.0;
gl_Position = ftransform();
15.3.3. Фрагментный шейдер
Во фрагментном шейдере реализован алгоритм, описанный в предыдущем разделе. Отгогт-переменные определяют максимальное количество итераций и начальную точку множества Мандельброта (центр и коэффициент масштабирования). Приложение может устанавливать один цвет для внутренних точек и два цвета - для внешних точек. Для значений внешних точек переход от цвета СМегСої огі до цвета (МегСо1ог2 будет разделен на 20 отдельных полос, и цвета начнут повторяться, если количество итераций превысит 20, потом 40 и т. д.
Этот шейдер соотносит координату х с вычисленными координатами на плоскости комплексных чисел (Робттлоп.х) с действительным числом в итеративной функции, а координату у - с мнимым числом. После установки начальных условий шейдер начинает цикл, используя два критерия выхода: достижение максимального количества итераций или выход точки за пределы множества. После выхода из цикла вычисляется цвет фрагмента. Если точка расположена внутри множества, используется внутренний цвет. Если точка на краю или вне множества,
Нефотореалистичные шейдеры
происходит плавный переход от цвета края к внешнему цвету в зависимости от количества итераций.
Полный код фрагментного шейдера приведен в листинге 15.7.
Листинг 15.7. Фрагментный шейдер множества Мандельброта
varying vec3 Position; varying float Lightlntensity:
uniform float Maxlterations; uniform float Zoom; uniform float Xcenter: uniform float Ycenter: uniform vec3 InnerColor; uniform vec3 OuterColorl; uniform vec3 0uterColor2;
void main(void) {
float real = Position.x * Zoom + Xcenter:
float imag = Position.у * Zoom + Ycenter:
float Creal = real; // Эту строку нужно поменять…
float Cimag = imag: // …и эту тоже для множества Джулии
float г2 = 0.0: float iter;
for (iter = 0.0; iter < Maxlterations && r2 < 4.0; ++iter) {