\I[Voxel Landscapes - 2D and 3D|By Scout/C-Lous|Section: Coders Pool]
\F1\M\1(Continued from last page.)
\F3\3
{
U = U + Uinc
\2;Step 1 unit along U
\3 V = V + Vinc
\2;Step 1 unit along V
\3 Y = voxelYtab[U][V]
\2;Get Y coord
\3 Y = persp*Y/Z + (scrheight/2)
\2;Persp project
\3 if y < 0
{
y = 0
\2;Clip to top of screen
\3 }
if y < lasty
{
C = voxelCtab[U][V]
\2;Get colour of bar
\3 line from X,Y to X,lastY with colour C
lastY = Y
\2;New Y of last drawn bar
\3 }
if lastY = 0
{
End this ray
\2;Reached top of screen
\3 }
}
raydir = raydir + raydirinc
}
\F1\2
raydirinc is negative since the screen is gone through left-to-right. Vinc is set to -sin to change the V axis orientation (up to down). This routine MAY draw a mirrored landscape since I (the author of the article) made the pseudcode from scratch. The UV stepping should be done using 8:8 fixed point math. (I will not describe fixed point math here.)
It is easy to apply depth-shading to this since we always have the Z value at hand when drawing a bar. Precalculate another 2d table, that: given a colour C at depth Z, gives us a new colour C. (Use 24-bit truecolour when precalculating the new C values, and then, in order to get back to 256 colours, find the best matching colours in the palette. Save the 2d-table with 256-colour entries.) Then add one more line after "C = ..." in the voxelrout: C = VoxelZshade[Z][C]. That will give your voxel landscape good-looking Z-shading.
\M\F2\1Z-rotation
\F1\2Three alternatives here.
You can 'shear' the landscape. This looks good when you rotate max 30 degrees around the Z axis. It does not work well if you rotate more than 45 degrees. It is done by adding "shearXfactor*(x-(scrwidth/2))" to the Y-coord after perspective projection, where shearXfactor = sin(Zangle). If you want to be able to do full 360 degree rotations around the Z axis, you must either draw non-vertical lines or split the process into two parts, where the first part draws the landscape without Z-rotation, and the second part is a zoomrotator that rotates the newly generated picture around the Z axis.
\M\F2\1X-rotation
\F1\2This is the hardest effect of all. When you rotate around the X axis, the vertical stripes on screen should not remain vertical anymore. (Draw some vertical lines on a piece of paper and check what happens when you rotate the paper around the X axis, then you will see what I mean.) They should not even remain lines! (Perspective effects make them wider at the end that's closer to the eye... argh :)) The only sensible approximation I know of is 'shearing' the landscape in Z direction. It is done by adding "shearZfactor*Z" to the Y-coord before perspective projection, where shearZfactor = sin(Xangle).
If you want examples on some of these methods, Artwork's "The Gate" (first place at Symposium'96) uses the 'shear' method for both X- and Z-rotation, while C-Lous' "Kolor" (Icing'96) and "Kolor remix" (Remedy'96) uses 'shear' for X- and 2-pass for Z-rotation. Artwork's voxelroutine has some more features though:
\M\F2\1Y-coord interpolation
\F1\2In order to get rid of the "jaggedness" of the landscape (the individual bars are clearly visible if you don't have gazillions of them), you can interpolate the y-coordinates. It is done by interpolating between the four UV values closest to your current UV position. The interpolation shall be performed every time you read a Y-value out of voxelYtab, and in a fashion like this:
\F3\2
;UV are floating point values, Ufraction & Vfraction are fractional parts of them
\3slope1 = voxelYtab[U+1][V] - voxelYtab[U][V]
slope2 = voxelYtab[U+1][V+1] - voxelYtab[U][V+1]
Y1 = slope1 * Ufraction + voxelYtab[U][V];
Y2 = slope2 * Ufraction + voxelYtab[U][V+1];
slope3 = Y2 - Y1;
Y = slope3 * Vfraction + Y1;
\F1\3\M \S[Articles/voxel3.txt]\2\3Press this line to continue!