Graphics Reference
In-Depth Information
subdivided, the results are triangles whose vertices are on the surface of the
sphere. The variables V0 , V01 , and V02 are, respectively, vertex 0, the vector
from vertex 0 to vertex 1, and the vector from vertex 0 to vertex 2, as shown in
Figure 12.7. The rest of the computations of light intensity and actual projected
position are familiar because they are the same as would be made in a vertex
shader. We saw the EmitVertex( ) function above; it passes the vertex on to
be collected into a geometric primitive and then to go the rest of the graphics
pipeline.
void ProduceVertex( float s, float t )
{
const vec3 LIGHTPOS = vec3( 0., 10., 0. );
vec3 v = V0 + s*V01 + t*V02;
v = normalize(v);
vec3 n = v;
vec3 TransNorm = normalize(uNormalMatrix*n);
vec4 ECposition = uModelViewMatrix*vec4((Radius*v), 1.);
gLightIntensity = dot( normalize(LIGHTPOS-ECposition.xyz),
TransNorm );
gLightIntensity = abs( gLightIntensity);
gl_Position = uProjectionMatrix * ECposition;
EmitVertex( );
}
The main( ) function in the geometry shader is given below. It incre-
ments through the t and s parameters, in that order, and emits a triangle from
each set of three vertices it computes with the function above. Notice that the t
parameter is used to control the primary direction of subdivision through the
triangle, and the s parameter to control the secondary direction. The level of
subdivision that is shown in Figure 12.8 is used to set the increments in t and
the number of the t increment is used to set the increment in s . This nested
incrementing is a bit obscure when you first look at it, but it's soon understood
if you look carefully.
void
main( )
{
V0 = gl_PositionIn[0].xyz;
V01 = ( gl_PositionIn[1] - gl_PositionIn[0] ).xyz;
V02 = ( gl_PositionIn[2] - gl_PositionIn[0] ).xyz;
int numLayers = 1 << uLevel;
float dt = 1. / float( numLayers );
Search WWH ::




Custom Search