【问题标题】:Mathematical view of z-fightingz-fighting的数学视图
【发布时间】:2015-01-21 04:44:37
【问题描述】:

为了了解 z-fighting 的工作原理,我收到了这个问题。

考虑在局部坐标系中给出的点p = (0, 0, −500) 相机。导出在不同阶段分配给 p 的深度值 上述流水线,即导出p在眼睛空间的深度值,在 标准化设备坐标([−1, 1]),范围为 [0, 1] 和最终深度 缓冲值。其中 n = 200 和 f = 1000 和 m = 24

我认为此过程的第二步是:z1=z * -(f+n)/(f-n) - 2fn/(f-n) 来自预期变换矩阵。 之后z2= (1/2)*z1 + 1/2

但我不知道眼睛空间中的转换应该是什么样子,最后一步是什么。

我希望有人可以帮助我:) `

【问题讨论】:

  • 最后一步是同质划分,即 v' = v/v.w - 但是要理解 Z 战斗,这无关紧要。 Z-fighting 是由几乎相同的边界值(顶点位置)的插值中的数值舍入误差引起的,导致某些排序运算符( 等)发生变化。

标签: opengl math zbuffer


【解决方案1】:

要从对象空间(“局部坐标系”)获取,您必须考虑模型(对象到世界)和视图(世界到眼睛)的转换。通常,这些是一些矩阵描述的仿射变换。模型和视图变换可以组合成一个模型视图矩阵,因为世界空间不是明确需要的。这就是旧 GL 固定功能管道的工作方式。

由于不清楚具体给出了什么,我假设我们知道矩阵,或者您可以根据给出的任何内容确定/计算它们。由于您只需要z_eye,因此您可以将这些矩阵的第三行的点积与您的输入向量p 一起使用(正如您在投影的情况下所做的那样)。

投影后,你得到了clip space,需要用w_clip 进行齐次除法——这意味着只计算z 是不够的。您还需要w 坐标,如应用投影矩阵所定义的那样。在典型情况下,w_clip=-z_eye。但在一般情况下,您可能会得到其他东西。这意味着您可能还需要x_eyey_eyew_eye,因为模型和视图转换可能不是仿射的(非常不可能),请使用w(一种粗略的缩放方式)或投影方向与z 轴不同(仍然不太可能,但理论上完全可能)。

z_ndc=z_clip/w_clip 之后,您需要视口变换。默认情况下,OpenGL 将在此处将范围 [-1,1] 转换为 [0,1],并且您的问题假设相同。最后,将值转换为最终格式。由于默认情况下使用整数深度缓冲区,因此范围 [0,1] 只是线性映射到 [0,max],而忽略小数部分。 您的 queuestion 似乎建议使用 24 位深度缓冲区,所以 max=2^24-1

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多