FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

Add support for WebGPURenderer and TSL example by vincentfretin · Pull Request #5655 · aframevr/aframe · GitHub

Add support for WebGPURenderer and TSL example - #5655

Merged
dmarcos merged 14 commits into
aframevr:masterfrom
vincentfretin:webgpu
Feb 14, 2025
Merged

Add support for WebGPURenderer and TSL example#5655
dmarcos merged 14 commits into
aframevr:masterfrom
vincentfretin:webgpu

Conversation

vincentfretin commented Feb 4, 2025
edited
Loading

Copy link
Copy Markdown
Contributor

Description:

For those that want to play with WebGPURenderer and TSL.
Run

npm run dist # to build dist/aframe-master.module.min.js used in tsl example
npm run start:webgpu

Start from
https://localhost:8080/showcase/tsl/
and port an example from https://threejs.org/examples/?q=tsl

Changes proposed:

  • Rename a-node isNode to isANode, this was the cause of infinite loop with build function on WebGPURenderer when building a shader
  • Add a start:webgpu command that will import from three/webgpu instead of three via a webpack alias
  • Set dummy renderer.xr.setPoseTarget for now when it's WebGPURenderer
  • Import UniformsUtils and UniformsLib from three/src (used by sdf/msdf text shaders), those are not exposed on the three/webgpu build
  • Fix vendor/rStats.extras.js where renderer.info.programs is undefined with WebGPURenderer

All the changes here are backward compatible with the default WebGLRenderer umd aframe build.

You can use WebGPURenderer in two ways:

  • via an importmap defining three and three/webpgu to use three.webgpu.js instead of three.module.js

  • in your webpack project defining the correct alias:

  resolve: {
    alias: {
      'three$': path.resolve(__dirname, 'node_modules/three/build/three.webgpu.js')
    }
  };

and using in package.json this PR for now:

"dependencies": {
  "aframe": "vincentfretin/aframe#webgpu"
}

Using WebGPURenderer with classic aframe umd build is not supported, we don't generate a build for that.

Comment thread src/core/a-node.js Outdated

