[v11] withUniforms materials cannot be cloned — affects all 16 WebGPU materials
withUniforms materials cannot be cloned or copied
#2826 introduced withUniforms() and rebuilt all 16 WebGPU materials on it, fixing the accessor-during-super() crash (#2813, #2765). The PR carries this caveat from its author:
This is still a workaround. If a user tries to copy or clone the material there will be issues.
That is now the state of every material under src/webgpu/: Outlines, Caustics, ConvolutionMaterial, MeshDistortMaterial, MeshPortalMaterial, MeshReflectorMaterial, MeshRefractionMaterial, MeshTransmissionMaterial, MeshWobbleMaterial, SparklesMaterial, SpotLightMaterial, StarsMaterial, WireframeMaterial, AccumulativeShadows, ContactShadows, Grid.
Why it matters
material.clone() is not exotic. three's own Mesh.clone(), Object3D.clone() with materials, SkeletonUtils.clone(), and drei's <Clone> all reach for it. A user cloning a GLTF that carries one of these materials, or drei's own Clone component wrapping an object that does, will hit it.
What is needed
- Pin down what "issues" means. Does
clone()throw, silently share uniform nodes between the two instances, or produce a material with no uniforms? Each has a different blast radius. - A test. One
describeper material is overkill — one test that clones each of the 16 and asserts the clone's uniform values are independent of the original would cover it. That would be the first asserting test in the WebGPU tree. - Either a
copy()override inwithUniformsthat re-creates the uniform table on the target, or a runtime error that says why cloning is unsupported. Silent wrongness is the outcome to avoid.
Found while verifying #2826 on v11-working @ f14045aa.
Source: pmndrs/drei