A Beginner's Guide to VRML


Overview: The Scope of This Document

This document is intended to provide a ground level introduction to VRML (Virtual Reality Modeling Language) for those wanting to author VRML worlds for use on the internet. It intends to outline some basic concepts necessary to begin designing and authoring VRML worlds. It assumes that the reader has no background in 3D graphics, but has some familiarity with the internet and HTML. This document will then attempt to provide basic instruction in the creation of VRML worlds, and to list other resources which may be helpful to the aspiring VRML author.

To create and view most of the examples given, all that is needed is an ascii text editor and a VRML browser, such as Live3D. Optionally, a graphics program may be used to create image files for use as textures. Textures are also widely available in the public domain.


Notes:

  1. This document only discusses the VRML V1.0 standard and Live3D extensions to that standard.
  2. Usage examples show default values for arguments.
  3. Indentation in the VRML source given in all examples is for clarity only, and is not required for creation of valid VRML files.
  4. Examples whose source is very long provide links to the source rather than displaying the source in this document.
  5. Click linked images or titles to see the world whose source is given in the example. You will need a VRML browser, such as Live3D to see the example worlds.


Basic Concepts: 3D Graphics

Defining 3D Space

3D graphics defines 3D space with a system of three axes (Fig.1):

Fig.1: XYZ Axes

Assuming a center point, (through which the X, Y and Z axes all pass), the description of objects in 3D space can be expressed as coordinates representing absolute locations in a 3-dimensional coordinate system, relative to the center point.

Each axis has a positive and a negative direction, extending from the center point of the scene. VRML assumes that, by default, the positive Y axis points up, the positive X axis points right and the positive Z axis points toward the user. Objects within a scene (and the scene itself) may be rotated, causing the orientation of their axes to change accordingly.

Once an object's location has been determined, relative to the absolute center, it can then be oriented in one or more of three ways:

Fig.2: Yaw, Y Rotation
Fig.3: Pitch, X Rotation
Fig.4: Roll, Z Rotation

The three axes (X,Y and Z) and the three rotations (yaw, pitch and roll), together, are referred to as the six degrees of freedom. The location and orientation of objects in 3D space are determined by these six pieces of information.


How Computers Represent 3D Objects

When a computer creates a 3D graphical object, a set of points is usually used to represent the shape. Since it is difficult to see the shape of the object clearly when only points are displayed, this set of points is called a point cloud (Fig.5). The points are then connected by lines to form a mesh or wireframe (Fig.6). The wireframe clearly shows a group of polygons (typically triangles, since they are easiest for the computer to generate quickly.) It is important to note that polygons have only one side or face. A polygon's face is the side from which its normal (a light ray passing through the polygon at a right angle) points away from the polygon. As it were, polygons are visible on the outside and invisible on the inside.

Fig.5: Point Cloud Fig.6: Wireframe

Once the polygons have been created, the computer can then shade the individual polygons to produce the appearance of a solid object (Fig.7). Optionally, the computer can apply a texture to the object (Fig.8). Texturing makes it possible to quickly create very complex object surfaces.

Fig.7: Solid Object Fig.8: Textured Object


Creating VRML Worlds: Standard Techniques

Scene Description and Parsers

VRML is a scene description language. Though VRML is a computer language, it is not a programming language. VRML files are not compiled, but are simple ascii text files which can be parsed by a VRML interpreter. These intpreter programs (or parsers) are often called VRML browsers. If you have ever written HTML documents, then you know how convenient it is to be able to see the results of your work immediately on an HTML browser. The process is the same when authoring basic VRML scenes: you start writing code with an ascii text editor, save the file, and view the VRML scene (or world) with a VRML browser. It's that easy to get started.

Since VRML code is interpreted, the visible results of the code may vary from one browser program to another. Furthermore, VRML is extensible, which means that browser developers, for example, can add new, non-standard functionality to the language, using standard components of the language. If a browser can parse the extensions to the standard VRML language which it encounters in a world file, then the new functionality described by the extensions will be interpreted for the user as that scene is rendered.


Scene Graphs and Nodes

A VRML browser has to be able to recognize a file as being VRML code in order to parse it. This is accomplished with a simple file header string at the beginning of the file:

    #VRML V1.0 ascii
    
