【Three.js】Geometry(ジオメトリ)の種類と変更方法-3Dモデルのデモ付きで紹介

2023年11月13日WebGL & Three.js

Three.jsのGeometry(ジオメトリ)の基本的な種類を実際に3Dモデルのデモを動かしながら確認してみてましょう。
もしThree.jsの基本的な操作の一連の流れを知らないという場合は、Three.jsの基本的な操作の一連の流れがとても短くまとめた記事なので参考にしてみてください。
具体的なコードとデモが見たい場合は、【WebGL&Three.js入門】Three.jsの一番シンプルなサンプルコードのチュートリアルの解説でデモもみれる状態にしているので参考にしてみてください。

Three.jsのGeometry(ジオメトリ)の基本的な種類のサンプル

さっそく3Dモデルのデモを確認してみましょう。

Three.jsのGeometry(ジオメトリ)をドキュメントで調べる方法

Three.jsの公式サイトのドキュメントにアクセスして、「geometry」と検索窓で検索します。
具体的には以下にアクセスするとgeometryを確認することができます。
https://threejs.org/docs/index.html?q=geometry#manual/en/introduction/Creating-a-scene

Three.jsの初期化 (initializeThreeJS 関数)

import * as THREE from "three";
export default function initializeThreeJS(geometryType) {
  const scene = new THREE.Scene();
  const camera = new THREE.PerspectiveCamera(
    75,
    window.innerWidth / window.innerHeight,
    0.1,
    1000
  );

  const renderer = new THREE.WebGLRenderer();
  renderer.setSize(window.innerWidth, window.innerHeight);

  document.body.appendChild(renderer.domElement);

  let geometry;
  switch (geometryType) {
    case "Box":
      geometry = new THREE.BoxGeometry();
      break;
    case "Capsule":
      geometry = new THREE.CapsuleGeometry();
      break;
    case "Circle":
      geometry = new THREE.CircleGeometry();
      break;
    case "Cone":
      geometry = new THREE.ConeGeometry();
      break;
    case "Cylinder":
      geometry = new THREE.CylinderGeometry();
      break;
    case "Dodecahedron":
      geometry = new THREE.DodecahedronGeometry();
      break;
    case "Edges":
      const baseGeometry = new THREE.BoxGeometry();
      geometry = new THREE.EdgesGeometry(baseGeometry);
      break;
    case "Extrude":
      geometry = new THREE.ExtrudeGeometry();
      break;
    case "Icosahedron":
      geometry = new THREE.IcosahedronGeometry();
      break;
    case "Lathe":
      geometry = new THREE.LatheGeometry();
      break;
    case "Octahedron":
      geometry = new THREE.OctahedronGeometry();
      break;
    case "Plane":
      geometry = new THREE.PlaneGeometry(2, 2);
      break;
    case "Polyhedron":
      const verticesOfPolyhedron = [
        /* 頂点の配列 */
        1, 1, 1,   // 頂点0
        -1, -1, 1, // 頂点1
        -1, 1, -1, // 頂点2
        1, -1, -1  // 頂点3
      ];
      const indicesOfFaces = [
        /* 面のインデックス配列 */
        2, 1, 0,   // 面0
        0, 3, 2,   // 面1
        1, 3, 0,   // 面2
        2, 3, 1    // 面3
      ];
      geometry = new THREE.PolyhedronGeometry(
        verticesOfPolyhedron,
        indicesOfFaces
      );
      break;
    case "Ring":
      geometry = new THREE.RingGeometry();
      break;
    case "Shape":
      geometry = new THREE.ShapeGeometry();
      break;
    case "Sphere":
      geometry = new THREE.SphereGeometry();
      break;
    case "Tetrahedron":
      geometry = new THREE.TetrahedronGeometry();
      break;
    case "Torus":
      geometry = new THREE.TorusGeometry();
      break;
    case "TorusKnot":
      geometry = new THREE.TorusKnotGeometry();
      break;
    case "Tube":
      geometry = new THREE.TubeGeometry();
      break;
    case "Wireframe":
      const wireframeBaseGeometry = new THREE.BoxGeometry();
      geometry = new THREE.WireframeGeometry(wireframeBaseGeometry);
      break;
    default:
      console.warn("Unknown geometry type: " + geometryType);
      return;
  }
  const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
  const cube = new THREE.Mesh(geometry, material);
  scene.add(cube);

  camera.position.z = 5;

  function animate() {
    requestAnimationFrame(animate);
    cube.rotation.x = cube.rotation.x + 0.01;
    cube.rotation.y += 0.01;

    renderer.render(scene, camera);
  }

  animate();
}

流れはいつもと同じで以下の通りです。

シーン、カメラ、レンダラーの設定

Scene, PerspectiveCamera, WebGLRendererのインスタンスを作成します。
カメラの位置を設定し、レンダラーのサイズをウィンドウのサイズに合わせます。

ジオメトリの生成

