シェーダー モデル 3 (HLSL リファレンス)
頂点シェーダーとピクセル シェーダーは、以前のバージョンのシェーダーから大幅に簡略化されています。 ハードウェアでシェーダーを実装する場合は、他のシェーダー バージョンでvs_3_0またはps_3_0を使用することはできません。また、固定関数パイプラインでシェーダーの種類を使用することはできません。 これらの変更により、ドライバーとランタイムを簡略化できます。 唯一の例外は、ソフトウェアのみのvs_3_0シェーダーは、任意のピクセル シェーダー バージョンで使用できることです。 さらに、以前のピクセル シェーダー バージョンでソフトウェアのみのvs_3_0 シェーダーを使用している場合、頂点シェーダーでは、フレキシブル頂点形式 (FVF) コードと互換性のある出力セマンティクスのみを使用できます。
頂点シェーダー出力で使用されるセマンティクスは、ピクセル シェーダー入力で使用する必要があります。 セマンティクスは、頂点シェーダーの出力をピクセル シェーダー入力にマップするために使用されます。これは、頂点宣言を頂点シェーダー入力レジスタと以前のシェーダー モデルにマップする方法と同様です。 「vs 3.0 シェーダーと ps 3.0 シェーダーの一致セマンティクス」を参照してください。
この新しいスキームで追加のテクスチャ座標が発生する可能性をカバーするために、ラップ モードのレンダリング状態が追加されました。 D3DDECLUSAGE_TEXCOORDと使用量インデックスが 0 から 15 の属性は、対応する D3DRS_WRAP* が設定されている場合、ラップ モードで補間されます。
- 頂点シェーダー モデル 3 の機能
- ピクセル シェーダー モデル 3 の機能
- vs_3_0 シェーダーとps_3_0 シェーダーの一致セマンティクス
- 霧、深度、シェーディング モードの変更
- 浮動小数点変換と整数変換
- 完全または部分的な有効桁数の指定
- ソフトウェア頂点シェーダーとピクセル シェーダー
頂点シェーダー モデル 3 の機能
頂点シェーダー出力レジスタの種類は、12 個のレジスタに折りたたまれています ( 「出力レジスタ」を参照)。 使用される各レジスタは、 dcl 命令とセマンティック (たとえば、o0.xyzw dcl_color0) を使用して宣言する必要があります。
3_0 頂点シェーダー モデル (vs_3_0) は、より強力なレジスタ インデックス作成、簡略化された出力レジスタのセット、頂点シェーダーでテクスチャをサンプリングする機能、シェーダー入力が初期化される速度を制御する機能を備えたvs_2_0の機能を拡張します。
任意のレジスタにインデックスを付けます
すべてのレジスタ ( 入力レジスタ と 出力レジスタ) は 、ループ カウンター レジスタ を使用してインデックスを作成できます (以前のバージョンでは定数レジスタのみインデックスを作成できます)。
入力レジスタと出力レジスタは、インデックスを作成する前に宣言する必要があります。 ただし、位置またはポイント サイズのセマンティックで宣言されている出力レジスタにインデックスを作成することはできません。 実際、インデックス作成を使用する場合、位置と psize セマンティクスをそれぞれ o0 レジスタと o1 レジスタで宣言する必要があります。
連続するレジスタの範囲に対してのみインデックスを作成できます。つまり、宣言されていないレジスタ間でインデックスを作成することはできません。 この制限は不便かもしれませんが、ハードウェアの最適化が可能になります。 連続していないレジスタ間でインデックスを作成しようとすると、未定義の結果が生成されます。 シェーダーの検証では、この制限は適用されません。
出力レジスタを簡略化する
出力レジスタのすべての種類は、1 つの出力レジスタに折りたたまれています。位置は 1、色の場合は 2、テクスチャの場合は 8、霧またはポイント サイズの場合は 1 です。 これらのレジスタは、ピクセル シェーダーに含まれるすべてのデータを補間します。 出力レジスタ宣言が必要であり、セマンティクスが各レジスタに割り当てられます。
レジスタは次のように分割できます。
- 少なくとも 1 つのレジスタを 4 コンポーネントの位置レジスタとして宣言する必要があります。 これは、必要な唯一の頂点シェーダー レジスタです。
- シェーダーによって使用される最初の 10 個のレジスタでは、最大 4 つのコンポーネント (xyzw) を使用できます。
- 最後の (または 12 番目の) レジスタには、スカラー (ポイント サイズなど) のみが含まれる場合があります。
レジスタの一覧については、「 Registers - vs_3_0」を参照してください。
頂点シェーダーのテクスチャ サンプル
頂点シェーダー 3_0 では、 texldl - vs を使用した頂点シェーダーでのテクスチャ参照がサポートされています。
ピクセル シェーダー モデル 3 の機能
ピクセル シェーダーの色とテクスチャ レジスタが 10 個の入力レジスタに折りたたまれています (「 入力レジスタの種類」を参照)。 Face Register は浮動小数点スカラー レジスタです。 このレジスタの符号のみが有効です。 符号が負の場合、プリミティブは背面になります。 これはピクセル シェーダー内で使用して、たとえば両面照明を実現できます。 位置レジスタは、現在の (x,y) ピクセルを参照します。
シェーダー定数レジスタは、次を使用して設定できます。
vs_3_0 シェーダーとps_3_0 シェーダーの一致セマンティクス
vs_3_0とps_3_0でのセマンティック使用にはいくつかの制限があります。 一般に、シェーダー出力で使用されるセマンティックと一致するシェーダー入力にセマンティックを使用する場合は注意が必要です。
たとえば、このピクセル シェーダーは複数の名前を 1 つのレジスタにパックします。
ps_3_0
dcl_texcoord0 v0.x
dcl_texcoord1 v0.yz // Valid to pack multiple names into one register
dcl_texcoord2_centroid v1.w
...
各レジスタには異なるセマンティックがあります。 書き込みマスクを使用しているため、異なる (複数の) セマンティクスで v0.x と v0.yz という名前を付けることもできます。
ピクセル シェーダーを指定すると、次のvs_3_0 シェーダーとペアにすることはできません。
vs_3_0
...
dcl_texcoord0 o5.x
dcl_texcoord1 o6.yzw
...
これら 2 つのシェーダーは、 D3DDECLUSAGE_TEXCOORD0 および D3DDECLUSAGE_TEXCOORD1 セマンティクスの使用と競合します。
セマンティック競合を回避するために、次のように頂点シェーダーを書き換えます。
vs_3_0
...
dcl_texcoord2 o3
dcl_texcoord3 o9
...
同様に、ピクセル シェーダーの異なる入力レジスタ (ピクセル シェーダーの v0 と v1) で宣言されたセマンティック名は、この頂点シェーダーの 1 つの出力レジスタでは使用できません。 たとえば、ピクセル シェーダー入力レジスタ (v0、v1) と頂点シェーダー出力レジスタ o3 の両方にD3DDECLUSAGE_TEXCOORD1が使用されるため、この頂点シェーダーをピクセル シェーダーとペアにすることはできません。
vs_3_0
...
dcl_texcoord0 o3.x
dcl_texcoord1 o3.yz
dcl_texcoord2 o3.w // BAD! Would be valid if this were not o3
dcl_texcoord3 o9 ...
一方、特定のセマンティックを持つパラメーターの出力マスクではピクセル シェーダーによって要求されるデータが提供されないため、この頂点シェーダーをピクセル シェーダーとペアにすることはできません。
vs_3_0
...
dcl_texcoord0 o5.x
dcl_texcoord1 o5.yzw
dcl_texcoord2 o7.yz // BAD! Would be valid if w were included
dcl_texcoord3 o9
...
この頂点シェーダーは、ピクセル シェーダーによって要求されたセマンティック名の 1 つを含む出力を提供しないため、シェーダーのペアリングは無効です。
vs_3_0
...
dcl_texcoord0 o5.x
dcl_texcoord1 o5.yzw
dcl_texcoord3 o9
// The pixel shader wants texcoord2, with a w component,
// but it isn't output by this vertex shader at all!
...
霧、深度、シェーディング モードの変更
クリッピングと三角形のラスター化時にフラット シェーディングにD3DRS_SHADEMODEが設定されている場合、D3DDECLUSAGE_COLORを持つ属性はフラット シェーディングとして補間されます。 レジスタのコンポーネントが色セマンティックで宣言されているが、同じレジスタの他のコンポーネントに異なるセマンティクスが与えられている場合、そのレジスタのコンポーネントに対して、カラー セマンティックなしでフラット シェーディング補間 (線形とフラット) は未定義になります。
フォグ レンダリングが必要な場合は、vs_3_0シェーダーとps_3_0 シェーダーで霧を実装する必要があります。 シェーダーの外部では、霧の計算は行われません。 vs_3_0に霧レジスタがなく、追加のセマンティクス D3DDECLUSAGE_FOG (頂点ごとに計算された霧のブレンド係数の場合) とD3DDECLUSAGE_DEPTH (深度値をピクセル シェーダーに渡して霧のブレンド係数を計算するため) が追加されました。
ピクセル シェーダー 3.0 を使用する場合、テクスチャ ステージの状態D3DTSS_TEXCOORDINDEXは無視されます。
これらの変更に対応するために、次の値が追加されました。
// Fog and Depth usages
D3DDECLUSAGE_FOG
D3DDECLUSAGE_DEPTH
// Additional wrap states for vs_3_0 attributes with D3DDECLUSAGE_TEXCOORD
D3DRS_WRAP8
D3DRS_WRAP9
D3DRS_WRAP10
D3DRS_WRAP11
D3DRS_WRAP12
D3DRS_WRAP13
D3DRS_WRAP14
D3DRS_WRAP15
浮動小数点変換と整数変換
浮動小数点演算は、パイプラインのさまざまな部分で、さまざまな精度と範囲 (16 ビット、24 ビット、32 ビット) で行われます。 そのパイプラインに入るパイプラインの動的範囲より大きい値 (たとえば、32 ビットの float テクスチャ マップは、ps_2_0の 24 ビット float パイプラインにサンプリングされます) では、未定義の結果が作成されます。 予測可能な動作の場合は、このような値を動的範囲の最大値にクランプする必要があります。
浮動小数点値から整数への変換は、次のようないくつかの場所で行われます。
- mova - vs 命令が発生した場合。
- テクスチャのアドレス指定中。
- 浮動小数点以外のレンダー ターゲットに書き出す場合。
完全または部分的な有効桁数の指定
ps_3_0とps_2_xの両方で、次の 2 つのレベルの精度がサポートされます。
ps_3_0 | ps_2_0 | Precision | 値 |
---|---|---|---|
x | [完全] | fp32 以降 | |
x | 部分精度 | fp16=s10e5 | |
x | x | [完全] | fp24=s16e7 以上 |
x | x | 部分精度 | fp16=s10e5 |
ps_3_0では、ps_2_0よりも高い精度がサポートされます。 既定では、すべての操作は完全な精度レベルで実行されます。
部分的な精度 ( 「ピクセル シェーダー レジスタ修飾子」を参照) は、シェーダー コードに _pp 修飾子を追加することによって要求されます (基になる実装でサポートされている場合)。 実装は常に修飾子を無視し、影響を受ける操作を完全な精度で実行できます。
_pp修飾子は、次の 2 つのコンテキストで発生する可能性があります。
- 部分的な精度のテクスチャ座標をピクセル シェーダーに渡すテクスチャ座標宣言。 これは、テクスチャ座標がカラー データをピクセル シェーダーに中継する場合に使用できます。これは、一部の実装では、完全な精度よりも部分的な精度で高速になる可能性があります。
- テクスチャの読み込み命令を含む、部分的な精度の使用を要求する任意の命令。 これは、実装で命令を部分有効桁数で実行し、部分有効桁数の結果を格納することが許可されていることを示します。 明示的修飾子がない場合、命令は完全な有効桁数で実行する必要があります (入力オペランドの有効桁数に関係なく)。
アプリケーションでは、パフォーマンスのために精度のトレードオフを意図的に選択する場合があります。 部分的な精度処理の自然な候補であるシェーダー入力データには、いくつかの種類があります。
- 色反復子は、部分有効桁数の値で適切に表されます。
- ほとんどの形式のテクスチャ値は、部分有効桁数の値で正確に表すことができます (32 ビット浮動小数点形式のテクスチャからサンプリングされた値は明らかな例外です)。
- 定数は、シェーダーに応じて部分精度表現で表される場合があります。
これらの場合すべてにおいて、開発者は、入力データの精度が失われることがないことを認識して、データを処理する部分的な精度を指定することを選択できます。 場合によっては、シェーダーでは、入力と最終出力の値が部分的な精度を超えない場合でも、計算の内部ステップを完全な精度で実行することが必要になる場合があります。
ソフトウェア頂点シェーダーとピクセル シェーダー
バージョン 2_0 以降のソフトウェア実装 (頂点シェーダーのランタイムと参照、ピクセル シェーダーの参照) では、検証が緩和されています。 これは、デバッグとプロトタイプ作成の目的で役立ちます。 アプリケーションはランタイム/アセンブラーに対し、アセンブラーの _sw フラグ (たとえば、vs_2_sw) を使用して、一部の検証を緩和する必要があることを示します。 ソフトウェア シェーダーはハードウェアでは機能しません。
vs_2_swは、vs_2_xの最大キャップへのリラクゼーションです。同様に、ps_2_swはps_2_xの最大キャップに対する緩和です。 具体的には、次の検証が緩和されます。
シェーダー モデル | リソース | 制限 |
---|---|---|
vs_2_sw、vs_3_sw、ps_2_sw、ps_3_sw | 命令数 | 無制限 |
vs_2_sw、vs_3_sw、ps_2_sw、ps_3_sw | Float 定数レジスタ | 8192 |
vs_2_sw、vs_3_sw、ps_2_sw、ps_3_sw | 整数定数レジスタ | 2048 |
vs_2_sw、vs_3_sw、ps_2_sw、ps_3_sw | ブール型定数レジスタ | 2048 |
ps_2_sw | 依存読み取り深度 | 無制限 |
vs_2_sw | フロー制御命令とラベル | 無制限 |
vs_2_sw、vs_3_sw、ps_2_sw、ps_3_sw | ループ開始/ステップ/カウント | rep 命令とループ命令の反復開始および反復ステップ サイズは、32 ビット符号付き整数です。 カウントは最大MAX_INT/64 です。 |
vs_2_sw、vs_3_sw、ps_2_sw、ps_3_sw | ポートの制限 | すべてのレジスタ ファイルのポート制限が緩和されます。 |
vs_3_sw | 補間器の数 | vs_3_sw内の 16 個の出力レジスタ。 |
ps_3_sw | 補間器の数 | 14(16-2) ps_3_swの入力レジスタ。 |
関連トピック