-
-
Notifications
You must be signed in to change notification settings - Fork 21.9k
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 Frustum Sky projection translation logic shearing #86138
Conversation
FYI I added the commit hooks to my local system before the second commit, it should be all good now. I rebased as recommended to bury my bad commits. |
servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp
Outdated
Show resolved
Hide resolved
servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp
Outdated
Show resolved
Hide resolved
5cd57e8
to
2cad084
Compare
There was a problem hiding this 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. The fix makes sense to me, although it would benefit from a second look just to make sure.
simplescreenrecorder-2023-12-15_14.26.20.mp4
Updated again, please keep me posted if I can do anything to help expedite. |
Hey, We've reviewed this PR and we're a bit concerned by the double flipping of projection and view matrix. Specifically, this could work only in your usecase (where you have a horizonatal reflection plane). This PR needs more testing to make sure it's not working only for this specific usecase. |
Happy to talk through the concern. By double flip do you mean changing the projection matrix and the transform or a further up the chain operation in the render flow? The truth is I dont know why the sky is drawn as it is, I assumed it was to do with the frustrum being flipped intentionally in engine to be inside the skybox. I have not hacked the basis of the camera for my water surface, the mirror I use can rotate on any axis and correctly draw the sky so long as I relect my current camera's transform AND correct for the transform flaw included in this PR. You can completely ignore mirrors and focus on the frustrum camera with skybox sample stand alone. The attached minimum replication project should be sufficient to demo the solution and prove it is agnostic of any reflections. If any of the other axis were out of alignment @Calinou's video would show unexpected rotation about another axis as the pitch and yaw changes (only roll isn't really in the demo, it was tested), the rotation of the camera about the origin shows a correction to the basis of the frustrum transform. I hope that helps but again im very happy to give more info. |
Here is evidence that you can yaw, pitch and roll the camera and have the frustrum sky draw correctly @Calinou's video is a better overall demo I didn't have a lot of time to record something after recompiling, this is done in Compatibility mode but I tested it in Mobile + Forward: Please note that the camera in the test sample is a bit crappy but which is why I decided to rotate the thing in the editor to make the rendering accuracy clear. |
@EnlightenedOne What would be beneficial is explaining why flipping the y-axis in both the projection and view matrices is necessary for the frustum offset camera. Intuitively, it doesn't really make sense. I think there is a good chance that this just happens to fix the problem for this MRP rather than being the correct solution. |
It is possible that the solution is suboptimal (might be an easier fix for to the matrix), I assume the components are internally consistent. The MRP for this is Godot's sky solution + frustrum cam with y offset, No scenario exists where the fix can fail as the scope is limited to that. We are not trying to invert the image but invert the rotational influence to align the way the sky is setup with the way the frustrum is calculated. The transform scale inversion flips the rotational view data on the axis which is where the two are out of sync and the projection inversion reflips the image so the sky is drawn the right way up (trying to get to frustrum orientation to sky orientation). I guess you are asking 'why' they are not aligned on this axis. I will dig some more and see if I can qualify it better. |
I spent some time wondering where between the frustum offset and the sky rendering things get messed up. As I understand it the sky in Godot is in a nutshell upside down. In the frustum projection creation one of the cells infers an up direction for the offset: Based on projection math here https://songho.ca/opengl/gl_projectionmatrix.html So the solve is simply to flip that field: sky.setup_sky... |
8412b64
to
8bbc6c2
Compare
Additional FYI I did look into getting rid of the flag for Frustum camera and flipping the projection matrix for all projections but it seemed pretty dangerous and might bite later on if you expose projection matricies to end users or add new custom projection options. My view is this is as good as the solution can be unless the sky gets flipped later. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We discussed this in today's rendering meeting. The approach makes sense now, thank you for looking into this further.
From the look of the code, it seems like the flip could be done when the matrix is created since it is always enabled when using frustum offset. Is there a good reason to apply the flip each frame when drawing instead of just applying it when creating the projection matrix? Doing so seems more foolproof.
@clayjohn the projection matrix is shared between the regular right way up rendering and the sky rendering which is upside down. If we flip it earlier the problem will be inverted, the sky will move correctly and every other thing will move with inverted y coords. It looks like it would go against the grain of Godot's render setup to have a separate projection matrix just for the sky but I am open to suggestions. |
Hi @clayjohn I ran an experiment with the recommended changes and several permutations tweaking the sky glsl + environment/sky.cpp to try and make it draw the same way up as the rest of the scene: I cleared the projects shader cache between tests. The view frustum was corrected offset wise in the frustum but the sky rendering inverted/mirrrored the sun to the opposite position relative to the sky. The main perspective cameras view of the sky was completely broken with these changes such that the sky was both upside down and offset incorrectly relative to the angle of the camera such that the sky triangle became visible. I tried a bunch of permutations but you would have to cut deeper to fix this is my view.
Thanks, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@EnlightenedOne Thank you for trying. I suspect that we are on the right track with the changes we discussed last night. But indeed, the problem is wrapped up in how we inconsistently use the y-flip.
Let's go ahead with this for now, despite it being a bit hacky as I think we all agree that it is a fix even if its not the best one. Then we can remove this once we clean up the y-flip handling.
That sounds good, any other things necessary for this to be merged? |
Nope! It's in the queue to be merged next time we do a batch |
Projection projection = render_data.cam_projection; | ||
if (is_reflection_probe) { | ||
Projection correction; | ||
correction.columns[1][1] = -1.0; | ||
projection = correction * render_data.cam_projection; | ||
} else if (render_data.cam_frustum) { | ||
// Sky is drawn upside down, the frustum offset doesn't know the image is upside down so needs a flip |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// Sky is drawn upside down, the frustum offset doesn't know the image is upside down so needs a flip | |
// Sky is drawn upside down, the frustum offset doesn't know the image is upside down so needs a flip. |
Per the comment style.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
sky.setup_sky(p_render_data->environment, rb, *p_render_data->lights, p_render_data->camera_attributes, p_render_data->scene_data->view_count, p_render_data->scene_data->view_projection, p_render_data->scene_data->view_eye_offset, p_render_data->scene_data->cam_transform, p_render_data->scene_data->cam_projection, screen_size, p_render_data->scene_data->taa_jitter, this); | ||
Projection projection = p_render_data->scene_data->cam_projection; | ||
if (p_render_data->scene_data->cam_frustum) { | ||
// Sky is drawn upside down, the frustum offset doesn't know the image is upside down so needs a flip |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// Sky is drawn upside down, the frustum offset doesn't know the image is upside down so needs a flip | |
// Sky is drawn upside down, the frustum offset doesn't know the image is upside down so needs a flip. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
sky.setup_sky(p_render_data->environment, p_render_data->render_buffers, *p_render_data->lights, p_render_data->camera_attributes, p_render_data->scene_data->view_count, p_render_data->scene_data->view_projection, p_render_data->scene_data->view_eye_offset, p_render_data->scene_data->cam_transform, p_render_data->scene_data->cam_projection, screen_size, p_render_data->scene_data->taa_jitter, this); | ||
Projection projection = p_render_data->scene_data->cam_projection; | ||
if (p_render_data->scene_data->cam_frustum) { | ||
// Sky is drawn upside down, the frustum offset doesn't know the image is upside down so needs a flip |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// Sky is drawn upside down, the frustum offset doesn't know the image is upside down so needs a flip | |
// Sky is drawn upside down, the frustum offset doesn't know the image is upside down so needs a flip. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
bool flip_y = false; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unrelated, please restore as it helps readability
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you, done
8bbc6c2
to
1d141ab
Compare
Thanks! Congratulations on your first contribution! 🎉 |
Thank you, it is contribution 2, fix 3 but I am very pleased to have this one in! |
Found a bug dealing with frustum sky in planar reflections.
Identified that camera frustum was responsible and that existing defect had been created.
Tested using MRP on the bug ticket fix works for compatibility/mobile/forward+.
The fix is based on how reflection probes work and aims to be lightest touch.
Tests passing but no new unit tests written.
Extra bonus picture (the floor clouds are Frustum projected):


Angle shot showing sky has moved as expected from MRP
Fixes #63863 .