React-Three-Fiber中如何让平面匹配相机视口大小?
问题分析与解决方案
问题根源
- 正交相机代码错误:你把
PlaneGeometry嵌套在了OrthographicCamera组件内部,相机不能作为渲染对象的父容器;同时缺少Mesh组件包裹几何体与材质,且相机参数未匹配画布宽高比,导致平面显示异常。 - ScreenQuad使用不当:
ScreenQuad是为后期处理设计的组件,需配合EffectComposer等渲染管线使用,单独直接渲染无法正常工作。
正确实现方式
方式一:基于正交相机的全屏平面
通过动态计算画布宽高比,调整正交相机参数,确保平面始终铺满视口:
import { Canvas, useThree } from '@react-three/fiber' import { OrthographicCamera, Mesh, PlaneGeometry, MeshBasicMaterial } from '@react-three/drei' const FullscreenPlane = () => { const { size } = useThree() // 根据画布宽高比计算相机参数 const aspect = size.width / size.height const cameraParams = { left: -aspect, right: aspect, top: 1, bottom: -1, near: 0, far: 1 } return ( <> <OrthographicCamera {...cameraParams} position={[0, 0, 1]} /> <Mesh> <PlaneGeometry args={[2 * aspect, 2]} /> <MeshBasicMaterial color="blue" /> </Mesh> </> ) } // 使用组件 const App = () => { return ( <Canvas style={{ width: '100vw', height: '100vh' }}> <FullscreenPlane /> </Canvas> ) }
方式二:使用全屏后期处理Quad(适用于着色器效果)
如果需要实现全屏着色器效果,推荐配合EffectComposer使用ScreenQuad,示例如下:
import { Canvas } from '@react-three/fiber' import { EffectComposer, ScreenQuad } from '@react-three/postprocessing' import { shaderMaterial } from '@react-three/drei' // 自定义全屏着色器材质 const FullscreenShader = shaderMaterial( {}, /* vertex shader */ ` varying vec2 vUv; void main() { vUv = uv; gl_Position = vec4(position, 1.0); } `, /* fragment shader */ ` varying vec2 vUv; void main() { gl_FragColor = vec4(vUv, 0.5, 1.0); } ` ) const FullscreenEffect = () => { return ( <EffectComposer> <ScreenQuad> <FullscreenShader /> </ScreenQuad> </EffectComposer> ) } // 使用组件 const App = () => { return ( <Canvas style={{ width: '100vw', height: '100vh' }}> <FullscreenEffect /> </Canvas> ) }
关键注意点
- 所有渲染对象(Mesh、几何体等)必须直接放在
Canvas或其下的group中,不能嵌套在相机组件内部。 - 正交相机的参数必须与画布宽高比同步,否则会出现拉伸或显示不全的问题。
- 后期处理组件需配合正确的渲染管线使用,单独使用
ScreenQuad无法正常渲染。
内容的提问来源于stack exchange,提问作者Cécile Lebleu
相关产品推荐
相关产品推荐

