You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A space settled 3D game where both very far away celestial bodies and closer objects (terrains, spaceships ...) are rendered at the same time.
Describe the problem or limitation you are having in your project
I need both a normal near plane distance (say 5e-2) and a far plane very far away (say 1e18, or even INF).
When near and far planes are apart from each other of an order of magnitude greater than ~1e7, an error is raised at culling and the scene doesn't render.
Worth noting that now Reverse z-buffer is a reality, it opens the door in theory to rendering such deep scenes without z-fighting (especially when objects are spaced and sized exponentially, like stars, planets and ground objects), and without having to rely on heavier solutions like rendering in multiple passes or multiple cameras.
In detail, when near and far places are set very far apart, the projection matrix generated rounds to an infinite projection matrix (see slide 7) due to numerical precision effects.
At scene culling stage, the 6 clipping plans are extracted from the matrix following the popular Ggribb's method (see Projection::get_projection_planes(). This yields by construction a zero vector for the far plane normal when the projection matrix is infinite.
This zero vector raises an error later during the light culling preparation.
Describe the feature / enhancement and how it helps to overcome the problem or limitation
Support infinite far planes on Camera3D in PROJECTION_PERSPECTIVE, PROJECTION_FRUSTUM and PROJECTION_ORTHOGONAL modes.
This should be supported for both scene culling and geometry projection.
Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams
Because the near and far distances are used for both scene culling and geometry projection, they are 2 potential changes to consider :
Default to infinite projection matrix for geometry projection
There is some litterature on the fact that combining infinite projection with reverse-z doesn't degrade numerical error rates, even with scenes where geometry is not far away (see this one : https://developer.nvidia.com/content/depth-precision-visualized and that one : https://www.reedbeta.com/blog/depth-precision-visualized/).
In practice, this would mean that for PROJECTION_PERSPECTIVE, PROJECTION_FRUSTUM and PROJECTION_ORTHOGONAL, the far distance value provided by the user is ignored and an infinite projection matrix is generated regardless.
Allow ignoring far distance for scene culling
There could be a new boolean attribute on Camera3D to allow the user to toggle it on/off.
When toggled on, Projection::get_projection_planes() could branch and generate an adequate normal and distance-to-origin for the far plane.
I tested this scrappy implementation and at first sight it seems to work :
///////--- Far Plane ---///////if (ignore_far_plane_for_culling) {
/* Take the opposite of the near plane's normal. Assumption is made they're parallel. As godot currently doesn't allow the user to build the projection matrix from scratch, there shouldn't be any edge case */
new_plane.normal = -planes[0].normal;
new_plane.d = INFINITY; // distance is infinity
} else {
new_plane = Plane(matrix[3] - matrix[2],
matrix[7] - matrix[6],
matrix[11] - matrix[10],
matrix[15] - matrix[14]);
new_plane.normal = -new_plane.normal;
new_plane.normalize();
}
planes.write[1] = p_transform.xform(new_plane);
Alternatively, if we don't want to go down the route of defaulting to infinite projection, there could be additional projection modes added to Camera3D, say PROJECTION_PERSPECTIVE_INFINITE, PROJECTION_FRUSTUM_INFINITE and PROJECTION_ORTHOGONAL_INFINITE, that would trigger both changes above.
If this enhancement will not be used often, can it be worked around with a few lines of script?
No, it's core
Is there a reason why this should be core and not an add-on in the asset library?
Culling and projection are core.
The text was updated successfully, but these errors were encountered:
Flarkk
changed the title
Infinite projection matrices support
Infinite projection matrix support
Aug 21, 2024
Alternatively, if we don't want to go down the route of defaulting to infinite projection, there could be an additional projection mode added to Camera3D, say PROJECTION_PERSPECTIVE_INFINITE, that would trigger both changes above.
What about the Orthogonal and Frustum modes? It seems these could support an infinite far distance too.
Describe the project you are working on
A space settled 3D game where both very far away celestial bodies and closer objects (terrains, spaceships ...) are rendered at the same time.
Describe the problem or limitation you are having in your project
I need both a normal near plane distance (say 5e-2) and a far plane very far away (say 1e18, or even INF).
When near and far planes are apart from each other of an order of magnitude greater than ~1e7, an error is raised at culling and the scene doesn't render.
Worth noting that now Reverse z-buffer is a reality, it opens the door in theory to rendering such deep scenes without z-fighting (especially when objects are spaced and sized exponentially, like stars, planets and ground objects), and without having to rely on heavier solutions like rendering in multiple passes or multiple cameras.
In detail, when near and far places are set very far apart, the projection matrix generated rounds to an infinite projection matrix (see slide 7) due to numerical precision effects.
At scene culling stage, the 6 clipping plans are extracted from the matrix following the popular Ggribb's method (see
Projection::get_projection_planes()
. This yields by construction a zero vector for the far plane normal when the projection matrix is infinite.This zero vector raises an error later during the light culling preparation.
Describe the feature / enhancement and how it helps to overcome the problem or limitation
Support infinite far planes on
Camera3D
inPROJECTION_PERSPECTIVE
,PROJECTION_FRUSTUM
andPROJECTION_ORTHOGONAL
modes.This should be supported for both scene culling and geometry projection.
Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams
Because the near and far distances are used for both scene culling and geometry projection, they are 2 potential changes to consider :
Default to infinite projection matrix for geometry projection
There is some litterature on the fact that combining infinite projection with reverse-z doesn't degrade numerical error rates, even with scenes where geometry is not far away (see this one : https://developer.nvidia.com/content/depth-precision-visualized and that one : https://www.reedbeta.com/blog/depth-precision-visualized/).
In practice, this would mean that for
PROJECTION_PERSPECTIVE
,PROJECTION_FRUSTUM
andPROJECTION_ORTHOGONAL
, the far distance value provided by the user is ignored and an infinite projection matrix is generated regardless.Allow ignoring far distance for scene culling
There could be a new boolean attribute on
Camera3D
to allow the user to toggle it on/off.When toggled on,
Projection::get_projection_planes()
could branch and generate an adequate normal and distance-to-origin for the far plane.I tested this scrappy implementation and at first sight it seems to work :
Alternatively, if we don't want to go down the route of defaulting to infinite projection, there could be additional projection modes added to
Camera3D
, sayPROJECTION_PERSPECTIVE_INFINITE
,PROJECTION_FRUSTUM_INFINITE
andPROJECTION_ORTHOGONAL_INFINITE
, that would trigger both changes above.If this enhancement will not be used often, can it be worked around with a few lines of script?
No, it's core
Is there a reason why this should be core and not an add-on in the asset library?
Culling and projection are core.
The text was updated successfully, but these errors were encountered: