Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable rendering with unbounded far distance #99986

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

Flarkk
Copy link
Contributor

@Flarkk Flarkk commented Dec 3, 2024

This PR allows rendering with unlimited camera zfar - or rather limited by the sole floating point range i.e. ~3.4e+38 in single precision.

This effectively untaps the potential of reverse-z depth buffer with single precision build, in all 3 renderers Forward+, Mobile and Compatibility. XR is not covered though (see notes below).

Outline

Currently zfar cannot be pushed further than barely ~1e6 times znear because of numerical precision limitations with some methods of struct Projection.
With the default znear = 0.05 this sets the maximum view distance to ~50 km.
While it's enough in most cases, it can be a hard limitation for open worlds, space games, and any very large scene.
Beyond this limit, scene rendering currently breaks and Godot starts spaming errors.

This PR removes this limitation with 3 key changes :

  • Stores the 6 frustum planes alongside the projection matrix in the rendering server's internals. Both are equivalent representations except that the former allows retrieving near/far distances and boundary points with much more accurate numerical precision
  • Restricts the use of the matrix representation to the sole cases where projections / un-projections are performed. Use the 6 planes in any other situation (typically to retrieve znear / zfar, get boundary points, etc...)
  • Bundles the 6 planes representation into a new struct Frustum with a few helper methods for convenience. This avoids relying of Vector<Plane> everywhere and improves readability

This PR is in a good enough state to get first reviews. There are still a few details to be ironed out though :

  • The sky seems to mask some (but not all) far away objects - only in Compatibility and Mobile
  • Objects farther than 1e20 disappear when Occlusion culling is on

Demo : full-scale scene

large_zfar.zip

Vegetation is ~1m tall and ~10m from the observer
The terrain is 10 km large
The moon's radius is 1,700 km and is 400,000 km from the observer
The Andromeda galaxy is 152,000 light-years wide and is 2.5 million light years from the observer

image

Performance

This PR improves very slightly the frame process time of an empty scene by ~ 0.5%.
This is likely due to the significant number of planes retrieval operations avoided by the fact the 6 planes are already made available.

Before After
Capture d’écran du 2024-12-06 13-16-21 Capture d’écran du 2024-12-06 12-56-13

Notes

  • XR is left unchanged for now because this would require the XR APIs to return frustum planes in addition to the projection matrix. This may be the subject of another PR
  • I spent a considerable amount of time making sure all effects work with large zfar. Some require additional PRs to be merged.
    Test project for effects : effects.zip (make sure to preview the large znear camera in each scene)
Effects Works with large zfar Issue
Bokeh DOF ✔️ with #99755
SSR ✔️ with #99693
SSIL ✔️
SSAO ✔️
Sky ✔️ Sometimes hides far away objects in Compatibility and Mobile ?
Shadows ✔️
SDFGI Crash with zfar or znear > ~1e+20 : #99967
SSS ✔️ with #99755
Fog ✔️

Closes godotengine/godot-proposals#10515
Closes #55070
Supersedes #95944

@Flarkk Flarkk requested review from a team as code owners December 3, 2024 21:43
core/math/frustum.cpp Show resolved Hide resolved
core/math/frustum.cpp Show resolved Hide resolved
core/math/frustum.cpp Show resolved Hide resolved
core/math/frustum.cpp Show resolved Hide resolved
core/math/frustum.cpp Show resolved Hide resolved
core/math/frustum.cpp Show resolved Hide resolved
core/math/frustum.cpp Show resolved Hide resolved
core/math/frustum.cpp Show resolved Hide resolved
core/math/frustum.cpp Show resolved Hide resolved
core/math/projection.cpp Show resolved Hide resolved
@Flarkk
Copy link
Contributor Author

Flarkk commented Dec 4, 2024

Rebased and fixed style issues to allow CI to run.

@Flarkk Flarkk force-pushed the large_zfar branch 3 times, most recently from 06693c1 to b8eda47 Compare December 4, 2024 09:09
@Mickeon Mickeon added this to the 4.x milestone Dec 4, 2024
@Flarkk Flarkk changed the title Unbound camera zfar for scene rendering Enable rendering with unbounded far distance Dec 5, 2024
@Flarkk
Copy link
Contributor Author

Flarkk commented Dec 9, 2024

Rebased on top of #99974

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
3 participants