WebGLRenderer: Let transmissionRenderTarget size match relevant viewport size#28088
WebGLRenderer: Let transmissionRenderTarget size match relevant viewport size#28088Mugen87 merged 1 commit intomrdoob:devfrom
Conversation
📦 Bundle sizeFull ESM build, minified and gzipped.
🌳 Bundle size after tree-shakingMinimal build including a renderer, camera, empty scene, and dependencies.
|
|
|
||
| // Remove viewport from camera to avoid nested render calls resetting viewport to it (e.g Reflector). | ||
| // Transmission render pass requires viewport to match the transmissionRenderTarget. | ||
| const currentCameraViewport = camera.viewport; |
There was a problem hiding this comment.
It's good that you added a comment that explains this bit 👍 .
Maybe we can find a different XR viewport handling in the future that avoids the viewport reset in Reflector in the first place.
There was a problem hiding this comment.
@mrxz I understand it makes sense to use the viewport to define the size of the render target. However, is the temporary removal really necessary?
What can be irritating is that the viewport can be defined via render targets and camera.viewport. When a reflector is used in a XR scene without transmissive objects, the viewport isn't correct after restoring the XR render target. camera.viewport holds the correct values. So after renderer.setRenderTarget( currentRenderTarget ); at the end of onBeforeRender(), the reflector restores the viewport of the sub camera.
In context of transmission, the transmission render target should now have the same size as camera.viewport. So is the temporary removal of camera.viewport really necessary? When debugging the latest changes today, it seems to me these lines are redundant. If not, can you please explain what bit I am missing?
There was a problem hiding this comment.
In context of transmission, the transmission render target should now have the same size as camera.viewport. So is the temporary removal of camera.viewport really necessary?
@Mugen87 The camera.viewport holds both the size and offset. It's the offset that trips up the transmission rendering. The Reflector first restores the transmission render target, at which point the viewport is also (temporarily) correct. Directly afterwards it notices the camera.viewport and "restores" the viewport. For the left eye this should still all line up, but for the right eye the offset basically lies entirely outside of the bounds of the transmission render target.
In the webxr_vr_sandbox example it's quite difficult to see the difference. Since the viewport is only incorrect after the Reflector is rendered in the right eye, the transmission render target for the right eye will already have the background rendered into it, so it doesn't look completely off.
Hope this clarifies it
There was a problem hiding this comment.
Thanks! That helped quite a lot!
|
Tested the PR on a Quest to with |
Related issue: #28073 (split off from #28078)
Description
This PR ensures that the
transmissionRenderTargetdimensions match the current viewport size (or would-be viewport in case of WebXR). As a result the render target size matches that of each eye, instead of the full WebXR framebuffer size. Similarly when rendering to a render target, it will match its size instead of the full drawing buffer size.There is one additional fix for WebXR with nested render calls (e.g. when using a
Reflector). TheReflectortries to "restore" the viewport when in a WebXR session (Reflector.js#L164-L172), but when rendering the transmission pass, the viewport should be left unchanged (matching the transmission render target)This contribution is funded by Fern Solutions