Skip to content

Cloned ShaderMaterial won't upload its uniform textures #22718

@0b5vr

Description

@0b5vr

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:

this.uniforms = cloneUniforms( source.uniforms );

and here is how the cloneUniorms clone textures:

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:

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

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions