我正在尝试对计算机图形进行试验,并希望实现Z Buffer算法以在软件中进行渲染。

因此,我尝试使用以下平面方程式:

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

使用平面形式方程式计算像素的Z坐标
我应该计算三角形的人脸法线吗?还是顶点的法线就足够了?

这是我的计算方法:
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顶点,x,y像素坐标,顶点的法线,nx,ny,nz

现在,对于每个顶部或底部三角形,我检查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

底部三角形相同

现在,我完全打破了模型。 Z缓冲区已正确初始化。

c&#43;&#43; - 实现Z缓冲区算法-LMLPHP

最佳答案

在实现Z缓冲时,您无需对面法线做任何事情。您只需要每个三角形的顶点“深度”即可。

此外,我只为您浏览问题代码而道歉,但是如果您要进行透视投影,请确保每个像素线性插值的“深度”不是世界/相机深度,而是成比例的( ?SO上没有mathjax?)到1 / Z_world或1 / W。

也就是说,您有一个投影三角形,其中每个顶点Vi都有{Vi_screenX,Vi_screenY,Vi_projectedDepth}和
Vi_projectedDepth = linear_function_of(1 / Vi_Z_camera)。

非常简单的示例包括:



然后,您必须在整个三角形上线性插值Vi_projectedDepth值,但不必取这些插值的倒数(至少不需要Z缓冲区顺序。如果要进行透视校正贴图,OTOH,则_may_需要最终计算出倒数)。

如果不执行此操作,则每当几何体具有隐式相交时,您都会得到非常奇怪的结果-我只记得我在SE Graphics中对此发表了评论。

关于c++ - 实现Z缓冲区算法,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/59707984/

10-12 16:00