z战斗的数学观点

时间:2014-11-23 11:29:17

标签: opengl math zbuffer

了解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

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

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

1 个答案:

答案 0 :(得分:0)

要从对象空间("本地坐标系")获取,您必须采用模型(对象到世界)和视图(世界到眼睛)转换考虑到了。通常,这些是由某些矩阵描述的仿射变换。模型和视图变换可能由modelView矩阵组成,因为世界空间不是明确需要的。这就是旧GL固定功能管道的工作方式。

由于不清楚究竟给出了什么,我只是假设我们知道矩阵,或者你可以从给定的任何东西中确定/计算它们。由于您只需要z_eye,因此您可以将这些矩阵的第三行的点积与输入向量p一起使用(正如您在投影时所做的那样)。

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

z_ndc=z_clip/w_clip之后,您需要视口转换。默认情况下,OpenGL会将范围[-1,1]转换为[0,1],并且您的问题假设相同。最后,该值将转换为最终格式。由于默认情况下使用整数深度缓冲区,因此范围[0,1]仅线性映射到[0,max],忽略小数部分。 您的队列似乎表明使用了24位深度缓冲区,因此max=2^24-1