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

WebGLRenderer: Introduce asyncShaderCompilation flag. #26964

Closed
wants to merge 1 commit into from

Conversation

Mugen87
Copy link
Collaborator

@Mugen87 Mugen87 commented Oct 14, 2023

Related issue: #19752 (comment)

Description

Thanks to @toji's preparation in #19745, this change was actually easy to implement. WebGLRenderer now has a new flag called asyncShaderCompilation. When set to true, the renderer automatically makes use of KHR_parallel_shader_compile for all shader programs.

Using the new async mode potentially breaks apps if they rely on certain patterns like on-demand rendering though. Sync renderings like the code below do not work anymore (it just produces a black screen since the shader program isn't ready in the first frame):

let camera, scene, renderer;

init();
render();

function init() {

	camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 0.1, 100 );
	camera.position.z = 2;

	scene = new THREE.Scene();

	const geometry = new THREE.BoxGeometry();
	const material = new THREE.MeshBasicMaterial();

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

	renderer = new THREE.WebGLRenderer( { antialias: true } );
	renderer.setPixelRatio( window.devicePixelRatio );
	renderer.setSize( window.innerWidth, window.innerHeight );
	renderer.asyncShaderCompilation = true;
	document.body.appendChild( renderer.domElement );

}

function render() {

	renderer.render( scene, camera );

}

Unfortunately, a global async mode also breaks modules like PMREMGenerator which rely on a sync pattern as well.

@github-actions
Copy link

📦 Bundle size

Full ESM build, minified and gzipped.

Filesize dev Filesize PR Diff
652.3 kB (161.6 kB) 652.4 kB (161.7 kB) +113 B

🌳 Bundle size after tree-shaking

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

Filesize dev Filesize PR Diff
445 kB (107.6 kB) 445.1 kB (107.7 kB) +113 B

@Mugen87 Mugen87 marked this pull request as draft October 14, 2023 14:54
@sunag
Copy link
Collaborator

sunag commented Oct 19, 2023

Could we have a renderer.renderAsyn() and preserve compatibility with previous versions?

@Mugen87
Copy link
Collaborator Author

Mugen87 commented Oct 19, 2023

TBH, it is not my intention to merge this PR^^. I have primarily filed it for testing.

After some investigations and trial/error I have realized the consequences of this change are severe. Components like PMREMGenerator require a complete different code path. I'm afraid this will also be true for something like renderAsync(). Not sure this kind of separate, async rendering mode is manageable for WebGLRenderer.

@sunag
Copy link
Collaborator

sunag commented Oct 19, 2023

Hmm... at first I thought we could have synchronous render() inside a renderAsync() call, maybe the RTT could be run immediately?

@Mugen87
Copy link
Collaborator Author

Mugen87 commented Nov 3, 2023

Yes, initially I think we need to approach async rendering differently than via a global flag. Closing.

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.

2 participants