인스턴스드 매시는 다음처럼 생성할 수 있습니다. 지오메트리의 좌표 구성을 위해 BoxGeometry의 것을 가져다 쓰는 경우입니다. 지오메트리의 index와 position만을 필요로 하니 아래처럼 했고, 그냥 new THREE.InstancedBufferGeometry.copy(baseGeometry)로 하면 지오메트리를 그대로 복사합니다.
const baseGeometry = new THREE.BoxGeometry(0.5, 0.5, 0.5); const geometry = new THREE.InstancedBufferGeometry(); geometry.index = baseGeometry.index; geometry.attributes.position = baseGeometry.attributes.position; // 위의 코드는 참조인지라 아래의 코드로 대체하는게 맞죠. // geometry.setIndex(baseGeometry.index); // geometry.setAttribute("position", baseGeometry.attributes.position);
인스턴스로 만들 개수를 지정해야 합니다.
const count = 100; geometry.instanceCount = count;
인스턴스화된 것들에 대한 개별 요소들은 위치, 회전, 크기, 색상에 대해 개별적으로 지정이 가능한데 위치와 색상에 대한 지정 코드입니다.
const offsets = new Float32Array(count * 3); for (let i = 0; i < count; i++) { offsets[i * 3 + 0] = (Math.random() - 0.5) * 10; // x offsets[i * 3 + 1] = (Math.random() - 0.5) * 10; // y offsets[i * 3 + 2] = (Math.random() - 0.5) * 10; // z } geometry.setAttribute("instanceOffset", new THREE.InstancedBufferAttribute(offsets, 3)); const colors = new Float32Array(count * 3); for (let i = 0; i < count; i++) { colors[i * 3 + 0] = Math.random(); // R colors[i * 3 + 1] = Math.random(); // G colors[i * 3 + 2] = Math.random(); // B } geometry.setAttribute("instanceColor", new THREE.InstancedBufferAttribute(colors, 3));
쉐이더를 통해 직접 인스턴스 매시를 렌더링하기 위해 재질을 설정하는 코드입니다.
const material = new THREE.ShaderMaterial({ vertexShader: /*glsl*/ ` attribute vec3 instanceOffset; attribute vec3 instanceColor; varying vec3 vColor; void main() { vec3 transformed = position + instanceOffset; vColor = instanceColor; gl_Position = projectionMatrix * modelViewMatrix * vec4(transformed, 1.0); } `, fragmentShader: /*glsl*/ ` varying vec3 vColor; void main() { gl_FragColor = vec4(vColor, 1.0); } ` });
이제 장면에 매시를 넣으면 화면에 딱... 표시되어야 합니다.
const mesh = new THREE.Mesh(geometry, material); this._scene.add(mesh);