基本の 3D理論の説明
本記事では 3D を始める人が知るべき基本的な理論について説明します。
座標系
3D とは一般的に 3D空間内で描写されているすべての形であり、それらの位置を計算するために座標系が使われています。
WebGL は右手系座標系を利用します - 上記の図のように x
軸は右方向へ、y
軸は上方向へ、z
軸はスクリーンの外の方向へ向かいます。
オブジェクト
さまざまな種類のオブジェクトは頂点を用いて構築されます。頂点 は空間上の点であり、座標系における 3D の位置を持ち、たいていはいくつか追加で情報が定義されています。すべての頂点は次の属性を描写します:
- 位置: 3D空間の位置を特定します(
x
,y
,z
)。 - 色: RGBA値を持ちます(R、G、B は赤、緑、青のチャンネルを、alpha は透過度を - すべての値の範囲は
0.0
から1.0
までです)。 - 法線: 頂点の表面の方向を示す方法。
- テクスチャ: 単色の代わりに頂点の表面を飾る 2D画像。
この情報を用いて形状を構築することができます - 次は立方体の例です:
形から定義される表面は頂点同士の表面となります。例えば、立方体は 8 つの異なる頂点(空間上の点)と 6 つの異なる表面を持ち、それぞれの表面が 4 つの頂点から構築されています。法線は表面がどの方向に向いているかを定義します。そしてまた、立方体の端で点が接続されています。形状は頂点と法線から構築され、また材質は色や画像のテクスチャになります。形状が材質と接続されている場合、メッシュを得ることができます。
レンダリングパイプライン
レンダリングパイプラインはスクリーン上に画像を準備し、スクリーン上に出力するためのプロセスです。画像のレンダリングパイプラインは 3D オブジェクトを 頂点 を用いて作図された 単純なオブジェクト(プリミティブ) から作り、処理を加え、断片(フラグメント) を計算し、そして 2D のスクリーン上に ピクセル として出力します。
上記の図で使われる専門用語は以下の通りです:
- プリミティブ(Primitive): パイプラインの入力 - これは頂点から構築され、三角形や点、ラインとなります。
- 断片(Fragment): ピクセルを 3D に投影したもの、すべての属性はピクセルと同じ属性を持つ。
- ピクセル(Pixel): スクリーン上の二次元のグリッドに配置された点、それぞれ RGBA の色を持つ。
頂点とフラグメントの処理はプログラミング可能です - あなたは 自分自身でシェーダを書いて 出力を操作することができます。
頂点の処理
頂点の処理は個々の座標の情報をつなげることでプレミティブを作成し、それらの座標を 3D空間のビューアで見られるように設定します。これは風景の写真を撮る準備に似ています - 最初にオブジェクトを配置し、カメラを設定し、そして撮影します。
この処理には4つの段階があります: 最初の処理はオブジェクトを配置するのに必要な処理で、これは model transformation(モデル変換) と呼ばれています。そして view transformation(視野変換) で 3D 空間上のカメラの位置の設定と向きを設定をします - 位置、方角、そして角度 - これは新しいシーンを作成したときに定義しなくてはなりません。
Projection transformation(投影変換) (または perspective transformation(透視変換) とも呼ばれます) はカメラの設定を定義します。これはカメラから何が見えるのかを設定します - 設定には field of view(視野)、aspect ratio(アスペクト比) そして任意の 近く(near) と 遠くの平面(far planes) を含みます。これらを学ぶには Three.js の Camera paragraph の記事を読んでください。
最後の処理は viewport transformation(ビューポート変換) で、レンダリングパイプラインの次の処理で出力に使うすべての処理を含みます。
ラスタ化
ラスタ化は(頂点で接続された)プリミティブを断片の集まりに変換します。
それらの断片 - 3D 投影からなる 2D のピクセル - はピクセルのグリッドに整列されていて、最終的に出力統合の段階の間ピクセルとして 2D のスクリーン上に出力可能になります。
断片処理
断片処理はテクスチャと照明に焦点を当てます - これは与えられたパラメータを元に最終的な色を計算します。
テクスチャ
テクスチャは 3D 空間上でより見た目がよく、よりリアルなオブジェクトを作成するために使われる 2D 画像です。テクスチャは texels と呼ばれる単一テクスチャ要素から組み合わされており、texels は写真の要素と同様のピクセルの組み合わせです。レンダリングパイプラインの断片処理の段階でテクスチャをオブジェクトに追加することで必要によってオブジェクトを覆うよう調整したり、フィルターリングをすることができます。
テクスチャは 3D オブジェクトの間で繰り返し 2D画像を覆うことができます。テクスチャのフィルターリングは元の解像度またはテクスチャの画像が表示される断片と異なる場合に適用されます - これは結果的に縮小または拡大となります。
照明
私たちがスクリーン上で見る色は光とオブジェクトの素材自体の表面の色との相互作用の結果となります。光は吸収されるか、反射されるでしょう。WebGL で実装されている標準的な Phong Lighting Model には4つの光のタイプがあります:
- Diffuse: 太陽のような、遠くからの指向性のある光。
- Specular: 部屋の中の電球や閃光のような、光のポイント。
- Ambient: シーンにあるすべてに絶え間なく当てられる光。
- Emissive: オブジェクトから直接発せられる光。
出力統合
出力処理の段階の間で、スクリーンディスプレイ上に出力するために 3D空間上のすべてのプリミティブの断片を 2D グリッドのピクセルに変換する。
出力統合の間はいくつかの処理は必要のないものであれば無視されます - 例えばオブジェクトがスクリーンの外や他のオブジェクトの後ろにあったりすることでそれらは不可視であれば計算はされません。
終わりに
これで 3D の処理の基本的な背景を知ることができました。もし練習に進んだり、動作するデモを見たいのでえあれば、下のチュートリアルを引き続き調べてください:
- Three.js でデモを作る
- Building up a basic demo with Babylon.js
- Building up a basic demo with PlayCanvas
- A-Frame を使った基本的なデモの作成
さらに進んで、クールな最先端な 3D の試みをあなた自身で作ってください!