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

Exploring asynchronous compilation of materials with Suspense #3073

Open
Mike-Dax opened this issue Oct 30, 2023 · 1 comment
Open

Exploring asynchronous compilation of materials with Suspense #3073

Mike-Dax opened this issue Oct 30, 2023 · 1 comment

Comments

@Mike-Dax
Copy link
Contributor

With this PR, three.js v158 supports a compileAsync method which can compile shaders and return a Promise that resolves when they're ready.

Taking the Frosted glass example, my M1 Macbook spends several frames (74.6ms in total) blocked on shader compilation.

image

This new method sounds like a good fit for react-three-fiber's ability to leverage React's lifecycle management, to Suspend during compilation, then attach the objects to the scene.

Taking a step back, in my applications I don't mind if the 3D components 'arrive' a few frames later, but this kind of blocking of the main thread is visually noticeable.

I'm not too familiar with the internals of three or r3f at this level but I'd be happy to contribute, given some pointers in the right direction.

  • Should the Preload component in Drei handle this?
    • Is moving the minimum three.js version to v158 a breaking change for Drei?
    • Is changing Preload to have it suspend a breaking change?
  • Should there be a new component in Drei where the children are compiled asynchronously, and only added to the 'real' scene when compilation has completed?
  • Should this just be the default behaviour for everything, and built into the r3f reconciler itself?
  • How does this work in the context of something like the MeshTransmissionMaterial making its own calls to gl.render?

From what I can tell, this will only be an improvement for non-firefox browsers, due to the availability of the KHR_parallel_shader_compile extension.

@CodyJasonBennett
Copy link
Member

CodyJasonBennett commented Oct 30, 2023

This should be an addition in Drei at the very least. Preload suspending by default is a breaking change (similar to async/await for imperative APIs) as well as changing peer deps range, but you can have a prop to opt-in for that behavior or create an AsyncPreload with/without that prop. R3F can't assume much about the renderer since it has to support everything in three (SVGRenderer, etc.), and the API surface of renderers are increasingly volatile with the upcoming universal renderer (mrdoob/three.js#26079). If you look into the Preload component, notice there's a guard for initTexture since it doesn't exist on the universal backend.

If you want something for Firefox, you can try a fence check to wait until GPU idle. This is a bit more crude, but it should offer comparable results if apps are idle on startup. Maybe this should be added to three now that parallel compile has finally been merged. https://gist.github.com/CodyJasonBennett/fedde93b69b8ecaefa402ee306189761

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

No branches or pull requests

2 participants