Playing God...
Some few years back I ran into a
book called "Microcomputer Graphics" by Roy E. Myers (Addison-Wesley, 1982). I
thought I had died and gone to Heaven. For a long time prior to that find, I
had been struggling with how to handle 3-d graphics in computer code space. I
never got very far on my own. This wonderful book traced each step in the path
from 2-d to 3-d graphic manipulation in clear, easy language with oodles of
BASIC code examples all along the way. On about the 4th page of the "Basics of
Three-Dimensional Graphics" chapter, it presented the concept of tranformation
matrices.
While I recall having had a taste of matrix math as far back as (I think)
12th grade, I somehow successfully managed to avoid it for the balance of my
academic years. Now it clicked, when I actually had a use for it. For I was
absolutely enthralled by Mysttm (Copyright Cyan) when it came out,
and I suddenly got a wild hair to try to create structures, scenes and objects
just like those seen in that game. I began to avidly pursue this line of
exploration, and plunged into lots of experimental 3-d graphics programs using
MS QuickBasictm -- sadly, a product now obsoleted by MS VisualBasictm
but still very useful for quick studies without a lot of "environmental"
hassle. I soon embarked on a project to build a really massive edifice, block
by block, in VisualBasictm -- a full-blown, 3-d design program,
sort of a "dimensionless" CAD program. I called it the "Worldmaker".
I say block by block, because it truly was one of the few times I managed
to lay a proper, structured, modular groundwork that lent itself to be added
onto and enhanced easily - quite unlike my normal "hacking" jobs. I
constructed some 3-d point-and-plane data set files for basic shapes using QB
as a fast utility tool: cubes, tetrahedrons, simple arches, domes, spanels,
rings, pyramids, columns, etc. - I even did gothic arches. I could import
these shapes on top of each other and move them around individually in X-Y-Z
space, rotate them, make them bigger or smaller, stretch them in any X-Y-Z
dimension, and also rotate the viewer's eyeball (POV) around the objects. I
learned from the Myers book how to establish which planes were "hidden" based
on the angle between the normal vector of each individual plane of the shape
and the POV line-of-sight to that plane. I learned how to include perspective
in the transformation matrices. I learned how to move the POV closer and
farther away during runtime. This was an exciting time for me, I can tell you!
The book didn't talk about color fills, but it didn't take too long to figure
out how to do that. Simply a matter of plotting fill points across each plane,
row by row, in 3-d space. Once I got a taste for the Z dimension, this was not
too tough at all. I did a little bit of "jittering" in the color plot
definition algorithms to "fuzz up" the result a bit -- which to me looked a
lot more realistic than just using one solid palette color. I learned how to
use the VB palette selection function, so as to change the shape colors during
runtime. And by extending Myers' book's math, I figured out how to adjust the
brightness of the fill color according to the angle between the normal vector
of each plane and the vector from the plane to a predefined light point source
- in other words, the light incidence angle. I figured out how to determine
the distance of each visible plane from the POV so they could be rendered in
proper order, back to front. This was getting to be a real rush…
It was as if I had tapped into a pure narcotic source; I couldn't stop. I
added the capability to select any two point pairs and join them, so that I
could turn the basic shapes into other more complicated shapes. I added a
"fuse corners" feature to make sure the individual shapes were intimately
connected. I added a screen backdrop .bmp import feature. I added the means to
save a collection of shapes as a set, to preserve that set definition, and to
import it on top of other sets. I added the ability to move and manipulate
whole sets independently from other sets in the master picture collection. By
this time, I was literally reeling. But there was something still missing.
That something was surface texture mapping. I scratched my head for a long
time over this. At length, I made up a separate utility program that I used to
import .bmp images copied from the Web, crop them to a reasonally small
pattern "tiling" dimension - one that could repeat itself seamlessly if copied
edge-to-edge - then do a raster scan across the image and save the tile
dimensions and point color definition to a custom "bitmap pattern" sequential
data file. I did brick walls, basketweave, stone and marble, textiles, wood
and parquet, all kinds of patterns in this manner -- even small pictures and
friezes. I figured out how to take these 2-d bitmap scan pattern maps, rescale
them, and plot them onto my shape planes oriented in 3-d space -- using some
of the same subroutines I already created for doing a straight palette color
fill. And the brightness-adjusting routine that I had previously installed
worked great on the pattern maps as well! Lastly, I added a feature to specify
how many rows and columns of pattern tiles to apply to the planes of each
shape.
In the many months I spent involved in this particular project, my self-esteem
got a real boost. This was undoubtedly the most challenging, complex and
math-intensive program I have ever worked on. In retrospect, however,
Worldmaker does have some distinct shortcomings. For one thing , the plane
rendering precedence routine does not guarantee perfect results. If big planes
are tilted a certain way and are in front of smaller ones, the rendering order
is not always correct. Maybe someday I can work that out. Also, while the
brightness of each individual plane is controlled by the light incidence
angle, there are no true shadows produced - but I didn't want to learn and
pursue ray-tracing methods to get them, since I didn't want to wait all day
long for a picture to render. For the same reason, I never intended to
introduce surface reflectivity variables into this program. Another
shortcoming is that the program variable array dimensions are really huge, so
I can't always add as many total shapes as I would like. All in all, I guess I
have to say I didn't hit my original target of true Mysttm-quality images --
but I came close enough to be at least partially satisfied...
Here are some sample images from the runtime screen:
A collection of sets, made of objects, made
of planes, defined by points with x, y and z coordinates.
Rendered image, with pattern-mapped planes.