简体   繁体   English

实现 Z 缓冲算法

[英]Implementing Z Buffer Algorithm

I'm trying to experiment with computer graphics and would like to implement Z Buffer algorithm for rendering in Software.我正在尝试使用计算机图形学,并希望实现 Z 缓冲区算法以在软件中进行渲染。

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 ?要使用平面形式方程计算像素的 Z 坐标,我应该计算三角形的面法线吗? 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 vx,vy,vz 顶点,x,y 像素坐标,nx,ny,nz 顶点法线

Now for each TOP or Bottom Triangle I check the Z Pixel to ZBuffer pixel现在对于每个顶部或底部三角形,我检查 Z 像素到 ZBuffer 像素

// 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. Z 缓冲区已正确初始化。

3

You don't need to do anything with face normals when implementing Z buffering.在实现 Z 缓冲时,您不需要对面法线做任何事情。 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.此外,我很抱歉只浏览了您的问题代码,但是如果您想进行透视投影,那么请确保您对每个像素进行线性插值的“深度”不是世界/相机深度,而是成比例的东西(什么? SO 上没有 mathjax?)到 1/Z_world 或 1/W。

That is, you have a projected triangle where each vertex, Vi , has也就是说,您有一个投影三角形,其中每个顶点Vi都有
{Vi_screenX, Vi_screenY, Vi_projectedDepth} and {Vi_screenX, Vi_screenY, Vi_projectedDepth}
Vi_projectedDepth = linear_function_of(1 / Vi_Z_camera) . Vi_projectedDepth = linear_function_of(1 / Vi_Z_camera)

Very simple examples include:非常简单的例子包括:

Vi_projectedDepth = 1/Vi_Z_camera or Vi_projectedDepth = 1/Vi_Z_camera
Vi_projectedDepth = 1.0 - 1/Vi_Z_camera 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 ).然后,您必须线性内插整个三角形Vi_projectedDepth值,但你不需要把这些插值的倒数(至少对于Z缓冲区排序。如果你想要做透视校正纹理,OTOH,你_may_需要最终计算倒数)。

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 .如果你不这样做,当几何体有隐式交集时,你会得到非常奇怪的结果 - 我只记得我在SE Graphics 中对此发表了评论。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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