scene.org File Archive

File download

<root>­/­mirrors­/­the_scene_archives­/­The_Scene_Archives_Vol_05­/­Disks_are_in_Here­/­Disks_4801_To_4851­/­4806-No_Sense_2­/­Articles/voxel3.txt

File size:
3 504 bytes (3.42K)
File date:
2005-01-22 23:20:16
Download count:
all-time: 509

Preview

\I[Voxel Landscapes - 2D and 3D|By Scout/C-Lous|Section: Coders Pool]
\F1\M\1(Continued from last page.)


\F1\2//Then Y is the interpolated Y coordinate

Observe that if your landscape has voxelYtab as bytes, slope1 is -255 .. +255, and if UV are 8:8 fixed point vals, Ufraction and Vfraction is 0 .. +255, so you can relpace the multiplications with table lookups: Have a mul-table that is 512*256 bytes large and index it via: multab[slope1][Ufraction].

This sceme can be simplified even more if necessary. (For example only interpolating along U or V axis, depending on which has the largest step length.)

\M\F2\1C-value interpolation
\F1\2This is just vertical Gouraud-shading. If Y-coords are interpolated, interpolate C-values the same way. Have a 'last C-value' variable. Then have your linedrawer draw Gouraud shaded vertical lines:
\F3\3//Vertical Gouraud shader
Cinc = (C2 - C1) / (Y2 - Y1)
for pixelY = Y1 to Y2
{
        putpixel(X,Y,C)
        C = C + Cinc
}
\F1\2
Tables can be used here as well. Since C2-C1 is -255 .. 0 .. +255 and Y2-Y1 is 0 .. +scrheight, have a Cinctab that is scrheight*512 words large. (words since Cinc is 0 .. +255.255 with 8:8 fixed point)

\M\F2\1Correcting some errors
\F1\2The Ustep and Vstep expression has an error. It would be correct if we had 3d hologram-styled screens, but as we use 2d screens we distort the contents to make it look good. One of the rules we use is that distance to a point on screen is measured along the eye direction, which makes that changing x or y doesn't change the distance to the point. Z = distance of the point. However, this error makes the steps at the edges of the screen 'shorter' in terms of change in Z. We can correct this error by dividing Ustep and Vstep
with cos(eyedir - raydir) (= -30 .. 0 .. +30). That will make Z change correctly, and the shading correct. It also looks better performing rotations about the Y axis. This tweak makes the rays at the edges longer than 1, so you may want to make steps with a Z-length of cos(30) instead of 1 (= cos(0)).



\M\F2\1Full 3d
\F1\2Despite the 3d look of all the prevoiusly described algorithms, they are technically still just 2d algorithms with perspective projection. How about a full 3d one...? Instead of raycasting every vertical stripe you raycast EVERY PIXEL. The rays are stepped in UVW direction. A hit is when voxelYtab[U][V] < W. (This means that the ray has collided with a bar.) When a bar is hit, a pixel is drawn with the colour of the bar, and that ray is finished.

There are many ways of calculating the directions of the rays. One is placing a grid in front of you in 3d space and calculating the direction from the eye to every intersection in the grid. One advantage of this method is that the rays' steplength in Z direction is automatically corrected for the 3d->2d distortion.

Another method is measuring the screen in degrees. It has alreay been done along the X-axis (-30 .. 0 .. +30), but if you have degrees along the Y-axis as well you have some very interesting calculations ahead... The calculation of UVWstep sure don't look easy, but maybe it can be performed using spherical coordinates or something like that? Then the UVWstep should be divided by (cos(Xdeg)*cos(Ydeg)) to correct Z-step length.

An example of one version of the full 3d technique can be found in TBL's demo "MindProbe" (TP95). That routine uses a 3d cube with pixels instead of a 2d voxeltable, but it is almost the same technique. 

\C[ClipArts/pinnen.Chnk]