Guide: materials and lighting

cjcliffe edited this page Aug 16, 2012 · 4 revisions

Materials and Lighting

Starter document

To get started with demonstrating material and lighting parameters we'll use an example from the previous section, separate the creation of the Mesh object and change the primitive type to a "sphere".

Document:

<!DOCTYPE html>
<html>  
    <head>
        <title>My Project</title>
        <script src="path_to/CubicVR.js" type="text/javascript"></script>
        <script type='text/javascript'>
            function webGLStart(gl,canvas) {
                // init and setup here
                var meshObject = new CubicVR.Mesh({
                    primitive: {
                        type: "sphere",
                        radius: 0.75,
                        lat: 32, // horizontal slices
                        lon: 32  // vertical slices
                    },
                    compile: true
                });

                // build the scene
                var scene = new CubicVR.Scene({
                    camera: {
                        name: "the_camera",
                        fov: 60.0,
                        position: [1.0, 1.0, -1.0],
                        lookat: [0.0, 0.0, 0.0],
                        width: canvas.width,
                        height: canvas.height,
                    }, 
                    light: {
                        name: "the_light",
                        type: "point",
                        position: [1.0, 1.5, -2.0]
                    },
                    sceneObject: {
                        name: "the_sphere",
                        position: [0.0, 0.0, 0.0],
                        mesh: meshObject
                    }
                });

                // Add the default scene camera to the resize list to update on browser resize
                CubicVR.addResizeable(scene.getCamera());


                // Start our main drawing loop, it provides a timer and the gl context as parameters
                CubicVR.MainLoop(function(timer, gl) {
                    // perform any per-frame operations here
                    // perform any drawing operations here
                    scene.render();
                });
            }
        </script>
    </head>
    <body onload="CubicVR.start('auto',webGLStart);"></body>
</html>

Resulting render output:

The new starter scene

Adding some color

The simplest material we can create is to simply use the color, diffuse and specular.

Alter the code to the following to make the sphere blue, note the primitive will recursively build and apply the material:

                var meshObject = new CubicVR.Mesh({
                    primitive: {
                        type: "sphere",
                        radius: 0.75,
                        lat: 32,
                        lon: 32,
                        material: {
                            color: [0.2, 0.1, 0.6],
                            diffuse: [0.2, 0.1, 1.0],
                            specular: [0.4, 0.4, 0.8]
                        }
                    },
                    compile: true,
                });

The sphere now appears blue, with a more saturated shade of blue for diffuse light response and a light blue specular light response. If not provided, color, diffuse and specular are set to [0.5, 0.5, 0.5] by default.

Resulting render:

Sphere with the color material applied

Adding some texture

With the material applied we can expand it's properties to define what type of texture to apply. Texture will provide the surface with image sources we've defined instead of solid colors, but it requires a counterpart of u,v mapping.

U,V mapping

U,V is an x,y image coordinate, u,v (or sometimes s,t) normalised to the range of 0.0 - 1.0 and is applied to each vertex on each face. This information provides each vertex on the mesh with a point in the u,v, image space, allowing it to texture the surface accordingly. Without u,v coordinates the material will appear as the color of one of the corner pixels of the image only.

Luckily the CubicVR.UVMapper() is provided to handle most procedural u,v mapping operations, so you don't have to define it by hand.

Adding the textures and U,V mapping to the example.

For this example, we'll use a texture from the CubicVR.js repository, (samples/images/concrete3.jpg) and apply it to the Material. We'll also add a UVMapper definition to the primitive so that it can be applied. Also note that we've removed the surface color to allow the texture to provide the color, otherwise it will let it be over-saturated by the original blue (which may be desirable in other cases).

The color image is added to the material's texture property which will recursively create a Texture object.

Note that repeat use of the same image name for subsequent materials and objects will be recognized and share a single instance internally to save memory.

To get all that done, alter the code with the following update:

                var meshObject = new CubicVR.Mesh({
                    primitive: {
                        type: "sphere",
                        radius: 0.75,
                        lat: 32,
                        lon: 32,
                        material: { // Define basic colors
                            diffuse: [0.2, 0.1, 1.0],
                            specular: [0.4, 0.4, 0.8],
                            textures: { // color  map
                                color: "concrete3.jpg",
                            }
                        },
                        uv: { // U,V project in spherical coordinates
                            projectionMode: "spherical"
                        }                       
                    },
                    compile: true,
                });

Resulting render output:

Sphere with the color texture and u,v applied

It's relevant to note that the U,V mapping is per-primitive, and is not placed within the Material constructor. When building a mesh with multiple materials and u,v coordinates it can be done in face groups with shared or individual point sets. But that will be touched on more in the next guide.

The U,V projection can be altered with size, rotation and scale relative to the primitive. Since we used a sphere primitive localised at [0,0,0] the default spherical map radius, scale, wrap and position will apply neatly without intervention.


WIP

Additional texture types and classes

More exciting lighting

Applying shadows