\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!