正交相机(Orthographic Camera)渲染场景被切割一半的问题求助
问题排查与修复方案
核心问题分析
场景被切割一半,主要由以下几个关键问题导致:
1. 正交相机构造参数缺失
THREE.OrthographicCamera的构造函数需要6个参数:left, right, top, bottom, near, far,但你的代码只传入了5个,缺失far参数后默认值为0。这会导致相机视锥体范围异常(near=0.1 > far=0),渲染时只能显示部分场景内容。
2. MapControls未适配正交相机
MapControls默认是为透视相机设计的,直接用于正交相机时,交互逻辑(平移、缩放)与相机参数不匹配,会进一步加剧渲染异常。
3. 相机初始化未考虑设备像素比
仅使用offsetWidth/offsetHeight设置相机视口,未结合设备像素比(devicePixelRatio),会导致渲染比例失调,出现画面拉伸或切割。
具体修复代码
1. 修复正交相机初始化
补充far参数,加入设备像素比适配,同时用更直观的方式设置相机位置:
export class OrthoCamera extends THREE.OrthographicCamera { constructor(renderingContext: HTMLCanvasElement) { const pixelRatio = window.devicePixelRatio; const width = renderingContext.offsetWidth * pixelRatio; const height = renderingContext.offsetHeight * pixelRatio; // 补充far参数(设置足够大的值覆盖所有场景物体) super( width / -2, width / 2, height / 2, height / -2, 0.1, 1000 // 新增far参数 ); this.position.set(2, 2, 2); // 替代move方法,更清晰 } }
2. 修改MapControls适配正交相机
关闭屏幕空间平移,新增最小距离限制,确保相机与目标的距离在视锥体范围内:
export class Controls extends MapControls { constructor(camera: OrthoCamera, renderingContext: HTMLCanvasElement) { super(camera, renderingContext); this.enablePan = true; this.enableRotate = true; this.target.set(40.0, 3.0, 40.0); // 适配正交相机的关键配置 this.screenSpacePanning = false; // 改用世界空间平移,避免参数冲突 this.maxDistance = 240; this.minDistance = 1; // 新增最小距离,防止相机穿过场景 this.maxPolarAngle = Math.PI / 3.2; this.minPolarAngle = Math.PI / 3.2; this.update(); // 强制更新控制器状态 } }
3. 添加窗口大小变化监听(必加)
当窗口或canvas尺寸变化时,同步更新相机视口和渲染器尺寸,避免再次出现切割:
// 在你的整合代码中添加监听逻辑 window.addEventListener('resize', () => { const pixelRatio = window.devicePixelRatio; const width = this.renderingContext.offsetWidth * pixelRatio; const height = this.renderingContext.offsetHeight * pixelRatio; // 更新相机视口参数 this.camera.left = width / -2; this.camera.right = width / 2; this.camera.top = height / 2; this.camera.bottom = height / -2; this.camera.updateProjectionMatrix(); // 更新渲染器尺寸 this.renderer.setSize(width, height); });
额外验证点
- 检查场景中所有物体的位置,确保它们都在相机的
near(0.1)到far(1000)范围内 - 若缩放时仍有异常,可自定义
Controls的缩放逻辑:通过调整相机的left/right/top/bottom值实现正交缩放,替代默认的距离缩放逻辑
内容的提问来源于stack exchange,提问作者wpsimon09
相关产品推荐
相关产品推荐

