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

ピクセル単位の陰影処理を行うピクセルシェーダ~テクスチャは画像テクスチャだけじゃない

[7]の「ラスタライズ処理」によって生成されたピクセル単位の陰影処理の仕事をこなすのが[8][9]で表されるピクセルシェーダ(Pixel Shader)だ。また、レンダーバックエンドまでを含んだ枠全体を「ピクセルパイプライン」と呼ぶことがある。

GPUによってその実装形態は様々で、[8]のピクセル単位のさまざまな陰影処理を行う機能ブロックの方だけをあえて「ピクセルシェーダ」と呼ぶ場合もあるし、後述する「テクスチャユニット」の[9]をひっくるめてピクセルシェーダと呼んだりもする。

さて、その[8]のピクセルシェーダで行う計算だが、実は単位がピクセルになっただけで、行う処理内容そのものは頂点シェーダと似通った部分が多い。

ピクセル単位においても、光源ベクトル、視線ベクトル、そのピクセルにおける法線ベクトルを用いて反射方程式を解き、そのピクセルが何色になるかを求める「ピクセル単位のライティング」を計算することになる。

その場合、頂点単位のライティング結果をただ補間してそのピクセル色とする簡易的なライティングよりもなだらかな陰影や美しいハイライトが出せるようになる。これを特に「パー・ピクセル・ライティング」(Per Pixel Lighting)と呼んだりすることがある。

頂点シェーダで求められたテクスチャ座標を元にテクスチャからテクセルを読み出すのが[9]のテクスチャユニットだ。

このテクスチャユニットから取り出したテクセル色と、先ほど求めたピクセル単位の陰影処理結果から求めたピクセル色の両方を配慮して、最終的なピクセル色とする。

このピクセルシェーダで実行させるシェーダプログラムがピクセルシェーダプログラムで、その工夫次第でそのピクセル単位のライティングを特殊なものにすることができる。

通常「テクスチャ」というと、ポリゴンに貼り付ける画像を連想するが、現在のプログラマブルシェーダ時代では、その応用のされ方が拡張されてきており、なんとテクスチャに、画像ではない数学的な(あるいは物理的な)意味を持つ様々な数値データを入れておく活用が台頭してきたのだ。ピクセルシェーダでピクセル単位に陰影処理を行う際には、その数値テクスチャから数値データ逐次取り出して計算に利用することになる。

テクスチャも、PC画面の画素(ピクセル)がαRGB各8ビットで成り立っているのと全く同じ理屈で、αRGBの4つの色要素から成り立ってする。例えば32ビットカラーのテクスチャならばα(透明度)8ビット,R(赤)8ビット,G(緑)8ビット,B(青)8ビットという配分になっている。数値データをテクスチャに入れ込む場合、αRGBの4要素に入れ込むことを考えれば最大4要素のベクトルや行列を格納することができる。例えば3次元ベクトルならば、そのX,Y,Zの3要素の数値をαRGBのRGBに入れて格納しておくことができるわけだ。

実際のピクセルシェーダの処理では、このベクトルテクスチャから適当なテクセルを取り出してこれをベクトルデータとし、視線ベクトル、光源ベクトル、法線ベクトルなどと組み合わせて特殊な反射方程式を解くことで、独特な材質表現を実現する。

図6では法線ベクトルをテクスチャに入れ込んだ「法線マップ」を用いたバンプマッピングの例を示しておく。これは以降の連載の中でもう一度解説するので、ここでは「ピクセルシェーダの仕事はこんな感じなんだ」ということが分かればいいだろう。(続く)

図6: ピクセルシェーダのお仕事の例--バンプマッピングが完成するまでの概念図。ハイトマップから法線マップへの変換もピクセルシェーダで行うことができる。法線マップは法線ベクトルを格納したテクスチャで、1テクセルあたりに1個のXYZで表される3次元の法線ベクトル値が格納されている(XYだけを格納してZは計算で求めるという手法もあり)

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