本日は昨日に引き続きShader枠です。
昨日に引き続き先日筆者の所属している会社で行ったShader勉強会の内容をまとめていきます。
〇ShaderとGPU
第一章ではShaderはGPU上で実行されるプログラム言語と述べました。
ではGPU上ではShaderによってどのような処理が動いているのでしょうか?
今回はここを簡単にまとめていきます。
〇グラフィックスパイプラインとは?
Shaderを理解するうえでグラフィックスパイプラインの大まかな理解は重要です。
グラフィックスパイプラインは3DCGを構築、描画するうえでGPU上で実行される処理の流れを指します。
GPUやアプリケーション、GraphicsAPIによって若干変わってきますが、ここではDirectXのグラフィックスパイプラインの例をもとに紹介します。
Shaderはグラフィックスパイプラインの中で実行されています。
〇Inputステージ
描画はCPUから描画処理が呼び出され始まります。
この信号をDrawCallと呼んでいます。
この際に描画を行うオブジェクト(頂点やメッシュの情報など)のデータが渡されます。
〇頂点シェーダーステージ
頂点シェーダーステージでは与えられた3DCGの頂点を座標に配置します。
これは3DCGの描画を行う際はアプリケーションごとに異なる座標軸やカメラの設定に基づいた描画が行われていることを考えると理解がしやすいです。
前者は例えば、UnityとBlenderやUnrealEngineを比較した際にUnityではY軸が鉛直上向きの軸になっていますがBlenderやUnrealEngineではZ軸が鉛直上向きになっています。
アプリケーションごとに異なる空間座標を処理する必要があります。
後者は例えば距離による遠近感を再現した遠視投影と遠近感が無視された並行投影では座標としてはオブジェクトは同一のものになっていますが、カメラに描画される際の描画方法が異なっています。
頂点シェーダーステージではこれらのすべての情報に基づいて頂点を最終的に出力するディスプレイに対してどの位置に配置するかを決定しています。
〇ジオメトリシェーダーステージ
ジオメトリシェーダーステージはグラフィックスAPIの依存があり、DirectXではDirectX9以降で使用が可能です。
グラフィックスAPIのサポートはGPUの型番依存なので古いGPUでは実行できない場合があり、またShaderを理解するうえで最初は理解しなくてもよいものですが軽く紹介します。
ジオメトリシェーダーステージでは頂点シェーダーで処理された頂点をさらに加工することができます。
頂点シェーダーはInputステージで与えられた頂点を処理して配置していますが、ジオメトリシェーダーでは頂点自体を複製することでメッシュを複製して、再配置することなどができます。
また、ここで処理された頂点をさらに頂点シェーダーへ返すこともできます。
〇ラフタライズステージ
ラフタライズステージでは配置された頂点をもとにピクセルシェーダー(フラグメントシェーダー)で塗りつぶす領域を指定しています。
イメージとしてメッシュを張っているという感じです。
〇ピクセルシェーダーステージ
ピクセルシェーダーステージではラフタライズステージで定まった領域を塗りつぶします。
これによって画像として出力されています。
以上が超簡単なグラフィックスパイプラインの処理ですが、この中でプログラマブル(プログラミング可能)なステージを任意にプログラムする言語がShaderになります。
Shaderには頂点シェーダー、フラグメントシェーダーなど言葉がありますが、これらはこのグラフィックスパイプラインの各頂点シェーダー、フラグメントシェーダーブロックの処理を記述していることになります。
第二章ではShaderがどのようにGPUで実行されているかを簡単に紹介しました。