-
-
Notifications
You must be signed in to change notification settings - Fork 36.1k
Description
Describe the bug
ShaderMaterial.clone() fails? to clone texture uniforms to cloned one.
The intention of "?" above is I don't know I should treat this as a bug or an intended behavior.
The behavior is counter-intuitive anyway imo.
Inside the code
Here is what ShaderMaterial.clone() will do:
three.js/src/materials/ShaderMaterial.js
Line 86 in d9af995
| this.uniforms = cloneUniforms( source.uniforms ); |
and here is how the cloneUniorms clone textures:
three.js/src/renderers/shaders/UniformsUtils.js
Lines 17 to 22 in d9af995
| if ( property && ( property.isColor || | |
| property.isMatrix3 || property.isMatrix4 || | |
| property.isVector2 || property.isVector3 || property.isVector4 || | |
| property.isTexture || property.isQuaternion ) ) { | |
| dst[ u ][ p ] = property.clone(); |
This will leave .version of cloned textures to be 0.
Constructor of texture sets version to 0, and clone does not change the value.
And this leads to not upload assigned textures to GPU.
Reproducing the issue
I've made a working example that triggers the issue.
https://glitch.com/edit/#!/grand-plume-windflower
Workaround
There is a workaround code commented out in the Glitch example above.
Manually copying uniform textures to the cloned one will resolve the issue.
Setting .needsUpdate of cloned textures will also resolve this.
Expected behavior
I have to ask first whether the current behavior is intended or not. If this is not intended, I would like to make it ( reference copy || bump .version ) these uniform textures when ShaderMaterial.clone() is called.
Detailed context which probably doesn't matter for you
I'm doing the development of three-vrm.
I was trying to bump three.js version from r126 to r133.
three-vrm 1.0 uses extended ShaderMaterial (MToonMaterial namely) and a GLTFLoader plugin which loads the material.
(my current working branch is #1.0 if you're interested)
In GLTFLoader, there is a code which clones materials for corresponding material variants:
three.js/examples/jsm/loaders/GLTFLoader.js
Line 2980 in d9af995
| cachedMaterial = material.clone(); |
Recently, one of variant conditions are changed from useVertexTangents to useDerivativeTangents
and this triggers the issue for the first time for us.
PR: #22584
Since this issue has a workaround it can be resolved by our side but it takes a whole business day to resolve this 😭
Understandable difficulty since we're using ShaderMaterial in an unusual way and there is no other users who combines ShaderMaterial with GLTFLoader plugins...
Platform
- Device: *
- OS: *
- Browser: *
- Three.js version: r133, at least. I don't see anyone changing these codes recently