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

THREE.BufferGeometry.computeBoundingSphere()计算半径为NaN问题求助

问题:带倒角的TextGeometry出现NaN位置属性错误

项目原本仅使用@react-three,后续加入原生Three.js和Cannon补充功能,导致代码结构复杂。该错误仅在启用倒角的TextGeometry上触发,已完成问题复现。

已尝试的解决方案

  • 添加或移除computeBoundingBox()与computeBoundingSphere()
  • 移除position常量外层的数组包裹
  • 为PlaneBufferGeometry添加宽度分段和高度分段参数
  • 参考带倒角TextGeometry的示例代码进行修改

TextGeometry实现代码

export function Font({ letter, position: initialPosition }) {
  const { size, viewport } = useThree();
  const [position, setPosition] = useState(initialPosition);
  const [quaternion, setQuaternion] = useState([0, 0, 0, 0]);
  const aspect = size.width / viewport.width;
  const font = new FontLoader().parse(Roboto);

  const textOptions = {
    font,
    size: 1,
    height: 0,
    curveSegments: 0,
    bevelEnabled: true,
    bevelThickness: 0.3,
    bevelSize: 0.1,
    bevelOffset: -0.01,
    bevelSegments: 12
  };

  const letterGeom = new TextGeometry(
    letter,
    textOptions
  );

  letterGeom.computeBoundingBox();
  letterGeom.computeBoundingSphere();

  const letterMat = new THREE.MeshLambertMaterial();
  const letterMesh = new THREE.Mesh(letterGeom, letterMat);
  letterMesh.size = letterMesh.geometry.boundingBox.getSize(new THREE.Vector3());

  const box = new CANNON.Box(new CANNON.Vec3().copy(letterMesh.size).scale(0.5));
  const { center } = letterMesh.geometry.boundingSphere;
  const { ref, body } = useCannon({ bodyProps: { mass: 10 } }, body => {
    body.addShape(box, new CANNON.Vec3(center.x, center.y, center.z));
    body.position.set(...position);
  }, []);

  const bind = useDrag(({ offset: [,], xy: [x, y], first, last }) => {
    if (first) {
      body.mass = 0;
      body.updateMassProperties();
    } else if (last) {
      body.mass = 10000;
      body.updateMassProperties();
    }
    body.position.set((x - size.width / 2) / aspect, -(y - size.height / 2) / aspect, -0.7);
  }, { pointerEvents: true });

  useFrame(() => {
    const deltaX = Math.abs(body.position.x - position[0]);
    const deltaY = Math.abs(body.position.y - position[1]);
    const deltaZ = Math.abs(body.position.z - position[2]);
    if (deltaX > 0.001 || deltaY > 0.001 || deltaZ > 0.001) {
      setPosition(body.position.clone().toArray());
    }
    const bodyQuaternion = body.quaternion.toArray();
    const quaternionDelta = bodyQuaternion.map((n, idx) => Math.abs(n - quaternion[idx]))
      .reduce((acc, curr) => acc + curr);
    if (quaternionDelta > 0.01) {
      setQuaternion(body.quaternion.toArray());
    }
  });

  // extend TextGeometry to THREE
  extend({ TextGeometry })

  return (
    <mesh ref={ref} castShadow position={position} quaternion={quaternion} {...bind()}
      onClick={e => {
        e.stopPropagation();
      }}
    >
      <textGeometry attach='geometry' args={[letter, textOptions]} />
      <meshLambertMaterial attach='material' color="lightcoral" />
    </mesh>
  );
}

控制台错误信息

THREE.BufferGeometry.computeBoundingSphere():计算得到的半径为NaN,推测"position"属性存在NaN值。
TextGeometry {isBufferGeometry: true, uuid: '49e5c324-9134-407e-962f-6ff170a6afb7', name: '', type: 'TextGeometry', index: null, …}
attributes:
normal: BufferAttribute {isBufferAttribute: true, name: '', array: Float32Array(12852), itemSize: 3, count: 4284, …}
position: Float32BufferAttribute
array: Float32Array(12852) [NaN, NaN, -0.30000001192092896, NaN, NaN, -0.30000001192092896, NaN, NaN, -0.30000001192092896, NaN, NaN, -0.30000001192092896, NaN, NaN, -0.30000001192092896, NaN, NaN, -0.30000001192092896, NaN, NaN, -0.30000001192092896, NaN, NaN, -0.30000001192092896, NaN, NaN, -0.30000001192092896, NaN, NaN, -0.30000001192092896, 0.0689999982714653, 0.4771421253681183, -0.30000001192092896, NaN, NaN, -0.30000001192092896, NaN, NaN, -0.30000001192092896, NaN, NaN, -0.30000001192092896, NaN, NaN, -0.30000001192092896, NaN, NaN, -0.30000001192092896, NaN, NaN, -0.30000001192092896, NaN, NaN, -0.30000001192092896, NaN, NaN, -0.30000001192092896, NaN, NaN, -0.30000001192092896, NaN, NaN, -0.30000001192092896, NaN, NaN, -0.30000001192092896, 0.8880000114440918, 0.5088578462600708, -0.30000001192092896, NaN, NaN, -0.30000001192092896, NaN, NaN, -0.30000001192092896, NaN, NaN, -0.30000001192092896, NaN, NaN, -0.30000001192092896, NaN, NaN, -0.30000001192092896, NaN, NaN, -0.30000001192092896, NaN, NaN, -0.30000001192092896, NaN, NaN, -0.30000001192092896, NaN, NaN, -0.30000001192092896, NaN, NaN, -0.30000001192092896, NaN, …]
count: 4284
isBufferAttribute: true
itemSize: 3
name: ""
normalized: false
updateRange: {offset: 0, count: -1}
usage: 35044
version: 0
[[Prototype]]: BufferAttribute
uv: Float32BufferAttribute {isBufferAttribute: true, name: '', array: Float32Array(8568), itemSize: 2, count: 4284, …}
[[Prototype]]: Object
boundingBox: Box3 {isBox3: true, min: Vector3, max: Vector3}
boundingSphere: Sphere
center: Vector3
x: 0.47850000485777855
y: 0.49300000071525574
z: 0
[[Prototype]]: Object
radius: NaN
[[Prototype]]: Object
drawRange: {start: 0, count: Infinity}
groups: (2) [{…}, {…}]
index: null
isBufferGeometry: true
morphAttributes: {}
morphTargetsRelative: false
name: ""
parameters: {shapes: Array(1), options: {…}}
type: "TextGeometry"

内容的提问来源于stack exchange,提问作者paq

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 15:33:34