Depth interpolation for z-buffer, with scanline

Posted by Twodordan on Game Development See other posts from Game Development or by Twodordan
Published on 2012-10-03T21:50:04Z Indexed on 2012/10/03 21:56 UTC
Read the original article Hit count: 513

I have to write my own software 3d rasterizer, and so far I am able to project my 3d model made of triangles into 2d space:

I rotate, translate and project my points to get a 2d space representation of each triangle. Then, I take the 3 triangle points and I implement the scanline algorithm (using linear interpolation) to find all points[x][y] along the edges(left and right) of the triangles, so that I can scan the triangle horizontally, row by row, and fill it with pixels.

This works. Except I have to also implement z-buffering. This means that knowing the rotated&translated z coordinates of the 3 vertices of the triangle, I must interpolate the z coordinate for all other points I find with my scanline algorithm.

The concept seems clear enough, I first find Za and Zb with these calculations:

var Z_Slope = (bottom_point_z - top_point_z) / (bottom_point_y - top_point_y);
var Za = top_point_z + ((current_point_y - top_point_y) * Z_Slope);

Then for each Zp I do the same interpolation horizontally:

var Z_Slope = (right_z - left_z) / (right_x - left_x);
var Zp = left_z + ((current_point_x - left_x) * Z_Slope);

enter image description here

And of course I add to the zBuffer, if current z is closer to the viewer than the previous value at that index. (my coordinate system is x: left -> right; y: top -> bottom; z: your face -> computer screen;)

The problem is, it goes haywire. The project is here and if you select the "Z-Buffered" radio button, you'll see the results... (note that the rest of the options before "Z-Buffered" use the Painter's algorithm to correctly order the triangles. I also use the painter's algorithm -only- to draw the wireframe in "Z-Buffered" mode for debugging purposes)

PS: I've read here that you must turn the z's into their reciprocals (meaning z = 1/z) before you interpolate. I tried that, and it appears that there's no change. What am I missing? (could anyone clarify, precisely where you must turn z into 1/z and where to turn it back?)

© Game Development or respective owner

Related posts about JavaScript

Related posts about depth-buffer