actual batching

This commit is contained in:
tresabhi committed 2026-10-18 00:08:43 -05:00
1 parent 28c30f210e
commit 5c3ab2e10d
1 file changed
+27 -13
+27 -13
View File
@@ -33,7 +33,10 @@ interface BatchedProps extends ComponentProps<"group"> {
function useBatched(map: ObjectMap, shadows = false) { function useBatched(map: ObjectMap, shadows = false) {
return function Batched({ slicer, mutator, ...props }: BatchedProps) { return function Batched({ slicer, mutator, ...props }: BatchedProps) {
const groups = new Map<MeshStandardMaterial, Mesh[]>(); const groups = new Map<
MeshStandardMaterial,
{ clonedMaterial: MeshStandardMaterial; meshes: Mesh[] }
>();
for (const node of Object.values(map.nodes)) { for (const node of Object.values(map.nodes)) {
if (!slicer(node)) continue; if (!slicer(node)) continue;
@@ -41,44 +44,55 @@ function useBatched(map: ObjectMap, shadows = false) {
node.traverse((object) => { node.traverse((object) => {
if (!(object instanceof Mesh)) return; if (!(object instanceof Mesh)) return;
let material = object.material; const originalMaterial = object.material;
if (!(material instanceof MeshStandardMaterial)) return; if (!(originalMaterial instanceof MeshStandardMaterial)) return;
if (!groups.has(object.material)) { let group = groups.get(originalMaterial);
material = object.material.clone();
groups.set(material, []); if (!group) {
group = {
clonedMaterial: originalMaterial.clone(),
meshes: [],
};
groups.set(originalMaterial, group);
} }
groups.get(material)!.push(object.clone()); group.meshes.push(object);
}); });
} }
const wrapper = new Group(); const wrapper = new Group();
for (const [material, meshes] of groups) { for (const { clonedMaterial: material, meshes } of groups.values()) {
let vertices = 0; let vertices = 0;
let indices = 0;
for (const mesh of meshes) { for (const mesh of meshes) {
vertices += mesh.geometry.attributes.position.count; vertices += mesh.geometry.attributes.position.count;
indices += mesh.geometry.index!.count;
} }
const batched = new BatchedMesh( const batched = new BatchedMesh(
meshes.length, meshes.length,
vertices, vertices,
undefined, indices,
material, material,
); );
for (const mesh of meshes) { for (const mesh of meshes) {
const geometryId = batched.addGeometry(mesh.geometry);
const instanceId = batched.addInstance(geometryId);
mesh.updateWorldMatrix(true, false);
batched.setMatrixAt(instanceId, mesh.matrixWorld);
if (shadows) { if (shadows) {
mesh.castShadow = true; batched.castShadow = true;
mesh.receiveShadow = true; batched.receiveShadow = true;
} }
mutator?.(mesh); mutator?.(mesh);
batched.add(mesh);
} }
wrapper.add(batched); wrapper.add(batched);