我正在尝试创建仓库的 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 来减少由于对象数量而导致的冻结,但无论如何我在我的应用程序中遇到了这种冻结
像往常一样,让某件事变得更快的诀窍是让它做更少的工作。
渲染 20 个
<S112>
副本的示例通过一些更改即可渲染得更快:
generateBoxPositions()
时,您都会再次调用 Shelf
– 记住结果(或将其分配给全局变量,如下所示)。同样,对于包含 5 项内容的数组,不要使用 new Array(5)
,只需将其写出来...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>
);
}