DirectX 11のHLSLを学習していますが、頂点シェーダーの出力であるSV_POSITIONと、ピクセルシェーダーの入力は正確には何であるか疑問に思いました。
1:これは画面上のすべてのピクセルのx、y、zですか、それともオブジェクトのx、y、zですか?
2:なぜ4つの32ビットフロートなのですか?
3:頂点出力にこのシステム変数が必要ですか?
ありがとうございました!
頂点シェーダーステージには、頂点の位置という1つの必要な出力しかありません。次に、この値は、固定関数ラスタライザーによって使用され、描画されているピクセルを計算し、各ピクセルのピクセルシェーダーを呼び出します。これが、システム値セマンティックSV_Position
が頂点シェーダーの出力に示すものです。ピクセルシェーダーは、実際にはピクセル位置を入力として受け取る必要はありませんが、それが役立つ場合は可能です。入力レイアウトには、SV_Position
セマンティクスも使用する頂点シェーダーの位置も必要です。
通常の設定は次のとおりです。
SV_Position
として示されるワールド空間内の頂点の位置を記述します。入力レイアウトは、データの形式を記述します。例えば:
D3D11_INPUT_ELEMENT_DESC layout[] =
{
{ "SV_Position", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
};
頂点シェーダー入力は、頂点バッファーからの入力レイアウトによってデコードされた情報を入力アセンブラーから受け取ります。オプションでインデックスバッファーも使用します。位置の形式が何であれ、通常、シェーダーで使用するためにfloat
に変換されます。
頂点シェーダーは、出力頂点位置を生成する必要があります。これもSV_Position
で示されます。これは、(x, y)
から(-1, -1)
の範囲の正規化された座標でのピクセルの(1, 1)
位置です。 z
は、正規化された範囲0
から1
の深度位置(深度バッファーに使用)です。
例えば:
float4 VS( float4 Pos : SV_Position ) : SV_Position
{
return Pos;
}
ピクセルシェーダーはオプションで位置をとることができますが、そうする必要はありません。 (x,y)
はピクセル座標です。頂点出力(「クリップスペース」)は、D3D11_VIEWPORT
で提供されたビューポート状態を使用してピクセルに変換されます。
ピクセルシェーダーは、float4
としてマークされたSV_Target
結果を生成する必要があります。
例えば:
// We can omit the position
float4 PS() : SV_Target
{
return float4( 1.0f, 1.0f, 0.0f, 1.0f );
}
// Or you can take it as input if that's helpful
float4 PS( float4 Pos : SV_Position ) : SV_Target
{
return float4( 1.0f, 1.0f, 0.0f, 1.0f );
}
技術的には、頂点シェーダーは入力として位置を取る必要はありません。 Shader Model 4.0以降のハードウェアでは、SV_VertexId
を使用して、入力レイアウト、頂点バッファー、またはを使用しない次のようなコードで、頂点シェーダーのクワッドのコーナーを自己生成できます。インデックスバッファ。もちろん、ピクセルシェーダーの出力位置を生成する必要があります。
VSInputTx VSQuad(uint vI : SV_VertexId)
{
VSInputTx vout;
float2 texcoord = float2(vI & 1, vI >> 1);
vout.TexCoord = texcoord;
vout.Position = float4((texcoord.x - 0.5f) * 2, -(texcoord.y - 0.5f) * 2, 0, 1);
return vout;
}
新しい
SV_Position
(またはSV_POSITION
)セマンティクスを使用できるほとんどすべての場所で、古いDirect3D 9POSITION
セマンティックを使用できることに注意してください。唯一の要件は、入力レイアウトと頂点シェーダー入力の間で一貫している必要があることです。そうしないと、バインドに失敗します。
DirectXを初めて使用する場合は、 DirectXツールキット 、特に 組み込みのシェーダーソース を確認することをお勧めします。