Graphics Reference
In-Depth Information
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
/ ** Color of the light source * /
uniform vec3 lightColor;
/ ** Color of ambient light * /
uniform vec3 ambientLightColor;
varying vec3 wsInterpolatedNormal;
varying vec3 wsInterpolatedEye;
void main() {
// Unit normal in world space
vec3 wsNormal = normalize(wsInterpolatedNormal);
// Unit vector from the pixel to the eye in world space
vec3 wsEye = normalize(wsInterpolatedEye);
// Unit vector giving the dir'n of perfect reflection into eye
vec3 wsReflect = 2.0 * dot(wsEye, wsNormal) * wsNormal - wsEye;
gl_FragColor.rgb = diffuse * diffuseColor *
(ambientLightColor +
(max(dot(wsNormal, wsLight), 0.0) * lightColor)) +
specular * specularColor *
pow(max(dot(wsReflect, wsLight), 0.0), shine) * lightColor;
}
33.6 Environment Mapping
To implement environment mapping (see Section 20.2.1), we can use the same
vertex shader as before to compute the interpolated eye vector and normal vector.
Rather than computing the diffuse or specular lighting, we can use the reflected
vector to index into an environment map, which is specified by a set of six texture
maps (see Figure 33.4). The host program must load these six maps and make
them available to the shader; to do so, we declare a new member variable in the
App class and then, during initialization of the application, invoke
environmentMap = Texture::fromFile("uffizi * ,png", ...)
to load the cube map with one of G3D's built-in procedures. Within the
configureShaderArgs procedure, we must add
Figure 33.4: An environment map
of the Uffizi, specified by six tex-
ture maps, one each for the top,
bottom, and four vertical sides
of a cube, displayed here in a
cross-layout. (Courtesy of Paul
Debevec. Photographs used with
permission. ©2012 University of
Southern California, Institute for
Creative Technologies.)
myShader->args.set("environmentMap", environmentMap);
to link the host-program variable to a shader variable.
The fragment shader (see Listing 33.7) is very simple: A fragment is colored
by using its normal vector as an index into the cube map, via a GLSL built-in.
The color that's returned is multiplied by the specular color for the model (which
we set to a very pale gold) so that the reflections take on the color of the surface,
simulating a metallic surface, rather than retaining their own color, as would occur
with a plastic surface.
The result (see Figure 33.5) shows a shiny teapot reflecting the plaza of the
Uffizi gallery using the environment map we showed earlier.
Anytime a shader uses a texture, the texture is automatically MIP-mapped for
you by GL (unless you explicitly request that it not be). The semantics of GL are
such that the derivative of any quantity with respect to pixel coordinates can be
 
 
 
Search WWH ::




Custom Search