THREE.InterleavedBuffer는 단일 배열에 용도가 다른 데이터를 섞어 저장해 사용할 수 있도록 해주는 클래스로써 메모리와 퍼포먼스 양쪽 측면 모두에 대해 최적화할 수 있습니다.
예를들어 다음처럼 하나의 배열에 정점의 위치와 색상 값을 저장하고 있습니다.
// 1. 하나의 배열에 위치(3)와 색상(3) 데이터를 교차해서 넣습니다. // 구조: [ X, Y, Z, R, G, B, ... ] const arrayBuffer = new Float32Array([ // 좌하단 정점 -1.0, -1.0, 0.0, 1.0, 0.0, 0.0, // Pos(XYZ), Color(RGB) // 우하단 정점 1.0, -1.0, 0.0, 0.0, 1.0, 0.0, // 우상단 정점 1.0, 1.0, 0.0, 0.0, 0.0, 1.0, // 좌상단 정점 -1.0, 1.0, 0.0, 1.0, 1.0, 0.0 ]);
위의 배열 하나에 대해 정점과 색상에 대한 데이터를 별도의 Attribute로 쪼개 GPU에 전달하기 위해 THREE.InterleavedBuffer 객체를 생성합니다.
// 2. InterleavedBuffer 생성 // 하나의 정점 데이터 크기(Stride)는 6 (XYZ + RGB)입니다. const interleavedBuffer = new THREE.InterleavedBuffer(arrayBuffer, 6);
이제 지오메트리 객체를 생성해서 앞서 만든 THREE.InterleavedBuffer 객체를 통해 정점과 색상에 대한 Attribute 데이터를 주입합니다.
// 3. BufferGeometry 생성 및 InterleavedBufferAttribute 연결
const geometry = new THREE.BufferGeometry();
// 위치(position) 속성: 데이터 크기는 3(XYZ), 시작 오프셋은 0
geometry.setAttribute('position', new THREE.InterleavedBufferAttribute(interleavedBuffer, 3, 0));
// 색상(color) 속성: 데이터 크기는 3(RGB), 시작 오프셋은 3 (XYZ 다음이므로)
geometry.setAttribute('color', new THREE.InterleavedBufferAttribute(interleavedBuffer, 3, 3));
인덱스 데이터도 주입해야겠죠.
// 4. 인덱스 버퍼 설정 (삼각형 2개로 사각형 구성) const indices = new Uint16Array([ 0, 1, 2, 0, 2, 3 ]); geometry.setIndex(new THREE.BufferAttribute(indices, 1));
이제 Mesh를 생성합니다.
// 5. 메쉬 생성 (정점 색상을 사용하기 위해 vertexColors: true 설정)
const material = new THREE.MeshBasicMaterial({ vertexColors: true, side: THREE.DoubleSide });
const mesh = new THREE.Mesh(geometry, material);
this.scene.add(mesh);
THREE.InterleavedBufferd의 장점은 다음과 같습니다.
- GPU 캐시 효율성: GPU가 화면에 점을 그릴 때, 특정 정점의 위치를 읽어오면서 바로 옆에 있는 색상 데이터도 함께 캐시에 로드하므로 메모리 접근 속도가 빨라집니다.
- 단일 버퍼 관리: 여러 개의 버퍼를 바인딩할 필요 없이 하나의 큰 버퍼만 GPU에 넘겨주면 되므로 오버헤드가 줄어듭니다.
