You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Forge Viewer中使用THREE.ShaderMaterial导致选择功能异常

Forge Viewer自定义ShaderMaterial选择/高亮问题解决方案

问题现象

  • 框选功能(Ctrl+左键拖动)几乎无法选中目标网格
  • 鼠标悬停网格时,会错误高亮无关网格
  • 选中单个网格时,自定义材质与选择材质出现Z-fighting/拼接异常(需切换到“Leaf Object”或“Last Object”选择模式触发)

问题根源

Forge Viewer的拾取、高亮机制依赖于材质中正确集成Viewer内置的ID渲染管线和深度处理逻辑,直接使用原生THREE.ShaderMaterial会缺失这些关键环节:

  1. 顶点着色器未处理Viewer的instanceId和drawId,导致拾取时无法正确识别网格ID
  2. 未正确传递深度信息,引发Z-fighting和拾取判定错误
  3. 缺少Viewer材质必须的标记属性,导致拾取管线忽略该材质的网格

修复方案

1. 完善Shader代码,集成Viewer拾取逻辑

修改顶点和片段着色器,加入Viewer所需的ID传递和深度处理:

const customMaterial = new THREE.ShaderMaterial({
    vertexShader: `
        #include <pack_normals>
        #include <id_vert> // 加入Viewer的ID顶点处理
        void main() {
            #include <id_vert_impl> // 执行ID传递逻辑
            gl_Position = projectionMatrix * modelViewMatrix * vec4(position.xyz, 1.0);
        }
    `,
    fragmentShader: `
        #include <id_decl_frag>
        uniform vec3 color;
        void main() {
            gl_FragColor = vec4(color, 1.0);
            #include <id_frag> // 加入Viewer的ID片段处理
            #include <final_frag>
        }
    `,
    uniforms: {
        color: {type: 'v3', value: new THREE.Vector3(0.5, 0, 0)},
        // 手动添加Viewer拾取所需的uniform(Viewer会自动填充)
        objectId: { value: 0 },
        drawId: { value: 0 },
        instanceId: { value: 0 }
    },
    // 添加Viewer材质标记
    isTHREEShaderMaterial: true,
    needsCustomDepthMaterial: true
});
customMaterial.needsUpdate = true;

2. 替换深度材质(解决Z-fighting)

Viewer的选择高亮会使用深度测试,需要为自定义材质指定匹配的深度材质:

// 创建深度材质
const depthMaterial = new THREE.MeshDepthMaterial({
    depthPacking: THREE.RGBADepthPacking,
    side: THREE.DoubleSide
});
// 关联到自定义材质
customMaterial.customDepthMaterial = depthMaterial;

3. 确保材质被Viewer拾取管线识别

Viewer会过滤不符合要求的材质,需添加必要的属性:

// 标记为Viewer可处理的材质
customMaterial.__isTransparent = false; // 根据实际情况设置
customMaterial.alphaTest = 0.5; // 如果有透明需求,设置alphaTest避免拾取异常

关键说明

Viewer的StandardSurface和Prism材质虽然基于THREE.ShaderMaterial,但内部已经封装了所有拾取、深度、ID处理的逻辑,直接使用原生ShaderMaterial必须手动补充这些环节才能兼容Viewer的交互系统。

内容的提问来源于stack exchange,提问作者xblz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 02:24:49