React ThreeJs 渲染问题 - 计算半径为 NaN

3

我是threejs的新手,我在尝试在屏幕上显示星星模型时遇到了问题。点可以正常工作,但我收到了以下消息:

THREE.BufferGeometry.computeBoundingSphere(): Computed radius is NaN. The "position" attribute is likely to have NaN values.

在查看我的代码并发现出现问题的部分是stars canvas之后。

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 * as random from "maath/random/dist/maath-random.esm";
...
const Stars = (props) => {

  const ref = useRef();
  const [sphere] = useState(() =>
    random.inSphere(new Float32Array(5000), { radius: 1.2 })
  );

  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.002}
          sizeAttenuation={true}
          depthWrite={false}
        />
      </Points>
    </group>
  );
};

使用useFrames让星星移动,它正在工作。

导致问题的部分很可能是 random.inSphere(new Float32Array(5000), { radius: 1.2 }) 它显然会给出使半径变为NaN的值(也许是在加载后?)。 我正在使用"@react-three/fiber"和"@react-three/drei"库。

我阅读了文档,但没有找到解决方案,希望能得到一些帮助。 谢谢!

重新编写随机位置代码仍然不起作用。 尝试另一种方式来显示星星。


我无法运行您的示例。对象random从哪里来? - kca
它来自数学库 import * as random from "maath/random/dist/maath-random.esm"; - yarinl4
1
也许与computeBoundingBox默认值为null有关?“默认情况下不会计算边界框。必须明确计算,否则它们将为null。” - kca
6个回答

6
我找到了解决方案!
随机函数生成了5000个点。 threejs向量从数组中取出3个点 - x,y,z。 使最后一个z点不存在!(5000/3 -> 1666 2/3) 我需要改成一个可以被3整除的数字 - 5001 这样错误就消失了。
const [sphere] = useState(() =>
random.inSphere(new Float32Array(5001), { radius: 1.2 }));

0

请展示一下您是如何实现的!我也遇到了困难,我正在做JSM 3D Web Portfolio项目。


const [sphere] = useState(() => random.inSphere(new Float32Array(5001), { radius: 1.2 }) ); 可以用以下代码替换 - yarinl4

0
不知道为什么其他人在这个问题上得到了不同的解决方案。
我尝试将半径从1.2更改为整数5-10,结果成功了。以下是代码部分:
const [sphere] = useState(() =>
random.inSphere(new Float32Array(5000), {radius:10}));

就像我说的那样,这个数字需要被整除,不能有余数。所以5000除以10没有余数。 - Yarin_Lanaido

0
奇怪,将半径调整为5-10没有起到作用,但是修正5000至6000,并使用1.2的半径解决了问题。

0
const sphere = random.inSphere(new Float32Array(5000), { radius: 1 });

你的回答可以通过提供更多支持性信息来改进。请编辑以添加进一步的细节,比如引用或文档,以便其他人可以确认你的回答是正确的。你可以在帮助中心找到关于如何撰写良好回答的更多信息。 - DSDmark

0
我有答案,你只需要在<Contact/>中像这样渲染<StarsCanvas/>
 <motion.div
        variants={slideIn('right', 'tween', 0.2, 1)}
        className='xl:flex:1   xl:h-auto md:h-[550px] h-[350px] w-4/6'
      >
        <EarthCanvas />
      </motion.div>
      <StarsCanvas />
    </div>
  );
};

export default SectionWraper(Contact, 'contact'); 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接