Instancing Mesh
인스턴싱 메시(Instancing Mesh)는 동일한 지오메트리와 재질을 공유하는 수천, 수만 개의 객체를 단 한 번의 드로우 콜(Draw Call)로 렌더링하는 고성능 객체입니다. 숲 (나무), 잔디, 군중 등을 표현할 때 필수적입니다.
1. 왜 인스턴싱인가?
일반적인 Mesh를 1만 개 생성하여 씬에 추가하면 1만 번의 드로우 콜이 발생하여 CPU 오버헤드로 인해 프레임이 급격히 떨어집니다. 반면, InstancingMesh는 데이터들을 하나의 버퍼로 묶어 단 1번의 드로우 콜로 GPU에 전송하여 처리하므로 압도적인 렌더링 성능을 제공합니다.
2. 기본 사용법
InstancingMesh는 생성 시 할당할 최대 인스턴스 개수 (maxInstanceCount)와 초기 활성 개수 (instanceCount)를 지정해야 합니다.
import * as RedGPU from "https://redcamel.github.io/RedGPU/dist/index.js";
// 1. 최대 10만 개 공간 할당, 초기 5,000개 설정
const maxCount = 100000;
const initCount = 5000;
const geometry = new RedGPU.Primitive.Box(redGPUContext);
const material = new RedGPU.Material.PhongMaterial(redGPUContext);
const instancedMesh = new RedGPU.Display.InstancingMesh(
redGPUContext,
maxCount, // 최대 버퍼 크기 (생성 후 변경 불가)
initCount, // 현재 렌더링할 개수 (`instanceCount`로 동적 변경 가능)
geometry,
material
);
scene.addChild(instancedMesh);3. 개별 인스턴스 제어
instancedMesh.instanceChildren 배열을 통해 각 인스턴스 (InstancingMeshObject3D)의 트랜스폼 (위치, 회전, 크기)과 불투명도 (opacity)를 개별적으로 제어할 수 있습니다.
// 각 인스턴스 위치, 회전, 스케일, 불투명도 설정
const instances = instancedMesh.instanceChildren;
for (let i = 0; i < instancedMesh.instanceCount; i++) {
const instance = instances[i];
// 위치 설정
instance.setPosition(
Math.random() * 100 - 50,
Math.random() * 100 - 50,
Math.random() * 100 - 50
);
// 회전, 스케일 및 불투명도 설정
instance.rotationY = Math.random() * 360;
instance.scale = Math.random() * 2 + 0.5;
instance.opacity = Math.random() * 0.5 + 0.5;
}[자식 구조 제약]
InstancingMesh의 자식 인스턴스 (InstancingMeshObject3D)는 일반 Mesh와 유사한 트랜스폼 인터페이스를 가지지만, 독립된 3D 객체가 아니라 GPU 인스턴싱 버퍼 데이터를 제어하는 대리자 객체입니다. 따라서 addChild() 등을 통해 하위 자식 객체를 계층적으로 가질 수 없습니다.
4. 실습 예제: 대량 인스턴스 제어
슬라이더를 조작하여 활성 인스턴스 개수 (instanceCount)를 실시간으로 변경하고 성능을 확인해 보세요.
관련 예제
다음 학습 추천
3D 공간 내에서 항상 카메라를 마주보거나 간결한 2D 리소스를 효과적으로 활용하는 방법에 대해 알아봅니다.