如何调整Orthographic Camera正交相机位置使其居中对准黑色正方形
正交相机居中对准平面异常问题
想要设置Orthographic Camera正交相机的位置,使其居中对准场景中的黑色正方形。目前出现异常问题:相机会自动旋转,仅显示黑色正方形的顶视图,只能看到一条细黑线;偶尔修改代码后页面自动刷新时,才能恢复显示黑色正方形的正确面。
在居中函数中分别尝试了更新相机参数、操作controls两种方案都没有解决问题,相关实现代码如下:
相机居中函数
const centerCamera = (controls, camera) => { const point = new THREE.Vector3(0, 500, 1); camera.position.copy(point); camera.lookAt(point.x, point.y, 10); controls.target.copy(point); controls.update(); camera.updateProjectionMatrix(); camera.updateMatrix(); };
场景实现代码
import "./styles.css"; import * as THREE from "three"; import React from "react"; import { Canvas } from "@react-three/fiber"; import { MapControls, OrthographicCamera } from "@react-three/drei"; const CONTENT_GEOMETRY = roundedRect(-350, -50, 700, 100, 100 / 3.7); function roundedRect(x = 0, y = 0, width = 50, height = 50, radius = 5) { const ctx = new THREE.Shape(); ctx.moveTo(x, y + radius); ctx.lineTo(x, y + height - radius); ctx.quadraticCurveTo(x, y + height, x + radius, y + height); ctx.lineTo(x + width - radius, y + height); ctx.quadraticCurveTo(x + width, y + height, x + width, y + height - radius); ctx.lineTo(x + width, y + radius); ctx.quadraticCurveTo(x + width, y, x + width - radius, y); ctx.lineTo(x + radius, y); ctx.quadraticCurveTo(x, y, x, y + radius); ctx.closePath(); return ctx; } const centerCamera = (controls, camera) => { const point = new THREE.Vector3(0, 500, 1); camera.lookAt(point.x, point.y, point.z); controls.target.copy(point); controls.update(); camera.updateProjectionMatrix(); camera.updateMatrix(); }; export default function App() { const dpr = typeof window !== "undefined" ? window?.devicePixelRatio ?? 0 : 0; return ( <div className="App"> <Canvas frameloop="always" style={{ height: "100vh" }} linear dpr={Math.max(dpr, 2)} > <Content onMount={(controls, camera) => { centerCamera(controls, camera); }} /> </Canvas> </div> ); } const Content = ({ onMount }) => { const controls = React.useRef(null); const camera = React.useRef(); React.useEffect(() => { if (controls.current && camera.current) { onMount(controls.current, camera.current); } }, [onMount]); return ( <> <MapControls ref={controls} screenSpacePanning dampingFactor={1} enableRotate={false} /> <OrthographicCamera ref={camera} makeDefault position={[0, 0, 2]} /> <mesh position={[0, 500, 1]}> <shapeBufferGeometry args={[CONTENT_GEOMETRY]} /> <meshBasicMaterial color="#000000" /> </mesh> </> ); };
解决方案
异常的核心原因是相机和目标平面共面、视线方向参数异常,controls的参数覆写了手动设置的相机属性,按以下方式修改即可:
- 相机位置要和目标平面拉开z轴距离,避免共面导致的视口计算异常
- 先设置相机朝向,再同步controls参数,避免被controls覆写
- 移除不需要的矩阵更新调用,只有修改正交相机的视口/缩放参数时才需要调用
updateProjectionMatrix
修改后的居中函数参考:
const centerCamera = (controls, camera) => { // 黑色正方形的中心点坐标 const targetPoint = new THREE.Vector3(0, 500, 1); // 相机和平面保持z轴距离,正对着平面 camera.position.set(targetPoint.x, targetPoint.y, 10); // 相机看向平面中心点 camera.lookAt(targetPoint); // 同步controls的观察目标 controls.target.copy(targetPoint); controls.update(); };
如果显示的正方形尺寸不符合预期,可以手动调整OrthographicCamera组件的zoom属性,或者传入left/right/top/bottom参数自定义正交视口大小。
内容的提问来源于stack exchange,提问作者João Sobral
相关产品推荐
相关产品推荐

