如何有条不紊地选择透视投影的近剪辑平面距离?



我有一个3D场景和一个使用gluPerspective定义的相机。我有一个固定的FOV,我知道任何几何体到摄像机的最小距离(这是第一人称视角,所以这是从视点到角色碰撞体的最小距离)。

我如何选择最靠近剪辑平面的(对于最佳深度缓冲分辨率),无论玩家如何移动和观看,都不会导致任何剪辑 ?

这些距离不是简单相等的,因为近平面的离原点比离中心远。

公式:

nearPlane = nearestApproachToPlayer/sqrt(1 + tan(fov/2)2·(aspectRatio2 + 1)))

JavaScript代码:

  var nearPlane = nearestApproachToPlayer 
                  / Math.sqrt(1 + Math.pow(Math.tan(fov/180*Math.PI/2), 2)
                                  * (Math.pow(aspectRatio, 2) + 1));

派生:

在几何上,考虑金字塔,其底部是近夹面,尖端是原点。设nearPlane为金字塔的高度,wh为金字塔底部的宽度和高度。

w = aspectRatio·h

视场决定了金字塔高轴边的斜率:

slope = tan(fov/2)

h/nearPlane = 2 tan(fov/2)

h /2 = nearPlane 棕褐色( fov /2)

近剪辑平面的任何角点与剪辑平面的中心偏移(w/2, h/2),因此距离为sqrt((w/2)2 + (h/2)2)。这个角点到原点的距离是由nearPlane形成的直角三角形的斜边和前距离,所以是sqrt((w/2)2 + (h/2)2 + nearPlane2)

我们希望到拐角点的距离等于任何几何图形的最近距离

nearestApproachToPlayer = sqrt (w (/2) <一口> 2> /2) <一口> 2> nearPlane <一口> 2> /blockquote>

应用简单的代数可以得到上面的公式。

我没有检查我的代数,但我有经验地测试了这个公式:如果我将nearPlane乘以1.1,那么它会产生一个剪辑平面,对于各种宽高比来说,这有点太远了。我没有尝试过60°以上的不同视场

选择近剪辑距离和远剪辑距离的最佳实践是使它们紧贴场景,即近剪辑平面尽可能远,远剪辑平面尽可能近。

大多数3D应用程序用于透视转换的标准截锥体投影是平行平面投影。这意味着从这个角度确定平面距离。这其实很简单:

你将在3D渲染程序中携带的参数之一是视图向量,即相机指向的方向。假设你有这个向量归一化(即单位长度),然后将标量(=点)与物体的位置相乘,得到到原点的平面距离。这是一种更直接的方法,因为它直接给出所需的值,而不需要平方、平方根和除法。只有乘法和,即MAD指令,SIMD指令集直接支持。

我如何选择最接近剪辑平面(最佳深度缓冲分辨率),这将不会导致任何剪辑,无论玩家如何移动和看?

简单:关闭临近剪辑。我真不敢相信大家都没听说过这个。您启用深度夹紧,这将导致小于近(或大于远)的近(和远)值被夹紧,而不是被夹紧。

这并不能阻止实际在相机后面的物体被剪切。由于深度是固定的,你就失去了深度缓冲区在固定区域的效用。在合理的地方使用它仍然是一个好主意,如果你不能选择一个离得太远的近剪辑,否则

一般来说,启用夹紧并将近夹推出比选择绝对最小的近夹要好。

最新更新