So I have this Collada (dae) export from a 3d model application for creating packaging.
I've managed to import this model in my scene with
var loader = new THREE.ColladaLoader();
loader.load("model.dae", collada => {
this.scene.add(collada.dae);
});
This works. Animations do also work.
However this dae file has some references to external textures. And I want to programmaticly replace some of them.
The dea from an export uses ShaderMaterial
elements and I have no idea to apply a new texture to it. Everything I do will make it black or does nothing.
What I tried
I know the name of the image texture that is beeing used that I want to replace. The name is TextureResource129.png
.
So what I do:
- Load the new texture
- Loop through all nodes/children in the
dea
that is in the scene. - I check if the node has a
material object
andis a mesh
- I clone the material
- I replace everywhere the old texture image is in the object tree by the new texture image. The export has them on 4 possible locations.
- Then I add the adjusted material again.
- Then the object turns black in the scene
The code:
var loader = new THREE.TextureLoader();
loader.load("/assets/images/texture2/TextureResource129.png", texture => {
this.dae.traverse(node => {
if (node.material && node.isMesh) {
if (
node.material.uniforms.EnvDiff0 &&
node.material.uniforms.EnvDiff0.value.image.currentSrc.indexOf("TextureResource129.png") > -1 ||
node.material.uniforms.paperBump1 &&
node.material.uniforms.paperBump1.value.image.currentSrc.indexOf("TextureResource129.png") > -1 ||
node.material.uniforms.matDiff1 &&
node.material.uniforms.matDiff1.value.image.currentSrc.indexOf("TextureResource129.png") > -1 ||
node.material.uniforms.matDiff2 &&
node.material.uniforms.matDiff2.value.image.currentSrc.indexOf("TextureResource129.png") > -1
) {
var material = node.material.clone();
if(material.uniforms.EnvDiff0) material.uniforms.EnvDiff0.image = texture;
if(material.uniforms.paperBump1) material.uniforms.paperBump1.image = texture;
if(material.uniforms.matDiff1) material.uniforms.matDiff1.image = texture;
if(material.uniforms.matDiff2) material.uniforms.matDiff2.image = texture;
node.material = material;
}
}
});
});
This makes the object black. So I tried only cloning the material and attaching it again to the same node
, without changes.
But even then it also turns black again:
var loader = new THREE.TextureLoader();
loader.load("/assets/images/texture2/TextureResource129.png", texture => {
this.dae.traverse(node => {
if (node.material && node.isMesh) {
if (
node.material.uniforms.EnvDiff0 &&
node.material.uniforms.EnvDiff0.value.image.currentSrc.indexOf("TextureResource129.png") > -1 ||
node.material.uniforms.paperBump1 &&
node.material.uniforms.paperBump1.value.image.currentSrc.indexOf("TextureResource129.png") > -1 ||
node.material.uniforms.matDiff1 &&
node.material.uniforms.matDiff1.value.image.currentSrc.indexOf("TextureResource129.png") > -1 ||
node.material.uniforms.matDiff2 &&
node.material.uniforms.matDiff2.value.image.currentSrc.indexOf("TextureResource129.png") > -1
) {
var material = node.material.clone();
node.material = material;
}
}
});
});
So the question is:
How can I change the texture of a collada (.dea) file programatic when it is in the scene?