This file header must be the first line of a VRML file for it to be parsed correctly. Note that, though in all other cases the pound symbol (#) indicates a comment, the file header (which is not treated as a comment) begins with a pound sign.

The objects in a VRML file are called nodes. When arranged hierachically (that is, so as to affect each other or not based on their type and sequence), nodes comprise a scene graph. Each VRML world, however simple, is a scene graph. Nodes are basically of three types:

The cumulative effect of nodes in a scene graph is called state.

For most purposes, the most important grouping node is the Separator node, whose usage is:

    Separator {

        other nodes here

    }
    
The Separator node keeps contained the modifying effects of property nodes within it. That is, only nodes within a Separator can be affected by property nodes within that same Separator; nodes outside of that Separator will not be affected by those property nodes. The following examples will make extensive use of the Separator node.


Units of Measurement

VRML assumes the following values for units of measurement:


Primitives and Materials

Though any geometry in a scene graph is considered a shape, VRML pre-defines a few basic shapes. These shapes are called primitives. The shape nodes which define primitives are Cube, Sphere, Cone and Cylinder, whose usage is:

    #VRML V1.0 ascii

    Separator {
        Cube {
            width   2
            height  2
            depth   2
        }
    
        Sphere {
            radius  1
        }

        Cone {
            parts           ALL
            bottomRadius    1
            height          2
        }
    
        Cylinder {
            parts   ALL
            radius  1
            height  2
        }
    }
    
It's not necessary to specify any or all of the arguments for these nodes. The parts argument in the Cone and Cylinder nodes supports the following values:


The material properties for any shape can be specified with the Material node, whose usage is:

    #VRML V1.0 ascii

    Separator {
        Material {
            ambientColor    0.2 0.2 0.2
            diffuseColor    0.8 0.8 0.8
            specularColor   0 0 0
            emissiveColor   0 0 0
            shininess       0.2
            transparency    0
        }
    }
    
Each of the Material node arguments which specifies a type of color uses RGB values (red, green and blue intensities), the red value being leftmost, the green value center, and the blue rightmost. Theoretically, any color (hue, saturation and value) can be created by combining red, green and blue in varying intensities.

Let's say that we want to make a blue sphere. By using some of the VRML components which we've reviewed, file header, Separator, Material and Sphere, we can now create a VRML file which, when parsed by a VRML browser, will describe a VRML world which contains a blue sphere (Fig.9). For example:

    #VRML V1.0 ascii

    Separator {
        Material {
            emissiveColor    0 0 1
        }
        Sphere {}
    }
    
Fig.9: Blue Sphere

Notice that the radius argument was not supplied for the Sphere node in this example. When an argument is not supplied for a node, its default value is used.


Textures

Any shape can have a texture applied to its surface. The texture can be from an image file external to the VRML world file or specified within the world file as a series of coordinates. For these examples, we will use image files, since this is the easiest way to quickly "wrap" a VRML shape object in a texture. A texture from an image file can be applied to a shape with the Texture2 node, whose usage is:

    #VRML V1.0 ascii

    Separator {
        Texture2 {
            filename    ""
            image       0 0 0
            wrapS       REPEAT
            wrapT       REPEAT
        }
    }
    
For our purposes, only the filename argument will be used in these examples.

Let's say that we want to make a stone slab. By using some of the VRML components which we've reviewed, file header, Separator, Texture2 and Cube, we can now create a VRML file which, when parsed by a VRML browser, will describe a VRML world which contains an object which resembles a stone slab (Fig.10). For example:

    #VRML V1.0 ascii

    Separator {
        Texture2 {
            filename    "stone.jpg"
        }
        Cube {
            width   1
            height  2
            depth   0.15
        }
    }
    
Fig.10: Textured Cube (Stone Slab)


Transformations

By default, objects in a VRML scene

Whenever it is necessary to change some of these defaults for an object (which will be almost always), one or more of the transformation nodes must be used. The transformation nodes are a type of property node.

Special terms used to describe the functions performed by the transformation nodes are


The Transform node contains all the transformation functions mentioned above. Its usage is:

    #VRML V1.0 ascii

    Separator {
        Transform {
            translation         0 0 0
            rotation            0 0 1  0
            scaleFactor         1 1 1
            scaleOrientation    0 0 1  0
            center              0 0 0
        }
    }
    

For the purposes of simplicity and to better clarify the hierarchical relationship of nodes in a VRML scene graph, three other transformation nodes, which perform only one type of transformation each, will be used for these examples. Those nodes are Translation, Rotation and Scale.


The Translation node can translate an object along one or more of its three axes. Its usage is:

    #VRML V1.0 ascii

    Separator {
        Translation {
            translation 0 0 0
        }
    }
    

Let's say that we want to include both the blue sphere which we made earlier and a red sphere in the same world. By using the VRML nodes which we have already used to make the spheres, we can now create a VRML world which contains both a red and a blue sphere (Fig.11). However, by default, both spheres will be located in the exact center of the scene. Therefore, we will use the Translation node to change the location of one of the spheres, the blue one, placing them side by side. For example:

    #VRML V1.0 ascii

    Separator {

        Separator { # red sphere, defaulting to the center of the scene
            Material {
                emissiveColor    1 0 0
            }
            Sphere {}
        }

        Separator { # blue sphere, translated along the positive X axis
            Translation {
                translation 2.25 0 0
            }
            Material {
                emissiveColor    0 0 1
            }
            Sphere {}
        }
    }
    
Fig.11: Red Sphere and Translated Blue Sphere

Notice that each Sphere node has been placed within a different Separator node with the property nodes that affect it. This contains the effects of those property nodes (Material and Translation, in this example) so that each will affect only the shape nodes (Sphere, in this example) whose properties we want them to change. Notice also the Separator which contains all the other nodes in the scene graph. Though not absolutely necessary, it is a good practice to use a "scene Separator" in each scene graph. The descriptions which follow the pound symbols are comments.


The Rotation node can rotate an object along one or more of its three axes, but is typically used to perform rotation along only one axis at a time. The Rotation node affects orientation. Its usage is:

    #VRML V1.0 ascii

    Separator {
        Rotation {
            rotation 0 0 1  0
        }
    }
    

Let's say that we want to make a world containing two cones, one above the other, one pointing straight up and one pointing to the side. By using the VRML property nodes which we have already used and the Cone shape node, we can now create a VRML world which contains both a brown and a blue cone, one above the other (Fig.12). However, by default, both cones will be pointing straight up. Therefore, we will use the Rotation node to change the orientation of one of the cones, the blue one, causing it to point 90 degrees to the side. For example:

    #VRML V1.0 ascii

    Separator {

        Separator { # brown cone, translated along the negative Y axis
            Translation {
                translation 0 -2 0
            }
            Material {
                emissiveColor   1 0.6 0.44
            }
            Cone {
                height          2
                bottomRadius    0.5
            }
        }

        Separator { # blue cone, rotated 90 degrees on the Z axis
            Rotation {
                rotation    0 0 1  1.57
            }
            Material {
                emissiveColor   0.4 0 1
            }
            Cone {
                height          2
                bottomRadius    0.5
            }
        }
    }
    
Fig.12: Brown Cone and Rotated Blue Cone


The Scale node can scale an object along one or more of its three axes. Its usage is:

    #VRML V1.0 ascii

    Separator {
        Scale {
            scaleFactor 1 1 1
        }
    }
    

Let's say that we want to use the world containing the blue and red spheres which we created earlier to demonstrate the Translation node, but "squash" one of the spheres to make it appear oblong. By adding the Scale node to that world, we can create a version whose blue sphere is oblong (Fig.13). For example:

    #VRML V1.0 ascii

    Separator {

        Separator { # red sphere
            Material {
                emissiveColor   1 0 0
            }
            Sphere {}
        }

        Separator { # blue sphere, scaled down on the X and Z axes
            Translation {
                translation 2.25 0 0
            }
            Scale {
                scaleFactor 0.6 1 0.6
            }
            Material {
                emissiveColor   0 0 1
            }
            Sphere {}
        }
    }
    
Fig.13: Red Sphere and Scaled Blue Sphere

Notice that the Scale node was placed after the Translation node within the blue sphere's Separator. Since the state of a scene will vary depending upon the order of its nodes, the effect of "Scale, Translation" is different from "Translation, Scale." Try creating this example with the blue sphere's Translation and Scale nodes in reverse order and comparing its appearance to the example to see how important node sequence can be.


Instancing

In all the examples we've reviewed so far, one shape or material node was used for each shape or material to be created in the VRML world. VRML provides two ways of reducing the number of nodes that are used in a world file which describes many shapes. One is called instancing. The other, inlines, is reviewed in the next section.

Instancing allows you to reuse object definitions in a scene. This is done with the DEF and USE statements, whose usage is:

#VRML V1.0 ascii

Separator {

    DEF name
    shape node

    or

    DEF name
    Material {}

    or 

    DEF name
    Separator {
        grouping, property and shape nodes
    }

    Separator {
        USE name
    }
}

Let's say that we want to make a deep sea crab (let's also assume that none of us is a marine biologist!) Though the crab's body can be represented by a single simple shape, its arms and legs will require many segments. Even its eyes require multiple shapes and repetition of those shapes. If the crab has a body with one shape, two eyes with two shapes each, and six legs with three shapes each, then a total of 23 shapes will be needed to create it. Even if that doesn't seem like many shapes, keep in mind that those shapes are just to describe one crab.

