3D Graphic Tools
Volume Number: 8
Issue Number: 1
Column Tag: Tools of the trade
High-performance 3D drawing & rendering in your programs
By David Harr, Alhambra, California
Note: Source code files accompanying article are located on MacTech CD-ROM orsource code disks.
The Macintosh Toolbox provides good support for doing 2 dimensional computer
graphics in the form of QuickDraw. Basic QuickDraw (B&W) provides 6 geometric
primitives: line, rectangle, round-cornered rectangle, and circle, a polygon data
structure, and a region data structure, which allows the programmer to deal with
arbitrary areas and shapes. All of these can be drawn, outlined, filled, pattern filled,
resized and used as masks. Color QuickDraw adds the capabilities of drawing in color,
filling in color, using color patterns, palette animation, color masking, and provides
support for photo-realistic color and double-buffered on-screen animation.
With all of this attention to 2 dimensional graphics, however, Apple has been lax
in supporting the needs of those who are interested in doing 3 dimensional graphics and
modeling. The only support that Apple gives is in the form of a set of slow, buggy library
routines collectively known as Graf3D supplied in object form with MPW. The
“documentation” of Graf3D consists of eleven pages in an appendix at the back of the
MPW reference manual, Volume 1. This is a bare-bones listing of the routines and a
short explanation of the calling conventions, parameters and purpose of each routine.
Graf3D itself is a minimal effort in supporting 3d graphics. It provides only rotation,
scaling, translation, clipping, and 2d projection. There are no provisions for hidden
line removal, polygon fills, z-buffer rendering, light sources, or shading. It can be
used, at best, for wire-frame drawings.
3D Graphic Tools version 3.0, published by Micro System Options of Seattle,
Washington, is a set of routines written for programmers who wish to use
high-performance 3 dimensional drawing and rendering in their programs. The package
contains the source code for over 100 routines for 3D graphics. It provides a set of
tools for graphics programmers, and is a good basis for someone interested in writing
their own software for custom graphics applications.
This review discusses the C version of the package, which supports MPW C
version 3.0 and later, and THINK C version 4.05 and later. There is also a Pascal
version which is functionally identical to the C version and supports MPW Pascal
version 3.0 and later, and THINK Pascal version 3.01 and later.
Rendering Environment
All of the drawing in 3D Graphic Tools is done in a three dimensional extension of
the normal QuickDraw coordinate space. In other words, while most QuickDraw
operations take place in a plane with (-32000, -32000) in the top, left corner and
(32000, 32000) in the bottom, right corner, the coordinate space in 3D Graphic Tools
is a cube that is 64000 units on a side. This gives a space that is large enough for most
purposes, yet is small enough to allow the arithmetic operations to be carried out using
high speed integer mathematics.
Figure 1
By convention, the three axes of the coordinate system are labeled the x, y, and z
axes. The x and y axes are perpendicular to each other and lie in a horizontal plane,
while the z-axis is perpendicular to them both, and runs straight up and down. Each
axis runs from approximately -32000 to 32000, and each point in space has a unique
coordinate given by (x, y, z), where x, y, and z each represent the respective
coordinate of the three axes.
Mathematical Basis
Three dimensional rotations, transformations and scalings all involve
considerable linear algebra, so they require a lot of multiplication. In order to speed
the rendering of images and to make image manipulation as rapid as possible, it is
common to use fixed-point, or integer mathematics in the calculations, with some loss
in accuracy. 3D Graphic Tools supports a complete set of mathematical functions using
both the Fixed and Fract data types, as described in Inside Macintosh volumes I and IV.
These routines are not the routines included in the Macintosh ROMs, however. They are
hand-crafted assembly language routines that have been optimized for speed. On
average, the fixed math routines in 3D Graphic Tools are between 40% to 50% faster
than the Toolbox routines. This makes 3D Graphic Tools significantly faster than
Graf3D when performing line and point manipulation in three dimensions. In addition,
many of the conversion routines between types, such as frac2fix or fix2frac are
implemented as macros in 3D Graphic Tools, removing the overhead of a function call,
again adding to the speed of the package. In those situations where accuracy is
paramount, such as in zbuffer rendering, the routines revert to floating-point
mathematics, which is slower (e specially in those machines without a 68881/68882
FPU), but is more accurate.
Rendering Attributes
3D Graphic Tools has a full range of functions for performing three dimensional
image manipulation and rendering. These include basic operations such as rotations,
scalings, translations, and projections onto the two dimensional screen. In addition,
once a three dimensional scene has been constructed, it can be rendered to almost any
desired level of realism, from wire-frame drawings with no hidden line removal, to an
image incorporating such sophisticated techniques as multiple inde-pendent light
sources, shadows, specular highlighting, and texturing of objects. The only effort
required of the programmer is that they set the appropriate global variables.
The basic data unit in 3D Graphic Tools is the patch. A patch is a set of vertices
and facets that determines the shape of the object that the patch represents [see listing
1]. In addition to this shape information, however, the patch also contains an extensive
set of rendering attributes that are needed when making use of the more sophisticated
rendering options in the package. The rendering information associated with a patch is
used to determine the effect of illumination on the object. Some of the information is
also used to add texture and supply visual effects to the surface of the object.
Each vertex is defined by the coordinate (x, y, z) that it occupies in space and a
number in the vertex list. Thus, vertex 7 might be at (17, 23, 48). Each facet is
defined by a list of vertices, which are referenced by number, not by coordinate. This
list is arranged so that the vertices are listed counterclockwise in order. The reason
that each vertex is addressed by number is so that if an object is translated, rotated, or
scaled, the changes need only be made to the master list of vertices, and all facets of the
patch will automatically be correctly positioned. This is much faster than stepping
through each facet and individually repositioning each vertex in that way, because each
facet shares at least two vertices with other facets in the same object.
The ambience, diffusion, and reflection coefficients all control how light
reflecting off the object is treated. The reflection coefficients consist of three numbers
in the range 0 to 65535. Each controls what percentage of the red, green and blue light
is reflected from the object. A coefficient of 0 indicates 0%, 32767 is 50%, and
65535 is 100% reflection. When using the zbuffer rendering, then the ambience and
diffusion coefficients come into play also. If there is ambient light, then the ambience
coefficient determines what percentage of that light is reflected from the object, while
the diffusion coefficient determines what percentage of the light is reflected uniformly
in all directions.
The specular index, the specularity and transparency coefficients all determine
the quality of the illumination of the object. The transparency coefficient determines
the percentage of the background color which is added to the final color of the object. If
it is 0, then the object is opaque, and none of the background color is added, whereas if
it is 1, then the object is invisible, and its color is 100% determined by the
background color. The specular index and the specular coefficient are related and
determine how shiny the object is and how that shininess is distributed across the
surface of the object.
In addition to all of these rendering options for the patch, there are also several
miscellaneous attributes. There are three attributes that are specifically concerned
with lighting effects. If a patch is declared as a light source, then it emanates light of the
color determined by the reflection coefficients. If the ambient effect and distance effect
booleans are set, then the ambient light is added directly to the light reaching the
viewer’s eye, causing more distant objects to become grayed out. The farther away an
object is, the lower the intensity of the light reaching the viewer’s eye, causing more
distant objects to become darker. There are also three attributes that are used to
determine how the object is rendered. If the framed boolean is set, then all facets are
drawn with the edges in a different color than the facet itself. The color to draw the
edges in is given in the frameColor field. If the pattern boolean is set, then the facet is
drawn with a QuickDraw color pattern inside. Related to the pattern boolean is the
grayscale boolean, which fills the facet with one of 65 gray levels ranging from white
to black.
Advanced Options
In order to give the objects displayed a more photo-realistic look, 3D Graphic
Tools also has several advanced rendering options. These options, although they increase
the time required to display the scene, do not require nearly as much time as
full-blown ray traces, yet they provide a level of realism approaching that of ray
tracing. These advanced functions include texture mapping, anti- aliasing, and shadows.
Texture mapping is one of the most impressive features of the package. It allows
the programmer to add any one of six “textures” to an object. Each texturemap may be
rotated, scaled, or translated to produce interesting effects when projected onto the
object. The first of the six texture types is not really a texture at all, it is a PICT file of
the programmer’s choosing that will be placed onto the object in much the same way as
if the PICT were projected onto the object by a movie projector or slide projector.
However, it is also possible for the PICT to be repeated in every facet of the object,
causing it to appear again and again. In addition, the PICT can be enlarged or reduced to
any desired extent. Three more “naturalistic” textures include wood, rock, and bumps.
These have other attributes such as grain and roughness to make them even more
versatile.
Anti- aliasing is a technique that is used to soften and smooth the appearance of
the object. There are several algorithms used in computer graphics for anti- aliasing.
The one used in 3D Graphic Tools is to create a 3 X 3 convolution matrix of the selected
pixel and the eight pixels surrounding it, and then use that matrix to get a weighted
average of the color of the pixels. This color is then used to determine the displayed
color in the pixel. The main use for this technique is to soften the edges of facets in the
object. Once an object is rendered, if edge anti- aliasing is enabled, then each visible
facet in an object is processed a second time, but only the edge pixels are redrawn. In
addition, it is possible to apply anti- aliasing to a rectangular portion of an image,
allowing anti- aliasing to work either on any portion or the entirety of a rendered
image.
Shadows are the result of a reduction in illumination intensity caused by the
presence of an object between a light source and another object. The object between the
light source and the second object will cast a shadow on the far object. The degree to
which the illumination is reduced is a function of the transparency of the interposing
object. The more opaque the interposing object is, the less light reaches the far object.
This is the model that 3D Graphic Tools uses to generate shadows. This model does have
one limitation. If there are multiple objects between a light source and the far object,
only the first object encountered will be used to cast a shadow.