-
-
Notifications
You must be signed in to change notification settings - Fork 21.8k
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
Add stereoscopic rendering through multiview #48207
Add stereoscopic rendering through multiview #48207
Conversation
909cc65
to
2fef14f
Compare
f364d64
to
1df8d27
Compare
Currently broken and just prototyping with loads of shortcuts but getting closer to it actually rendering in stereo. Its now creating the main render buffers as multiview buffers and compiling shaders with the main code hopefully properly rendering stuff in stereo. Need to figure out why it currently has a mismatch in buffers causing it to fail rendering |
1df8d27
to
9ad7787
Compare
38a5848
to
02e55fa
Compare
Why RenderDoc? Why?!? :)
|
02e55fa
to
51990fc
Compare
Working on changing things over to use texture arrays, I missed that they should be configured as such.. still not rendering properly |
51990fc
to
acc49fc
Compare
It's now rendering correctly but only when started from RenderDoc. Examining a frame from within RenderDoc I can see stereo is being applied correctly. edit looks like the issue running it without RenderDoc is related to the shaders being bound to the wrong pipeline. Multiview shaders must be bound to a multiview pipeline and normal shaders to a normal pipeline. Need to think about how to improve this. |
acc49fc
to
8958a5a
Compare
Currently stuck on this, when using a multiview shader something we are sending to As mentioned before, the weird thing is that it works when running using RenderDoc |
a30aba2
to
0eb6667
Compare
With some help from people on the Vulkan Slack I was able to solve all the validation issues and this now runs properly. Still a LOT of work to do to make everything that needs stereo support have stereo support but most of the difficult stuff is now done. Will first work on making this work on the mobile renderer too. Would be good to get some early eyes on things because this is a BIG job that touches on a lot of parts. |
servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp
Outdated
Show resolved
Hide resolved
servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp
Outdated
Show resolved
Hide resolved
Just a recap on my discussion with @reduz last night on Godot chat about the next steps. First in relation to our camera data. The plan we discussed yesterday is to change the data structure to the following:
These will be determined either at the start of This approach means that we can keep a lot of the code that doesn't need to change for stereoscopic the same and more efficiently handle things that would otherwise need to be handled for stereoscopic just to accommodate the two eye positions. The logic that combines the two frustums for clipping will initially be the implementation we currently have in Godot 3 which only works properly if the two eyes share the same near and far clipping planes. But we do need to improve on this as not all devices have that guaranteed. Second, we're going to concentrate on making the rest of the stereoscopic rendering work properly in the mobile renderer first, and then port the solution to the clustered renderer. Finally seeing this PR is getting pretty big I'm going to look at which changes could be moved to separate PRs. For instance multiview support in the driver could be a separate PR we can apply without it getting in the way of anyone. |
0c4d05e
to
e1e0830
Compare
Rebased and fixed up the I'm setting this ready for review. There is more to do around the XRInterface (for which I've started a new PR) and solving a lighting issue if the stereo camera isn't in the same plane (a future use case) but I think this is getting to a point where the work done so far needs to be evaluated and may even be ready to merge. |
e1e0830
to
2e56b05
Compare
31dabcd
to
be7a45b
Compare
@@ -656,6 +657,11 @@ void SceneShaderForwardClustered::init(RendererStorageRD *p_storage, const Strin | |||
actions.renames["CUSTOM2"] = "custom2_attrib"; | |||
actions.renames["CUSTOM3"] = "custom3_attrib"; | |||
|
|||
// not implemented but need these just in case code is in the shaders | |||
actions.renames["VIEW_INDEX"] = "0"; | |||
actions.renames["VIEW_MONO_LEFT"] = "0"; |
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.
I would kinda expect that VIEW_INDEX 0 and 1 should be enough. Also should it not be MULTIVIEW_INDEX ? I am not sure this is very useful outside multiview.
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.
VIEW_INDEX
is the actual variable, it's only 0 here because its turned off in the forward clustered, this code is only there so the compiler doesn't throw up. See the mobile implementation for the proper code.
servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp
Outdated
Show resolved
Hide resolved
servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp
Outdated
Show resolved
Hide resolved
2e131c7
to
a4fee11
Compare
a4fee11
to
15c1a76
Compare
Should be ready to merge once it passes CI |
The only problem I see to this is that its still missing the usage of the proper eye vector on each view, so reflections and specular blobs will most likely not be correct. We can add this later as a separate PR if you wish. |
Yeah let's do this as a separate PR I think, so that we can merge this and @JFonS' #48847. |
Thanks! |
godotengine/godot-proposals#2648
The idea here is too re-introduce stereoscopic rendering into Godot 4 but take a different approach to Godot 3. Instead of rendering one eye after the other we're going to provide multiple cameras to the render server and have it make the right decision. The initial implementation will be using multiview which means that all render buffer textures get an extra layer and we'll end up rendering left and right eye images in parallel with the Vulkan driver performing the duplication. This means we get stereoscopic rendering with a minimum of state changes and a minimum of changes to the render engine itself.
To support this there are a number of areas that are changing.
While we are focusing on implementing stereoscopic rendering wherever possible we're building things in a way that additional views can be supported going forward.
Adding Multiview to render device
While detection of Multiview capabilities was already merged this PR introduces further changes that enable the Vulkan implementation of Multiview. These include:
Changes to XRInterface
XRInterface
is changing to accommodate this new approach.is_stereo
is replaced withget_view_count
which return the number of views we need to supportget_camera_transform
has been added to get the center position and is used to place our node and determine our reference frame when recentering our player. This replaces callingget_transform_for_eye(EYE_MONO, ...
get_transform_for_view
replacesget_transform_for_eye
and now takes a view indexget_projection_for_view
replacesget_projection_for_eye
and now takes a view index, note that this removes the ability to call this withEYE_MONO
but as that never worked for any stereoscopic implementation and for mono applications it returns the correct projection matrix it isn't a great losscommit_eyes
replacescommit_for_eye
and is now called after rendering of both eyes is finished with a render buffer RID that contains our render result. This functions can optionally return a blit list that tells the render engine whether output to screen is required (many VR runtimes will output to the headset only).get_external_texture_for_eye
for now is deprecated. A new implementation of this will need to be introduced.Note, further changes are delegated to #49301
Changes to viewports
The
use_xr
flag (wasarvr
) has been re-enabled and will trigger the use of the primary XR interface for this viewport.use_xr
is trueget_view_count
is used to ensure the render buffer related to the viewport will contain the correct number of layersuse_xr
is trueget_transform_for_view
andget_projection_for_view
are called for each view to create the camera data send to the rendererChanges to shader compilation
Where shaders are used for stereo rendering they need to be altered to support Multiview. The changes themselves are generally minor mostly revolving around choosing a different projection matrix based on
ViewIndex
. SpirV already adds the requires support.has_VK_KHR_multiview
MULTIVIEW
in the shader versionChanges to the render engine
edit note that the changes to the clustered forward renderer were moved to PR #49092, this PR will focus purely on the mobile renderer implementation.
This is where there is still a lot of work to do with only the core rendering now working properly:
scene_data
now contains additional projection matrices for each viewWe may introduce a fallback if required later on in case multiview is not supported though according to the Vulkan documentation any Vulkan 1.1 device should provide a multiview implementation.