09.Geometry 幾何学図形
導入
これまでは、BoxGeometryクラスを使用してキューブを作成するだけでした。このレッスンでは、他のさまざまな幾何学的形状を発見しますが、その前に、幾何学的形状が実際にはどのようなものかを理解する必要があります。
幾何学とは何ですか?
Three.js では、ジオメトリは頂点 (3D 空間内の点座標) と面 (これらの頂点を接続してサーフェスを作成する三角形) で構成されます。
ジオメトリを使用してメッシュを作成しましたが、後のレッスンでジオメトリを使用してパーティクルを形成することもできます。各頂点 (単一の頂点) がパーティクルに対応します。
頂点位置よりもはるかに多くのデータを保存できます。良い例は、UV 座標または法線についての話です。これらについては後ほど詳しく見ていきます。
さまざまな組み込みジオメトリ
Three.js には多くの組み込みジオメトリがあります。それぞれをインスタンス化する方法を正確に知る必要はありませんが、それらが存在することを知っておくと良いでしょう。
これから説明するすべての組み込みジオメトリは、BufferGeometryクラスから継承しています。translate(...)
このクラスには、rotateX(...)
、などの多くの組み込みメソッドがありますnormalize()
が、このレッスンではそれらを使用しません。
ほとんどのジオメトリのドキュメント ページには例が含まれています。
- BoxGeometry はボックスを作成します。
- PlaneGeometry は長方形の平面を作成します。
- CircleGeometry は、円または円の一部 (円グラフなど) を作成します。
- ConeGeometry は、円錐または円錐の一部を作成します。コーンの底は開閉可能です。
- CylinderGeometry は円柱を作成します。円柱の端を開閉したり、各端の半径を変更したりできます。
- RingGeometry は、平らなリングまたは平らな円の一部を作成します。
- TorusGeometry は、厚みのあるリング (ドーナツのような) またはリングの一部を作成します。
- TorusKnotGeometry は、ある種の幾何学的な結び目を作成します。
- DodecahedronGeometry は12 の面を持つ球を作成します。丸い球にディテールを追加できます。
- OctahedronGeometry は8 つの面を持つ球を作成します。丸い球にディテールを追加できます。
- TetrahedronGeometry は4 面の球体を作成します (詳細を追加しなければ、それほど大きな球体にはなりません)。丸い球にディテールを追加できます。
- IcosahedronGeometry は、ほぼ同じサイズの三角形の球を作成します。
- SphereGeometry は、面が四角形のように見える最も一般的なタイプの球を作成します (四角形は 2 つの三角形を組み合わせたものです)。
- ShapeGeometry はパスからシェイプを作成します。
- TubeGeometry はパスに従ってチューブを作成します。
- ExtrudeGeometry はパスから押し出しを作成します。ベベルを追加して制御できます。
- LatheGeometry は花瓶または花瓶の一部を作成します (革命に似ています)。
- TextGeometry は3D テキストを作成します。フォントは font json 形式で指定する必要があります。
Three.js がサポートしていない特定の特別なジオメトリが必要な場合は、JavaScript で独自のジオメトリを作成するか、3D ソフトウェアで作成してエクスポートし、プロジェクトにインポートすることができます。詳細については後のレッスンで説明します。
ボックスの例
立方体を作成しましたが、パラメータについてはあまり話していません。ほとんどのジオメトリにはパラメータがあるため、使用する前に必ずドキュメントを確認してください。
BoxGeometry には 6 つのパラメータがあります。
widthx
: 軸上の寸法heighty
: 軸上の寸法depthz
: 軸上の寸法widthSegmentsx
: 軸のサブディビジョンの数heightSegmentsy
: 軸のサブディビジョンの数depthSegmentsz
: 軸のサブディビジョンの数
サブディビジョンは、面を構成する三角形の数に対応します。デフォルトでは です1
。これは、面ごとに三角形のみが存在することを意味します2
。サブディビジョンを に設定すると2
、最終的に面ごとに 8 つの三角形が作成されます。
const geometry = new THREE.BoxGeometry(1, 1, 1, 2, 2, 2)
問題は、これらの三角形が見えないことです。
良い解決策は、wireframe: true
マテリアルに追加することです。ワイヤーフレームには、各三角形を区切る線が表示されます。
const material = new THREE.MeshBasicMaterial({
color: 0xff0000, wireframe: true })
ご覧のとおり、顔には 8 つの三角形があります。
これは平らな立方体とは何の関係もありませんが、次のものを使用するとSphereGeometry
さらに興味深いものになります。
const geometry = new THREE.SphereGeometry(1, 32, 32)
サブディビジョンを追加するほど、グラフは完璧に近づきます。ただし、頂点と面が多すぎるとパフォーマンスに影響を与える可能性があることに注意してください。
独自のバッファ ジオメトリを作成する
場合によっては、独自のジオメトリを作成する必要があります。ジオメトリが非常に複雑であるか、正確な形状をしている場合は、3D ソフトウェアで作成するのが最善です (これについては後のレッスンで説明します)。しかし、ジオメトリがそれほど複雑でない場合は、 BufferGeometryを使用して自分で構築できます。独自のバッファ ジオメトリを作成するには、まず空のBufferGeometryをインスタンス化します。例として単純な三角形を作成します。
// Create an empty BufferGeometry
const geometry = new THREE.BufferGeometry()
BufferGeometryに頂点を追加するには、Float32Arrayから始める必要があります。
Float32Array は、ネイティブ JavaScript 配列型です。内部的には浮動小数点数のみを格納でき、配列は固定長です。Float32Array
を作成するには、値を入力する前に長さを指定します。
const positionsArray = new Float32Array(9)
// First vertice
positionsArray[0] = 0
positionsArray[1] = 0
positionsArray[2] = 0
// Second vertice
positionsArray[3] = 0
positionsArray[4] = 1
positionsArray[5] = 0
// Third vertice
positionsArray[6] = 1
positionsArray[7] = 0
positionsArray[8] = 0
または、配列を渡すこともできます。
const positionsArray = new Float32Array([
0, 0, 0, // First vertex
0, 1, 0, // Second vertex
1, 0, 0 // Third vertex
])
ご覧のとおり、頂点の座標は線形に指定されています。配列は 1 次元配列で、最初の頂点の合計を指定し、次にx
2番目の頂点の合計y
を指定します。この配列をBufferGeometry に送信する前に、BufferAttributeに変換する必要があります。最初のパラメータは型配列に対応し、2 番目のパラメータは頂点属性の値に対応します。前に見たように、頂点の位置は 3 つの値 ( 、、)で構成されるため、この配列を読み取るには 3 x 3 を読み取る必要があります。z
x
y
z
x
y
z
const positionsAttribute = new THREE.BufferAttribute(positionsArray, 3)
次に、 .setAttribute(…) メソッドを使用して、この属性をBufferGeometryに追加できます。最初のパラメータはプロパティの名前で、2 番目のパラメータは値です。
geometry.setAttribute('position', positionsAttribute)
'position'
Three.js の内部シェーダーが頂点を配置するためにこの値を探すため、この名前を選択しました。これについては、シェーダーのレッスンで詳しく説明します。
面は頂点の順序で自動的に作成されます。
一度にすべて:
// Create an empty BufferGeometry
const geometry = new THREE.BufferGeometry()
// Create a Float32Array containing the vertices position (3 by 3)
const positionsArray = new Float32Array([
0, 0, 0, // First vertex
0, 1, 0, // Second vertex
1, 0, 0 // Third vertex
])
// Create the attribute and name it 'position'
const positionsAttribute = new THREE.BufferAttribute(positionsArray, 3)
geometry.setAttribute('position', positionsAttribute)
ランダムな三角形の束を作成することもできます。
// Create an empty BufferGeometry
const geometry = new THREE.BufferGeometry()
// Create 50 triangles (450 values)
const count = 50
const positionsArray = new Float32Array(count * 3 * 3)
for(let i = 0; i < count * 3 * 3; i++)
{
positionsArray[i] = (Math.random() - 0.5) * 4
}
// Create the attribute and name it 'position'
const positionsAttribute = new THREE.BufferAttribute(positionsArray, 3)
geometry.setAttribute('position', positionsAttribute)
count * 3 * 3
理解するのが難しいのは部品だけかもしれませんが、説明は簡単です。50
三角形が必要です。各三角形は頂点で構成され、各頂点は値 3 ( x
、y
、z
) で構成されます。
インデックスインデックス
BufferGeometryの興味深い点の 1 つは、このindex
プロパティを使用して頂点を往復させて立方体を形成できることです。複数の面では、立方体の 8 つの角にある頂点など、いくつかの予期される頂点を使用できます。よく見ると、各頂点は隣接する別の三角形によって使用されていることがわかります。これにより、属性配列が小さくなり、パフォーマンスが向上するように最適化されます。ただし、このレッスンではその部分については説明しません。