-
-
Notifications
You must be signed in to change notification settings - Fork 35.9k
NodeMaterialObserver: Force refresh for video textures. #31397
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
base: dev
Are you sure you want to change the base?
Conversation
📦 Bundle sizeFull ESM build, minified and gzipped.
🌳 Bundle size after tree-shakingMinimal build including a renderer, camera, empty scene, and dependencies.
|
I'd like to analyze this in more detail. Currently we can take a uniform to an isolated group using |
I'm not sure this fixes the issue. What irritates me is that the scope/lifetime of an external texture is so short. I've assumed calling @greggman Can you enlighten us, please? 😇 In the fiddle, we use the same external texture and bind group for two plane meshes. The browser complains now with the warning: "External texture [ExternalTexture (unlabeled)] used in a submit is not active.". |
Without looking, |
And to be more clear, you must call |
Also, not that this explains anything but it seems every other frame the code calls |
Okay, things are more clear now. A new video frame is not available in every frame. When no new video frame is ready, the material observer does not trigger a refresh since it thinks the video texture has not changed. However, that will not trigger the required call for There is one thing we can optimize: Use |
@sunag External textures are now cached per frame id. I've also made sure the video texture refresh is only forced for the WebGPU backend. I'm curious to see if you can improve the approach somehow via |
It sounds like you solved the issue? One more caveat. While the external texture needs to be used in the same task, if you call In other words, in pseudo code let prevTexture;
let bindGroup;
rAF/rVFC/setTimeout/mouseEvent/etc...
const texture = device.importExternalTexture(...);
if (texture !== prevTexture) {
prevTexture = texture;
bindGroup = device.createBindGroup({
entries: [
...
{ ..., resource: texture },
...
],
]);
} I don't feel like this really matters but just for completeness it seemed good not to leave it out. |
Yes, I think it's just a matter of how we organize our code now^^. The |
Related issue: #31330 (comment)
Description
Using video textures in WebGPU seems more complicated than in WebGL since it is not possible to share an external texture. We have to recreate the bind group and the external texture for each render item. For material properties, we can enforce this in
NodeMaterialObserver
.However, if video textures are used as spot light maps, there is no obvious way to enforce a refresh. Hence, I have removed the video texture from the
webgpu_lights_projector
demo. I think we can only properly support them on material level. And even then they are a bit problematic for performance in WebGPU since we can't share bindings in the same way like with normal textures.I suggest to state in the documentation that video textures are not supported in
SpotLight.map
.