Normal Map Short Tutorial
Maps & Shaders Provide Light and Shadow
Introduction
This short tutorial discusses WebGL normal maps, with example image maps and projects.
The example, Cube with Normal Maps, applie GLSL lighting to a prism with a normal map rather than normal attributes. Normals are vectors (like arrows), which are perpendicular to a surface. Normals indicate which direction a surface faces, for use in calculating lighting. With WebGL, you can upload normals for each vertex, where each normal's like a point, with X, Y, and Z floating point coordinates. The coordinates define a vector direction. However this example explains how to use an image, instead of normal coordinates, to calculate lighting. Red, green, and blue values, of the image, represent X, Y, and Z normal coordinates.
Maps
The prism's baked texture is simply grey. The prism's texture map doesn't supply the appearance of light and shadow. It's just a set of flat planes with no value. Value refers to the amount of light or dark which displays. Lighting, in the fragment shader, defines value for the surface of the prism, based on the prism's relationship to the light.
The fragment shader declares constant vectors for light location, light color, and ambient color. The fragment shader samples both the normal map and the prism's texture map to determine both the color of the prism and the amount of light or shadow to apply. The amount of light or shadow's determined by the normal map and the prism's current orientation with respect to the light vector.
Normal Map Purpose
The prism's normal map defines red, green, and blue channels for use as X, Y, and Z normal attributes.
As the prism rotates and moves, JavaScript uploads a normal transformation matrix to the GPU. The model matrix represents rotation and translation for the prism. The normal matrix represents rotation and translation for the prism normals. The fragment shader uses the normal map and normal matrix to compute lighting per frame.
The prism, texture map, and normal map were prepared with 3ds Max. The following graphic, the texture map, defines color for the prism.
Prism Color
Prism Normals
The following graphic represents normals for the prism.
Red represents X. Green represents Y. Blue represents Z. Therefore the more blue, the more direct the normal.
Fragment Shader
The fragment shader samples the normal map, referenced with Sampler2D u_sampler1
.
vec4 v4_normal_map = texture2D( u_sampler1, v_tex_coord0 );
The fragment shader samples the texture map, referenced with Sampler2d u_sampler0
.
vec4 v4_tex = texture2D( u_sampler0, v_tex_coord0 );
The fragment shader processes light as explained in Seven Thunder Software's
Point Light Tutorial
. However substitute attribute vec3 a_normal;
for vec4 v4_normal_map
. The fragment shader, in the GPU, processes
normals from an image map, rather than a set of coordinate attributes.
Summary
This short tutorial discussed normal maps with WebGL.
The example, Cube with Normal Maps, applies GLSL lighting to a prism with a normal map rather than normal attributes. Normals are vectors (like arrows), which are perpendicular to a surface. Normals indicate which direction a surface faces, for use in calculating lighting. With WebGL, you can upload normals for each vertex, where each normal's like a point, with X, Y, and Z floating point coordinates. The coordinates define a vector direction. However this example explained how to use an image, instead of normal coordinates, to calculate lighting. Red, green, and blue values, of the image, represent X, Y, and Z normal coordinates.