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

Forge Viewer 2D模式下自定义几何体缩放时消失/抖动/裁切问题

问题分析

在Forge Viewer 2D模式下添加自定义几何体出现可见性不稳定、抖动裁切的核心原因:

  • 2D模式采用正交相机,模型深度范围极小,你设置的BoxGeometry z轴为0,极易与原有模型几何体的深度重叠,导致遮挡或裁切。
  • 未适配Viewer 2D视图的渲染层级与深度规则,自定义Mesh的深度测试未做特殊处理。
  • BoxGeometry的固定尺寸未考虑Viewer缩放级别,缩放时易出现视觉上的尺寸偏差或抖动。
解决方案

1. 替换几何体为平面类型,适配2D场景

用THREE.PlaneBufferGeometry替代BoxGeometry,2D场景下平面更贴合需求,且BufferGeometry性能更优,减少精度问题:

// 替换原BoxGeometry创建代码
const planeSize = 0.02; // 根据需求调整大小
const geom = new THREE.PlaneBufferGeometry(planeSize, planeSize);

2. 调整Mesh的Z轴位置,避免深度冲突

将自定义Mesh放在模型的最上层,确保不会被原有模型遮挡:

// 获取模型的最大Z值,让自定义Mesh在其上方
const modelBounds = this.viewer.model.getBoundingBox();
const safeZ = modelBounds.max.z + 0.05; // 加一个小偏移量避免重叠
mesh.position.set(result.point.x, result.point.y, safeZ);

3. 配置材质禁用深度测试,确保始终可见

禁用深度测试可以让自定义Mesh始终渲染在所有模型内容之上,避免缩放时的层级错乱:

var material = new THREE.MeshBasicMaterial({ 
  color: 0xff0000,
  depthTest: false, // 关键:禁用深度测试
  transparent: false // 可选,根据需求调整
});

4. 强制更新Mesh矩阵,避免抖动

添加Mesh后强制更新矩阵,确保位置和尺寸的计算准确:

this.viewer.overlays.addMesh(mesh, 'custom-scene');
mesh.updateMatrixWorld(true); // 强制更新矩阵

5. 可选:根据缩放级别动态调整几何体尺寸

如果需要自定义几何体在不同缩放级别下保持一致的屏幕大小,可以根据Viewer的当前缩放因子调整平面尺寸:

// 获取当前Viewer的缩放因子
const zoomFactor = this.viewer.navigation.getZoomFactor();
// 计算适配缩放的平面尺寸(示例值,可根据需求调整)
const adaptiveSize = 0.02 / zoomFactor;
const geom = new THREE.PlaneBufferGeometry(adaptiveSize, adaptiveSize);
修改后的完整代码
handleSingleTap(event) {
    const canvasX = event.canvasX;
    const canvasY = event.canvasY;
    const result = this.viewer.clientToWorld(canvasX, canvasY);
    
    if (result) { 
        // 根据缩放因子调整平面尺寸
        const zoomFactor = this.viewer.navigation.getZoomFactor();
        const adaptiveSize = 0.02 / zoomFactor;
        const geom = new THREE.PlaneBufferGeometry(adaptiveSize, adaptiveSize);
        
        var material = new THREE.MeshBasicMaterial({ 
            color: 0xff0000,
            depthTest: false
        });
        
        var mesh = new THREE.Mesh(geom, material); 
        
        // 设置安全的Z轴位置,避免深度冲突
        const modelBounds = this.viewer.model.getBoundingBox();
        const safeZ = modelBounds.max.z + 0.05;
        mesh.position.set(result.point.x, result.point.y, safeZ); 
        
        if (!this.viewer.overlays.hasScene('custom-scene')) { 
            this.viewer.overlays.addScene('custom-scene'); 
        } 
        
        this.viewer.overlays.addMesh(mesh, 'custom-scene');
        mesh.updateMatrixWorld(true); // 强制更新矩阵
    }
    return true; 
}
额外注意事项
  • 确保在Viewer完全加载完成后再绑定点击事件,避免viewer.model未初始化导致的错误。
  • 如果仍有裁切问题,可以检查Viewer的视口设置,或者尝试将自定义Mesh添加到viewer.impl.sceneAfter(替代overlays场景),但overlays是官方推荐的自定义内容添加方式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 01:38:15