By using the various nodes which we've already reviewed and the DEF and USE statements, we can create the deep sea crab using relatively few nodes (Fig.14). For example:

Deep Sea Crab, VRML Source

Fig.14: Deep Sea Crab with Instanced Parts

Notice that the USE statements not only replicate the shape nodes, but also preserve the effects of the property nodes which were defined by the DEF statements that they reference. Therefore, for example, the relative location, orientation and scale, and the material properties of the leg segments are preserved for each instance of the Leg definition, though those instances are themselves further affected as single objects by other property nodes.


Inlines

As mentioned in the previous section, VRML provides two ways of reducing the number of nodes that are used in a world file which describes many shapes. One is called inlines, the other, instancing, which is reviewed in the previous section. Inlines are accomplished with the WWWInline node, whose usage is:

    #VRML V1.0 ascii

    Separator {
        WWWInline {
            name        ""
            bboxSize    0 0 0
            bboxCenter  0 0 0
        }
    }
    
The name field takes the pathname of the world file being inlined. The bboxSize and bboxCenter fields optionally describe a bounding box, which can give the user an indication of the object's location and size before it has been rendered. Bounding boxes can be especially useful when used in large or complicated worlds.

What if we wanted to create a world with five crabs? 115 shape nodes, and the property nodes used to locate, orient, scale and color them, would be needed. In addition to the time spent creating and maintaining such a world, the world file itself would be quite large, an undesireable trait for a file which is going to be downloaded. By using the deep sea crab we have already created, the DEF and USE statements and the WWWInline node, we will be able to define an object in a VRML world which, instead of being a shape or property node, will be a reference to an existing world. We will then be able to instance that object repeatedly (Fig.15). For example:

