Graphics Reference
In-Depth Information
float real = vST.s * uTS + uS0;
float imag = vST.t * uTS + uT0;
float real0 = real;
float imag0 = imag;
float newr;
int numIters;
vec4 color = vec4( 0., 0., 0., 1. );
for( numIters = 0; numIters < uMaxIters; numIters++ )
{
float newreal = real0 + real*real - imag*imag;
float newimag = imag0 + 2.*real*imag;
newr = newreal*newreal + newimag*newimag;
if( newr >= uLimit )
break;
real = newreal;
imag = newimag;
}
// choose the color
if( newr < uLimit )
color = uConvergeColor;
else
color = mix( uDivergeColor1, uDivergeColor2,
fract(numIters/uCS) );
color.rgb *= vLightIntensity;
fFragColor = color;
}
This works by choosing the color for each pixel in the fragment based on
the way the Mandelbrot sequence converges at the point in texture space, vST ,
offset into the teapot's surface. If the pixel is in the area where the Mandelbrot
process converges (i.e., newr < u Limit ), it is colored with uConvergeColor ; if it
does not converge it is colored by a color that blends two other colors, using
the built-in mix( ) function, depending on the number of iterations needed.
Notice that the resolution just keeps increasing as the image is zoomed. An
advantage of procedural texturing in fragment shaders is that the texture can be
computed at the pixel level, no mater what size that pixel actually represents
in the model. The potentially large number of iterations for the Mandelbrot
sequence gives us the opportunity to illustrate the power of double preci-
sion in shaders. Figure 9.5 shows two views of a highly-zoomed region of the
Mandelbrot set. The top figure shows this region with single-precision compu-
tation, while the botom igure shows it with double precision.
Search WWH ::




Custom Search