引数geometryTypeに基づいて、さまざまなタイプのジオメトリ(Box, Sphere, Cylinderなど)を生成します。
ジオメトリのタイプはswitch文で管理されており、各ケースは特定のジオメトリを作成します。

今回はここがメインですのでコード解説します。

let geometry;
  switch (geometryType) {
    case "Box":
      geometry = new THREE.BoxGeometry();
      break;
    case "Capsule":
      geometry = new THREE.CapsuleGeometry();
      break;
    case "Circle":
      geometry = new THREE.CircleGeometry();
      break;
    case "Cone":
      geometry = new THREE.ConeGeometry();
      break;
    case "Cylinder":
      geometry = new THREE.CylinderGeometry();
      break;
    case "Dodecahedron":
      geometry = new THREE.DodecahedronGeometry();
      break;
    case "Edges":
      const baseGeometry = new THREE.BoxGeometry();
      geometry = new THREE.EdgesGeometry(baseGeometry);
      break;
    case "Extrude":
      geometry = new THREE.ExtrudeGeometry();
      break;
    case "Icosahedron":
      geometry = new THREE.IcosahedronGeometry();
      break;
    case "Lathe":
      geometry = new THREE.LatheGeometry();
      break;
    case "Octahedron":
      geometry = new THREE.OctahedronGeometry();
      break;
    case "Plane":
      geometry = new THREE.PlaneGeometry(2, 2);
      break;
    case "Polyhedron":
      const verticesOfPolyhedron = [
        /* 頂点の配列 */
        1, 1, 1,   // 頂点0
        -1, -1, 1, // 頂点1
        -1, 1, -1, // 頂点2
        1, -1, -1  // 頂点3
      ];
      const indicesOfFaces = [
        /* 面のインデックス配列 */
        2, 1, 0,   // 面0
        0, 3, 2,   // 面1
        1, 3, 0,   // 面2
        2, 3, 1    // 面3
      ];
      geometry = new THREE.PolyhedronGeometry(
        verticesOfPolyhedron,
        indicesOfFaces
      );
      break;
    case "Ring":
      geometry = new THREE.RingGeometry();
      break;
    case "Shape":
      geometry = new THREE.ShapeGeometry();
      break;
    case "Sphere":
      geometry = new THREE.SphereGeometry();
      break;
    case "Tetrahedron":
      geometry = new THREE.TetrahedronGeometry();
      break;
    case "Torus":
      geometry = new THREE.TorusGeometry();
      break;
    case "TorusKnot":
      geometry = new THREE.TorusKnotGeometry();
      break;
    case "Tube":
      geometry = new THREE.TubeGeometry();
      break;
    case "Wireframe":
      const wireframeBaseGeometry = new THREE.BoxGeometry();
      geometry = new THREE.WireframeGeometry(wireframeBaseGeometry);
      break;
    default:
      console.warn("Unknown geometry type: " + geometryType);
      return;
  }

ここでは単にswitch文でTHREE. ● ●Geometryをインスタンス化しているだけです。
なので、変更したい場合は、上の ● ●部分を探して希望のものに差し替えるだけで、他のコードを流用して変更することができます。

Three.jsのこのスクリプトでは、上のように様々な3Dジオメトリタイプが使用されています。
それぞれのジオメトリタイプについて簡単に説明します:

BoxGeometry

箱形(立方体)のジオメトリです。幅、高さ、奥行きをパラメータとして持ちます。
基本的な使用法: new THREE.BoxGeometry(width, height, depth)。width, height, depthはそれぞれ幅、高さ、奥行きを指定します。

CapsuleGeometry

カプセル形状のジオメトリです。両端が半球で、中央が円柱形状です。
使用法: new THREE.CapsuleGeometry(radius, length, radialSegments, heightSegments)。radiusは半球の半径、lengthは中央部の長さ、radialSegmentsとheightSegmentsは形状の滑らかさを決定します。

CircleGeometry

円形のジオメトリです。半径とセグメントの数(円の滑らかさ)をパラメータとして持ちます。
使用法: new THREE.CircleGeometry(radius, segments)。radiusは円の半径、segmentsは円の滑らかさを決定します。

ConeGeometry

円錐形のジオメトリです。頂点から底面までの高さと底面の半径をパラメータとして持ちます。

使用法: new THREE.ConeGeometry(radius, height, radialSegments)。radiusは底面の半径、heightは高さ、radialSegmentsは円錐の滑らかさを決定します。

CylinderGeometry

円筒形のジオメトリです。上面と下面の半径、高さ、および面の数をパラメータとして持ちます。
使用法: new THREE.CylinderGeometry(radiusTop, radiusBottom, height, radialSegments)。radiusTopとradiusBottomは上下の半径、heightは高さ、radialSegmentsは円筒の滑らかさを決定します。

DodecahedronGeometry

正十二面体のジオメトリです。12個の正五角形の面で構成されています。
使用法: new THREE.DodecahedronGeometry(radius, detail)。radiusは形状のサイズを決定し、detailは形状の複雑さを制御します。