Inlined and Instanced Deep Sea Crabs, VRML Source

Fig.15: Inlined and Instanced Deep Sea Crabs

Notice that the inlined crab, like the instanced crabs, has been treated like a shape node. It is within a Separator and affected discreetly by various property nodes. For clarity, the background of this world was made white, using the Live3D BackgroundColor VRML extension, reviewed in detail in the next section.


Lights

We have, so far, created and positioned shapes in VRML worlds, given them material properties, and even applied textures to them. But we have been viewing our worlds with only the default lighting provided by the VRML browser. If we want to specify light sources in our VRML worlds, we can use light nodes.

VRML uses light nodes to create illumination sources. Depending upon their position in the scene graph and type, light nodes may affect shapes in the scene, and may be affected by transformation nodes. Like other property nodes, if a light node is within a Separator, it will not affect shapes outside that Separator.

It is good practice to include a light in your VRML worlds, since some browsers' rendering performance is optimized by the presence of a light node in the scene which they are rendering. For the purpose of optimization, it doesn't matter whether the light is on or off, as long as it is in the scene.

The VRML light nodes are DirectionalLight, PointLight and SpotLight. For our lighting example, we will use the DirectionalLight node. As its name suggests, DirectionalLight creates a light source that illuminates any affected shapes in a specified direction. Its usage is:

    DirectionalLight {
        on         TRUE
        intensity  1
        color      1 1 1
        direction  0 0 -1
    }
Let's return to the example we used to demonstrate rotation, the two cones, modifying that world to demonstrate use of light nodes (Fig.16). Since some VRML browsers may turn on a "headlight" by default, which shines into the scene, along the negative Z-axis, we'll define light sources that shine along the X-axis so that the lighting will be more likely to be obviously different from the original version of the world. For example:

Two Cones With Lights, VRML Source

Fig.16: Two Cones With Lights


Cameras (Viewpoints)

A viewpoint is an exact position from which a VRML world is seen, which has been defined in the world's scene graph. In each of the examples we've reviewed so far, only the default viewpoint is available. The default viewpoint is often called the entry view. The entry view is the position from which we see the scene when the VRML world is first rendered by the browser, if no viewpoint has been defined in the world.

