Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I methodically choose the near clip plane distance for a perspective projection?

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.

like image 979
Kevin Reid Avatar asked Nov 11 '11 23:11

Kevin Reid


People also ask

What is near clipping plane?

The near clipping plane is nearest point of the Camera's view frustum. The Camera cannot see geometry that is closer this distance. For more information, see Understanding the view frustum. In the Unity Editor, this corresponds to the Clipping Planes: Near property in the Camera component Inspector.

What are clipping distances?

Near clipping distance and far clipping distance refer to the near and far plane of the viewing frustum. Anything closer to the eye than the near clipping distance isn't displayed (it's too close), and anything further away from the eye than the far clipping distance isn't displayed either (it's too far away).

Does perspective projection preserve angles?

Unlike the orthographic projection, the perspective projection doesn't preserve distances or angles, and parallel lines no longer remain parallel. The perspective projection is a reasonably close match to how an eye or camera lens generates images of the 3D world.


1 Answers

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°.

like image 176
Kevin Reid Avatar answered Oct 02 '22 14:10

Kevin Reid