Skip to content

fixed far plane intersection test for fogvolumes#24220

Open
JeroenHoogers wants to merge 1 commit into
bevyengine:mainfrom
JeroenHoogers:fix-fog-volume-backplane-intersection-tests
Open

fixed far plane intersection test for fogvolumes#24220
JeroenHoogers wants to merge 1 commit into
bevyengine:mainfrom
JeroenHoogers:fix-fog-volume-backplane-intersection-tests

Conversation

@JeroenHoogers
Copy link
Copy Markdown
Contributor

Objective

Fixes #22574

Solution

The previous code assumed there are only 3 back faces visible at any time for the FogVolume. This assumption is incorrect and breaks in some instances: e.g. when the camera is looking head-on at one of the faces of a cube. Depending on the distance and size of the cube, 5 back faces will be visible.

The solution is to consider all visible back faces for testing in the shader.

Testing

Tested with this command and on another test scene without atmospherics (see showcase)
cargo run -r --example atmosphere --features free_camera


Showcase

Before:

screenrecording-2026-05-09_19-52-43.mp4

After:

screenrecording-2026-05-09_19-51-07.mp4

@kfc35 kfc35 added A-Rendering Drawing game state to the screen S-Needs-Review Needs reviewer attention (from anyone!) to move forward labels May 9, 2026
@github-project-automation github-project-automation Bot moved this to Needs SME Triage in Rendering May 9, 2026
@kfc35 kfc35 added C-Bug An unexpected or incorrect behavior D-Straightforward Simple bug fixes and API improvements, docs, test and examples labels May 9, 2026
Copy link
Copy Markdown
Contributor

@kfc35 kfc35 left a comment

Choose a reason for hiding this comment

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

The math makes sense to me

And I’ve verified the fix in the atmosphere example with free camera enabled

I suggest adding documentation about far_planes for why its of length 6 (greater than length 3) and that it’s padded with vec’s of zeros if there are less than the max of 6

@@ -144,10 +144,13 @@ fn fragment(@builtin(position) position: vec4<f32>) -> @location(0) vec4<f32> {
// Calculate the end position of the ray. This requires us to raytrace the
// three back faces of the AABB to find the one that our ray intersects.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
// three back faces of the AABB to find the one that our ray intersects.
// back faces of the AABB to find the one that our ray intersects.

/// plane and Q is any point in it, in view space. The equation of the plane
/// for homogeneous point P = (Px, Py, Pz, Pw) is V⋅P = 0.
far_planes: [Vec4; 3],
far_planes: [Vec4; 6],
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Is it possible for this to be 6? The PR description seems to imply the max is 5, and that seems like a correct assumption to make, but 🤷 considering the assumption of 3 far planes was wrong before, I’m not going to advocate for this to be lowered.

However, I do think a doc comment would be useful in describing why this number is greater than 3 now, which some people might expect, or that the extra planes will be appended as Vec4::Zero

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good point, I initially implemented it with 5 as the max, but I noticed when the camera moves inside the fog volume the plane_coords.w <= 0.0 test doesn't filter any planes since they all face the camera, meaning the (NEG_Z) plane would disappear. I could solve this by filtering based on a dot product between the eye vector and the plane normal instead, however, I thought the current implementation was a bit nicer / cleaner for a few reasons:

  • Works correctly for FoV > 90 degrees
  • 6 is the total number of planes (no more assumptions based on specific cases)
  • Implementation is slightly faster / simpler. I don't have to pass / compute the eye vector and I don't have to perform additional math (on CPU)

@ChristopherBiscardi ChristopherBiscardi added S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it and removed S-Needs-Review Needs reviewer attention (from anyone!) to move forward labels May 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-Rendering Drawing game state to the screen C-Bug An unexpected or incorrect behavior D-Straightforward Simple bug fixes and API improvements, docs, test and examples S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it

Projects

Status: Needs SME Triage

Development

Successfully merging this pull request may close these issues.

FogVolume is glitchy at distances and certain angles on example.

3 participants