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

Provide a WebGPU build that re-exports from three #29156

Open
isaac-mason opened this issue Aug 17, 2024 · 12 comments
Open

Provide a WebGPU build that re-exports from three #29156

isaac-mason opened this issue Aug 17, 2024 · 12 comments
Labels

Comments

@isaac-mason
Copy link
Contributor

isaac-mason commented Aug 17, 2024

Description

When using the WebGPU build introduced in r167 with vite, using recommended aliases configuration, I am unable to use renderer agnostic exports from libraries that also have webgl imports. Bundlers will have errors attempting to import webgl specific imports that are not exported by the webgpu build.

Solution

If the three/webgpu build re-exported from three, aliases would not be required to use the webgpu build with bundlers, and libraries could export both webgl and webgpu utilities that import from both three and three/webgpu.

Alternatives

A build that has both webgl and webgpu exports could solve some issues, but this is not as desirable as the proposed solution as bundler aliases would still be required to prevent duplication issues.

Additional context

https://twitter.com/onirenaud/status/1824688713542341119

@hybridherbst
Copy link
Contributor

+1 from me.

Besides the missing exports, I think what also should be clarified is how libraries are supposed to start adding support for WebGPU – not everyone will be able/willing to provide/maintain separate bundles for webgl vs. webgpu.

That unclarity includes three.js examples themself – an example:

  • GLTFExporter currently imports decompress, which is used to bring textures back from the GPU to the CPU
  • decompress (in TextureUtils) imports WebGLRenderer
  • is there a current plan for how that will work in WebGPURenderer, and how GLTFExporter will support both? Or will there be a hard cut at some point in time X, where GLTFExporter will switch over to WebGPURenderer?

@GitHubDragonFly
Copy link
Contributor

+1 from me as well but there is a forum topic which suggests that this might not be happening.

@donmccurdy
Copy link
Collaborator

is there a current plan for how that will work in WebGPURenderer, and how GLTFExporter will support both?

My feeling here would be that we may need to work out a way for GLTFExporter not to import a renderer. Either to require pre-processing the scene, or specifying some configuration on the exporter that provides a decompress implementation or renderer.

@Mugen87
Copy link
Collaborator

Mugen87 commented Sep 3, 2024

How about doing something like this:

const exporter = new THREE.GLTFExporter();
exporter.setTextureUtils( utils ); 

decompress() also relies on ShaderMaterial. According to the migration that has been done up to this point, it's probably best to create a separate TextureUtilsGPU module and implement all helper functions based on WebGPURenderer and node material.

USDZExporter requires the same change as well, btw.

@isaac-mason
Copy link
Contributor Author

isaac-mason commented Sep 3, 2024

To clarify the proposal in this issue with regards to the forums post
https://discourse.threejs.org/t/three-webgpu-min-js-to-provide-webglrenderer-export/69075

The idea of separate builds is to avoid having both renderers in one file. So I would say no, it is not possible to have WebGLRenderer included in three.webgpu.min.js.
When WebGPURenderer more matures, there will be no need for WebGLRenderer anymore so you can rely on the built-in WebGL fallback.

In my mind this issue is not in opposition to having another WebGPURenderer build that does not contain WebGLRenderer exports, this would primarily support use cases where bundlers are not used.

However, using that same build for bundler use cases is problematic, which is why this issue is asking for the three/webgpu entrypoint to re-export from three.

Something we can anticipate will be common during the transition period is libraries exporting both WebGLRenderer and WebGPURenderer versions of utilities. Without the proposed change, libraries cannot easily do this.

@Mugen87
Copy link
Collaborator

Mugen87 commented Sep 4, 2024

If the three/webgpu build re-exported from three,

How does this work? Does the project need a specific configuration in its package.json?

@isaac-mason
Copy link
Contributor Author

isaac-mason commented Sep 8, 2024

I imagine we could approach changing three/webgpu to re-export from three like this:

  1. WebGPURenderer related code would need to import from three, not from src

  2. The existing Three.WebGPU.js barrel file would change from exporting from src, to re-exporting from three, e.g. export { ... } from 'three' and exporting WebGPURenderer specific exports.

  3. The three/webgpu and three/tsl entrypoints would change from build/three.webgpu.js to the new Three.WebGPU.js barrel file, which imports and re-exports code common to both renderers from three. At this point imports to e.g. Mesh from both three and three/webgpu would now resolve to the same class.

  4. The existing rollup builds for three.webgpu.js and three.webgpu.min.js that don't contain WebGLRenderer code could remain, but entrypoints in package.json wouldn't refer to them. Usage of these webgpu-only builds in non-bundled projects wouldn't change, importmaps would still be used as they are now.

@mrdoob
Copy link
Owner

mrdoob commented Sep 12, 2024

How about we introduce a new package?

Package three: WebGLRenderer and WebGLRenderer-Supported Addons
Package three-next: WebGPURenderer and WebGPURenderer-Supported Addons

We'd have to figure out how to publish two packages from a single repo...

Then, maybe in 10 years (😶)... We could make both the same?

/cc @sunag

@hybridherbst
Copy link
Contributor

I think that would force each thing in the ecosystem to also provide multiple packages, instead of being able to support "three" with WebGL and WebGPU with one ecosystem package...

My opinion is that re-exporting with WebGPU, making sure the code in three supports both systems, and providing examples for how third-party code supports both systems would be better.

@donmccurdy
Copy link
Collaborator

donmccurdy commented Sep 13, 2024

Yes, I am worried three-next as a separate package would break a great many things, and then require another large break to consolidate later on.

If we had no other solution, then publishing two versions (not two packages) under three and three@next instead might be an option. A package that supports both can specify that in the peer dependencies ranges. But there are still a lot of implications to think through here.

The suggestion from @isaac-mason sounds workable to me, @mrdoob do you have
particular concerns with that? You're worried about making sure that WebGPURenderer can be used without a bundler, and without getting WebGL stuff by accident, I think?

@CodyJasonBennett
Copy link
Contributor

CodyJasonBennett commented Sep 13, 2024

Another idea is re-exporting from three.module.js instead of three (or some manner of code-splitting) since we know WebGPU code relies on top-level-await and is therefore ESM only. Ideally, this doesn't change how tools will resolve or bundle three and should work OOTB for import maps. I've been keeping an eye on tree-shaking in core so WebGL stuff isn't pulled in by accident for this exactly #28670.

@donmccurdy
Copy link
Collaborator

donmccurdy commented Sep 15, 2024

I like @CodyJasonBennett's proposal in #29404.

Possibly related... do we need/want the three/webgpu and three/tsl entrypoints to be separate and identical? Unless there's a longer-term plan for that, I think we should consider consolidating.

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

No branches or pull requests

8 participants