如何有条理地选择透视投影的近剪裁平面距离?

发布于 2024-12-15 05:40:36 字数 326 浏览 2 评论 0原文

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

我如何选择最远的近裁剪平面(以获得最佳深度缓冲区分辨率),无论玩家如何移动和看起来,都不会导致任何裁剪

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

I have a 3D scene and a camera defined using gluPerspective. I have a fixed FOV, and I know the minimum distance of any geometry to the camera (it is a first-person view, so that is the minimum distance from the viewpoint to the character's collision volume).

How can I choose the farthest near clip plane (for the best depth buffer resolution) which will will not cause any clipping, no matter how the player moves and looks?

These distances are not simply equal because the corners of the near plane are farther from the origin than the center.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

挽心 2024-12-22 05:40:36

公式:

nearPlane = 最近的ApproachToPlayer / 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

FOV 确定金字塔高度轴边的斜率:

斜率 = tan(fov/2)

h/nearPlane = 2 tan(fov/2)

h/2 = nearPlane tan(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 + (h/2) 2 + 近平面2)

应用简单的代数可得出上面给出的公式。

我没有检查我的代数,但我凭经验测试了这个公式:如果我将nearPlane乘以1.1,那么它会产生一个对于各种纵横比来说有点太远的剪裁平面。我还没有尝试过 60° 以外的不同 FOV。

Formula:

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

JavaScript code:

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

Derivation:

Geometrically, consider the pyramid whose base is the near clip plane and tip is the origin. Let nearPlane be the height of the pyramid, and w and h the width and height of the pyramid's base.

w = aspectRatio · h

The FOV determines the slope of the height-axis sides of the pyramid:

slope = tan(fov/2)

h/nearPlane = 2 tan(fov/2)

h/2 = nearPlane tan(fov/2)

Any corner point of the near clip plane is offset from the center of the clip plane by (w/2, h/2), so the distance is sqrt((w/2)2 + (h/2)2). The distance from the origin of this corner point is the hypotenuse of the right triangle formed by nearPlane and the former distance, so is sqrt((w/2)2 + (h/2)2 + nearPlane2).

We want that distance to the corner point to be equal to the closest approach of any geometry.

nearestApproachToPlayer = sqrt((w/2)2 + (h/2)2 + nearPlane2)

Applying straightforward algebra produces the formula given above.

I have not checked my algebra, but I have empirically tested the formula: if I multiply nearPlane by 1.1, then it produces a clip plane which is just a bit too far, for various aspect ratios. I have not tried different FOVs than 60°.

时光是把杀猪刀 2024-12-22 05:40:36

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

大多数 3D 应用程序用于透视变换的标准平截头体投影是平行平面投影。这意味着从视点确定平面距离。这实际上相当简单:

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

The best practice for choosing the near and far clip distances is to have them snugly envelope the scene, i.e. the near clip plane as far as possible and the far clip plane as near as possible.

The standard frustum projection employed by the majority of 3D applications for a perspective transformation is a parallel plane projection. That means determining the planar distance from the point of view. This is actually rather easy:

One of the parameters you'll carry around in a 3D rendering program is the view vector, i.e. the direction the camera points to. Say you have this vector normalized (i.e. unit length), then taking the scalar (=dot) product with the objects positions gives you the planar distance to the origin. This is a more direct approach, as it gives you the desired value directly, without the need for a squares, square root, and divides. It's only multiply-sum, i.e. MAD instructions, which are directly supported by SIMD instruction sets.

柳絮泡泡 2024-12-22 05:40:36

如何选择最远的近裁剪平面(以获得最佳深度缓冲区分辨率),无论玩家如何移动和看起来如何,都不会导致任何裁剪?

简单:关闭近剪裁。我不敢相信人们还没有听说过这个。您启用深度钳制,这会导致小于近(或大于远)的近(和远)值被钳制,而不是剪裁。

但这并不能阻止实际位于相机后面的对象被剪裁。由于深度被钳制,因此对于发生钳制的那些区域,您将失去深度缓冲区的效用。如果您无法选择距离太远的近剪辑,那么在合理的情况下使用它仍然是一个好主意。

通常,启用夹紧并将近剪辑推出比选择绝对最小近剪辑更好。

How can I choose the farthest near clip plane (for the best depth buffer resolution) which will will not cause any clipping, no matter how the player moves and looks?

Simple: turn off near clipping. I can't believe that people haven't heard of this yet. You enable depth clamping, which causes near (and far) values that are less than the near (or greater than the far) to be clamped, rather than clipped.

This won't prevent objects that actually go behind the camera from being clipped though. And since the depths are clamped, you lose the utility of a depth buffer for those regions where clamping occurs. It's still a good idea to use it where reasonable, if you can't choose a near clip that's too far away otherwise.

It's generally better to enable clamping and push the near clip out than it is to pick the absolute minimum near clip.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文