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.
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.
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
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.
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 asciiThis 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.
VRML assumes the following values for units of measurement:
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.
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)
By default, objects in a VRML scene
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.
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:
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.
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.
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
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
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.
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
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
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