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/voxel2.txt

File size:
3 919 bytes (3.83K)
File date:
2005-01-22 23:20:16
Download count:
all-time: 514

Preview

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