Virtual Reality Modeling Language, or VRML, isn't technically HTML at all, but the two are close cousins. Born out of a desire for a more "human" interface to the Web, VRML is a readable, ASCII-based description language for creating 3D interfaces to the World Wide Web. Eventually, the point is to be able to create rich multimedia 3D worlds for you to explore via the Web, perhaps offering something useful in the process. That really hasn't happened yet, but VRML is definitely the next level of "cool" on the Web.
VRML is still in its infancy, as the 1.0 standard was only fully completed in the spring of 1995. As I write, version 1.1 is waiting in the wings while version 2.0 is being held out as the next great leap. Currently, VRML 2.0 may not even be based on the same basic file format as VRML 1.0. Better, smaller, faster technology has already overtaken the old standard.
Currently, VRML 1.0 has only limited support for things like "walk through" interfaces. Right now, it's basically a way to render 3D polygons in a way that may or may not seem somewhat realistic (see fig. 24.1). It does have the ability to embed hyperlinks in objects, though, and VRML "worlds" are fairly easy to create with nothing more than a text editor. So, we'll try our hands at it.
Figure 24.1 : A VRML world on the web.
Note |
It may be wishful thinking, but VRML documents are generally called "worlds," perhaps because the word "document" seems rather two-dimensional. A single ASCII listing can be used to create a world, however. |
What happens in the future remains to be seen. More than likely,
VRML will move quickly toward a standard that requires sophisticated
programs to render objects. The VRML 2.0 standard, only recently
decided, will incorporate more advanced commands and an optional
binary file format from Apple's QuickTime VR technology. Perhaps
some backward compatibility will remain, but I wouldn't count
on it. Unlike HTML documents, which are largely made up of text,
VRML worlds are almost completely graphical. The ability for normal
human beings to continue to render them seems unlikely. For now,
though, you can.
The Past and Future of VRML |
VRML was first conceived in the spring of 1994 at the first WWW Conference in Geneva. With the ambition of having a specification by the fall, an existing Web-friendly 3D file format was sought. It was found in the Open Inventor ASCII file format from Silicon Graphics (SGI). VRML 1.0 went on to become a subset of this file format, with extensions for the purposes of adding hyperlink abilities. In May 1995, the third and final draft of VRML 1.0 was completed, and work was begun by interested Web developers and applications developers to add VRML functionality to Web browsers, plug-ins, and authoring/rendering solutions. With the growth in popularity, VRML 2.0 was sought to fill some of the gaping holes in VRML 1.0, like sound support, interaction with objects, and the ability to create "solid" objects that can't be walked through. In late March of 1996, it was announced that the Moving Worlds proposal from SGI, including the last minute addition of binary file technology in the form of Apple Computer's 3DMF file format, would be the basis of the standard. While not exactly backward-compatible with VRML 1.0, programs should be created to make changing 1.0 documents to 2.0 fairly straightforward. While hopefully not overwhelmingly more complex, there's also a good chance that VRML 2.0 will be beyond the scope of typical Web authors who will instead rely on VRML 2.0 3D authoring utilities. This will be especially true when using the 3DMF file format, which is a binary (non-ASCII) file format. |
Plug-ins are being developed for browsers that allow the user to view VRML worlds as inline images, but this too is a young industry. Currently, there is no standard way to embed VRML worlds in Web pages, so plug-ins use their own HTML extensions. This will perhaps be changed by the HTML 3.0 level <INSERT> tag.
Generally, VRML worlds are simply another hypermedia link, used to call a file of MIME type x-world/x-vrml with the file extension .wrl for "world." The following hypermedia link is an example of a link to a VRML world:
<A HREF="http://www.fakecorp.com/worlds/support.wrl">Enter Virtual Support</A>
The VRML world would then be loaded into a helper application designed to give the user access to the VRML world, including controls for manipulating the VRML graphics in 3D (see fig. 24.2). Double-clicking different objects will generally send a command back to the browser, which can then move on to another URL.
Figure 24.2 : A VRML 1.0 world gives you some of the sensations of moving around in a video game.
In general, VRML browsers are configured as helper applications that recognize the x-world/x-vrml MIME type and are loaded whenever a link to a .wrl file is clicked. The VRML browser can then pass links back to the Web browser, so that new worlds (or Web pages) can be loaded when items in the VRML world are selected.
Generally speaking, VRML doesn't require much interaction from your server. Currently, there really aren't any VRML specific servers, although this may change if downloading VRML "streams" becomes popular. (Streams are "just-in-time" downloads that display information as it's sent, like the popular RealAudio radio feeds, for instance.)
One common problem with VRML worlds is that not all servers are
set up for the correct MIME type yet, which means users often
receive text of VRML worlds instead of a multimedia file that
automatically launches a helper or plug-in. If you have this problem
with your server, ask your server administrator to set up the
x-world/x-vrml MIME type
for filename extension .wrl.
Once they do that, you should have little trouble making your
VRML worlds available on your Web site.
As I've said, it's possible to create a VRML world with nothing more than a text editor and some know-how. VRML can get rather complicated, but you can start out with the basics and see how far you can get into Virtual Reality before you throw your hands up.
In your text editor, you'll need to start out with a new text file. Type the following as the first line of your document:
#VRML 1.0 ascii
This tells VRML browsers what format you're using. (Later standards
will have a different first line.)
Note |
Most of the VRML browsers I've encountered are case-sensitive about this first line. Enter it exactly as above. |
You can also use the # sign to begin comments in your VRML document. For instance, the following is a comment that will be ignored by the VRML browser, but useful to you and others as documentation of your VRML commands:
# This is the left front leg of the chair
The other thing you need to do with VRML is switch over to a 3D way of thinking. Many VRML objects and commands have coordinates, which include X, Y, and Z components, usually in that order. On your screen, X is left and right, Y is up and down, and Z is from the back of your head to the back of the monitor.
These directions are also in positive and negative numbers from a point directly in the middle of the screen or, at least, from the active part of the VRML's display (see fig. 24.3.). Left is negative from center, down is negative, and into the monitor is negative.
Figure 24.3 : How coordinates work in VRML.
Distances in VRML are measured in meters, while angles are given in radians. While VRML objects aren't actually rendered in meters (you'd have trouble fitting them on a computer monitor), this is a relative measurement. It allows something the size of .01 meters, for instance, to be a pencil, while something the size of 1 meter might be a table top.
Radians are the angle (e.g., 45 degrees) divided by 180, times
Pi (approximately 3.14). Most browsers will accept best guess
radians, so multiplying by 3.14 for Pi is acceptable.
Note |
Remember radians? (Hey, I had to look them up.) To get the radians of an angle in degrees, divide the degrees by 180, and then multiply by Pi. For instance, a 360 degree angle, divided by 180 is 2. 2 times Pi gives you the answer-about 6.28 radians. |
Just a short and sweet example. Starting with a new text document,
enter
Listing 24.1.
Listing 24.1 template.wrl Creating your VRML Template
#VRML V1.0 ascii
#
#Comments about this
#world go here.
#
Don't forget to save it as your template. No big deal, right? Remember, though, that you're dealing with something other than the HTML page. This is a completely different format, with a different template, different commands, and a different extension.
The basic building block of a VRML world is called a node. Nodes can do a number of different things, including creating shapes, moving shapes, describing colors and textures, and creating hyperlinks. Nodes can be used together to achieve different effects-in fact, they very commonly are.
Curly brackets are used (as in JavaScript and many programming languages) to represent the beginning and end of a node. The pattern is similar to the following:
Cube {
shape properties
}
A node like this might create a sphere, cone, cylinder, or other shape. The shape will be white (without color description) and centered on the screen. In order to change those characteristics, it's necessary to use nodes together, somewhat like the following:
Transform {
transformation properties
}
Cube {
shape properties
}
Using the various properties for Transform, the cube created can be moved in three dimensions, rotated, and scaled. In fact, every node that follows this Transform node will be affected unless a Separator node is used to enclose the Transform and shape nodes. For instance:
Separator {
Transform {
transformation properties
}
Cube {
shape properties
}
}
more VRML
What's important here to notice is that both nodes are required to create the shape and change its position in the VRML world. On its own, the shape node would simply create a basic shape. The Transform node is designed to affect other nodes, and creates nothing on the screen by itself. The Separator node is used to separate these two cooperating nodes from others in the VRML document.
Let's begin the discussion of VRML nodes with the primitives, which are simply the basic geometric shapes you can use to create 3D worlds. These include spheres, cylinders, cones, cubes, and text. You'll quickly look at how to create each of these, then you'll figure out how to move them around in our virtual world.
Most primitives follow the basic format of the following:
primitive_name {
properties
}
Spacing is unimportant, but braces are required around the shape's properties.
Probably the easiest shape to create in VRML is a sphere. All you really need to know is what you want the radius to be in meters (well, virtual meters). This is done with curly brackets. The primitive name is Sphere and the property name is radius, so an example would be:
Sphere {radius 3}
That's it. In a properly-formatted VRML document (with the information
in Listing 24.1), this single command would create a sphere in
a VRML world (see
fig. 24.4).
Figure 24.4 : Our first, rather primitive, sphere.
Some other one-line primitives are cylinders and cones. Both take the property height, but a cylinder and a cone handle their radius differently. These shapes can also take the property parts, which is used to determine which parts of the shape will be rendered. The general format for Cylinder is the following:
Cylinder {
parts part_names
height size
radius size
}
The part_names can be SIDES, TOP, BOTTOM, or ALL, depending on how you want the cylinder to appear. An example for a cylinder could be the following:
Cylinder { height 4 radius .5 }
Notice that ALL is always the default for parts so it isn't necessary when you want to render the entire shape. This example creates a cylinder about four meters high and one meter in diameter (see fig. 24.5). Probably perfect for the columns outside of a virtual house. At the same time, a cylinder like the following might be correctly sized and rendered for an eight-ounce drinking glass:
Figure 24.5 : A sample cylinder.
Cylinder {
height .15
radius .04
}
Notice that spacing isn't important, but when you have more than one or two properties, it's probably best to space them out for the sake of clarity.
The cone primitive requires a radius for its base, and a height. Since the radius of a cone changes consistently from bottom to top, you use the property bottomRadius:
Cone { height 15 bottomRadius 10 }
This one might make a good approximation of a pine tree outside of your virtual mountain cabin (see fig. 24.6).
On the other hand, you might use the following:
Cone {
parts SIDES
height .10
bottomRadius .02
}
This could easily represent an ice cream cone (albeit upside down for now). The parts property for cones accepts the values SIDES, BOTTOM, or ALL.
Perhaps more appropriately called the "cuboid," the cube primitive can have unequal sides, making it more or less a 3D rectangular shape. It's also probably the most useful shape, if for no other reason than the fact that you'll generally want to use it as the floor in your virtual world.
Actually, a cube is useful for representing many different things, from appliances and furniture to buildings and ceilings. Since you can stretch the cube in 3D, you have limitless possibilities-as long as you don't mind jagged edges.
The basic format for a cube is the following:
Cube {
width size
height size
depth size
}
When initially rendered, the width is in the X axis, the height is in the Y axis, and depth is in the Z access. An example might be the following:
Cube {
width 1
height 1
depth 1
}
This one actually is a cube, a meter on each side. It might be good to represent a nice-sized shipping box.
An example that meets the challenge of being a virtual room's "floor" would be the following:
Cube {
width 20
height .01
depth 25
}
This is just about the right size for a reasonably dimensioned den or family room-maybe even a master suite. You can see it extending out into the distance in figure 24.7.
The final primitive accepts a string value of ASCII text and writes it to the screen-AsciiText. You can choose values for the spacing, justification (alignment), and width of the string, if you want to confine it to a particular size. The basic format is the following:
AsciiText {
string "Text"
spacing number
justification DIRECTION
width size
}
You enter the text you want to use between the quotation marks. spacing is used to determine the distance between lines when you include more than one string statement.
The justification property takes the values LEFT, CENTER, and RIGHT, and aligns the text relative to the point where X=0 (the center of the screen). LEFT, for instance, causes the string to end at X=0; RIGHT causes the text to begin at X=0.
The width property is often set to zero (which is also the default), but can be used to cause your text to conform to a certain width. The following is an example of AsciiText:
AsciiText {
string "A long, long time ago,"
spacing 2
justification CENTER
}
Figure 24.8 shows how this text looks in a VRML browser.
Figure 24.8 : Ascii Text in your virtual world.
With what you know now about primitives, you can create some fairly interesting shapes-but you can't do much about where they appear in your virtual world. You'll look into that next. For now, let's see what it's like when you put two shapes in the same world.
Enter Listing 24.2 in a new VRML document.
Listing 24.2 twoshape.wrl Two Shapes in the Same Space
#VRML V1.0 ascii
#
#Two shapes in
#one space
#
Sphere { radius 2.5}
Cube {
width 20
height .02
depth 20
}
(Don't forget to save the file with a .wrl extension.) When you load this file into your VRML browser, you should notice that the two have the same point of origin, and are trying to occupy the same space. Things are a bit difficult to puzzle out, since both are the same color, but if you pan up or down slightly, you should be able to see how the two shapes seem fused (see fig. 24.9). From certain perspectives, the sphere is a bump on the road-or perhaps a lone mountain!
Figure 24.9 : Are two shapes better than one?
Here, you'll move on to using nodes that move your primitives around in the VRML world. You're using a node called Transform, which is designed to affect the location, rotation, and scale of the objects that come after it.
The basic format is:
Transform {
translation X-distance Y-distance Z-distance
rotation X-axis Y-axis Z-axis Angle
scaleFactor X-factor Y-factor Z-factor
}
Primitive to move/rotate/scale
Just to keep this from seeming too intimidating, let's quickly look at an example:
Transform {
translation 2 2 0
rotation 0 1 0 3.14
scaleFactor 1 1 1
}
The translation property is responsible for actually moving the object in VRML space, and it uses a basic 3D vector to do that. This vector can be seen as a 3D description of how the object should be moved from the point of origin. Consider this part of the last example:
translation 2 2 0
Whatever shape comes after this Transform node will be moved two meters to the right (+2 in the X axis), two meters up (+2 in the Y axis), and will stay at the same distance near/far (0 in the Z axis).
Since this is the most common use of the Transform node, it's perfectly reasonable to have a node like this:
Transform {translation -2 0 -5}
The rotation property allows you to choose which axis you would like to rotate the shape around, and then lets you enter an angle (in radians) for that rotation. Look at the following example:
Transform {rotation 0 1 0 1.57}
I've chosen to rotate the shape 90 degrees around its Y axis. This would be akin to "spinning" the shape, since the Y axis can be seen as a line from the top of the screen to the bottom of it. Here's another example:
Transform {rotation 1 0 0 3.14}
This rotates any associated shapes 180 degrees around the X axis. This would be "flipping" the shape. The X axis runs from left to right across the screen, so rotating a shape around the X axis 180 degrees would turn the shape "upside-down."
The scaleFactor property very simply allows you to choose a factor by which a shape can be sized in each access, as in the following example:
Transform {scaleFactor 1 4 -2}
This would keep any subsequent shapes the same size in the X axis, make the shape larger by a factor of four in the Y axis, and make it smaller by a factor of two in the Z axis.
Of course, the Transform node does nothing on its own. But it will now affect any primitives that occur after it until it is separated from the rest of the document with a separator node.
The separator node is very simple. An example would be as follows:
Separator {
Transform {
translation 2 2 0
rotation 0 1 0 3.14
scaleFactor 1 1 1
}
Cylinder{}
}
Cube{}
Using the Separator node in this way, the Transform node will affect only the default cylinder you've created. The cube, which is defined outside of the separator, will not be affected by the Transform node. Instead of moving, the cube will appear centered in the screen, like the primitives you created earlier in the chapter.
Using everything you've learned up until now, let's create a scoop of ice cream and an ice cream cone-except that they'll be appropriate for someone with the same sized neck as, say, King Kong.
You'll use the sphere and cone primitives to create the basic shapes and the Transform node to move those shapes around. On top of that, you'll need Separator nodes to transform the shapes individually. Let's also make the shapes a little larger than life so they're easier to see.
Create a new VRML document and enter Listing 24.3.
Listing 24.3 moving.wrl Moving and Flipping Primitives in the VRML World
#VRML V1.0 ascii
#
# Moving and flipping
# VRML primitives
#
Separator {
Transform {
translation -1 0 0
rotation 1 0 0 3.14
}
Cone {
height .75
bottomRadius .12
}
}
Separator {
Transform {
translation 0 0 -1
}
Sphere {radius .5}
}
Each of the shapes has an associated Transform node that is enclosed with it in a Separator node. In the first Separator node, you're creating a Transform node that moves the shape two meters to the left and "flips" it 180 degrees. You then create the cone primitive, which is 1/2 of a meter in height and about .24 meters in diameter at its bottom. (Of course, flipping it makes the bottom the top, at least insofar as this is supposed to represent an ice cream cone.)
The second Separator node uses Transform to move the primitive two meters to the right and two meters behind the center point of the screen. Then it creates a sphere with a diameter of .4 meters, which hopefully will make it about the right size for Kong's ice cream appetite (see fig. 24.10).
Figure 24.10 : A helluva lot of virtual calories
VRML is more of a cousin to HTML than part of the specification. In some ways it is similar-it's text-based and can be used to navigate the Web. In many ways, it is very different, including the fact that it is basically graphical and 3D. New standards are emerging that may eventually make it difficult for non-programmers to create VRML worlds without special applications.
For now, though, you can create documents that are properly formatted for VRML, and then enter the correct nodes to create various primitive shapes. On their own, primitives appear at the 0,0,0 point in your browser, and will overlap one another when rendered together.
To get past this, you use another node, Transform, to move objects around in the virtual world. Transform is designed to affect every object that comes after it though, so you run into similar overlapping problems unless you use the Separator node.
The Separator node allows you to "nest" nodes within it, thus separating those nodes from the rest of the VRML description. So, a Transform node can be made to affect only the primitive that is in the same Separator.