使用React-Three-Fiber与drei的Points组件添加BufferGeometry时页面黑屏
问题:react-three-fiber + drei 实现雨滴效果时页面黑屏
我正在用react-three-fiber和drei开发逼真的雨滴效果,但在drei的Points组件中使用BufferGeometry后,页面直接黑屏,浏览器里看不到任何场景。
我的代码:
const RainScene = () => { // Initialize rain particles const rainCount = 1500; const rainGeo = new THREE.BufferGeometry(); const positions = []; for(let i = 0; i < rainCount; i++) { const rainDrop = new THREE.Vector3( Math.random() * 400 - 200, Math.random() * 500 - 250, Math.random() * 400 - 200 ); positions.push(rainDrop.x, rainDrop.y, rainDrop.z); } const positionAttribute = new THREE.BufferAttribute(new Float32Array(positions), 3); rainGeo.setAttribute('position', positionAttribute); return ( <> <group> <ambientLight intensity={0.55} /> <directionalLight position={[0, 0, 1]} color={0xffeedd} /> <Points limit={1000} // Optional: max amount of items (for calculating buffer size) range={1000} // Optional: draw-range geometry={rainGeo} > <pointsMaterial/> </Points> </group> </> ); }; export default RainScene;
解决方法及修改后的代码
黑屏的核心原因是参数配置冲突、材质不可见、相机位置不对,还有几何体未缓存导致的潜在问题。以下是修复后的完整代码:
import { useMemo } from 'react'; import { PerspectiveCamera } from '@react-three/fiber'; import { Points } from '@react-three/drei'; import * as THREE from 'three'; const RainScene = () => { const rainCount = 1500; // 用useMemo缓存几何体,避免每次渲染重复创建 const rainGeo = useMemo(() => { const geometry = new THREE.BufferGeometry(); const positions = []; for (let i = 0; i < rainCount; i++) { positions.push( Math.random() * 400 - 200, // x轴范围:-200 到 200 Math.random() * 500 - 250, // y轴范围:-250 到 250 Math.random() * 400 - 200 // z轴范围:-200 到 200 ); } geometry.setAttribute('position', new THREE.Float32BufferAttribute(positions, 3)); return geometry; }, [rainCount]); return ( <> {/* 添加默认相机,位置设为z=200,确保覆盖所有雨滴的分布范围 */} <PerspectiveCamera position={[0, 0, 200]} makeDefault /> <group> <ambientLight intensity={0.55} /> {/* 调整方向光位置,让光照更自然 */} <directionalLight position={[50, 100, 50]} color={0xffeedd} intensity={0.8} /> {/* 移除limit和range参数,自定义geometry时不需要这两个配置 */} <Points geometry={rainGeo}> {/* 配置点材质:设置尺寸、颜色、透明度,让雨滴可见且逼真 */} <pointsMaterial size={0.5} color="#ffffff" transparent opacity={0.8} /> </Points> </group> </> ); }; export default RainScene;
关键修改点说明:
- 移除Points组件的limit和range:这两个参数是drei Points用于动态生成粒子的专属配置,传入自定义BufferGeometry时不需要,反而会限制粒子渲染数量(你生成了1500个雨滴,但limit设为1000,会导致部分粒子不显示)。
- 添加PerspectiveCamera:默认相机位置可能不在可视范围内,设置
position=[0,0,200]刚好能覆盖所有雨滴的分布区域。 - 配置pointsMaterial:默认材质尺寸极小且无明显颜色,设置size、color、透明度后才能看到雨滴效果。
- 用useMemo缓存几何体:避免组件重渲染时重复创建BufferGeometry,提升性能同时避免潜在的渲染异常。
内容的提问来源于stack exchange,提问作者Mario Francisco
相关产品推荐
相关产品推荐

