ArcGIS JS使用externalRenderers渲染three.js TubeGeometry出现抖动失真
问题根因
该抖动扭曲问题本质是大坐标下32位浮点数精度丢失导致:ArcGIS JS 渲染坐标系原点通常为地心,你转换后的经纬度对应渲染坐标数值可达数百万量级,而管道长度、半径仅为米级甚至更小,小尺寸几何体的顶点在大坐标下浮点精度不足,视角移动时计算误差被放大,就会出现明显的抖动、变形,尺寸越小现象越突出。
修复方案
1. 做本地坐标偏移(最核心修复)
不要直接使用全局渲染坐标创建几何体,新增基准点偏移逻辑,让几何体顶点本身保持小数值:
// create the Tubegeometry let v3List=[]; path.forEach((item)=>{ var renderPos = [0, 0, 0]; externalRenderers.toRenderCoordinates(view, [item[0], item[1], 100], 0, SpatialReference.WGS84, renderPos, 0, 1); v3List.push(new THREE.Vector3(renderPos[0], renderPos[1], renderPos[2])); }) // 新增:取第一个点为基准点,所有顶点减去基准点得到本地坐标 const basePoint = v3List[0].clone(); v3List = v3List.map(point => point.clone().sub(basePoint)); let curve = new THREE.LineCurve3(v3List[0], v3List[1]); // 两点路径用直线曲线即可,无需样条 let tubeGeometry = new THREE.TubeBufferGeometry(curve, 1, 10, 8, false); // 径向分段从20降到8,减少不必要的顶点 // 建完网格后将网格整体偏移到基准点位置 let tube1 = new THREE.Mesh(tubeGeometry, material); tube1.position.copy(basePoint); this.scene.add(tube1); let tubeGeometry2 = new THREE.TubeBufferGeometry(curve, 1, 10, 8, false); let tube2 = new THREE.Mesh(tubeGeometry2, tubeMaterial2); tube2.position.copy(basePoint); this.scene.add(tube2);
2. 优化渲染器与材质配置
- 创建WebGLRenderer时开启对数深度缓冲,优化大场景深度精度:
this.renderer= new THREE.WebGLRenderer({ context:context.gl, premultipliedAlpha:false, logarithmicDepthBuffer: true // 新增该配置 });
- 你的调试代码中将两个管道材质的
opacity设为了0,实际使用时改回1;不需要透明效果时可删除depthWrite: false配置,保证深度计算准确。 - 无需使用尺寸过大的坐标轴辅助器,将
AxesHelper的参数从10000000调整为1000即可,避免额外精度损耗。
内容的提问来源于stack exchange,提问作者周复港
相关产品推荐
相关产品推荐

