매시는 하나의 지오메트리와 2개 이상의 재질로 정의됩니다. three.js 중급 개발자라면 메시가 1개가 아닌 2개 이상의 재질로 정의된다는 점에 의구심을 가질 수 있을텐데요. 하지만 맞습니다. 매시는 2개 이상의 재질을 갖습니다. 하지만 지오메트리는 1개입니다. 이상하죠? 지오메트리가 1개면 그에 대한 재질도 1개여야 맞는거 같은데 말이죠. 그래서 지오메트리의 구성 좌표를 그룹화할 수 있습니다. 재질이 2개라면 2개의 그룹으로 지오메트리의 구성 좌표를 구성하는거죠.
예를들어 다음과 같은 결과를 봅시다.
SphereGeometry로 만든 매시입니다. 그런데 위 아래로 다른 재질이 부여되어 있습니다. 마치 2개의 매시를 뭍여 놓은 것처럼요.
아래는 코드입니다.
const geom = new THREE.SphereGeometry(2); const indexCount = geom.index.count; const midIndex = Math.floor(indexCount / 2); geom.clearGroups(); geom.addGroup(0, midIndex, 0); geom.addGroup(midIndex, indexCount - midIndex, 1); const mesh = new THREE.Mesh(geom, [ new THREE.MeshPhysicalMaterial({ metalness: 1, roughness: 0 }), new THREE.MeshNormalMaterial() ]); scene.add(mesh);
지오메트리에 대한 2개의 그룹핑, 2개의 재질을 적용해 만든 매시에 대한 코드가 보이죠? 지오메트리에 대한 정점의 그룹핑 단위는 인덱스(삼각형을 구성하는 인덱스)입니다. 하지만 경우에 따라서 인덱스가 아닌 정점 하나 하나를 지정해서 만든 넌-인덱스 방식도 존재합니다. 아래는 결과는 동일하지만 넌-인덱스 방식의 지오메트리에 대한 그룹핑 코드입니다.
let geom = new THREE.SphereGeometry(2, 128, 64); geom = geom.toNonIndexed(); // Non-indexed 지오메트리 const vertexCount = geom.getAttribute("position").count; const midVertex = Math.floor(vertexCount / 2); geom.clearGroups(); geom.addGroup(0, midVertex, 0); geom.addGroup(midVertex, vertexCount - midVertex, 1); const mesh = new THREE.Mesh(geom, [ new THREE.MeshPhysicalMaterial({ metalness: 1, roughness: 0 }), new THREE.MeshNormalMaterial() ]); scene.add(mesh);
이번에는 지오메트리에 대한 2개의 그룹을 만들기 위해 버텍스에 대한 인덱스를 사용한 것을 알 수 있습니다.
여튼 지금까지 봤던 three.js에서의 지오메트리에 대한 그룹핑과 매시에 여러개의 재질을 지정할 수 있다는 것을 아셔야, 3D 모델링 툴에서 만들어진 모델들의 구성을 이해할 수 있게 됩니다.