The purpose of these tutorials is to guide you through the process of designing three dimensional worlds in VRML, a standard vr language.
box.wrl
#VRML V2.0 utf8
Shape {
geometry Box { }
}
This demonstrates the simplest VRML world of all. Let's examine it
closely. The first line simply tells the browser to expect VRML. All
your VRML files will begin with this line.
The next line tells us we will be defining a shape node VRML is all about nodes. The shape node is used to define ... a shape!!! Note the {. This tells us we are starting a structure. We end it later. The indentation is fairly standard. Now look at the geometry line. Geometry is the name of a FIELD. Nodes have fields, which are just places to put stuff. Field names usually begin with a lowercase letter, and node names begin with an uppercase letter. Much of vrml consists of the name of a field followed by its contents. The contents of a field might be a number, text, or (very often) a node. In this case, we are telling the shape what kind of geometry to use. The contents of the geometry field will be one of a number of special nodes designed to fit here. Huh? Examples are better than words, so look at these as well:
sphere.wrl
#VRML V2.0 utf8
Shape {
geometry Sphere { }
}
cone.wrl
#VRML V2.0 utf8
Shape {
geometry Cone { }
}
cylinder.wrl
#VRML V2.0 utf8
Shape {
geometry Cylinder { }
}
Look carefully at the code, and examine these files in a VRML browser,
and you will quickly understand that just by changing the node in the
geometry field, you can make different kinds of shapes appear.
Each of these geometry nodes has its own fields. Here's another version of the sphere world:
#VRML V2.0 utf8
Shape {
geometry Sphere {
radius 4
}
}
The only addition is the radius field. The radius field expects a
number (which could be a decimal value). You can see how simple it is
to change the size of a sphere.
More complex shapes might have more complicated fields. Here's another version of the box world:
brick.wrl
#VRML V2.0 utf8
Shape {
geometry Box {
size 2, 1, 1
}
}
You'll note that the only change is the addition of the size field.
Size is pre-defined as a field in the Box node. A size field is
supposed to contain a 3D vector. This is simply a set of three
numbers that represent data in an XYZ 3D system. In VRML, the X axis
runs parallel to the top and bottom of the screen. The Y axis is
parallel to the sides of the screen. The Z axis is a little trickier
to imagine, because it is PERPENDICULAR to the screen. The Z axis
runs from the screen to your eyeball (more or less).
So by setting the size to 2, 1, 1, we said "This box should have an X value twice as large as the Y and Z values. Imagine what this will look like, then look at it in a browser. This will give you a standard brick shape. Play with the values and examine the other shapes you can get. Note that you can use decimal values. The box is handy for building walls, because you can make a box with large values on two dimensions, and a small value (like .1) for the third dimension.
EXPERIMENT!! Make a box and play with the dimensions until you are
comfortable with how this works.
Likewise, the other shapes have some fields you can play with to manipulate the size that results. The cone has TWO fields that are relevant. Look at this code:
tablet.wrl
#VRML V2.0 utf8
Shape {
geometry Cylinder {
radius 2
height .5
}
}
As you examine these fields, you will see that they make a certain
kind of sense. Again, play with the values yourself until you are
comfortable with the results.
You can combine multiple shapes together to generate a more complex
shape. Examine the UFO below:
ufo.wrl
#VRML V2.0 utf8
#the UFO
Shape {
geometry Sphere {
radius 1
}
}
#spine
Shape {
geometry Cylinder {
radius .1
height 4
}
}
#a flat shape around center
Shape {
geometry Cylinder {
radius 2
height .2
}
}
# a cone
Shape {
geometry Cone {
bottomRadius .5
height 4
}
}
# with a box to add corners
Shape {
geometry Box {
size 1.5 1.5 1.5
}
}
colorBox.wrl
#VRML V2.0 utf8
#blueBox.wrl
Shape {
appearance Appearance {
material Material {
diffuseColor 0, 0, 1
} # end material
} # end appearance
geometry Box {
size 1, 1, 1
} # end geometry
} # end shape
This seems a lot more complicated than the previous box, but it isn't
really. All we added was a color field. There are a bunch of
different kinds of color fields, and they all work differently. The
only one we're concerned about now is the diffuseColor. DiffuseColor
is a field of the material node, which is a field of the Material
node. (Don't panic, we'll come back to them another day and explain
the whole thing.) For now, just understand that in order to specify a
color, we have to also specify an appearance and a material. Note how
the code is indented. This helps to explain how the various
components are related. Note also the capitalization. Remember that
field names are in lowercase letters, while node names are
capitalized. So the way to read this is:
I have a shape. The shape has an appearance field which contains a Appearance node. The Appearance node has a material field, which contains a Material node. The Material node contains a diffuseColor field.Wow. That's ugly, but you'll get used to it. For now, you can just retype it as you see it. Get used to the order and the indentation. (I remember SAM for Shape, Appearance, Material).
This still doesn't explain why this makes the cube blue. The diffuseColor field takes as a value three numbers between 0 and 1. These three numbers represent amounts of red, green, and blue in the final color. So, here's some colors:
| Color | Red | Green | Blue |
|---|---|---|---|
| black | 0 | 0 | 0 |
| blue | 0 | 0 | 1 |
| green | 0 | 1 | 0 |
| ltblue | 0 | 1 | 1 |
| red | 1 | 0 | 0 |
| violet | 1 | 0 | 1 |
| yellow | 1 | 1 | 0 |
| white | 1 | 1 | 1 |
| gray | .5 | .5 | .5 |
| brown | .5 | .5 | 0 |