简体   繁体   中英

Implementing Z Buffer Algorithm

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

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 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM