godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
91.17k stars 21.2k forks source link

Distorted viewport when changing the `render_target_size_multiplier` of the `OpenXRInterface` (GL Compatibility) #79627

Open decacis opened 1 year ago

decacis commented 1 year ago

Godot version

v4.1.stable.official [970459615]

System information

Windows 10, GL Compatibility, NVIDIA GeForce GTX 1050 Ti (528.24)

Issue description

When you change the render_target_size_multiplier of the OpenXRInterface, the viewport seems to scale improperly. This is only an issue when using the GL Compatibility renderer - the Vulkan mobile renderer works fine (and I assume Forward+ too).

Even though you won't be able to fully see the effect I describe without using a VR headset, in the preview window that Godot shows when running the project from the editor you can see the borders when scaling down:

https://github.com/godotengine/godot/assets/6643844/4aca82da-fbfc-4148-a872-6f7b3e31ad55

The MRP I attached changes the render_target_size_multiplier when pressing the trigger. It goes from 1.0 -> 1.1 -> 1.2 -> 0.8 -> 0.9 and back to 1.0

I have tested using a Meta Quest 2 over AirLink and using the Oculus OpenXR runtime, but I imagine this is not an issue with OpenXR and rather with the GL Compatibility renderer, given that it works fine using Vulkan mobile.

Steps to reproduce

Change the render_target_size_multiplier to something other than 1.0

Minimal reproduction project

RenderTargetSizeMultiplier.zip

BastiaanOlij commented 1 year ago

Hmm in GLES3 we don't do scaling to internal size and target size should always match. Changing the target size multiplier should mean that when we process our viewport, we should be calculating the new size, and that should trigger scene buffers being recreated.

BastiaanOlij commented 1 year ago

So looking a bit further, the size change is triggered here: https://github.com/godotengine/godot/blob/master/servers/rendering/renderer_viewport.cpp#L652

Size2 xr_size = xr_interface->get_render_target_size();
_viewport_set_size(vp, xr_size.width, xr_size.height, xr_interface->get_view_count());

_viewport_set_size calls _configure_3d_render_buffer here: https://github.com/godotengine/godot/blob/master/servers/rendering/renderer_viewport.cpp#L885

Which ends up calling configure on the render buffers here: https://github.com/godotengine/godot/blob/master/servers/rendering/renderer_viewport.cpp#L195

BastiaanOlij commented 1 year ago

@dsnopek Owh but hang on, we're actually not using renderbuffers in GLES3, we're rendering directly to the render target, and the render target uses the swapchain buffer.

So could this be a problem that when the multiplier changes, we're not triggering recreating the swapchain buffer with the correct size?

dsnopek commented 1 year ago

So could this be a problem that when the multiplier changes, we're not triggering recreating the swapchain buffer with the correct size?

Yeah, that could be!