チュートリアル WebGLでカスタムジオメトリを作成する

WebGLでカスタムジオメトリを作成する

By Dave Pagurek, Austin Lee Slominski, Adam Ferriss

p5.jsには、box()sphere()のような多くの組み込みの基本的な形状があります。また、3Dモデルファイルやコードから複雑なカスタムジオメトリをレンダリングすることもできます。このチュートリアルでは、3Dモデルをp5.jsにインポートする方法と、ゼロからジオメトリを作成する方法について説明します。

ファイルから3Dモデルを読み込む

カスタムジオメトリは、OBJファイルまたはSTLファイルを使用してp5.jsにインポートできます。これらのファイルは通常、Blenderのような3Dモデリングツールで生成され、3Dシーンを構築する際にはるかに多くの制御が可能です。これはloadModel()メソッドを使用して行われ、preload()内で使用する必要があります。その後、以下の例で示すように、model()関数を使用してモデルを描画できます。

カスタムモデルで発生する一般的な問題の1つはスケーリングです。モデルの構築方法によっては、p5.jsで描画したときにサイズが大きく異なったり、描画するには小さすぎたりする場合があります。loadModel()メソッドにはnormalizeパラメータがあり、これによりモデルのサイズをp5.jsでより適切に機能するようにリサイズします。

モデルファイルからマテリアルや色を読み込むサポートは現在ありません。モデルを読み込んだ後、色、マテリアル、テクスチャを手動で追加できます。

試してみよう!

オンラインで3Dモデルを見つけて、スケッチに統合してみてください!

プロシージャルジオメトリの作成

ジオメトリはコードを使用してプロシージャルに定義することもできます。これは、動くジオメトリや独自のルールセットを使用して形成されるジオメトリを作成するのに最適な方法です。2D描画と同様の方法で3Dジオメトリを作成するために使用できるメソッドがいくつかあります。例えば、quad()triangle()rect()circle()などの関数には、3Dで使用できるようにする追加のパラメータがあります。

ジオメトリをより細かく制御できる他の関数もあります。形状はbeginShape()vertex()endShape()を使用してポイントごとに定義できます。次の例は、これらの関数を使用して3D形状を構築する方法を示しています。

試してみよう!

beginShape(QUAD_STRIP)を使用して3Dの稲妻を作成できますか?

プロシージャルジオメトリの再利用

この方法は、時間とともに変化するカスタム形状を作成するのに最適です。時には、固定された形状だけが必要な場合や、形状を何度も効率的に描画したい場合があります。このために、p5.jsにはbuildGeometry()という関数があり、カスタム形状を読み込まれたモデルと同じ形式に変換します。パーティクルシステムを作成する予定がある場合、これは使用すべき良いツールです。

この関数は、いくつかの形状を描画する関数を受け取ります。そして、model()で好きなだけ描画できるジオメトリを出力します。

試してみよう!

buildGeometryを使用していくつかの雪の結晶を作成し、それらを使用して大きな雪降りを作成してみてください!

スムーズなシェーディング

法線は面に垂直な方向であり、p5.jsが表面全体の照明を計算するのに役立ちます。

面の法線を表す矢印が直接出ている三角形の面

面の法線を表す矢印が直接出ている三角形の面

接触している面間で共有されるすべての頂点が同じ法線を持っている限り、シェーディングはスムーズに見えます。各vertex(x, y, z)の前にnormal(x, y, z)を呼び出すことで法線を手動で指定できますが、p5.jsにはこれらを計算する機能が含まれています。次の例ではgeometry.calculateNormals(SMOOTH)を使用して、スムーズな照明を持つ歪んだチューブを作成しています。

試してみよう!

p5でスムーズで有機的な形状を作ってみてください。フランク・ゲーリーのスタイルで、スムーズで波打つストリップで構成された建物を作れますか?

高度なジオメトリ技術

時には、形状を作る際にさらに柔軟性が必要になることがあります。例えば、頂点を格子状ではなく不規則に面に接続したい場合や、すべての頂点を生成した後にカスタムの法線やテクスチャ座標を使用したい場合などです。p5.Geometryクラスは、頂点、面、テクスチャ座標、法線の作成に完全な柔軟性を提供します。p5.jsはloadModel()buildGeometry()の内部でp5.Geometryを使用しています。

3Dでは、面は表面を形成する3つの点の集合を指し、ジオメトリに固体の外観を与えます。p5.Geometryでは、以下の方法で面を作成します:

  1. 使用するすべての点をgeometry.verticesプロパティの大きな配列に入れ、点が追加された順序を覚えておきます。
  2. 3つのインデックスのセットをgeometry.faces配列に入れます。点のインデックスは、追加された順序によって決定される配列内の位置を指します。インデックス0は最初に追加した点に、インデックス1は2番目に、インデックス2は3番目に対応し、以下同様です。

配列内の位置を参照して面を作成する方法を示す図。4つの頂点が左から右へ、次に上から下への順序で正方形に作成されています。インデックス[0, 3, 2]で正方形の左下に三角形が形成され、インデックス[0, 1, 3]で右上に三角形が形成されています。

配列内の位置を参照して面を作成する方法を示す図。4つの頂点が左から右へ、次に上から下への順序で正方形に作成されています。インデックス[0, 3, 2]で正方形の左下に三角形が形成され、インデックス[0, 1, 3]で右上に三角形が形成されています。

次の例では、この頂点と面を作成する方法を使用して、カスタムの四面体形状を作成しています。

また、geometry.verticesに頂点をプッシュするたびに、p5.Vectorgeometry.normals配列にプッシュすることもできます。ただし、buildGeometry()で構築されたジオメトリと同様に、カスタムのp5.Geometryに対してもgeometry.computeNormals()を呼び出すことができます。

試してみよう!

四面体はプラトンの立体と呼ばれる形状のグループの一部です。他のプラトンの立体をp5.Geometryとして生成してみてください!

まとめ

これで、カスタムジオメトリを作成できるようになり、他のツールやコードから独自の形状を作成することが可能になりました。様々な3Dモデリングツールを使って、自分に最適なものを見つけてください。バグを見つけた場合はGithubで問題を報告し、困ったことがあればDiscordProcessing Foundation Discourseフォーラムで質問してください。

用語集

プロシージャル

ファイルのような保存されたデータではなく、数学的に定義されていることを意味します。

モデル

ジオメトリの表現。

STL

STL(多くの場合「standard tesselation language」の略)は3Dモデルのファイル形式です。ジオメトリに関する情報のみを保存します。

OBJ

OBJはジオメトリデータだけでなく、一部のマテリアルとテクスチャデータも保存するオープンなファイル形式です。p5.jsでは、そのジオメトリに限定されますが、テクスチャを使用して画像を表面にマッピングすることはできます。

頂点

面の角を形成する形状の点。

3つの点の間に生成される固体の表面。

法線

面に垂直な方向で、照明の計算やマテリアルの使用時によく必要とされます。

正規化

標準的な範囲内に収まるように何かを変更すること。

インデックス

頂点配列内の位置。面は頂点をこれらの位置で参照します。

loadModel()

OBJまたはSTLファイルから形状を読み込むp5.js関数。

p5.Geometry

p5.jsが形状を保存するために使用するクラス。

model()

形状を画面に描画するp5.js関数。

buildGeometry()

描画されるすべての形状を記録し、新しいp5.Geometryオブジェクトに保存するp5.js関数。

computeNormals()

p5.Geometryで呼び出すことができるメソッドで、各面から出る方向を計算し、手動で作成する必要がないようにします。