Graphics Reference
In-Depth Information
Between the pushState and popState calls, the program says which shader
should be used for rendering this part of the scene (line 10) and which variable
values are to be passed to the shader (line 9), establishes the model-to-world trans-
formation for this model (line 13), and then (line 14) sends the geometry of the
model to the graphics pipeline.
In the case of this simple shader, we send (lines 19-25) the world-space coor-
dinates of the light, the color of the light, the position of the eye, the diffuse
color we're using for our icosahedron, and the diffuse reflectivity constant. The
args.set procedure establishes the link between the host program's value for,
say, the directional light's world-space direction vector and the shader program's
value for the variable called wsLight .
Finally, following the call to onGraphics , the shader wrapper tells the
pipeline to process the vertices of the mesh one at a time with the vertex shader,
assemble these into triangles which are then rasterized and clipped, and then pro-
cess the rasterized fragments with the fragment shader. Let's look at the GLSL
vertex shader code (Listing 33.3) to see what it does.
Listing 33.3: The vertex shader for the Gouraud shading program.
1
2
3
4
5
6
7
8
9
10
11
12
/ ** How well-lit is this vertex? * /
varying float gouraudFactor;
/ ** Unit world space direction to the (infinite, directional) light source * /
uniform vec3 wsLight;
void main(void) {
vec3 wsNormal;
wsNormal = normalize(g3d_ObjectToWorldNormalMatrix * gl_Normal);
gouraudFactor = dot(wsNormal, wsLight);
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}
As you can infer from the code, certain variables are predefined in GLSL, as
are some useful functions, like normalize and dot . Table 33.1 lists a few of these.
Built-in data types include the C-like float and int , and others that help us
perform vector operations like vec3 and mat33 . GLSL also provides tools for
accessing any portion of a vec3 or vec4 through a construction called slicing:
If v is a vec3 , we can use v.x to access its first entry, and v.yz to access its second
and third entries, for instance. Since a vec3 is also used to represent colors (and a
vec4 is used to store colors with alpha), we can also write myColor.rga to access
the red, green, and alpha portions of a color, for instance. Mixing xyzw -slicing and
rgba -slicing is allowed, but seldom makes sense.
As described in Chapter 16, each kind of shader is responsible for establishing
values used by later shaders. For instance, a vertex shader like the one used here
gets gl_Vertex , the 3D world-space location of the vertex, as input; each time
the shader is called, gl_Vertex has a new value, the world-space coordinates for
another vertex, in the input. The vertex shader is responsible for assigning a value
to gl_Position , which is meant to represent the position of the vertex in camera
coordinates, or, expressed alternatively, the position of the vertex after the camera
transformation has been applied to move the view frustum to the standard per-
spective view volume. In the case of our shader, this is accomplished by line 11,
which multiplies the vertex coordinates by the appropriate matrix.
 
 
Search WWH ::




Custom Search