"매 InstancedMesh 매 1 draw call로 N copies — but 매 frustum culling, material variation, animation, picking 의 cost가 instance 수에 따라 explode.". 매 naive 사용 시 draw call 매 줄어들어도 GPU vertex/fragment 매 burden, CPU matrix update 매 bottleneck. 매 production 매 LOD + spatial partition + GPU culling 매 결합.
매 핵심
매 한계 list
No per-instance frustum culling: 매 single bounding sphere → 매 모든 instance가 frustum 안에 있다고 GPU가 가정.
No per-instance material: 매 same material → color/texture variation 매 instanceColor / instance attribute 의 manual.
Animation cost: 매 instance마다 matrix update → CPU bound at 10k+.
Picking 어려움: raycaster 매 instance index 매 별도 처리.
Memory: 16 floats × N instances = 매 1M instances → 64MB matrix buffer.
Shadow map: 매 light 마다 또 한 번 instanced draw — culling 없으면 shadow waste.
매 case: 100k cubes
Naive InstancedMesh: 매 1 draw call, GPU 60fps but matrix update 60ms/frame on CPU.
Static (setMatrixAt once): 매 GPU bound, fillrate 매 issue → LOD 필요.
Dynamic: 매 매 frame matrix update → useDynamicDrawUsage + partial updates.
매 응용 (해결 전략)
GPU instancing + GPU culling: compute shader 매 frustum check, 매 indirect draw.
Spatial partitioning: octree / BVH로 매 chunk 단위 InstancedMesh.
LOD groups: distance 별 다른 InstancedMesh (high/med/low/billboard).
BatchedMesh (Three.js r170+): 매 different geometries를 single draw call.
Hierarchical LOD + impostor: 매 far away는 single quad billboard.
constbatched=newTHREE.BatchedMesh(maxGeoms,maxVerts,maxIdx);constgeoIdA=batched.addGeometry(geoA);constgeoIdB=batched.addGeometry(geoB);constinstA=batched.addInstance(geoIdA);batched.setMatrixAt(instA,matrixA);// 매 different geometries 매 single draw call
언제: 매 같은 geometry+material의 N copies, 매 N > 50, 매 draw call 매 hot path bottleneck.
언제 X: 매 highly varying geometry (use BatchedMesh), 매 < 50 copies (overhead > benefit), 매 fully dynamic mesh (skinning per instance은 expensive).
❌ 안티패턴
No bounding 갱신: 매 instance 매 spread out 매 single boundingSphere가 too large → frustum culling 작동 안 함.
매 frame full matrix rebuild: 매 instance 매 100% update assumption 매 wrong → updateRange 활용.
Different materials → multiple InstancedMesh: 매 점 defeats the purpose. Use texture atlas + instance attribute.
Skip LOD: 매 far instance 매 close instance와 same vertex count → fillrate explosion.
InstancedMesh on top of skinned mesh: 매 shader 매 manual instancing 필요 — Three.js native skinning 매 instance와 conflict.