I have an extension with such methods, and when I call this method to change the material (color it red), the object becomes transparent and the following errors appear in the console
WebGLRenderer.js:5561 WebGL: INVALID_VALUE: uniform3fv: no array
[.WebGL-0000737C06582900] GL_INVALID_OPERATION: Active draw buffers with missing fragment shader outputs.
setColorToItem = (id) => {
const material = this.createMaterial('#ff0000');
const model = this.viewer.model;
const frags = model.getFragmentList();
model.unconsolidate();
this.tree.enumNodeFragments(
id,
(fragId) => {
frags.setMaterial(fragId, material);
this.viewer.impl.getFragmentProxy(model, fragId).updateAnimTransform();
},
true,
);
this.viewer.impl.invalidate(true);
};
createMaterial = (color) => {
const threeColor = new THREE.Color(color);
const material = new THREE.MeshPhongMaterial({
side: THREE.DoubleSide,
flatShading: true,
color: threeColor,
});
const materials = this.viewer.impl.matman();
materials.addMaterial('CustomMaterial' + color.toString(), material, true);
return material;
};
What could be the problem? I tried using different materials (MeshBasicMaterial, MeshLambertMaterial) version forge-viewer 7 version threejs 0.71 as indicated here https://forge.autodesk.com/en/docs/viewer/v7/developers_guide/viewer_basics / also tried the latest
I tried this with a slightly modified version of your code snippet (as shown below) with the viewer version 7.*, and I can set the color to the material successfully. Is there perhaps any other custom JavaScript logic in your app that could interfere with the new materials? From the error logs it looks like the shader is having issues obtaining the 3 float values (red, green, blue) from the THREE.Color
object.
function createMaterial(viewer, color) {
const material = new THREE.MeshPhongMaterial({
side: THREE.DoubleSide,
flatShading: true,
color: new THREE.Color(color),
});
const materials = viewer.impl.matman();
materials.addMaterial('CustomMaterialRed', material, true);
return material;
}
function applyMaterial(model, dbid, material) {
const tree = model.getInstanceTree();
const frags = model.getFragmentList();
tree.enumNodeFragments(
dbid,
(fragid) => frags.setMaterial(fragid, material),
true
);
model.unconsolidate();
}
// ...
let mat = createMaterial(viewer, '#ff0000');
applyMaterial(viewer.model, 1234, mat);