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

Fix Occlusion Culling Buffer occasionally getting corrupted. #98758

Merged
merged 1 commit into from
Nov 10, 2024

Conversation

Rudolph-B
Copy link
Contributor

Fixes #98756

The issue was caused by an inverse matrix operation (p_cam_projection.inverse()) failing due to a determinant evaluating to 0 under certain circumstances. The underlying implementation uses Math::is_zero_approx(), which checks for values less than 1e-5. Using 1e-7 also fixed the issue but could have unintended consequences, as both inverse() and is_zero_approx() are used throughout the codebase. For reference, a previous discussion can be found at #58507.

The provided solution sidesteps this issue by simplifying the math to avoid using the inverse operation altogether.

@Rudolph-B Rudolph-B requested a review from a team as a code owner November 2, 2024 10:50
@lawnjelly
Copy link
Member

Tested and seems to work fine.

Didn't look in detail at why the math broke down in the original case, but the half extents uses 3 plane intersections which should be fine with orthogonal cameras.

Copy link
Member

@Calinou Calinou left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested locally, it works as expected.

occlusion_culling_orthogonal.mp4

Perspective culling still works too.

@Repiteo Repiteo merged commit 3444611 into godotengine:master Nov 10, 2024
21 checks passed
@Repiteo
Copy link
Contributor

Repiteo commented Nov 10, 2024

Thanks!

@jamie-pate
Copy link
Contributor

jamie-pate commented Mar 15, 2025

When using OpenXR the new code produces different locations compared to the old code:

before left_corner_world (-6.465447, 1.908369, -0.349659)
after left_corner_world (-6.464384, 1.919102, -0.349172)
diff (-0.001063, -0.010733, -0.000487)

without OpenXR the numbers are much closer, but still not the same as the old code (maybe due to rounding error accumulation?):
before top_corner_world (-6.008293, 1.03659, -0.087287)
after top_corner_world (-6.009107, 1.036572, -0.088223)
diff (0.000814, 0.000018, 0.000937)
before left_corner_world (-5.915423, 0.962001, 0.02262)
after left_corner_world (-5.915436, 0.960764, 0.022656)
diff (0.000013, 0.001237, -0.000035)

Comment on lines +95 to +97
td.pixel_corner = p_cam_transform.xform(Vector3(-viewport_half.x, -viewport_half.y, -p_cam_projection.get_z_near()));
Vector3 top_corner_world = p_cam_transform.xform(Vector3(-viewport_half.x, viewport_half.y, -p_cam_projection.get_z_near()));
Vector3 left_corner_world = p_cam_transform.xform(Vector3(viewport_half.x, -viewport_half.y, -p_cam_projection.get_z_near()));

This comment was marked as resolved.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This has already been refactored the right way by #99974

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

Successfully merging this pull request may close these issues.

Occlusion Culling Buffer corrupted when zoomed out with an orthogonal camera
7 participants