instancedMesh instead of drei instances: much higher performance

This commit is contained in:
azykov@mail.ru
2026-06-13 19:56:45 +03:00
parent 6a16d39d88
commit 4fcb542eb8
@@ -1,7 +1,7 @@
import type { ObjectType, RuntimeGameObjectInstance, RuntimeObjectInstance } from "../types";
import { useEffect, useImperativeHandle, useRef, type Ref } from "react";
import { Euler, Quaternion, type Group } from "three";
import { Instance, Instances } from "@react-three/drei";
import type { VoxelGroup } from "../types/runtime/voxelGroup";
import { useEffect, useImperativeHandle, useLayoutEffect, useRef, type Ref, memo } from "react";
import { Euler, Matrix4, Quaternion, type Group, type InstancedMesh } from "three";
import type { ThreeEvent } from "@react-three/fiber";
import { ConvexHullCollider, RapierRigidBody } from "@react-three/rapier";
import { SyncRigidBody } from "./SyncRigidBody";
@@ -9,6 +9,30 @@ import { reaction, runInAction } from "mobx";
import { v3toRapier } from "../utils";
import { state } from "../state";
const _m4 = new Matrix4();
const VoxelGroupMesh = memo(function VoxelGroupMesh({ vg }: { vg: VoxelGroup }) {
const ref = useRef<InstancedMesh>(null);
useLayoutEffect(() => {
const mesh = ref.current;
if (!mesh)
return;
vg.positions.forEach(([x, y, z], i) => {
mesh.setMatrixAt(i, _m4.makeTranslation(x, y, z));
});
mesh.instanceMatrix.needsUpdate = true;
mesh.computeBoundingSphere();
}, [vg]);
return (
<instancedMesh ref={ref} args={[undefined, undefined, vg.positions.length]}>
<boxGeometry args={[1, 1, 1]} />
<meshStandardMaterial color={vg.color} opacity={vg.opacity} transparent={vg.opacity < 1} />
</instancedMesh>
);
});
export type ObjectViewInternalHandle = {
group: Group | null;
rb: RapierRigidBody | null;
@@ -118,11 +142,7 @@ export const ObjectViewInternal = function ({ object, objectType, ref, ...props
>
{
object.cache.voxelGroups.map((vg) =>
<Instances key={`${vg.id}-${object.cache.updatedAt}`} limit={vg.positions.length}>
<boxGeometry args={[1, 1, 1]} />
<meshStandardMaterial color={vg.color} opacity={vg.opacity} transparent={vg.opacity < 1} />
{vg.positions.map((pos, i) => <Instance key={i} position={pos} />)}
</Instances>
<VoxelGroupMesh key={`${vg.id}-${object.cache.updatedAt}`} vg={vg} />
)
}
{object.cache.colliderMesh && <ConvexHullCollider args={[object.cache.colliderMesh[0]]} />}