Skip to content

Fix reflection probes working in stereo on compatibility renderer#102447

Open
BastiaanOlij wants to merge 1 commit into
godotengine:masterfrom
BastiaanOlij:fix_reflection_stereo
Open

Fix reflection probes working in stereo on compatibility renderer#102447
BastiaanOlij wants to merge 1 commit into
godotengine:masterfrom
BastiaanOlij:fix_reflection_stereo

Conversation

@BastiaanOlij
Copy link
Copy Markdown
Contributor

When rendering in stereo we do not do our right-side-up rendering of the main buffer. There seems to be a condition where our culling direction remains reversed which stopped the cubemap filter from working and copying the final mipmap results of the reflection probe leaving the contents of the reflection probe empty.

Disabling culling before performing the cubemap filter ensures we always perform the process.

Note that when the reflection probe is set to once, it can take over 6 frames before the reflection probe is populated with data as we render one side of the reflection probe per frame to save performance. So for the first 6 to 15 frames the reflection probe still remains black in the MRP supplied on the bug report causing the pillars to not be lit up correctly.

Fixes #102443

@BastiaanOlij BastiaanOlij self-assigned this Feb 5, 2025
@AThousandShips AThousandShips added this to the 4.4 milestone Feb 5, 2025
@BastiaanOlij BastiaanOlij marked this pull request as ready for review February 6, 2025 02:24
@BastiaanOlij BastiaanOlij requested a review from a team as a code owner February 6, 2025 02:24
@Calinou
Copy link
Copy Markdown
Member

Calinou commented Feb 6, 2025

Note that when the reflection probe is set to once, it can take over 6 frames before the reflection probe is populated with data as we render one side of the reflection probe per frame to save performance. So for the first 6 to 15 frames the reflection probe still remains black in the MRP supplied on the bug report causing the pillars to not be lit up correctly.

See #97773, which could be amended to initially render reflection probes in a single frame while the scene is loading or being switched for another scene.

Copy link
Copy Markdown

@Eisenspalter Eisenspalter left a comment

Choose a reason for hiding this comment

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

Looks good

@Repiteo Repiteo modified the milestones: 4.4, 4.5 Feb 24, 2025
}

void CubemapFilter::filter_radiance(GLuint p_source_cubemap, GLuint p_dest_cubemap, GLuint p_dest_framebuffer, int p_source_size, int p_mipmap_count, int p_layer) {
glDisable(GL_CULL_FACE);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
glDisable(GL_CULL_FACE);
glDisable(GL_CULL_FACE);
scene_state.cull_mode = RS::CULL_MODE_DISABLED;

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.

@clayjohn I just had a check at this, scene_state is not exposed to any of the effects, and none of the other effects respect the scene state.

We really need to introduce a new object that keeps track of the global OpenGL state that we can access from different areas of compatibility renderer and remove this logic from scene state. But that goes a little beyond the scope of this PR.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I guess the shortest path forward is to move the change outside of this function and into the calling code. Otherwise it will break the scene shader

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.

Thing is, we do this stuff everywhere already. I think that is why we keep having issues like these popup at the strangest times. OpenGLs global state sucks :)

@clayjohn clayjohn added the cherrypick:4.4 Considered for cherry-picking into a future 4.4.x release label Feb 27, 2025
@akien-mga akien-mga requested a review from clayjohn March 13, 2025 22:55
@Repiteo Repiteo modified the milestones: 4.5, 4.6 Aug 4, 2025
@AThousandShips AThousandShips added the cherrypick:4.5 Considered for cherry-picking into a future 4.5.x release label Oct 20, 2025
@graywes
Copy link
Copy Markdown

graywes commented Dec 11, 2025

is this gonna be added? this seems like a pretty big issue

@BastiaanOlij
Copy link
Copy Markdown
Contributor Author

is this gonna be added? this seems like a pretty big issue

So far I haven't been able to reproduce the issue anymore. Seeing this is global state that is set wrong, the issue appears, or disappears depending on how the previous process leaves the global state. Probably another change in the engine has left the global state such that reflection probes now work. And sadly, its not unlikely as we enhance the engine, that this gets changed again in a way that breaks stuff which is why many effects just set the entire state the way they want, even if its already set correctly, and accept the overhead that brings.

The real solution here is the one @clayjohn suggested originally but that is a fairly big rewrite to move, and complete, the code that manages the global state into an object (as it is not accessible from effect/environment code in its current state). Not something we want to do in feature freeze, and something that has a high potential of breaking something unintentionally.

I've been wanting to tackle this for some time, just haven't worked up the courage to actually do it.

Anyway, long story short is that by the testing I did last time I looked into this, this was working fine. The only issue left is the 6 frame delay for full dynamic reflection probes but that is due to us spreading out the workload over 6 frames.

@RumarioVR
Copy link
Copy Markdown

I just tested this again with Godot 4.6.rc1 and the Compatibility Renderer. Same behavior. The Reflection Probe doesn't work on the Quest (PCVR works).

@Repiteo Repiteo modified the milestones: 4.6, 4.x Jan 25, 2026
@Repiteo Repiteo removed cherrypick:4.4 Considered for cherry-picking into a future 4.4.x release cherrypick:4.5 Considered for cherry-picking into a future 4.5.x release labels May 18, 2026
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.

Reflection Probe not working in stereo (Compatibility)

8 participants