Skip to content
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

WebGPURenderer: Fix ArrayCamera viewports #28593

Closed
wants to merge 5 commits into from

Conversation

cmhhelgeson
Copy link
Contributor

When switching from Three.WebGLRenderer() to WebGPURenderer in the webgl_camera_array.html example, the WebGPUBackend consistently specified viewport dimensions that exceeded the maximum dimensions of the canvas. Removing the multiplyScalar() command on the viewportValue in Renderer.js partially solved this issue, presumably because the RenderPassEncoder's setViewport command. I presume this is because setViewport only needs to have its arguments specified in pixel coordinates, but I might be wrong. It doesn't seem like a separate function is modifying the viewport value before it is sent to the WebGPU backend...

Additionally, since the viewport dimensions seems to only exist in an integer format, when adjusting the window size, it's common for the specified viewport to exceed the valid dimensions of the canvas by 1 pixel, so a check has been added to the width and account for this behavior.

I looked through the WebGL backend, and it doesn't seem like similar issues popup despite both backends receiving the same viewport values from the example, so further investigation of the issue might be warranted.

@cmhhelgeson cmhhelgeson force-pushed the webgpu_camera_array branch from e044724 to e55b069 Compare July 4, 2024 23:31
Copy link

github-actions bot commented Jul 4, 2024

📦 Bundle size

Full ESM build, minified and gzipped.

Filesize dev Filesize PR Diff
683.5 kB (169.2 kB) 683.5 kB (169.2 kB) +0 B

🌳 Bundle size after tree-shaking

Minimal build including a renderer, camera, empty scene, and dependencies.

Filesize dev Filesize PR Diff
460.6 kB (111.1 kB) 460.6 kB (111.1 kB) +0 B

@Mutefish0
Copy link
Contributor

I encountered the gpu error due to this viewport issue:
截屏2024-07-12 00 00 03
This will cause y to be negative:
Kapture 2024-07-12 at 00 03 03

@cmhhelgeson
Copy link
Contributor Author

cmhhelgeson commented Jul 11, 2024

I encountered the gpu error due to this viewport issue: 截屏2024-07-12 00 00 03 This will cause y to be negative: Kapture 2024-07-12 at 00 03 03 Kapture 2024-07-12 at 00 03 03

Yes, that's currently the result when modifying the webgl array camera sample and switching out the WebGLRenderer for the WebGPURenderer. This branch modifies the WebGPUBackend to adjust the dimensions of the current render pass' viewport should it move out of bounds.

const { currentPass } = this.get( renderContext );
const { x, y, width, height, minDepth, maxDepth } = renderContext.viewportValue;

const w = x + width > renderContext.width ? width - 1 : width;
const h = y + height > renderContext.height ? height - 1 : height;

currentPass.setViewport( x, y, w, h, minDepth, maxDepth );

If you want to use ArrayCameras, and until this pull request gets merged in, I'd recommend either using the WebGLRendererer or using { forceWebGL: true } as an argument. In my testing, the WebGLBackend didn't exhibit any errors when resizing the screen and seems to already possess internal mechanisms that handle when the dimensions move out of bounds. Depending on the conditions of what you would like to render, it may also be better to render out your scene to a texture, then apply it as a pattern to a quad fragment shader.

@Mutefish0
Copy link
Contributor

You are right.
But, there seems to have some issues in this patch:

const w = x + width > renderContext.width ? width - 1 : width;
// for example:
// let width = renderContext.width - x + 2
// x+w = x + width - 1 = renderContext.width + 1   // this will exceed renderContext.width

Maybe we can just do this ?

const w =  Math.min(width, renderContext.width - x);

@mrdoob mrdoob modified the milestones: r167, r168 Jul 25, 2024
@mrdoob mrdoob modified the milestones: r168, r169 Aug 30, 2024
@mrdoob mrdoob modified the milestones: r169, r170 Sep 26, 2024
@mrdoob mrdoob modified the milestones: r170, r171 Oct 31, 2024
@mrdoob mrdoob modified the milestones: r171, r172 Nov 29, 2024
@mrdoob mrdoob modified the milestones: r172, r173 Dec 31, 2024
@Mugen87
Copy link
Collaborator

Mugen87 commented Jan 15, 2025

WebGPURenderer assumes the sub camera's viewport unit is logical pixels. WebGLRenderer does not which is wrong, imo. The unit should match renderer.viewport which is logical (and not physical) pixel unit.

Yes, this is a breaking change but WebGPURenderer behaves more correct here.

On dev there is now webgpu_camera_array. The uniforms of the sub-cameras are not correct yet but #30313 tries to solve that.

@Mugen87 Mugen87 closed this Jan 15, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants