THREE.js PerspectiveCamera视场边缘点位置偏差问题求助
如何将点放置在PerspectiveCamera可视视场的边缘?
我尝试将一个点放置在PerspectiveCamera初始可视视场的边缘,但该点的位置明显比预期更靠内。相关三角函数计算看似简单,但可能存在疏漏,请问该如何解决此问题?
import * as THREE from "three"; let scene = new THREE.Scene(); let aspect = 300 / 200; let camera = new THREE.PerspectiveCamera(45, aspect, 0.1, 1000); camera.position.z = 10; let renderer = new THREE.WebGLRenderer(); renderer.setSize(300, 200); document.body.appendChild(renderer.domElement); const pointMesh = new THREE.Mesh( new THREE.SphereGeometry(0.1), new THREE.MeshBasicMaterial({ color: 0xff0000 }) ); pointMesh.position.x = Math.tan(THREE.MathUtils.degToRad(camera.fov) / 2) * camera.position.z; scene.add(pointMesh); renderer.render(scene, camera);

问题出在你只考虑了垂直方向的FOV(camera.fov),但忽略了相机的宽高比(aspect ratio)。PerspectiveCamera的fov是垂直方向的视场角,水平方向的视场范围需要结合宽高比计算。
修正方案
将水平方向的边缘计算乘以相机的宽高比:
pointMesh.position.x = Math.tan(THREE.MathUtils.degToRad(camera.fov) / 2) * camera.position.z * camera.aspect;
原因说明
camera.fov定义的是垂直方向的视场角,用tan(fov/2)*camera.position.z计算出的是垂直方向的半范围- 水平方向的视场范围是垂直范围按宽高比(宽度/高度)缩放后的结果,因此需要额外乘以
camera.aspect
如果要验证垂直方向的边缘,设置pointMesh.position.y时不需要乘以宽高比:
pointMesh.position.y = Math.tan(THREE.MathUtils.degToRad(camera.fov) / 2) * camera.position.z;
修改后的完整代码
import * as THREE from "three"; let scene = new THREE.Scene(); let aspect = 300 / 200; let camera = new THREE.PerspectiveCamera(45, aspect, 0.1, 1000); camera.position.z = 10; let renderer = new THREE.WebGLRenderer(); renderer.setSize(300, 200); document.body.appendChild(renderer.domElement); const pointMesh = new THREE.Mesh( new THREE.SphereGeometry(0.1), new THREE.MeshBasicMaterial({ color: 0xff0000 }) ); pointMesh.position.x = Math.tan(THREE.MathUtils.degToRad(camera.fov) / 2) * camera.position.z * camera.aspect; scene.add(pointMesh); renderer.render(scene, camera);
内容的提问来源于stack exchange,提问作者erikreppel
相关产品推荐
相关产品推荐

