使用React 3 Fiber构建仓库布局,在构建1/10项目时开始冻结

问题描述 投票:0回答:1

我正在尝试创建仓库的 3D 布局,但即使我构建了项目的一小部分,它也开始在第一人称移动中冻结。所以我想知道是否可以在 R3F 中创建这样的项目,或者我是否没有使用正确的结构。

我会提供我的一些代码。

const generateBoxPositions = () => {
  const positions = [];
  for (let i = 0; i < 5; i++) {
    for (let j = 0; j < 5; j++) {
      positions.push([-4 + j * 2, i * 1.5 + 0.5, 0]); // Adjust position
    }
  }
  return positions;
};

const Box = ({ position }) => (
  <mesh position={position}>
    <boxGeometry args={[1.5, 1, 1]} />
    <meshStandardMaterial color="brown" />
  </mesh>
);
const Shelf = ({ position, color }) => (
  <group position={position}>
    <group>
      {[...Array(5)].map((_, i) => (
        <mesh key={i} position={[0, i * 1.5, 0]}>
          <boxGeometry args={[10, 0.1, 2]} />
          <meshStandardMaterial color={color} />
        </mesh>
      ))}
      {[...Array(2)].map((_, i) => (
        <mesh key={i} position={[i === 0 ? -4.8 : 4.8, 3, 0]}>
          <boxGeometry args={[0.2, 7, 2]} />
          <meshStandardMaterial color={color} />
        </mesh>
      ))}
    </group>
    {generateBoxPositions().map((pos, index) => (
      <Box key={index} position={pos} />
    ))}
  </group>
);

export default Shelf;

我在这个组件中使用这个通用架子

import Shelf from "../Shelf";

export default function Row({ position, color }) {
  return (
    <group position={position}>
      <Shelf position={[0, 0, 0]} color={color} />
      <Shelf position={[0, 0, 2.1]} color={color} />
    </group>
  );
}

当我完成一排架子时,我正在为一个区域创建行

import React from "react";
import Shelf from "../../Generic/Shelf";
import Row from "../../Generic/Row";

export default function S112() {
  return (
    <group>
      <group position={[0, 0, 0]}>
        <Row position={[0, 0, 0]} color={"grey"} />
        <Row position={[0, 0, 8]} color={"grey"} />
        <Row position={[0, 0, 16]} color={"grey"} />
        <Row position={[0, 0, 24]} color={"grey"} />
        <Row position={[0, 0, 32]} color={"grey"} />
        <Row position={[0, 0, 40]} color={"grey"} />
        <Row position={[0, 0, 48]} color={"grey"} />
        <Row position={[0, 0, 56]} color={"grey"} />
        <Row position={[0, 0, 64]} color={"grey"} />
        <Row position={[0, 0, 72]} color={"grey"} />
        <Row position={[0, 0, 80]} color={"grey"} />
        <Row position={[0, 0, 88]} color={"grey"} />
        <Row position={[0, 0, 96]} color={"grey"} />
      </group>
      <group position={[30, 0, 0]}>
        <Row position={[0, 0, 0]} color={"grey"} />
        <Row position={[0, 0, 8]} color={"grey"} />
        <Row position={[0, 0, 16]} color={"grey"} />
        <Row position={[0, 0, 24]} color={"grey"} />
        <Row position={[0, 0, 32]} color={"grey"} />
        <Row position={[0, 0, 40]} color={"grey"} />
        <Row position={[0, 0, 48]} color={"grey"} />
        <Row position={[0, 0, 56]} color={"grey"} />
        <Row position={[0, 0, 64]} color={"grey"} />
        <Row position={[0, 0, 72]} color={"grey"} />
        <Row position={[0, 0, 80]} color={"grey"} />
        <Row position={[0, 0, 88]} color={"grey"} />
        <Row position={[0, 0, 96]} color={"grey"} />
      </group>
      <group position={[45, 0, 0]}>
        <Row position={[0, 0, 0]} color={"grey"} />
        <Row position={[0, 0, 8]} color={"grey"} />
        <Row position={[0, 0, 16]} color={"grey"} />
        <Row position={[0, 0, 24]} color={"grey"} />
        <Row position={[0, 0, 32]} color={"grey"} />
        <Row position={[0, 0, 40]} color={"grey"} />
        <Row position={[0, 0, 48]} color={"grey"} />
        <Row position={[0, 0, 56]} color={"grey"} />
        <Row position={[0, 0, 64]} color={"grey"} />
        <Row position={[0, 0, 72]} color={"grey"} />
        <Row position={[0, 0, 80]} color={"grey"} />
        <Row position={[0, 0, 88]} color={"grey"} />
        <Row position={[0, 0, 96]} color={"grey"} />
      </group>
      <group position={[70, 0, 0]}>
        <Row position={[0, 0, 0]} color={"grey"} />
        <Row position={[0, 0, 8]} color={"grey"} />
        <Row position={[0, 0, 16]} color={"grey"} />
        <Row position={[0, 0, 24]} color={"grey"} />
        <Row position={[0, 0, 32]} color={"grey"} />
        <Row position={[0, 0, 40]} color={"grey"} />
        <Row position={[0, 0, 48]} color={"grey"} />
        <Row position={[0, 0, 56]} color={"grey"} />
        <Row position={[0, 0, 64]} color={"grey"} />
        <Row position={[0, 0, 72]} color={"grey"} />
        <Row position={[0, 0, 80]} color={"grey"} />
        <Row position={[0, 0, 88]} color={"grey"} />
        <Row position={[0, 0, 96]} color={"grey"} />
      </group>
      <group position={[85, 0, 0]}>
        <Row position={[0, 0, 0]} color={"grey"} />
        <Row position={[0, 0, 8]} color={"grey"} />
        <Row position={[0, 0, 16]} color={"grey"} />
        <Row position={[0, 0, 24]} color={"grey"} />
        <Row position={[0, 0, 32]} color={"grey"} />
        <Row position={[0, 0, 40]} color={"grey"} />
        <Row position={[0, 0, 48]} color={"grey"} />
        <Row position={[0, 0, 56]} color={"grey"} />
        <Row position={[0, 0, 64]} color={"grey"} />
        <Row position={[0, 0, 72]} color={"grey"} />
        <Row position={[0, 0, 80]} color={"grey"} />
        <Row position={[0, 0, 88]} color={"grey"} />
        <Row position={[0, 0, 96]} color={"grey"} />
      </group>
    </group>
  );
}

