Implement multi-layer projection camera#116424
Implement multi-layer projection camera#116424BastiaanOlij wants to merge 1 commit intogodotengine:masterfrom
Conversation
|
Note for testing, you can use https://github.com/godotengine/godot-demo-projects/tree/master/xr/mobile_vr_interface_demo to test stereoscopic functionality. I'm also working on this little demo project that lets you play with various projections and see whats going on: |
|
cc @huwpascoe, finally getting around to doing my version of this. I'm far from finished and have still to go through issues I flagged on your original PR. we'll see where we get to ;) |
5d167e7 to
d7ba5e0
Compare
|
I've implemented I also need to rebase this because I think I'm on the faulty Vulkan build where the fallback code causes issues. So for now testing with OpenXR should be done with compatibility (Mobile VR is fine). I haven't looked into the needed changes for @dsnopek @m4gr3d might be good to already have a look at the OpenXR changes. @celyk it would be good to see if the way I've got combined frustum working solved our shadow shaking issue as we're now working off of the actual view pose instead of calculating it back from the individual eye poses. |
1a9e370 to
09d488c
Compare
Tested with the MobileVRInterface and it does seem to fix #84510 for XR, the jitter is gone. This is consistent with our findings, but remember that I can still reproduce the issue with a Camera3D under certain conditions. I've also tried setting the projection matrix of a Camera3D and that works nicely so far. Will get back to you with further testing of that feature, especially for XR portals and mirrors that I am a big fan of. |
Owh I definitely think there is more going on but this PR does fix the stability issue with how the combined frustum is calculated, which is being used to determine the center point of the shadow cascades. In the old solution it's actually some distance behind the head where the two eye frustums meet. |
09d488c to
f198260
Compare
|
I took some time to improve the test project I made, which can now be found here: I purposefully added a few things that I knew are broken as we only work around them when stereo rendering is enabled: The main one that is immediately obvious is SDFGI, where things are offset. These are all variations around unprojecting screen coordinates through an optimisation which does not work for asymmetrical projection matrices. So the next step is to find all the effected places and instead of checking for stereo, checking for asymmetrical projections. This will likely solve many other use cases that have previously prevented us from offering more freedom around projection matrices. |
d03cfa5 to
1023bde
Compare
|
The more I think about this, the more this is a problem. The unprojection in our current stereoscopic implementation works because we add our camera offset later and keep that transform. When doing a full unproject, your vertex position is in relation to the center position of the players head, and to get the actual unprojected value we need, we add the offset back in. If we just have a projection matrix with the eye offset (which can also include a rotation), but we don't have the offset transform, we're missing a vital ingredient. Now the new API allows us to both provide the projection matrix and the offset, and applies the offset inside of the rendering engine, I'm wondering if we should make a limitation that we only accept projection matrices where This would greatly reduce the risk of projection matrices being introduced that break. |
1023bde to
605005e
Compare
3921b1a to
f848572
Compare
5d6e10a to
ae541b6
Compare
d43b541 to
312f498
Compare
76bac8e to
8d70498
Compare
dsnopek
left a comment
There was a problem hiding this comment.
Overall, this looks amazing! Most of my notes are on the verge of nitpicking :-)
I've tested this with OpenXR on Linux via WiVRn and on Android (Meta Quest 3 and Samsung Galaxy XR). I've also tested WebXR in the Meta browser (Quest 3). Both seemed to work fine!
8d70498 to
4b2d096
Compare
4b2d096 to
cdbabc6
Compare
There was a problem hiding this comment.
Thanks!
The code is looking great to me from the perspective of XR and rendering, and it's working fine in my testing
It sounds like there may need to be some changes based on @lawnjelly's note regarding physics interpolation, but aside from that, IMO this is ready to go :-)
devloglogan
left a comment
There was a problem hiding this comment.
Tested this PR a fair bit and I wasn't bumping into anything unexpected. Explored @BastiaanOlij's projections test project, the mobile vr interface demo, as well as looked at some XR sample projects on Meta Quest 3 and Galaxy XR, as well as a recent XR jam project. It all appeared to be working correctly. 🙂
cdbabc6 to
c80bd1c
Compare
c80bd1c to
b56ca02
Compare









This PR implements a new projection camera mode that allows setting projections per eye/view/layer and removes the override code deep within the renderer targeted at XR use cases.
The change is meant to be transparent for the end user who configures cameras as before.
This also creates a method for developers to set any projection matrix by overriding the projection set by the built-in logic (a long outstanding wish for which many PRs have been risen before).
For XR specifically this attempts to unlock use cases such as:
Enhancements for future PRs:
XRServerobsolete as normal transform progression is now used. We should remove this in due time.RenderingServer.camera_set_perspective,RenderingServer.camera_set_orthogonal, andRenderingServer.camera_set_frustumin favour of callingRenderingServer.camera_set_projectionsdirectly fromCamera3D. This does requireCamera3Dfrom receiving a signal when it's parent viewport changes size as this will change the aspect ratio. The added advantage of doing so is that we don't calculate our projection matrix every frame, and we can thus improve logic within the rendering engine to only recalculate things if the projection matrix actually changes.RenderingServer.camera_set_projectionsless frequently as it's likely our projection matrices remain unchanged. Only when eye tracking is used it's possible (though still unlikely) there are adjustments that need to be made to the projection matrices per frame.BaseCamera3Dclass thatCamera3DandXRCamera3Dsubclass and allows for additional custom cameras to be implemented (via GDExtension).Important
With the removal of the camera override logic from the rendering engine, we are now determining
XR camera positioning slightly earlier in the frame render loop.
With all XR runtimes always performing a slight reprojection to correct for any tiny tracking differences
we feel that the pro's far out weigh the con's here.
Important
Deprecating
get_transform_for_viewandget_projection_for_viewin favour ofget_camera_offsetsandget_camera_projectionsis a breaking change forXRInterfaces implemented in extensions.These will need to be updated. While I'm thinking about adding a fallback, we still have a problem for especially TiltFive where we use a rather dirty workaround that won't work, while our changes here allow our TiltFive external to do things properly.
Implemented on top of #115799 (merged) ,#116752 (merged) and #117619
Implements part of godotengine/godot-proposals#4932