Contributors

VRML Post-Production

The secret of the best VRML worlds on the Web
By Bob Crispen
 

This is a slightly longer version of an article that appeared in InterActivity magazine, July, 1998, pp.20-21.

Ok, you've made your VRML world. Time to put it out on the Web, right? Wrong! All you've done is make that world. Now it's time to make that world good.

Here are some tips from the experts and lessons from experience that will take your VRML world to the next level. You won't need to buy any expensive tools. All you'll need is a plain text editor (not a word processor, but an old-fashioned editor that will generate vanilla ASCII text) and a handful of freeware tools.

These tips were culled from presentations at the three VRML Symposia, conversations, email on www-vrml, and lessons learned from personal experience with large VRML projects.

Making it small.

Diet time. The first thing we'll do is put your world on a serious weight loss program. As Sam Chen of Silicon Graphics said at the 1997 VRML Symposium, like high-fat foods, "Modelers are evil."

Load your VRML world into a plain text editor. You’ll see some brackets and braces and the names of the VRML nodes, but mostly you’ll numbers. If your modeler is typical, some of those numbers are your enemies. Why? Because they’re not necessary. Every unnecessary number and every unnecessary digit in a number brings you one step closer to a world that loads and renders like a ten-ton pig – and smells like one to your visitors.

Even the best modeling programs generate IndexedFaceSets with an appalling number of points, many of them completely unnecessary. If your modeling program has a polygon reduction tool, use it and reduce the polygons until the image starts to look bad. Then reduce the points a little bit more. Now increase the creaseAngle until it looks good again. Keep playing with it (if your modeler lets you snip out and move points, so much the better) until every point counts.

UnLOD extra weight. If your modeler can save an object as a VRML 1 file, you can use the marvelous free program LODestar by Dieter Schmalstieg and colleagues at http://www.cg.tuwien.ac.at/research/vr/lodestar/. LODestar is designed to generate levels of detail (LODs), but it has an option that will extract a single LOD. Start with LOD level 2 or 3 and increase the number until it starts to look bad. Import the reduced object back into your modeler or converter and turn it back into VRML 2. I have never used an object from a public repository without running it through LODestar.

Dare to be abnormal. Most modelers generate normal fields (and their corresponding normalIndex fields) as a matter of course. Do you really need them? Find out. Use your text editor and comment out the normal and normalIndex fields and see what the object looks like. If it looks fine, delete the lines you commented out and save your visitors the download time. Sometimes when removing the normals makes an object look wretched you can make it look good again by setting the convex field FALSE. Remember too that a big enough creaseAngle can cover a multitude of sins.

Data fat. Ever look at a VRML world and see numbers like 6.2e-14 or 123.4560000087? Unless you're modeling viruses at scale, that first number is pretty near zero. Replace it with "0" and save not only some bytes but maybe even some rendering time (a number that's almost zero won't take advantage of the shortcuts some algorithms have when a value is zero).

Now think about the second number. What would happen if you replace that number with "123.456" or even "123"? It depends. An average visitor won't see your world any larger than 1024x768. Round that first number down to 1000 to account for the borders on their browsers. That's four-place accuracy. For example, the difference between "123.4" and "123.5" translates into one pixel difference.

But that assumes you're seeing an object that's 100 units wide and it fills the whole screen. How close will a visitor with any sense come to your object? How much of the screen will it fill? You can answer that question for your own world. All you have to do is ask the question and think a little bit. Much of the time you'll discover that 3 digits of accuracy is overkill.

Note too that where precision counts most, at edges between two objects (like two walls in a room), the important thing isn't that the coordinates are accurate to 10 places, but that the coordinates are the same.

There are a number of programs that reduce data fat, including James Waldrop's VRML Datafat Munger at http://www.construct.net/vrmltools/datafat.html and my vwaif at http://www.crispen.org/src/#vwaif. And don't forget your color fields. I've never found a need for more than 2 significant digits in color fields.