EdgesGeometry

他のジオメトリのエッジ(角)だけを取り出して生成されるジオメトリです。ワイヤーフレームのような見た目になります。
使用法: new THREE.EdgesGeometry(geometry)。geometryは既存のThree.jsジオメトリオブジェクトです。

ExtrudeGeometry

2Dの形状を押し出して3Dオブジェクトを作成するジオメトリです。
使用法: new THREE.ExtrudeGeometry(shape, options)。shapeは2D形状、optionsは押し出し方法を指定します。

IcosahedronGeometry

正二十面体のジオメトリです。20個の正三角形の面で構成されています。
使用法: new THREE.IcosahedronGeometry(radius, detail)。radiusは形状のサイズを決定し、detailは形状の複雑さを制御します。

LatheGeometry

旋盤(ろくろ)で形作られるような回転対称の形状を作成するジオメトリです。
使用法: new THREE.LatheGeometry(points, segments, phiStart, phiLength)。pointsは形状の輪郭を定義する2Dベクトルの配列、segmentsは滑らかさを決定します。

OctahedronGeometry

正八面体のジオメトリです。8個の正三角形の面で構成されています。
使用法: new THREE.OctahedronGeometry(radius, detail)。radiusは形状のサイズを決定し、detailは形状の複雑さを制御します。

PlaneGeometry

平面のジオメトリです。幅と高さをパラメータとして持ちます。
使用法: new THREE.PlaneGeometry(width, height)。

PolyhedronGeometry

ポリヘドロン(多面体)のジオメトリです。頂点の配列と面のインデックス配列をパラメータとして持ちます。
使用法: new THREE.PolyhedronGeometry(vertices, indices, radius, detail)。verticesは頂点の配列、indicesは面のインデックス、radiusは形状のサイズ、detailは形状の複雑さを制御します。

RingGeometry

輪の形をしたジオメトリです。内半径と外半径をパラメータとして持ちます。
使用法: new THREE.RingGeometry(innerRadius, outerRadius, thetaSegments)。innerRadiusとouterRadiusは内外の半径、thetaSegmentsは輪の滑らかさを決定します。

ShapeGeometry

任意の2D形状から作成されるジオメトリです。
使用法: new THREE.ShapeGeometry(shape, options)。shapeは2D形状、optionsは形状の詳細を指定します。

SphereGeometry

球形のジオメトリです。半径、幅のセグメント数、高さのセグメント数をパラメータとして持ちます。
使用法: new THREE.SphereGeometry(radius, widthSegments, heightSegments)。radiusは球の半径、widthSegmentsとheightSegmentsは球の滑らかさを決定します。

TetrahedronGeometry

正四面体のジオメトリです。4個の正三角形の面で構成されています。
使用法: new THREE.TetrahedronGeometry(radius, detail)。radiusは形状のサイズを決定し、detailは形状の複雑さを制御します。

TorusGeometry

ドーナツ形のジオメトリです。主半径と管半径をパラメータとして持ちます。
使用法: new THREE.TorusGeometry(radius, tube, radialSegments, tubularSegments)。radiusはドーナツの主半径、tubeは管の半径、radialSegmentsとtubularSegmentsは形状の滑らかさを決定します。

TorusKnotGeometry

トーラスノット(ドーナツの表面を複雑な経路で巡る形状)のジオメトリです。
使用法: new THREE.TorusKnotGeometry(radius, tube, radialSegments, tubularSegments, p, q)。radius、tube、radialSegments、tubularSegmentsはトーラスと同様、pとqはノットの形状を決定します。

TubeGeometry

管状のジオメトリです。任意の曲線に沿って管を作成します。
使用法: new THREE.TubeGeometry(path, segments, radius, radialSegments, closed)。pathは3D曲線、segmentsは管の長さ、radiusは管の半径、radialSegmentsは管の滑らかさ、closedは管が閉じているかどうかを指定します。

WireframeGeometry

他のジオメトリのワイヤーフレームを生成するジオメトリです。
これらのジオメトリタイプは、Three.jsで3Dシーンを構築する際に多様な形状を提供します。それぞれのジオメトリは、特有のパラメータを持っており、これによって多種多様な3Dオブジェクトを作成することが可能になります。
使用法: new THREE.WireframeGeometry(geometry)。geometryは既存のThree.jsジオメトリオブジェクトです。

マテリアルとメッシュの設定

基本的なマテリアルを作成し、それを使用してメッシュ(3Dオブジェクト)を作成します。
このメッシュをシーンに追加します。

アニメーション関数

animate関数では、メッシュの回転を更新し、シーンを連続的にレンダリングします。

まとめ

Three.jsののジオメトリは、Three.jsで3Dビジュアライゼーションを行う際に基本的な構成要素となります。それぞれのジオメトリは特定のパラメータを持ち、これによって様々な形状とサイズの3Dオブジェクトを作成することが可能です。