You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 19:50:07