【Three.js】正多面体の面に、それぞれ色を塗り分ける方法

17473 ワード

調べても、どこにも載っていなかったので、メモする。

前提条件

既にシーンやライト、カメラの設定は出来ている状態で進めます。

立方体の場合

立方体の各面に色を塗る場合は、
6面分の色を配列で用意して、指定すれば良い。

const geometryCube = new THREE.BoxGeometry(200, 200, 200);
const materialColors = [
  new THREE.MeshBasicMaterial({color: 0xff0000}),
  new THREE.MeshBasicMaterial({color: 0x0000ff}),
  new THREE.MeshBasicMaterial({color: 0x00ff00}),
  new THREE.MeshBasicMaterial({color: 0xffff00}),
  new THREE.MeshBasicMaterial({color: 0x00ffff}),
  new THREE.MeshBasicMaterial({color: 0xff00ff}),
];
const cube = new THREE.Mesh(geometryCube, materialColors);
scene.add(cube);

正多面体の場合

正多面体の場合、上記の指定だけでは、何も表示されない。
色々調べた結果、groups を設定することで色分けできる。
今回は正二十面体でやってみた。

const geometryCube = new THREE.IcosahedronGeometry(200); // 正二十面体 Geometry の作成
// 色の設定
const materialColors = [
  new THREE.MeshBasicMaterial({color: 0xff0000}),
  new THREE.MeshBasicMaterial({color: 0x0000ff}),
  new THREE.MeshBasicMaterial({color: 0x00ff00}),
  new THREE.MeshBasicMaterial({color: 0xffff00}),
  new THREE.MeshBasicMaterial({color: 0x00ffff}),
  new THREE.MeshBasicMaterial({color: 0xff00ff}),
  new THREE.MeshBasicMaterial({color: 0xcccccc}),
  new THREE.MeshBasicMaterial({color: 0xffffff}),
  new THREE.MeshBasicMaterial({color: 0xff9100}),
  new THREE.MeshBasicMaterial({color: 0x87322f}),
  new THREE.MeshBasicMaterial({color: 0x87322f}),
  new THREE.MeshBasicMaterial({color: 0xff9100}),
  new THREE.MeshBasicMaterial({color: 0xffffff}),
  new THREE.MeshBasicMaterial({color: 0xcccccc}),
  new THREE.MeshBasicMaterial({color: 0xff00ff}),
  new THREE.MeshBasicMaterial({color: 0x00ffff}),
  new THREE.MeshBasicMaterial({color: 0xffff00}),
  new THREE.MeshBasicMaterial({color: 0x00ff00}),
  new THREE.MeshBasicMaterial({color: 0x0000ff}),
  new THREE.MeshBasicMaterial({color: 0xff0000}),
];

// addGroup 関数を使って、Geometry に groups を設定する
// addGroup 関数 → https://threejs.org/docs/#api/en/core/BufferGeometry.addGroup
// start は、index 値を3の倍数で増やしていく(他の倍数でも可)
// count は面の数を指定する (今回は20)
// materialIndex は materialColors の index 値を指定する(この値が色分けの指標になる。今回は長さが同じなので、このまま index 値を指定する)
for (let i = 0; i < 20; i++) {
  geometryCube.addGroup(i * 3, 20, i);
}
const cube = new THREE.Mesh(geometryCube, materialColors);
scene.add(cube);

完成

20面それぞれ、色分けされて表示される