2

I'm trying to experiment with computer graphics and would like to implement Z Buffer algorithm for rendering in Software.

So I'm trying to use the following plane equation:

z = -(ax + by + d)/c

To compute the Z coordinate of a pixel using the plane form equation should I compute the Face normal of the triangle ? or a normal of a vertex is enough ?

Here is how I compute it:

double zValueOfPoint(float vx, float vy, float vz, float x, float y, float nx, float ny, float nz)
{
    float A = nx;
    float B = ny;
    float C = nz;
    float D = -(nx*vx, +ny * vy + nz * vz);
    float z = -(A*x + B * y + D) / C;
    return z;
}

vx,vy,vz vertex, x,y pixel coordinate, nx,ny,nz normal of a vertex

Now for each TOP or Bottom Triangle I check the Z Pixel to ZBuffer pixel

// Top of the triangle
    for (int y = y0; y<y2; y++)
    {

        for (int x = xl_edge; x<xr_edge; x++)
        {
            float zOfPixel = zValueOfPoint(vx, vy, vz, x, y, nx, ny, nz);
            if (zOfPixel < zbuffer[int(x + y * m_Width)]) {
                zbuffer[int(x + y*m_Width)] = zOfPixel;
                SetPixel((unsigned int)x, (unsigned int)y, color);
            }

        }//end for loop x

The same for bottom triangle

Right now I get completely broken model. The Z Buffer is initialized correctly.

3

2
  • float D = -(nx*vx, +ny * vy + nz * vz) has an extra comma in the middle. Also, once you have implemented perspective interpolation in your rasterizer, this comes for free. Commented Jan 13, 2020 at 1:06
  • z is interpolated from the face vertexes directly the same way as x,y ... while rasterizing. No need to use plane equation... Commented Jan 13, 2020 at 8:25

1 Answer 1

3

You don't need to do anything with face normals when implementing Z buffering. You only need per vertex "depths" for your projected triangles.

Further, and I apologise for only skimming through your question's code, but if you want to do a perspective projection, then make sure the "depth" you are linearly interpolating per pixel is not the world/camera depth but something that is proportional (What? No mathjax on SO?) to 1/Z_world or 1/W.

That is, you have a projected triangle where each vertex, Vi, has
{Vi_screenX, Vi_screenY, Vi_projectedDepth} and
Vi_projectedDepth = linear_function_of(1 / Vi_Z_camera).

Very simple examples include:

Vi_projectedDepth = 1/Vi_Z_camera or
Vi_projectedDepth = 1.0 - 1/Vi_Z_camera

You must then linearly interpolate the Vi_projectedDepth values across the triangle but you don't need to take the reciprocal of these interpolated values ( at least not for Z-buffer ordering. If you want to do perspective correct texturing, OTOH, you _may_ need to eventually compute the reciprocal ).

If you don't do this, you can get very strange results whenever geometry has implicit intersection - I just remembered I made a comment on this in SE Graphics.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.