인스턴스드 매시는 다음처럼 생성할 수 있습니다. 지오메트리의 좌표 구성을 위해 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);
