Three.js报错:THREE.BufferGeometry.computeBoundingSphere()计算半径为NaN
解决Three.js中
computeBoundingSphere()返回NaN的错误 控制台反复出现的THREE.BufferGeometry.computeBoundingSphere(): Computed radius is NaN错误,核心问题有两个:
- 星点坐标过滤逻辑错误:直接对
Float32Array使用filter会将其转为普通数组,且按单个值过滤可能导致最终数组长度不是3的整数倍(每个点需要x/y/z三个坐标),Three.js解析时会产生异常值。 - 冗余的Renderer管理:React Three Fiber的
Canvas组件已自动处理渲染上下文,手动创建并替换WebGLRenderer的domElement会引发上下文冲突,间接导致几何数据处理异常。
修复步骤
1. 正确生成并过滤星点坐标
修改generatePoints函数,按x/y/z三个一组检查坐标有效性,确保数组长度符合Three.js要求,同时保留Float32Array类型以提升性能:
const generatePoints = () => { const spherePoints = random.inSphere(new Float32Array(5000), { radius: 1.2 }); const validPoints = []; // 按三个坐标一组遍历,确保每组都无NaN值 for (let i = 0; i < spherePoints.length; i += 3) { const x = spherePoints[i]; const y = spherePoints[i + 1]; const z = spherePoints[i + 2]; if (!isNaN(x) && !isNaN(y) && !isNaN(z)) { validPoints.push(x, y, z); } } // 转回Float32Array类型 return new Float32Array(validPoints); };
2. 移除手动管理Renderer的冗余代码
删掉StarsCanvas中手动创建WebGLRenderer的逻辑,React Three Fiber会自动处理渲染器:
const StarsCanvas = () => { return ( <div className='w-full h-auto absolute inset-0 z-[-1]'> <Canvas camera={{ position: [0, 0, 1] }}> <Suspense fallback={null}> <Stars /> </Suspense> <Preload all /> </Canvas> </div> ); };
完整修改后的代码
import React, { useRef } from "react"; import { Canvas, useFrame } from "@react-three/fiber"; import { Points, PointMaterial, Preload } from "@react-three/drei"; import * as random from "maath/random/dist/maath-random.esm"; import { Suspense, useState } from "react"; const Stars = (props) => { const ref = useRef(); const generatePoints = () => { const spherePoints = random.inSphere(new Float32Array(5000), { radius: 1.2 }); const validPoints = []; for (let i = 0; i < spherePoints.length; i += 3) { const x = spherePoints[i]; const y = spherePoints[i + 1]; const z = spherePoints[i + 2]; if (!isNaN(x) && !isNaN(y) && !isNaN(z)) { validPoints.push(x, y, z); } } return new Float32Array(validPoints); }; const [sphere] = useState(() => generatePoints()); useFrame((state, delta) => { ref.current.rotation.x -= delta / 10; ref.current.rotation.y -= delta / 15; }); return ( <group rotation={[0, 0, Math.PI / 4]}> <Points ref={ref} positions={sphere} stride={3} frustumCulled {...props}> <PointMaterial transparent color='#f272c8' size={0.003} sizeAttenuation={true} depthWrite={false} /> </Points> </group> ); }; const StarsCanvas = () => { return ( <div className='w-full h-auto absolute inset-0 z-[-1]'> <Canvas camera={{ position: [0, 0, 1] }}> <Suspense fallback={null}> <Stars /> </Suspense> <Preload all /> </Canvas> </div> ); }; export default StarsCanvas;
内容的提问来源于stack exchange,提问作者Amani
相关产品推荐
相关产品推荐

