Phongシェーディングは良いモデルであるが、例えば、肌の質感や髪の毛などをうまく表現することはできない。筆者は、これはPhongモデルの問題というより、肌の場合は微妙な凹凸があり、また、表面で反射される光だけではなく、少し皮膚に入り込んで反射する光があるなど半透明な層が重なっているので、単純なパネルでは表現できていないことが問題であると思う。また、髪の毛も一本一本をカーブした円筒で表し、それをトライアングルストリップで記述すると膨大なデータになってしまい、現実問題として処理しきれない。

肌や髪の毛をそれなりに表現するシェーディング法が色々と考案されているが、Phongシェーディングより多くの計算を必要とする。このような多種のシェーディング計算法をハードウェアに実装するのは大変であるし、ハードウェアに作りこんでしまうと、新しく考案された方法に対応することができないと言う問題がある。

また、ゲームなどでは、主人公の肌や髪の表現は重要であるが、バックグランドのピクセルにまで、計算量の多いシェーディングを使うのは無駄であり、対象によってシェーディングアルゴリズムを切り替えたいという要求も出てきた。

ハードウェアに実装されたジオメトリ処理やシェーディング処理アルゴリズムでは対処しきれなくなってきたので、これらの計算を行う演算器群をプログラムで制御できるようにし、ジオメトリ処理でもシェーディング処理でも、プログラムを替えればどのようなアルゴリズムでも処理できる構造としたものを「ユニファイドシェーダ」と呼ぶ。

頂点数とピクセル数は画面によって変わるので、固定機能のGPUでは、頂点が多い場合は頂点シェーダの性能がネックとなり、ピクセルが多い場合はピクセルシェーダの性能がネックになるということが起こったが、ユニファイドシェーダならば、頂点数やピクセル数に応じて、それぞれの処理の実行時間が変わるだけで、無駄な空き時間が生じないというメリットがあり、現在のGPUはユニファイドシェーダ構造を使っている。

図2.5はIDFで発表されたIntelのHaswellに搭載されているHD Graphics GPUのブロックダイヤであるが、左側の楕円で囲んだ部分がグラフィックスパイプラインで、この図では小さすぎて読めないが、上から順に、コマンドの読み出し、頂点の読み出し、頂点シェーダ、ハルシェーダ、テセレーション、ドメインシェーダ、ジオメトリシェーダ、ストリーム出力、クリップ/セットアップと並んでおり、そこから中央のブロックのラスタライザ/奥行処理に矢印の線がつながっている。

図2.5 IntelのHaswellのGPUの構造

ハルシェーダからジオメトリシェーダは、1つの三角パネルを多数の小さな三角パネルに分解して、頂点の座標や法線ベクトルの方向を滑らかにつながるように補完したりして、より滑らかな曲面を作ったりする処理で、頂点シェーダと同様に、シェーディングプログラムを呼び出して、ユニファイドシェーダのハードウェアを使って計算を行っている。

クリップ/セットアップは、画面の端に掛かる三角パネルを切り取り、ラスタライズを行うラスタライザに送り込む。

ラスタライザは、三角パネルをピクセル単位の分解し、前述のPhongシェーディングなどを使って、各ピクセルの明るさと色を決定するピクセルシェーディングを行う。また、奥行きを判定するDepth(Z-bufferともいう)ユニットは、そのパネルの各点が、視点から見て一番手前にあるかどうかを判定する。ピクセルのシェーディング計算はユニアフィドシェーダを使って行われるが、ピクセルへのラスタライズやDepth処理はグラフィックス処理専用のハードウェアで実行される。

実際の描画では、三角パネルに壁紙を張り付けるテクスチャマッピングという方法が多用されている。例えば戦車の迷彩塗装などの模様は、三角パネルで表わそうとするとデータ量が大きくなってしまうが、壁紙の絵としてかいて、それを張り付ければ、それらしい絵を簡単に作ることができる。しかし、壁紙を貼るといっても、貼る面までの壁紙パターンの拡大、縮小が必要であり、角度が斜めであると、壁紙パターンの非等方な拡大、縮小が必要となる。このような処理を行うテクスチャサンプラやテクスチャキャッシュなどの専用ハードウェアを持つのが一般的であるが、詳細については省略する。