【问题标题】:Interpolating Z depth in a interpolated perspective orthographic viewing frustum在插值透视正交视锥中插值 Z 深度
【发布时间】:2020-03-09 23:13:57
【问题描述】:

为了在透视投影和正交投影之间进行插值,我使用了以下公式(效果很好,因为剪裁平面完美对齐):

 X' = rw + X / ((Z * fwi - ox) * (1f - a) + ox);
 Y' = rh + Y / ((Z * fhi - oy) * (1f - a) + oy);

地点:
rw 或 rh 为 (renderWidth 或 Height - 1) / 2f,
ox 是 vSize / rw,oy 是 hSize / rh,
fwi 是 tan(vFOV/2) / rw,fhi 是 tan(hFOV/2) / rh,
a 是 lerp 系数; 0 = 透视,1 = 正交,0.5 = 介于两者之间。

现在为了正确计算每个片段的 Z 深度,我先计算 z = 1/z,然后通过 ScanLine 函数将其插入屏幕空间,最后通过 1/z 计算最后的真实深度。

但是正交投影不需要这种深度校正,所以我想知道在混合投影时确定真实 Z 的正确方法是什么。 当前的 XYZ 到 XY 公式可以总结为:


目前我正在通过深度对 UV 坐标进行插值,当投影介于透视和正交之间时,这显然是不正确的。当它达到 1 时,它会绕过 1/z 深度校正。


请注意,这是一个软件渲染器,因此性能非常重要。理想情况下,我希望在这些类型的情况下做 OpenGL 正在做的事情。

【问题讨论】:

  • VERTEX_DATA 不是任何 OpenGL 着色器语法的一部分,因此不清楚您使用的是什么。也不清楚你如何计算你的“混合视角”。从概念上讲,透视和正射投影之间的混合可以解释为将投影中心移向无穷远,所有中间步骤仍然只是简单的投影变换。在这种情况下,没有什么是 GL 的自动透视校正无法处理的。完全不清楚为什么要手动除以z。真正的解决方案是正确使用齐次w 坐标。
  • 那么当 OpenGL 在透视和正交投影之间混合时,真的只是将相机超远地向后移动并降低 FOV 直到接近零,然后切换到正交投影?
  • 没有。 OpenGL 不在乎。 只需变换你认为合适的坐标,你似乎想要的效果可以用标准的 4x4 齐次投影矩阵来表示

标签: c# opengl rendering


【解决方案1】:

虽然我用来插值的方法可能不会被任何人使用,但它背后的数学原理是可以的。

我的剪裁平面公式可以描述为:

其中 o = 基本尺寸,a = 基本 FOV,l = 0 到 1
它基于 y 轴以允许 FOV = 0 裁剪。

当 FOV 设置得非常小并且 Z 设置得非常靠后时,由于 1/z 切线很小,正交投影可能会被伪造。但是我不能使用小车缩放公式,因为我已经实现了自定义 XYZ 到 XY 系统。

所以我所要做的就是将 Z 值偏移一些数字。
查看小车缩放剪裁平面图,很明显 Z 偏移必须是 Y 截距。


使用小车缩放,顶点 Z 会偏移,而不是实际的剪裁斜率,但我的 XYZ 到 XY 方法需要偏移剪裁斜率。

反转公式以求解 0 得到 (*-1 表示 y 截距):

最后可以计算Z校正:

加上 Z 偏移,深度现在被正确插值:

【讨论】:

    猜你喜欢
    • 2012-05-27
    • 2020-12-19
    • 2013-02-15
    • 2020-03-27
    • 1970-01-01
    • 1970-01-01
    • 2014-08-17
    • 1970-01-01
    相关资源
    最近更新 更多