如何将自定义 material 添加到 Forge 查看器中的片段

how to add custom material to a fragment in forge viewer

我有一个带有此类方法的扩展,当我调用此方法更改 material(将其着色为红色)时,对象变为透明并且控制台中出现以下错误

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; 
    };

可能是什么问题? 我尝试使用不同的 materials (MeshBasicMaterial, MeshLambertMaterial) 版本 forge-viewer 7 版本 threejs 0.71 如此处所示 https://forge.autodesk.com/en/docs/viewer/v7/developers_guide/viewer_basics / 也尝试了最新的

我使用查看器版本 7.* 对您的代码片段稍作修改(如下所示)进行了尝试,我可以成功将颜色设置为 material。您的应用程序中是否可能有任何其他自定义 JavaScript 逻辑可能会干扰新的 materials?从错误日志来看,着色器似乎在从 THREE.Color 对象获取 3 个浮点值(红色、绿色、蓝色)时遇到问题。

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);