【问题标题】:Implementing Z Buffer Algorithm实现 Z 缓冲区算法
【发布时间】:2020-01-12 20:48:13
【问题描述】:

我正在尝试使用计算机图形进行实验,并希望实现 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 Buffer 已正确初始化。

【问题讨论】:

  • float D = -(nx*vx, +ny * vy + nz * vz) 中间多了一个逗号。此外,一旦您在光栅器中实现了透视插值,这是免费的。
  • z 直接从面顶点插入,与x,y 相同的方式...同时光栅化。无需使用平面方程...

标签: c++ graphics 3d rendering zbuffer


【解决方案1】:

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

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

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

非常简单的例子包括:

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

然后您必须在三角形上线性插值 Vi_projectedDepth 值,但您不需要需要取这些插值的倒数(至少对于 Z 缓冲区排序不需要。如果您想要做透视正确的纹理,OTOH,你_可能_需要最终计算倒数)。

如果你不这样做,只要几何有隐式交集,你就会得到非常奇怪的结果——我只记得我在 SE Graphics 中对此发表了评论。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-12
    • 1970-01-01
    相关资源
    最近更新 更多