我正在制作一个项目,即通过模拟制作电影。模拟从另一个定义投影矩阵的程序传递。
我遇到的问题是另一个程序有一种“假的”正交视图,我的意思是它的投影矩阵如下:
PerspectiveMatrix = glm::perspective(3.5, 1, 1.0f, 50.0f);
它使用LookAt函数:
ViewMatrix = glm::lookAt(
(2000,-3000,2000), // eye
(0,0,0), // center
(0,0,1)//up
);
所以我的意思是'假的'正交视图是他们已经将相机定位得足够远(以及小角度来放大场景),“视线”(缺少更好的术语)几乎是平行的在真实的正投影中。
所以这一切都很好,但是我遇到了,并且在另一个程序中也是一个问题,所有高精度深度测试都靠近相机,在我的情况下这是空的空间。这意味着有很多z战斗,如下面的链接所示:
所以我的问题是我可以通过哪些方式更改深度测试,以便将缓冲区偏向远方平面?或类似的规定。我已经尝试将NearPlane移动得更远,这会导致屏幕缩小,所以我在视角中用较窄的角度进行补偿。但是这样做足够的时间会使问题变得更糟,没有z战斗,但它并没有在正确的深度上绘制东西。球体最终落在一切之上。
我确实在Outerra找到了一些信息: http://outerra.blogspot.com/2012/11/maximizing-depth-buffer-range-and.html 他们有一些改变深度缓冲的想法,但它是Nvidia特有的,我需要兼容ATI和Nvidia
答案 0 :(得分:3)
blog post中描述的对数深度和反向深度映射都适合您。
反向浮点更好,它在DirectX中正常工作。在OpenGL中,由于设计缺陷,它不会为您带来任何额外的精度,除非驱动程序暴露NV_depth_buffer_float扩展,通过该扩展可以有效地关闭使其无法正常使用的偏差。
AMD自13.12 Catalyst驱动程序以来支持该扩展,因此该技术可用于所有5000+系列AMD GPU(驱动程序不支持旧系列)。答案 1 :(得分:2)
比上述任何一种都简单:将你的znear从相机移开。看起来它是glm :: perspective()的第三个参数,在你的例子中设置为1.0。在开始剪切场景前景中的内容之前,将其设置为尽可能大,并且z缓冲区精度问题可能会消失。
Reverse-float-z非常棒,但只有具有更宽视野和更深几何形状的场景才真正需要。对于像你这样的近似正交场景,只需适当设置你的znear / zfar。