I want to change a meshes material on the scene. But when I try to assign a new material it throws an error as following:
Uncaught TypeError: Cannot read property 'toArray' of undefined
at flatten (model-viewer.js:17482)
at PureArrayUniform.setValueV3fArray [as setValue] (model-viewer.js:17931)
at Function.WebGLUniforms.upload (model-viewer.js:18214)
at setProgram (model-viewer.js:25982)
at WebGLRenderer.renderBufferDirect (model-viewer.js:24754)
at renderObject (model-viewer.js:25467)
at renderObjects (model-viewer.js:25437)
at WebGLRenderer.render (model-viewer.js:25239)
at Renderer.render (model-viewer.js:56467)
at model-viewer.js:56407
Currently, I can only set color of an existing material though.
What I try is:
const materialsLib = [
new THREE.MeshStandardMaterial( { color: 0xff4400, metalness: 0.9, roughness: 0.2, name: 'orange' } ),
new THREE.MeshStandardMaterial( { color: 0x001166, metalness: 0.9, roughness: 0.2, name: 'blue' } ),
new THREE.MeshStandardMaterial( { color: 0x990000, metalness: 0.9, roughness: 0.2, name: 'red' } ),
new THREE.MeshStandardMaterial( { color: 0x000000, metalness: 0.9, roughness: 0.5, name: 'black' } ),
new THREE.MeshStandardMaterial( { color: 0xffffff, metalness: 0.9, roughness: 0.5, name: 'white' } ),
new THREE.MeshStandardMaterial( { color: 0x555555, metalness: 1.0, roughness: 0.2, name: 'metallic' } )
];
For brevity I did not write all code here. There are two select menus and a change event listener on them, and some arrays to hold the materials library and meshes on the scene. Change event handler as follows:
function updateMaterial (event) {
console.log("matMenu.selectedIndex: ", matMenu.selectedIndex, "meshMenu.selectedIndex: ", meshMenu.selectedIndex);
var meshName = meshNames[meshMenu.selectedIndex]
const mesh = scene.model.getObjectByName(meshName);
// mesh.material.color.setHex(colors[matMenu.selectedIndex].value);
mesh.material = materialsLib[matMenu.selectedIndex];
mesh.material.needsUpdate = true;
}
How can I update materials on run time?