function isNode (node) {
return node.tagName.toLowerCase() in knownTags || node.isNode;
return node.tagName.toLowerCase() in knownTags || node.isAframeNode;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

We should def understand what's going on here

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

The infinite loop was here https://github.com/mrdoob/three.js/blob/a5734130516db50c1de2cdfe27f477a33ecd1c87/src/nodes/core/Node.js#L640-L648
I don't know much about the new node system to say what that code is doing.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

As I said in #5363 (comment) my guess is that in aframe we set a reference to the entity with el on a three object.

Doing a search I get the following places:

$ ag "\.el = " src/
src/core/system.js
31:  this.el = sceneEl;

src/core/component.js
66:  this.el = el;

src/core/a-entity.js
36:    this.object3D.el = this;
111:    this.object3D.el = null;
140:    obj.el = this;
143:        child.el = self;

src/components/material.js
112:    shaderInstance.el = this.el;

src/components/light.js
205:      this.light.el = el;

src/components/text.js
437:  shaderObject.el = el;

My guess is that the one set on shaderInstance.el is the culprit and end up in the shader/material being build, but not sure how, I'm not familiar with the new webgpu code path.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

I'm not aware of any community components that is using an isNode check, I think it's fine to rename it to isANode and add a note about it in the release notes.

dmarcos commented Feb 4, 2025

Copy link
Copy Markdown
Member

Cool. I would postpone this to 1.8.0. I will be cool to have a WebGPU path.

Copy link
Copy Markdown
Contributor Author

sdf/msdf text is completely broken
WebGLRenderer

WebGPURenderer

Copy link
Copy Markdown
Contributor Author

http://127.0.0.1:8080/docs/basic-scene/
2 errors in console: NodeMaterial: Material "ShaderMaterial" is not compatible.
may be related to the text shader

http://127.0.0.1:8080/showcase/curved-mockups/
background image is black on Chrome Android where is really run on webgpu. On desktop it's okay but it fallbacks to webgl2 on Ubuntu, so not sure if it's a webgpu on mobile issue.

Copy link
Copy Markdown
Contributor Author

http://127.0.0.1:8080/boilerplate/hello-world/
WebGLRenderer

WebGPURenderer (webgpu backend or webgl2 fallback with r173)

vincentfretin changed the title testing WebGPURenderer and TSL (do not merge) Add support for WebGPURenderer and TSL example Feb 6, 2025
vincentfretin marked this pull request as ready for review February 6, 2025 11:55

arpu commented Feb 6, 2025

Copy link
Copy Markdown
Contributor

for me the only question is, what is the usecase for renderer.xr.setPoseTarget i never need this and its only used at

if (this.camera) { renderer.xr.setPoseTarget(this.camera.el.object3D); }

Copy link
Copy Markdown
Contributor Author

@dmarcos I think we could add a TSL example and then merge this, all the changes here are backward compatible with the WebGLRenderer aframe umd build. We can then make other changes if needed, mainly the text component that is completely broken by replacing it with troika-text if that one work with WebGPU backend.

As of three r173, VR mode is not working with WebGPU, we get the error:
THREE.XRManager: XR is currently not supported with a WebGPU backend. Use WebGL by passing "{ forceWebGL: true }" to the constructor of the renderer.

vincentfretin commented Feb 6, 2025
edited
Loading

Copy link
Copy Markdown
Contributor Author

for me the only question is, what is the usecase for renderer.xr.setPoseTarget i never need this and its only used at

if (this.camera) { renderer.xr.setPoseTarget(this.camera.el.object3D); }

Good question, we have that patch supermedium/three.js@3bfa95d (in 0.173.4 branch)
not sure what it does, maybe keep the xz position of the aframe camera when entering VR? The y position is overridden in VR that I know. I usually set a xz position on camera rig, not the camera.

mrxz commented Feb 6, 2025
edited
Loading

Copy link
Copy Markdown
Contributor

for me the only question is, what is the usecase for renderer.xr.setPoseTarget i never need this and its only used at

@arpu In Three.js the WebXRManager moves the "user" camera to match the xr camera. In A-Frame the camera is conceptually an <a-camera> or <a-entity camera>, which has the actual camera as a child. Just like how components such as look-controls and wasd-controls move the camera entity and not the camera itself, the setPoseTarget is there to let Three.js do the same.

Copy link
Copy Markdown
Contributor Author

So I guess we will need to do a similar patch to XRManager (used by WebGPU backend) to implement setPoseTarget when VR will be supported.

mrxz commented Feb 6, 2025

Copy link
Copy Markdown
Contributor

There is an alternative which I use in my fork, namely disabling XR camera updates in Three.js and doing it ourselves in the camera component. Not only does this avoid needing a modification to Three.js, it also ensures that the camera is up-to-date after the camera component. So any logic that is based on the users head position/orientation can use after: ['camera']. Currently these components tend to use 1 frame stale data.

dmarcos commented Feb 6, 2025

Copy link
Copy Markdown
Member

for me the only question is, what is the usecase for renderer.xr.setPoseTarget i never need this and its only used at

@arpu In Three.js the WebXRManager moves the "user" camera to match the xr camera. In A-Frame the camera is conceptually an <a-camera> or <a-entity camera>, which has the actual camera as a child. Just like how components such as look-controls and wasd-controls move the camera entity and not the camera itself, the setPoseTarget is there to let Three.js do the same.

Correct. That method or similar existed in WebVRManager and WebXRManager and was removed at some point. Since the pose applies only to the camera and one cannot apply it to an arbitrary Object3D. I raised the concern to THREE but was ignored.

dmarcos commented Feb 6, 2025

Copy link
Copy Markdown
Member

There is an alternative which I use in my fork, namely disabling XR camera updates in Three.js and doing it ourselves in the camera component. Not only does this avoid needing a modification to Three.js, it also ensures that the camera is up-to-date after the camera component. So any logic that is based on the users head position/orientation can use after: ['camera']. Currently these components tend to use 1 frame stale data.

How do you disable camera updates?

mrxz commented Feb 6, 2025
edited
Loading

Copy link
Copy Markdown
Contributor

How do you disable camera updates?

By setting renderer.xr.cameraAutoUpdate to false (see https://github.com/mrdoob/three.js/blob/dev/src/renderers/WebGLRenderer.js#L1160). But as with anything, it isn't without its drawbacks. If the camera component handles the updating, then any camera movement afterwards (directly or indirectly through a camera rig) needs to be propagated to the world matrices of the sub cameras. This only needs to be done right before rendering, but it no longer happens automatically.

Basically the above flag is an all-or-nothing and in an ideal world the part that transfers the WebXR pose onto the camera is done in the camera component and the part that updates the world matrices of the underlying eye cameras is done right before rendering.

But I have no idea if the XRManager for WebGPURenderer is going to have the same behaviour, probably best to wait and see how that implementation will behave.

dmarcos commented Feb 6, 2025

Copy link
Copy Markdown
Member

How do you disable camera updates?

By setting renderer.xr.cameraAutoUpdate to false (see https://github.com/mrdoob/three.js/blob/dev/src/renderers/WebGLRenderer.js#L1160). But as with anything, it isn't without its drawbacks. If the camera component handles the updating, then any camera movement afterwards (directly or indirectly through a camera rig) needs to be propagated to the world matrices of the sub cameras. This only needs to be done right before rendering, but it no longer happens automatically.

Basically the above flag is an all-or-nothing and in an ideal world the part that transfers the WebXR pose onto the camera is done in the camera component and the part that updates the world matrices of the underlying eye cameras is done right before rendering.

But I have no idea if the XRManager for WebGPURenderer is going to have the same behaviour, probably best to wait and see how that implementation will behave.

Thanks. I like the idea of having more control of the lower level parts that concern XR. So in your case the pose used for rendering is not the most current one since it’s done in the component?

Copy link
Copy Markdown
Contributor Author

I ported the galaxy example.
As far as I can tell, this is ready to be merged.

dmarcos commented Feb 11, 2025

Copy link
Copy Markdown
Member

I ported the galaxy example. As far as I can tell, this is ready to be merged.

Thanks. Does it work in VR?

Copy link
Copy Markdown
Contributor Author

No, three r173 doesn't support WebXR with WebGPU.

Comment thread examples/showcase/tsl/index.html Outdated
<head>
<meta charset="utf-8" />
<title>TSL • A-Frame</title>
<meta name="description" content="TSL • A-Frame" />

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Would probably name this example 'webgpu' instead of tsl?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

The main reason I did this example is to play with TSL that is currently only available with WebGPURenderer, but that example may also run with WebGL2 for systems that doesn't support WebGPU, so I would like to keep TSL here in the title.
I renamed directory to webgpu and changed the title to "WebGPURenderer and TSL" so that matches what I put in the root index.html

dmarcos commented Feb 14, 2025

Copy link
Copy Markdown
Member

Thanks!

This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
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.

4 participants


Back | FazBrowse Home | New Git URL