因此我有超过 10 个区域,我需要一些创建对象的方法

我尝试使用 InstancedMesh 来减少由于对象数量而导致的冻结,但无论如何我在我的应用程序中遇到了这种冻结

reactjs react-three-fiber r3f
1个回答
0
投票

像往常一样,让某件事变得更快的诀窍是让它做更少的工作。

渲染 20 个

<S112>
副本的示例通过一些更改即可渲染得更快:

  • 每次渲染
    generateBoxPositions()
    时,您都会再次调用
    Shelf
    – 记住结果(或将其分配给全局变量,如下所示)。同样,对于包含 5 项内容的数组,不要使用
    new Array(5)
    ,只需将其写出来...
  • 仅计算一次架子和盒子的几何形状以及材料并重复使用它们。 (请参阅文档。) 这可以节省大量 WebGL 绘制调用。
  • 使用
    drei
    <Instances>
    <Instance>
    渲染每个架子上的重复框,将它们合并到一个绘制调用中。
function generateBoxPositions() {
  const positions: [number, number, number][] = [];
  for (let i = 0; i < 5; i++) {
    for (let j = 0; j < 5; j++) {
      positions.push([-4 + j * 2, i * 1.5 + 0.5, 0]); // Adjust position
    }
  }
  return positions;
}

const boxPositions = generateBoxPositions();

const materialsByColor = {};
function getMaterialWithColor(color) {
  if (!materialsByColor[color]) {
    materialsByColor[color] = new THREE.MeshStandardMaterial({ color });
  }
  return materialsByColor[color];
}

const brownMaterial = getMaterialWithColor("brown");
const itemBoxGeometry = new THREE.BoxGeometry(1.5, 1, 1);
const shelfLongGeometry = new THREE.BoxGeometry(10, 0.1, 2);
const shelfEndGeometry = new THREE.BoxGeometry(0.2, 7, 2);

function Shelf({ position, color }) {
  const shelfMat = getMaterialWithColor(color);
  return (
    <group position={position}>
      {[0, 1, 2, 3, 4].map((i) => (
        <mesh
          key={i}
          position={[0, i * 1.5, 0]}
          material={shelfMat}
          geometry={shelfLongGeometry}
        />
      ))}
      {[0, 1].map((i) => (
        <mesh
          key={i}
          position={[i === 0 ? -4.8 : 4.8, 3, 0]}
          material={shelfMat}
          geometry={shelfEndGeometry}
        />
      ))}
      <Instances geometry={itemBoxGeometry} material={brownMaterial}>
        {boxPositions.map((pos, index) => (
          <Instance key={index} position={pos} />
        ))}
      </Instances>
    </group>
  );
}
© www.soinside.com 2019 - 2024. All rights reserved.