USE me. You already know about DEF and USE when you have duplicate objects. But very few modelers are smart enough to know that if you paint three objects the same color they can DEF and USE the colors to save some bytes. It's not uncommon for a modeler to generate 20 objects, all colored identically, each with an 40- or 50-byte Appearance node. DEF the first one and USE it in the rest.

Claustrophobia. Most VRML modelers will format your files neatly, indenting by a couple of spaces or a tab stop between levels. That's wonderful when you're debugging, but when you're ready to publish, clean out the extra spaces. And don't forget commas; they can all go. There's a VRML pretty printer at http://www.crispen.org/src/#vpp that you can use to restore the indentations in case you ever need to debug it again.

Squeeze me. Finally, use gzip to compress your file. You can get gzip (other kinds of compression like PKZip for Windows and stuffit for Mac will not work) for just about every platform at ftp://prep.ai.mit.edu/pub/gnu/. And if you have a shell account at your Internet Service Provider, you can just transfer the file over to your ISP with FTP, log in, and use their copy of gzip -- I have yet to find an ISP that doesn't have gzip.

A special note on file names: some browsers and some web servers have a problem with files named "foo.wrl.gz". Rename that file to "foo.wrl" (even though it's still gzipped) and the problems go away. All VRML browsers I know of are clever enough to figure out that the file is gzipped as they load it.

 

Making it fast.

Speeding up animations. Now let's really start to tweak. First of all, if you've got any animated objects (and you probably will), wrap them in VisibilitySensors. Set up a Script node to disable the TimeSensor that drives the animation whenever the object isn't visible. That way, only objects your visitors can actually see will take up CPU cycles for animation.

Note that some browsers' VisibilitySensors seem to take a lot of cycles themselves, so experiment to see whether you're paying a bigger price for invisible animations or for the VisibilitySensors that turn them off.

Careful with that ax, Eugene. VRML browsers do the very best job they can to render only what they have to. But in some browsers and some scenes, a huge, connected object can bring a browser to its knees as it tries to compute geometry and lighting for the 90% of the object that's invisible. Give the browser a helping hand. Chop up your big objects into little objects. This is especially true for ElevationGrids; nearly every browser will render an ElevationGrid faster when it's chopped up into 4 or 16 pieces. And as much as possible, group the objects that are near one another together to give the browser even more help.

Be a bulb-snatcher. Sometimes you can save cycles simply by turning off the lights for objects you can't see (using a VisibilitySensor again). If doing that seems to give you some extra frames per second, try setting the Scale on invisible objects to something very tiny. Or better yet, wrap your objects in Switch nodes and have the VisibilitySensor set whichChoice to an empty Group node when the object is out of sight.

Light it right. In the very nature of things, SpotLights take longer to compute than PointLights, which take longer to compute than DirectionalLights. Note too that while PointLights and SpotLights are global in scope, lighting everything within range, DirectionalLights light only the objects under their innermost parent. That means that you can (and should!) substitute DirectionalLights for PointLights and SpotLights wherever you can do that without doing damage to the effect you're trying to achieve. It also means that, unless your world is very small, you should never have DirectionalLights under the topmost parent, but should light each object or area of your scene separately.

Watch out for the ambientIntensity field of lights. The reason they're defaulted to zero is that they contribute lighting to every object in the scene. Since that can mean a drastic increase in CPU cycles, be sure that you only use the ambientIntensity field when nothing else will do.

Textures vs. Geometry. A good friend had a number of truly lovely bushes in her VRML world. Unfortunately, the time it took to render the geometry of the leaves and branches slowed things down to a crawl. She started flying again when she took a screen grab of the bush, turned it into an ImageTexture, and used a Billboard node to make the bush face the visitor. Didn't everybody notice the rotating bushes? Nope. Try it and see for yourself.

Control the Window. It takes a certain amount of time to compute each pixel in the scene. That's just the way things are. If only your visitors were sensible enough to make their browser windows smaller, they'd move much faster through your VRML worlds. Well, for goodness sakes, don't leave it up to them! Use the <EMBED> tag to embed the window in a web page or a JavaScript script to open up a window, so that you control the size. One more motivator: bring up your world full-page in your web browser. Now think about how much of the vertical image is a complete waste of space. If you cut the vertical size in half, you'll gain speed and lose almost none of the useful part of the image.

Making it pretty.

Light it right (part two). Anyone who's ever owned a camera knows that the only thing a flash mounted on the camera and pointing at the subject is good for is fill lighting when the subject is in shadow. Use a NavigationInfo node and set the headlight FALSE. Then start putting in lights that you control.

Straight-on lights look pretty crummy. Angle them so you bring out the details of your geometry instead of drowning them in light.

Color me unique. I'd guess about 90% of the VRML worlds I see never use anything but diffuseColor. The other 10% are the top 10%, at least in my opinion. Let's see if we can't move your world from the dull majority to the VRML elite.

Fog. Want to make your undersea world look like it's underwater? Want to make your Dante's Inferno look really hellish? Fog has a color field. Get it?

emissiveColor. Make your objects glow in the dark. Hook up a TimeSensor through a Script to your emissiveColor and you'll have the equivalent of an HTML <BLINK> tag! But tastefully applied emissiveColor is just the thing to make objects stand out in a scene.

specularColor. Figure 1 shows a tiny VRML airplane (66 polygons!) adapted from Alejandro Cifuentes's FST model, with color fields in the IndexedFaceSet and no lighting but the headlight. Yuck.

Figure 2 shows the same aircraft after some tweaking. Of all the tweaks (improving the colors, making the canopy transparent, putting in four angled lights with different intensities instead of the headlight, moving the color information to a Material node, and adding specularColor), specularColor had the most dramatic effect and made the object look most realistic.

Per-vertex coloring. While the color field in the IndexedFaceSet was worse than useless in the aircraft, it comes into its glory in the fish in Figure 3, adapted from Charles Eubanks's model at the VRML Repository. Look at the subtle color gradients on the bodies of these even tinier fish (the fish bodies are only 16 polygons each). Per-vertex coloring is probably too difficult to do by hand, except for very simple objects or parts of objects, but when you want a nice color gradient, nothing else does it better.

Making it right.

Think about the absolutely worst thing that could happen with your VRML world once it gets onto the net. My worst nightmare is that I've got the only VRML browser that the world won't crash, while everybody else's browsers are going up in smoke when they come anywhere near my world. While it's possible to try the world on a number of browsers, there is absolutely no excuse for publishing your world without running it through a real syntax checker. Vorlon from Trapezium is free and close to bulletproof, and Viper (also free) from NIST checks your syntax and builds a picture of your scene graph.

And if you're fanatical about making your worlds small, fast, and beautiful, watch for a new generation of VRML post-production tools. Trapezium's Chisel (http://www.trapezium.com/), which I've reviewed in alpha, automates many of the more tedious of the steps I've talked about above and does some other things that I wouldn't even have the courage to try. As people begin to realize that post-production makes the difference between the outstanding worlds and the ordinary, expect to see more of these tools.

Find out More.

The very best tutorial I've found on VRML post-production is the course notes for David Story, Delle Maxwell and David Marsland's course given at the 1997 VRML Symposium: http://cosmosoftware.com/developer/vrml98/courses/compel/. There are links to other excellent tutorials and some tips we didn't have space for here at the VRMLWorks http://vrmlworks.crispen.org/.

About the Author.

Bob Crispen researches new technologies for modeling and simulation for a large aerospace company. He developed VRML models for the IrishSpace project, led the VRML team for the VRML 98 conference website, wrote music for VRML Dream, has a widely reviewed website, the VRMLworks, and is currently a member of the VRML Review Board.