To see the previous example worlds from any position other than the entry view, it is necessary to manually navigate to that position. What if we wanted the user to be able to quickly see the VRML world from a particular position, other than the entry view, when the scene is first rendered? Or what if we wanted to pre-define other viewpoints in the world, to which the user could go at any time while viewing the world?

VRML uses camera nodes to define exact positions from which to view a scene. Though difficult to accurately define, camera nodes might be thought of as property nodes, since 1) they seem to transform the shapes in a scene and 2) some of their parameters, behaving much like a special effects lens, create the illusion of causing shapes to stretch, even after the user has navigated away from the camera's position.

Two camera nodes, PerspectiveCamera and OrthographicCamera, are defined in VRML. Of those two only one, PerspectiveCamera, is commonly supported by VRML browsers. Its usage is:

    #VRML V1.0 ascii

    Separator {
        PerspectiveCamera {
            position        0 0 1
            orientation     0 0 1  0
            focalDistance   5
            heightAngle     0.785398
        }
    }
    
To help demonstrate use of the PerspectiveCamera node in a world, we will introduce a new grouping node, Switch, which, though it has many uses, will for this example allow us to define multiple viewpoints which the user can choose while browsing the VRML world. Its usage is:
    #VRML V1.0 ascii

    Separator {
        Switch {
            whichChild  -1
        }
    }
    
By using the deep sea crab world we have already created, the WWWInline node, the PerspectiveCamera node and the Switch node, we will be able to define various viewpoints from which the user can select while browsing the world (Fig.17). For example:

Deep Sea Crab With Viewpoints, VRML Source

Fig.17: Deep Sea Crab With Viewpoints


Level of Detail

Its usage is:

    #VRML V1.0 ascii

    LOD {
        range   [ ]
        center  0 0 0
    }
    
By using three primitive shape nodes, instancing and the LOD node, we will be able to define three levels of detail, each containing a group of primitive shapes, each group having a different color. (Fig.18). For example:

Primitives With Level of Detail, VRML Source

Fig.18: Primitives With Level of Detail

To see the effect of the LOD node in this example world, you will have to navigate further into the world, beyond the entry view.


Creating VRML Worlds: Live3D

Background Color

Live3D lets you define the color of the backgrounds of your VRML worlds with the Live3D BackgroundColor VRML extension. Its usage is:

    DEF BackgroundColor Info {
        string ""
    }
    
Let's say that we want to create a version of the deep sea crab which attempts to show it in the ocean. By creating a world which inlines the model of the crab and using the BackgroundColor node, we can show the crab in a blue-green field (Fig.x). For example:
    #VRML V1.0 ascii

    Separator {

    DEF BackgroundColor Info {
        string "0.15 0.6 0.7"
    }

    Separator { # viewpoints
        DEF Cameras Switch {
            whichChild  0

            DEF "Crab!" PerspectiveCamera {
                position    0 0 7
            }
        }
    }

        Separator { # crab
            WWWInline {
                name "1crab1.wrl"
            }
        }

    }
    
Fig.x: Deep Sea Crab with Background Color


Background Image

Live3D lets you use images for the backgrounds of your VRML worlds. The BackgroundImage VRML extension makes this possible. Its usage is:

    DEF BackgroundImage Info {
        string ""
    }
    
Let's say that we want to create a more realistic version of the deep sea crab which attempted to show it in the ocean. By modifying the example used to review the BackgroundColor node, substituting the Live3D BackgroundImage node, we can give the impression of rippling water behind the model of the crab (Fig.x). For example:
    #VRML V1.0 ascii

    Separator {

    DEF BackgroundImage Info {
        string "bakimage.jpg"
    }

    Separator { # viewpoints
        DEF Cameras Switch {
            whichChild  0

            DEF "Crab!" PerspectiveCamera {
                position    0 0 7
            }
        }
    }

        Separator { # crab
            WWWInline {
                name "1crab1.wrl"
            }
        }

    }
    
Fig.x: Deep Sea Crab with Background Image


Axis Alignment


Transparent Texture


Animated Texture


SpinGroup


CollideStyle


Directed Sound and Point Sound


Environment Mapping


Animator


Corporate Sales: 415/937-2555; Personal Sales: 415/937-3777; Federal Sales: 415/937-3678
If you have any questions, please visit Customer Service.

Copyright � 1996 Netscape Communications Corporation