図1:GPU内部におけるレンダリングの流れ

頂点シェーダのもう一つの仕事~頂点単位の陰影処理

図1にある[3]の頂点シェーダの仕事は座標変換だけではない。頂点単位の陰影処理/光源処理(ライティング)も頂点シェーダの重要な仕事となっている。

「座標変換」は「数学的」な感じだし、"計算する"、というイメージが湧いて分かりやすい。しかし、コンピュータの中でライティングする……すなわち"光を当てる"、というイメージは湧きにくいかもしれない。もちろんGPUはカメラではなく計算機なので実際に光を当てて写真を撮るわけにもいかない。計算をしてこれを求めることになる。

光がモノに当たると光はそこで反射/拡散したり、吸収されたりする。そのモノに色や模様が付いていればその色が見えるかもしれないし、照らした光に色が付いていれば、そのモノの色や模様と合成された色が見えることだろう。こうした処理を計算して求めるのがコンピュータグラフィックスの基本的な考え方だ。

この処理をどのようにして計算機が得意な計算に落とし込むか。これも実はベクトル演算を利用する。

光の方向を表す「光源ベクトル」と視線の方向を表す「視線ベクトル」、そして光が当たるポリゴンを構成する頂点の向きを表す「法線ベクトル」の3つのベクトルを用い、それぞれのベクトルの相対関係からどのくらい光が視線方向に反射するかを表す反射方程式を用いて計算してやるのだ。

この反射方程式には、表現したい材質に応じて様々な種類があり、この反射方程式をプログラムとして表現したものが頂点シェーダプログラムになる。そして、この頂点単位の反射方程式プログラムを実行するのも、やはり頂点シェーダなのだ。

頂点シェーダでは、頂点単位の陰影処理に加え、ポリゴンに貼り付けるテクスチャ座標の計算も行う。テクスチャ座標の計算とはどのポリゴンに、どのテクスチャをどう貼り付けていくか、という対応を計算するもの。なお、実際にテクスチャマッピングするのは[8][9]のピクセルシェーダの時点で、ここではテクスチャマッピングを行う際の準備する、というイメージだ。

図3: 頂点シェーダのお仕事の例: 頂点シェーダを活用した屈折の表現

ジオメトリシェーダ~頂点の増減が出来る凄いヤツ

DirectX 9/SM3.0世代以前の、ジオメトリシェーダがない世代のGPUでは、3Dモデルの頂点情報というものはCPU側のソフトウェアであらかじめ準備しておくものであり、ひとたびGPUに入力したら、これをGPU側で勝手に増減することはできなかった。

それまでの"大原則の枠"を打ち砕き、頂点を自在に増減できる働きを持つシェーダが[4]の「ジオメトリシェーダ」になる。

どのように増減するかは、ジオメトリシェーダに実行させるシェーダプログラムで指定することになる。また、実際に増減できるのは複数の頂点になるので、実質的には線分、ポリゴン、パーティクルといった各種プリミティブの増減が可能となっている。

ジオメトリシェーダの活用手法はいろいろ考え出されているが、ポリゴンを自在に生成できるので、地面に草となるポリゴンを生やせたり、あるいは3Dキャラクタに毛を生やせるといったことが最も基本的な活用方針になる。ゲームなどでは、ゲームロジックとのインタラクティブ処理があまり必要でない、火花などのエフェクト表現を、ジオメトリシェーダで生成したパーティクルで表現する…といったこともできるだろう

ジオメトリシェーダで生成した頂点は、再び頂点シェーダにも戻すことも出来るので、再帰的な頂点処理が行えることになる。例えば(実装は一筋縄では行かないが)、低ポリゴンで出来たカクカクした3Dモデルから、ジオメトリシェーダでポリゴンを補間して丸みを伴った多ポリゴンモデルを生成する……といったことも理論上は可能だ(続く)。

少ポリゴンモデル(左)から、算術的にポリゴンを補って多ポリゴンモデル(右)に変形するような活用も考えられる

図4: ジオメトリシェーダのお仕事の例:ジオメトリシェーダで毛を生やす

(トライゼット西川善司)