bate's blog

調べたこと実装したことなどを取りとめもなく書きます。

tutorial03

Tutorial3: シェーダーとエフェクトシステム


まとめ
前のチュートリアルで、頂点バッファの設定し、GPUに1つの三角形を渡した。
今、グラフィックスパイプラインを実際に見渡して、各ステージがどうのように働くかを見る。
シェーダーの概念とエフェクトシステムについて説明する


グラフィックスパイプライン
前のチュートリアルで、頂点バッファを準備し、それから頂点シェーダーに頂点レイアウトを関連付けた。
シェーダーとは何かとどう働くかを説明する
個別のシェーダーを完全に理解するために、一歩引いてグラフィックスパイプラインの全体を眺める。
続くセクションは描画コマンドの後に何が起きるかを詳細に説明する。


チュートリアル2では、VSSetShader()とPSSetShader()を呼ぶ時に、パイプラインのステージにシェーダーを結びつけた。
それから、描画を呼んだ時、グラフィックスパイプラインを通す頂点データを処理する。
続くセクションは描画コマンドの後に何が起きるかを詳細に説明する。


シェーダー
DX11では、シェーダーはグラフィックスパイプラインの異なるステージに存在する。
それはGPUで実行する短いプログラムで、ある入力データを受け取り、そのデータを処理し、
パイプラインの次のステージに結果を出力する。
DX11は頂点シェーダ、ジオメトリシェーダー、ピクセルシェーダーの基本的なシェーダーをサポートする。
頂点シェーダーは1つの頂点を入力とし、頂点バッファからGPUに送られる各頂点に対して1度実行される。
ジオメトリシェーダーはプリミティブを入力とし、GPUを通る全てのプリミティブに対して1度実行される。
ピクセルシェーダーは、ピクセル、フラグメントとも呼ばれる、を入力とし、
描画したいプリミティブの各ピクセルに対して1度実行される。
頂点、ジオメトリー、ピクセルシェーダーはアクションの本質が起こるところだ。
DX11でレンダリングする時、GPUは有効な頂点シェーダーとピクセルシェーダーを持たなければならない。
ジオメトリーシェーダーはDX11の先進的な特徴で、オプションなので、ここでは議論しない。
DX11には、テッセレーションと計算のためのシェーダーとして、ハルシェーダーとドメインシェーダーも存在する
さらなる情報は他のサンプルを見ろ。


頂点シェーダー
頂点シェーダーは頂点をGPUで処理する短いプログラムです。
各頂点を入力として取るC言語の関数として頂点シェーダーをみなせば、
入力の処理、それから修正した頂点の出力と考えられる。
頂点バッファの形でGPUに頂点データを渡した後、GPUは頂点バッファの頂点に対して繰り返し、
そして各頂点に対して1度アクティブな頂点シェーダーを実行し、
頂点データを頂点シェーダーの入力パラメータとして渡す。


頂点シェーダーが多くのタスクを実行可能な間、頂点シェーダーの一番重要な仕事は変換だ。
変換はある座標系からもう一つの座標系にベクトルを変換する処理のことだ。
たとえば、3次元のシーンの1つの三角形が(0,0,0),(1,0,0),(0,1,0)の位置に頂点があるとする。
2次元テクスチャバッファに三角形を描画する時、GPUは頂点が描画されるバッファの点の2次元座標を知らなければならない。
これを達成するのを助けるのが変換だ。
変換の詳細は次のチュートリアルで議論する。
ここでは、入力頂点に対して何もしないで出力する簡単な頂点シェーダーを使う。


DX11のチュートリアルでは、HLSLでシェーダーを書く。頂点データは3次元の位置要素として呼び戻され、
頂点シェーダーは入力に対して何もしない。(サンプルの頂点シェーダーの説明)


頂点シェーダーはC言語の関数のようだ。HLSLはC言語に似たシンタックスを使いことでC/C++プログラマが学びやすくなっている。
サンプルの頂点シェーダーはfloat4型のパラメーターを受け取り、float4型の値を返す。
HLSLでは、float4は4つの要素のベクトルで、各要素は浮動小数だ。
コロンは返り値としてのパラメーターセマンティクスを定義する。
HLSLのセマンティクスはデータの本質だ。
サンプルのシェーダーでは、入力パラメーターであるPosのセマンティクスとしてPOSITIONを選んだ。
これは、このパラメーターが頂点位置を構成するからだ。
SV_POSITIONという戻り値のセマンティクスは、特別な意味を持つ事前定義のセマンティクスだ。
この位置はGPUで画面のピクセルを描画するために必要だ。
クリップスペースについては次のチュートリアルで扱う。
サンプルのシェーダーでは、入力位置データを受け取り、同じデータをパイプラインに戻して出力とする。


ピクセルシェーダー
現在のコンピュータモニターは、共通してラスターディスプレイで、
画面が実際にピクセルといわれるドットの2次元グリッドであることを意味する。
各ピクセルは他のピクセルから独立した色で構成される。
画面に三角形を描画した場合、一つの実体として三角形を本当に描画しない。
三角形が覆う領域のピクセル集合を明るくすることを選ぶ。


三角形の変換処理は、三角形によって覆われるたくさんのピクセルを作る3つの頂点で定義される。
この処理をラスタライゼーションという。
GPUはまず、描画する三角形によって覆われるピクセルを決定する。
それから、それらの各ピクセルにアクティブなピクセルシェーダーを実行する。
ピクセルシェーダーの1番の目的は、処理する各ピクセルの色を計算することだ。
シェーダは、色がつくピクセルについてのある入力を受け取り、
ピクセルの色を計算し、それからパイプラインに戻す色を計算する。
ジオメトリーシェーダーからの入力があれば受け取る。
しかし、ジオメトリーシェーダーが存在しない場合は、頂点シェーダーからの入力を直接受け取る。


サンプルの頂点シェーダーは、SV_POSITIONセマンティクスのfloat4を出力する。
これはピクセルシェーダーへの入力となる。
ピクセルシェーダーは色の値を出力するので、ピクセルシェーダーの出力はfloat4になる。
SV_TARGETセマンティクスの出力を与えるので、レンダーターゲットの形式に出力することは重要だ。

シェーダーの作成
アプリケーションコードにおいて、頂点シェーダーオブジェクトとピクセルシェーダーオブジェクトを作る必要がある。
これらのオブジェクトはシェーダーを表し、D3DX11CompileFromFile()のコールによって作られる。


組み立て
グラフィックスパイプラインを一通り見た後は、チュートリアル2で作った三角形のレンダリング処理を理解することができる。
Direct3Dアプリケーションの作成には、2つの異なったステップが必要だ。
ひとつめは、チュートリアル2でしたように頂点データのソースデータを作ること、
ふたつめは、このチュートリアルで示したようにレンダリングのためのデータを変換するシェーダーを作ることだ。