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

WebGLbackend: autoClear bug #30589

Closed
zonkypop opened this issue Feb 23, 2025 · 15 comments · Fixed by #30606
Closed

WebGLbackend: autoClear bug #30589

zonkypop opened this issue Feb 23, 2025 · 15 comments · Fixed by #30606
Milestone

Comments

@zonkypop
Copy link
Contributor

zonkypop commented Feb 23, 2025

Description

When using the WebGL fallback renderer, autoClear seems to be causing issues:

Image

This can be reproduced by adding:

function animate() {
				renderer.autoClear = true;
				renderer.render(scene, camera);

				const geometry = new THREE.SphereGeometry(5, 64, 32);

				const material = new THREE.MeshBasicMaterial({
					color: 0xffffff,
				});

				mesh = new THREE.Mesh(geometry, material);

				renderer.autoClear = false;
				renderer.render(mesh, camera);
			}

in the https://threejs.org/examples/?q=light%20probe#webgpu_lightprobe example and using forceWebGL: true for the renderer.

Setting antialias: false will make it not look mangled but there are still issues with it not clearing (update: I think those issues were unrelated).

I'm not getting the same issue when using WebGPU or the WebGL example.

Version

174dev

Device

Desktop

Browser

Chrome

OS

Linux

@Mugen87
Copy link
Collaborator

Mugen87 commented Feb 23, 2025

Can you please demonstrate the issue with a fiddle? You can use the following one that holds the code of webgpu_lightprobe but with your modification. The only bit I have changed is to create the mesh for the second render just once.

https://jsfiddle.net/j8qk0us5/1/

Both backends render the same for me, tested on latest Chrome on macOS 15.3.1.

@zonkypop
Copy link
Contributor Author

zonkypop commented Feb 23, 2025

Oh that is strange, I can't reproduce it on Linux with AMD integrated graphics, or macOS.

Here's the fiddle: https://jsfiddle.net/zonkypop/jyuchq4p/2/

But it does look mangled with an RTX 3090 on Linux on Chrome (tested 131, 133). It needs: antialias: true for it to happen, and looks fine without antialiasing.

It looks fine on Firefox with the same machine.

I'll have a poke around today and see if I can find any clues.

@zonkypop
Copy link
Contributor Author

zonkypop commented Feb 23, 2025

I'm able to reproduce it in on Windows 11 with a RTX 3070 as well, but only Chrome, not Firefox. So might be Chrome+Nvidia related.

@Mugen87
Copy link
Collaborator

Mugen87 commented Feb 23, 2025

So the combination is WebGLBackend + MSAA + Nvidia card + Chrome, right? The OS does not seem to matter.

@zonkypop
Copy link
Contributor Author

So the combination is WebGLBackend + MSAA + Nvidia card + Chrome, right? The OS does not seem to matter.

Yes seems to be, the bug's there for Linux and Windows

@zonkypop
Copy link
Contributor Author

A workaround is adding useFrameBufferTarget to:

render( scene, camera, useFrameBufferTarget ) {

		if ( this._initialized === false ) {

			console.warn( 'THREE.Renderer: .render() called before the backend is initialized. Try using .renderAsync() instead.' );

			return this.renderAsync( scene, camera, useFrameBufferTarget );

		}

		this._renderScene( scene, camera, useFrameBufferTarget );

	}

and calling: renderer.render( scene, camera, false )

To disable the final quad pass, which fixes the issue. This introduces other problems like needing color conversion in the shader and no post processing though.

@Mugen87
Copy link
Collaborator

Mugen87 commented Feb 23, 2025

Can you please share a GPU report from one of the affected systems by typing chrome://gpu/ into the address bar and then hit Download Report to File?

@Mugen87
Copy link
Collaborator

Mugen87 commented Feb 23, 2025

Can you also test if this example works on the affected devices?

https://threejs.org/examples/webgl_multisampled_renderbuffers

@zonkypop
Copy link
Contributor Author

Here's the report for the Linux machine:

about-gpu-2025-02-23T22-36-39-962Z.txt

https://threejs.org/examples/webgl_multisampled_renderbuffers seems to look fine

@Mugen87
Copy link
Collaborator

Mugen87 commented Feb 24, 2025

Can you try one thing and remove the following invalidate* calls from below section?

for ( let i = 0; i < textures.length; i ++ ) {
// TODO Add support for MRT
if ( renderContext.scissor ) {
const { x, y, width, height } = renderContext.scissorValue;
const viewY = renderContext.height - height - y;
gl.blitFramebuffer( x, viewY, x + width, viewY + height, x, viewY, x + width, viewY + height, mask, gl.NEAREST );
gl.invalidateSubFramebuffer( gl.READ_FRAMEBUFFER, renderTargetContextData.invalidationArray, x, viewY, width, height );
} else {
gl.blitFramebuffer( 0, 0, renderContext.width, renderContext.height, 0, 0, renderContext.width, renderContext.height, mask, gl.NEAREST );
gl.invalidateFramebuffer( gl.READ_FRAMEBUFFER, renderTargetContextData.invalidationArray );
}

@zonkypop
Copy link
Contributor Author

Can you try one thing and remove the following invalidate* calls from below section?

🥳 Wahay, that seems to have fixed it for both Linux and Windows!

@Mugen87
Copy link
Collaborator

Mugen87 commented Feb 24, 2025

I've remembered that the invalidate*() commands are problematic on certain devices. Hence, they are only done for Quest devices in WebGLRenderer.

@Mugen87
Copy link
Collaborator

Mugen87 commented Feb 24, 2025

Out of curiosity: Does the following WebGL conformance test pass on your affected devices?

https://registry.khronos.org/webgl/sdk/tests/conformance2/renderbuffers/invalidate-framebuffer.html?webglVersion=2&quiet=0&quick=1

@Mugen87 Mugen87 added this to the r174 milestone Feb 24, 2025
@zonkypop
Copy link
Contributor Author

All the tests are passing: TEST COMPLETE: 41 PASS, 0 FAIL

I've remembered that the invalidate*() commands are problematic on certain devices. Hence, they are only done for Quest devices in WebGLRenderer.

Ah that is interesting, hmm I can do a bit of testing on the Quest 3 to see the perf difference of removing/adding the gl.invalidateSubFramebuffer. I was wondering if the quad pass has much overhead? The Quest 3 seems to working fine with the new WebGLBackend / TSL though!

@Mugen87
Copy link
Collaborator

Mugen87 commented Feb 24, 2025

We need #30437 to restore foveation which does currently not work with the new renderer. That should further improve the performance on Quest devices.

Um, it would be good if the WebGL conformance test could actually catch the issue on your devices. If you could manage to reproduce the breakage by modifying the test and commiting the change that could be an welcome contribution to the WebGL conformance test suite.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants