可変レート シェーディング (VRS)
パフォーマンス上の制約から、グラフィックス レンダラーは必ずしもその出力画像のすべての部分に同レベルの品質を実現できるわけではありません。 可変レート シェーディング (粗ピクセル シェーディング) は、レンダリングイメージ全体で異なるレートでレンダリングパフォーマンス/パワーを割り当てることができるメカニズムです。
場合によっては、認識できる出力品質をほとんどまたはまったく低下させることなく、シェーディング レートを下げることができ、その結果、本質的にコストをかけることなくパフォーマンス向上を実現できます。
可変レート シェーディングを使用しない場合、シェーディング レートを制御する唯一の手段は、マルチサンプル アンチエイリアシング (MSAA) とサンプルベースの実行 (スーパーサンプリングとも呼ばれます) を使用することです。
MSAA は、ジオメトリック エイリアシングを減らし、MSAA を使用しない場合と比較して画像のレンダリング品質を向上させるためのメカニズムです。 MSAA サンプル数は 1 倍、2 倍、4 倍、8 倍、16 倍に設定でき、これによって、レンダー ターゲットのピクセルごとに割り当てられるサンプルの数が決まります。 MSAA サンプル数は、ターゲットが割り当てられるときに事前に認識されている必要があり、その後変更することはできません。
スーパーサンプリングでは、サンプルごとに 1 回ピクセル シェーダーが呼び出され、ピクセルごとの実行と比較して、品質は高くなりますが、パフォーマンス コストも高くなります。
アプリケーションは、ピクセルごとの実行か、"MSAA とスーパーサンプリング" を選択することによって、シェーディング レートを制御できます。 これらの 2 つのオプションでは、あまり細かな制御を行うことができません。 また、画像の残りの部分と比較して特定のクラスのオブジェクトのシェーディング レートを低くしたい場合があります。 このようなオブジェクトには、HUD 要素の背後にあるオブジェクト、透明性、ぼかし (被写界深度、モーションなど)、または VR 光学系による光学歪みが含まれる場合があります。 ただし、シェーディングの品質とコストは画像全体で固定されているため、それは不可能です。
可変レート シェーディング (VRS) モデルでは、粗シェーディングの概念を追加することによって、"スーパーサンプリングと MSAA" を逆方向の "粗ピクセル" に拡張します。 この場合、シェーディングをピクセルよりも粗い周波数で実行できます。 つまり、ピクセルのグループを 1 つの単位としてシェーディングすることができるため、その結果はそのグループ内のすべてのサンプルに送信されます。
粗シェーディング API を使用すると、アプリケーションは、シェーディング対象グループに属するピクセルの数、つまり "粗ピクセル" を指定できます。 粗ピクセル サイズは、レンダー ターゲットを割り当てた後で変更できます。 そのため、画面の異なる部分や異なる描画パスに異なるシェーディング レートを適用することができます。
粗い網かけをサポートするプラットフォームで、どの MSAA レベルがどの粗ピクセル サイズでサポートされているかを説明する表を次に示します。
- Y とマークされたセルの場合、その組み合わせが有効になります。
- [キャップ] とマークされたセルの場合、その組み合わせはキャップ (AdditionalShadingRatesSupported) に基づいて条件付きで有効になります。
- 空白のセルの場合、その組み合わせはサポートされていません。
- ハーフトーン シェーディングされたセルの場合、その組み合わせはサポート されておらず、ピクセル シェーダー呼び出しごとに 16 個を超えるサンプルを追跡する必要があります。 16 を超えるサンプルを追跡する場合は、他のケースと比較して、サポートするハードウェアアラインメント バリアが追加されています。
VRS の実装には 2 つの階層があり、2 つの機能を照会できます。 各階層については、表の後で詳しく説明します。
- シェーディング レートは描画ごとにのみ指定できます。それ以上細かく指定できません。
- シェーディング レートは、レンダー ターゲット内のどこにあるかに関係なく、描画される対象に一律に適用されます。
- シェーディング レートは、階層 1 と同様に、描画ごとに指定できます。 さらに、"描画ごと" と以下を組み合わせて指定することもできます。
- 誘発する各頂点からのセマンティック。
- 画面領域の画像。
- 3 つのソースのシェーディング レートは、コンバイナーのセットを使用して組み合わせます。
- 画面領域の画像のタイル サイズは 16 x 16 以下です。
- アプリケーションで要求されるシェーディング レートは、正確に供給されることが保証されています (時間フィルターやその他の再構成フィルターの精度のため)。
- SV_ShadingRate PS 入力がサポートされています。
- 1 つのビューポートが使用されていて
SV_ViewportArrayIndex
が書き込まれていない場合、誘発する頂点単位 (プリミティブ単位とも呼ばれます) のシェーディング レートが有効です。 -
SupportsPerVertexShadingRateWithMultipleViewports 機能が
true
に設定されている場合、誘発する頂点単位のレートを複数のビューポートで使用できます。 さらに、その場合、そのレートはSV_ViewportArrayIndex
が書き込まれるときにも使用できます。
-
AdditionalShadingRatesSupported
- ブール型。
- 単一サンプル レンダリングで 2 x 4、4 x 2、4 x 4 の粗ピクセル サイズがサポートされているかどうかと、粗ピクセル サイズ 2 x 4 が 2x MSAA でサポートされているかどうかを示します。
-
SupportsPerVertexShadingRateWithMultipleViewports
- ブール型。
- 頂点単位 ("プリミティブ単位" とも呼ばれます) のシェーディング レートで複数のビューポートを使用できるかどうかを示します。
アプリケーションの柔軟性を実現するため、シェーディング レートを制御するために提供されているさまざまなメカニズムがあります。 ハードウェアの機能階層に応じて、さまざまなメカニズムが使用可能です。
これはシェーディング レートを設定するための最も簡単なメカニズムです。 すべての階層で使用可能です。
アプリケーションでは、ID3D12GraphicsCommandList5::RSSetShadingRate メソッドを使用して、粗ピクセル サイズを指定できます。 この API は単一の列挙型引数を受け取ります。 この API は、レンダリングの品質レベルの全体的な制御を提供します。これは、描画ごとにシェーディング レートを設定する機能です。
この状態の値は、D3D12_SHADING_RATE 列挙型によって表されます。
シェーディング レート 1x1、1x2、2x1、2x2 はすべてのレベルでサポートされています。
2 x 4、4 x 2、および 4 x 4 がデバイスでサポートされているかどうかを示す機能として AdditionalShadingRatesSupported があります。
階層 2 以上では、画面領域の画像を使用してピクセル シェーディング レートを指定できます。
画面領域の画像を使用すると、モーション ブラー、被写界深度ぼかし、透過オブジェクト、または HUD UI 要素で覆われる領域など、さまざまな品質の領域を示す "詳細レベル (LOD) マスク" 画像をアプリケーションで作成できます。 画像の解像度はマクロブロック単位です。レンダー ターゲットの解像度ではありません。 言い換えると、シェーディング レート データは、VRS タイル サイズで示されるように、8 x 8 または 16 x 16 ピクセル タイルの細分性で指定されます。
アプリケーションでは、API を照会して、そのデバイスでサポートされている VRS タイル サイズを取得できます。
タイルは正方形で、そのサイズは、テクセルで表したタイルの幅または高さを表します。
ハードウェアが階層 2 の可変レート シェーディングをサポートしていない場合、機能によるタイル サイズの照会では 0 が返されます。
ハードウェアが階層 2 の可変レート シェーディングをサポート "している" 場合、タイル サイズは次の値のいずれかです。
- 8
- 16
- 32
サイズが {rtWidth, rtHeight} のレンダー ターゲットの場合、VRSTileSize という名前の指定されたタイル サイズを使用すると、それを覆う画面領域の画像は次の寸法になります。
{ ceil((float)rtWidth / VRSTileSize), ceil((float)rtHeight / VRSTileSize) }
画面領域の画像の左上 (0, 0) がレンダー ターゲットの左上 (0, 0) に固定されています。
レンダー ターゲット内の特定の位置に対応するタイルの (x, y) 座標を調べるには、小数部のビットを無視して、ウィンドウ領域の座標 (x, y) をタイル サイズで割ります。
画面領域の画像が、指定されたレンダー ターゲットに必要なサイズよりも大きい場合、右または下またはその両方にある余分な部分は使用されません。
指定されたレンダー ターゲットに対して画面領域の画像が小さすぎる場合、実際の範囲を超えて画像からの読み取りが試行されると、既定値のシェーディング レートの 1 x 1 が使用されます。 これは、画面領域の画像の左上 (0, 0) がレンダー ターゲットの左上 (0, 0) に固定されていて、"レンダー ターゲットの範囲を超えて読み取る" ことは x と y の値として読み取る値が大きすぎることを意味するためです。
このサーフェスの形式は、単一チャネル 8 ビット サーフェスです (DXGI_FORMAT_R8_UINT)。
リソースはディメンション TEXTURE2D です。
これは、配列やミップにすることができません。 明示的にミップ レベルを 1 に指定する必要があります。
そのサンプル数は 1、サンプル品質は 0 です。
テクスチャ レイアウトは UNKNOWN です。 クロスアダプターは許可されていないため、暗黙的に行優先のレイアウトにすることはできません。
画面領域の画像データを設定するために求められる方法は、次のいずれかになります。
- 計算シェーダーを使用してデータを書き込む。画面領域の画像は UAV としてバインドされます。
- データを画面領域の画像にコピーする。
画面領域の画像を作成する場合、次のフラグが許可されます。
- NONE
- ALLOW_UNORDERED_ACCESS
- DENY_SHADER_RESOURCE
次のフラグは使用できません。
- ALLOW_RENDER_TARGET
- ALLOW_DEPTH_STENCIL
- ALLOW_CROSS_ADAPTER
- ALLOW_SIMULTANEOUS_ACCESS
- VIDEO_DECODE_REFERENCE_ONLY
リソースのヒープの種類を UPLOAD または READBACK にすることはできません。
リソースを SIMULTANEOUS_ACCESS にすることはできません。 リソースをクロスアダプターにすることはできません。
画面空間イメージの各バイトは、 D3D12_SHADING_RATE 列挙の値に対応します。
リソースを画面領域の画像として使用する場合は、読み取り専用の状態に遷移する必要があります。 読み取り専用の状態 D3D12_RESOURCE_STATE_SHADING_RATE_SOURCE はこの目的で定義されています。
画像リソースを再び書き込み可能にするには、この状態から遷移します。
シェーダー レートを指定するための画面領域の画像は、コマンド リストに設定します。
シェーディング レート ソースとして設定されているリソースは、どのシェーダー ステージからも読み書きできません。
シェーダー レートを指定するために、画面領域の画像 null
を設定できます。 これには、画面領域の画像からのコントリビューションとして 1 x 1 が一貫して使用されるという効果があります。 画面領域の画像は、最初は null
に設定されていると見なすことができます。
画面領域の画像リソースは、昇格または降格に関して特別な影響はありません。
プリミティブ単位の属性により、誘発する頂点から属性としてシェーディング レート項目を指定する機能が加わります。 この属性はフラット シェーディングされます。つまり、現在の三角形または線プリミティブ内のすべてのピクセルに反映されます。 プリミティブ単位の属性を使用すると、他のシェーディング レート指定子と比較して、画質をより細かく制御できるようになります。
プリミティブ単位の属性は、SV_ShadingRate
という名前の設定可能なセマンティックです。
SV_ShadingRate
は、HLSL シェーダー モデル 6.4 の一部として存在します。
VS または GS で SV_ShadingRate
が設定されていても VRS が有効でない場合、セマンティック設定は効果がありません。 プリミティブ単位で SV_ShadingRate
の値が指定されていない場合は、シェーディング レート値 1 x 1 がプリミティブ単位のコントリビューションと想定されます。
次の図を使用して、シェーディング レートのさまざまなソースを順番に適用します。
A と B の各ペアは、コンバイナーを使用して結合されます。
* 頂点属性でシェーダー レートを指定する場合。
- ジオメトリ シェーダーを使用する場合は、それを介してシェーディング レートを指定できます。
- ジオメトリ シェーダーを使用しない場合、シェーディング レートは誘発する頂点によって指定されます。
次のコンバイナーがサポートされています。 コンバイナー (C) と 2 つの入力 (A と B) を使用します。
- パススルー。 C.xy = A.xy。
- オーバーライドします。 C.xy = B.xy。
- 高品質。 C.xy = min(A.xy, B.xy)。
- 品質を下げる。 C.xy = max(A.xy, B.xy)。
- コスト B を A に対して適用します。C.xy = min(maxRate, A.xy + B.xy).
ここで、maxRate
はデバイス上の粗ピクセルの最大許容寸法です。 これは次のようになります。
- AdditionalShadingRatesSupported が
false
の場合は D3D12_AXIS_SHADING_RATE_2X (つまり、値 1)。 - AdditionalShadingRatesSupported が
true
の場合は D3D12_AXIS_SHADING_RATE_4X (つまり、値 2)。
可変レート シェーディングのためのコンバイナーの選択は、ID3D12GraphicsCommandList5::RSSetShadingRate を介してコマンド リストに設定します。
コンバイナーが設定されていない場合は、既定値 (PASSTHROUGH) のままになります。
コンバイナーへのソースが (サポート表で許可されていない) D3D12_AXIS_SHADING_RATE である場合、入力は、サポート "されている" シェーディング レートにサニタイズされます。
コンバイナーの出力がプラットフォームでサポートされているシェーディング レートに対応していない場合、結果は、サポート "されている" シェーディング レートにサニタイズされます。
すべてのシェーディング レート ソースは次のとおりです。
- パイプラインの状態によって指定されるレート (コマンド リストで指定)
- 画面領域の画像によって指定されるレート
- プリミティブ単位の属性
これらの既定値は D3D12_SHADING_RATE_1X1 になっています。 既定のコンバイナーは {PASSTHROUGH, PASSTHROUGH} です。
画面領域の画像が指定されていない場合は、そのソースから 1 x 1 のシェーディング レートが推測されます。
プリミティブ単位の属性が指定されていない場合は、そのソースから 1 x 1 のシェーディング レートが推測されます。
ID3D12CommandList::ClearState は、パイプラインの状態によって指定されるレートを既定値にリセットし、画面領域の画像の選択を既定値の "画面領域の画像なし" にリセットします。
どのようなピクセル シェーダー呼び出しにおいても、どのシェーディング レートがハードウェアによって選択されたかを把握することは役立ちます。 これにより、PS コードでさまざまな最適化が可能になります。 PS 専用のシステム変数 SV_ShadingRate
は、シェーディング レートに関する情報を提供します。
このセマンティックの型は uint です。
データは、D3D12_SHADING_RATE 列挙型の値として解釈されます。
粗ピクセル シェーディングが使用されていない場合、SV_ShadingRate
は、細ピクセルを示す 1 x 1 の値として読み戻されます。
ピクセル シェーダーは、入力SV_ShadingRate
した場合にコンパイルに失敗し、サンプル ベースの実行も使用します。たとえば、 を入力SV_SampleIndex
したり、サンプル補間キーワード (keyword)を使用したりします。
遅延シェーディングに関する注意
遅延シェーディング アプリケーションの照明パスでは、どのシェーディング レートが画面のどの領域に使用されたかを知る必要があります。 これは、照明パスのディスパッチがより粗いレートで起動できるようにするためです。
SV_ShadingRate
変数が gbuffer に書き出される場合は、この変数を使用してこの操作を実現できます。
粗ピクセル シェーディングが使用されている場合、深度、ステンシル、およびカバレッジは常に計算され、完全なサンプル解像度で出力されます。
すべての階層において、シェーディング レートが要求され、それがデバイスと MSAA レベルの組み合わせでサポートされている場合、それがハードウェアによって提供されるシェーディング レートになることが期待されます。
"要求されたシェーディング レート" とは、コンバイナーの出力として計算されたシェーディング レートを意味します (このトピックの「シェーディング レートの要素の組み合わせ」を参照)。
サンプル数が 4 未満のレンダリング操作でサポートされるシェーディング レートは、1 x 1、1 x 2、2 x 1、または 2 x 2 です。
AdditionalShadingRatesSupported 機能が true
である場合、2 x 4、4 x 2、および 4 x 4 のシェーディング レートもいくつかのサンプル数でサポートされます (このトピックの「可変レート シェーディング (VRS) を使用する場合」を参照)。
ピクセルから隣接ピクセルへのグラデーションの計算は、粗ピクセル シェーディングの影響を受けます。 たとえば、2 x 2 の粗ピクセルを使用しているときのグラデーションのサイズは、粗ピクセルを使用していないときと比較して 2 倍になります。 アプリケーションでは、必要な機能に応じて、これを補うためにシェーダーを調整する必要がある場合があります。
ミップは画面領域の派生物に基づいて選択されるため、粗ピクセル シェーディングの使用はミップの選択に影響します。 粗ピクセル シェーディングを使用すると、粗ピクセルを使用していないときと比較して詳細レベルの低いミップが選択されます。
ピクセル シェーダーへの入力は、そのソース頂点に基づいて補間される可能性があります。 可変レート シェーディングは、ピクセル シェーダーの各呼び出しによって書き込まれるターゲットの領域に影響を与えるため、属性補間と相互作用します。 補間の種類には、中心、重心、サンプルの 3 種類があります。
粗ピクセルの中心補間位置は、粗ピクセル領域全体の幾何学的中心です。
SV_Position
は、常に粗ピクセル領域の中心で補間されます。
MSAA で粗ピクセル シェーディングを使用した場合、引き続き細ピクセルごとに、ターゲットの MSAA レベルに割り当てられている全サンプルへの書き込みが行われます。 そのため、重心補間位置では、粗ピクセル内の細ピクセルに対してすべてのサンプルが考慮されます。 つまり、重心補間位置は、サンプル インデックスの昇順で最初の覆われたサンプルとして定義されます。 サンプルの有効なカバレッジは、ラスタライザーの状態 SampleMask の対応するビットと AND で連結されます。
注意
階層 1 で粗ピクセル シェーディングが使用されている場合、SampleMask は常に完全なマスクです。 SampleMask が完全なマスクにならないように構成されている場合、階層 1 では粗ピクセル シェーディングが無効になります。
サンプル ベースの実行(サンプル補間機能の使用によって発生する スーパーサンプリング)は、粗いピクセル シェーディングで使用でき、サンプルごとにピクセル シェーダーが呼び出されます。 サンプル数 N のターゲットの場合、ピクセル シェーダーは細ピクセルごとに N 回呼び出されます。
プルモデル組み込み関数は、階層 1 の粗ピクセル シェーディングと互換性がありません。 階層 1 の粗ピクセル シェーディングと共にプルモデル組み込み関数を使用しようとすると、粗ピクセル シェーディングは自動的に無効になります。
EvaluateAttributeSnapped
組み込み関数は、階層 2 の粗ピクセル シェーディングと共に使用できます。 その構文は従来と同じです。
numeric EvaluateAttributeSnapped(
in attrib numeric value,
in int2 offset);
コンテキストに対し、EvaluateAttributeSnapped
には 2 つのフィールドを持つオフセット パラメーターがあります。 粗ピクセル シェーディングなしで使用した場合、全 32 ビットのうち下位 4 ビットのみが使用されます。 これらの 4 ビットは、範囲 [-8, 7] を表します。 この範囲は、ピクセル内の 16 x 16 グリッドにまたがります。 この範囲は、ピクセルの上辺と左辺が含まれ、下辺と右辺が含まれないような範囲です。 オフセット (-8, -8) は左上隅にあり、オフセット (7、7) は右下隅の近くにあります。 オフセット (0, 0) はピクセルの中心です。
粗ピクセル シェーディングで使用した場合、EvaluateAttributeSnapped
のオフセット パラメーターでより広い範囲の位置を指定することができます。 オフセット パラメーターは細ピクセルごとに 16 x 16 のグリッドを選択し、細ピクセルは複数あります。 表現可能な範囲と結果として使用されるビット数は、粗ピクセル サイズによって異なります。 粗ピクセルの上辺と左辺は含まれますが、下辺と右辺は含まれません。
次の表では、各粗ピクセル サイズに対する EvaluateAttributeSnapped
のオフセット パラメーターの解釈について説明しています。
粗ピクセル サイズ | インデックスを作成できる範囲 | 表現できる範囲のサイズ | 必要なビット数 {x, y} | 使用可能なビットのバイナリ マスク |
---|---|---|---|---|
1 x 1 (細) | {[-8, 7], [-8, 7]} | {16, 16} | {4, 4} | {000000000000xxxx, 000000000000xxxx} |
1 x 2 | {[-8, 7], [-16, 15]} | {16, 32} | {4, 5} | {000000000000xxxx, 00000000000xxxxx} |
2 x 1 | {[-16, 15], [-8, 7]} | {32, 16} | {5, 4} | {00000000000xxxxx, 000000000000xxxx} |
2 x 2 | {[-16, 15], [-16, 15]} | {32, 32} | {5, 5} | {00000000000xxxxx, 00000000000xxxxx} |
2 x 4 | {[-16, 15], [-32, 31]} | {32, 64} | {5, 6} | {00000000000xxxxx, 0000000000xxxxxx} |
4 x 2 | {[-32, 31], [-16, 15]} | {64, 32} | {6, 5} | {0000000000xxxxxx, 00000000000xxxxx} |
4x4 | {[-32, 31], [-32, 31]} | {64, 64} | {6, 6} | {0000000000xxxxxx, 0000000000xxxxxx} |
次の表は、固定小数点から 10 進表現と分数表現への変換に関するガイドです。 バイナリ マスクの最初の使用可能なビットは符号ビットで、バイナリ マスクの残りの部分は数値部分を構成します。
EvaluateAttributeSnapped
に渡される 4 ビット値の数体系は、可変レート シェーディングに固有のものではありません。 完全を期すために改めてここに示しておきます。
4 ビット値の場合。
バイナリ値 | Decimal | 1 秒未満の |
---|---|---|
1000 | -0.5f | -8/16 |
1001 | -0.4375f | -7/16 |
1010 | -0.375f | -6/16 |
1011 | -0.3125f | -5/16 |
1100 | -0.25f | -4/16 |
1101 | -0.1875f | -3/16 |
1110 | -0.125f | -2/16 |
1111 | -0.0625f | -1/16 |
0000 | 0.0f | 0/16 |
0001 | -0.0625f | 1/16 |
0010 | -0.125f | 2/16 |
0011 | -0.1875f | 3/16 |
0100 | -0.25f | 4/16 |
0101 | -0.3125f | 5/16 |
0110 | -0.375f | 6/16 |
0111 | -0.4375f | 7/16 |
5 ビット値の場合。
バイナリ値 | Decimal | 1 秒未満の |
---|---|---|
10000 | -1 | -16/16 |
10001 | -0.9375 | -15/16 |
10010 | -0.875 | -14/16 |
10011 | -0.8125 | -13/16 |
10100 | -0.75 | -12/16 |
10101 | -0.6875 | -11/16 |
10110 | -0.625 | -10/16 |
10111 | -0.5625 | -9/16 |
11000 | -0.5 | -8/16 |
11001 | -0.4375 | -7/16 |
11010 | -0.375 | -6/16 |
11011 | -0.3125 | -5/16 |
11100 | -0.25 | -4/16 |
11101 | -0.1875 | -3/16 |
11110 | -0.125 | -2/16 |
11111 | -0.0625 | -1/16 |
00000 | 0 | 0/16 |
00001 | 0.0625 | 1/16 |
00010 | 0.125 | 2/16 |
00011 | 0.1875 | 3/16 |
00100 | 0.25 | 4/16 |
00101 | 0.3125 | 5/16 |
00110 | 0.375 | 6/16 |
00111 | 0.4375 | 7/16 |
01000 | 0.5 | 8/16 |
01001 | 0.5625 | 9/16 |
01010 | 0.625 | 10/16 |
01011 | 0.6875 | 11/16 |
01100 | 0.75 | 12/16 |
01101 | 0.8125 | 13/16 |
01110 | 0.875 | 14/16 |
01111 | 0.9375 | 15/16 |
6 ビット値の場合。
バイナリ値 | Decimal | 1 秒未満の |
---|---|---|
100000 | -2 | -32/16 |
100001 | -1.9375 | -31/16 |
100010 | -1.875 | -30/16 |
100011 | -1.8125 | -29/16 |
100100 | -1.75 | -28/16 |
100101 | -1.6875 | -27/16 |
100110 | -1.625 | -26/16 |
100111 | -1.5625 | -25/16 |
101000 | -1.5 | -24/16 |
101001 | -1.4375 | -23/16 |
101010 | -1.375 | -22/16 |
101011 | -1.3125 | -21/16 |
101100 | -1.25 | -20/16 |
101101 | -1.1875 | -19/16 |
101110 | -1.125 | -18/16 |
101111 | -1.0625 | -17/16 |
110000 | -1 | -16/16 |
110001 | -0.9375 | -15/16 |
110010 | -0.875 | -14/16 |
110011 | -0.8125 | -13/16 |
110100 | -0.75 | -12/16 |
110101 | -0.6875 | -11/16 |
110110 | -0.625 | -10/16 |
110111 | -0.5625 | -9/16 |
111000 | -0.5 | -8/16 |
111001 | -0.4375 | -7/16 |
111010 | -0.375 | -6/16 |
111011 | -0.3125 | -5/16 |
111100 | -0.25 | -4/16 |
111101 | -0.1875 | -3/16 |
111110 | -0.125 | -2/16 |
111111 | -0.0625 | -1/16 |
000000 | 0 | 0/16 |
000001 | 0.0625 | 1/16 |
000010 | 0.125 | 2/16 |
000011 | 0.1875 | 3/16 |
000100 | 0.25 | 4/16 |
000101 | 0.3125 | 5/16 |
000110 | 0.375 | 6/16 |
000111 | 0.4375 | 7/16 |
001000 | 0.5 | 8/16 |
001001 | 0.5625 | 9/16 |
001010 | 0.625 | 10/16 |
001011 | 0.6875 | 11/16 |
001100 | 0.75 | 12/16 |
001101 | 0.8125 | 13/16 |
001110 | 0.875 | 14/16 |
001111 | 0.9375 | 15/16 |
010000 | 1 | 16/16 |
010001 | 1.0625 | 17/16 |
010010 | 1.125 | 18/16 |
010011 | 1.1875 | 19/16 |
010100 | 1.25 | 20/16 |
010101 | 1.3125 | 21/16 |
010110 | 1.375 | 22/16 |
010111 | 1.4375 | 23/16 |
011000 | 1.5 | 24/16 |
011001 | 1.5625 | 25/16 |
011010 | 1.625 | 26/16 |
011011 | 1.6875 | 27/16 |
011100 | 1.75 | 28/16 |
011101 | 1.8125 | 29/16 |
011110 | 1.875 | 30/16 |
011111 | 1.9375 | 31/16 |
細ピクセルの場合と同様に、粗ピクセル シェーディングを使用する場合、EvaluateAttributeSnapped
の評価可能な位置のグリッドは、粗ピクセルの中心に配置されます。
API ID3D12GraphicsCommandList1::SetSamplePositions を粗シェーディングで使用した場合、この API によって細ピクセルのサンプル位置が設定されます。
階層 1 で SV_Coverage
がシェーダー入力または出力として宣言されている場合、粗ピクセル シェーディングは無効になります。
SV_Coverage
セマンティックは、階層 2 の粗ピクセル シェーディングで使用でき、MSAA ターゲットのどのサンプルが書き込まれているかを反映します。
粗ピクセル シェーディングを使用する場合 (複数のソース ピクセルがタイルを構成できるようにする場合)、カバレッジ マスクはそのタイルから取得されるすべてのサンプルを表します。
MSAA との粗ピクセル シェーディングの互換性を考慮すると、指定される必要があるカバレッジ ビットの数は変わる場合があります。 たとえば、D3D12_SHADING_RATE_2x2 を使用する 4x MSAA リソースでは、各粗ピクセルによって 4 つの細ピクセルに書き込まれ、各細ピクセルに 4 つのサンプルがあります。 これは、各粗ピクセルによって合計 16 (4 * 4) サンプルに書き込まれることを意味します。
次の表に、粗ピクセル サイズと MSAA レベルの組み合わせごとに必要なカバレッジ ビット数を示します。
表に示すように、Direct3D 12 で公開される可変レート シェーディング機能を使用して、粗ピクセルを使用して一度に 16 個を超えるサンプルに書き込むことはできません。 この制限は、どの粗ピクセル サイズでどの MSAA レベルを使用できるかに関する Direct3D 12 の制限によるものです (このトピックの「可変レート シェーディング (VRS) を使用する場合」セクションの表を参照)。
カバレッジ マスクのビットは、明確に定義された順序に従います。 マスクは、左から右へ、次に上から下へ (列優先) 順にピクセルからのカバレッジで構成されます。 カバレッジ ビットは、カバレッジ セマンティックの下位ビットであり、密にパックされます。
次の表に、サポートされている粗ピクセル サイズと MSAA レベルの組み合わせに対するカバレッジ マスクの形式を示します。
次の表は、2x MSAA ピクセルを示しています。各ピクセルには、インデックス 0 と 1 の 2 つのサンプルがあります。
ピクセル上のサンプルのラベルの位置は説明用です。特にサンプル位置をプログラム的に変更できることを考えると、必ずしもこれがそのピクセル上のサンプルの空間的な {X, Y} 位置を示しているわけではありません。 サンプルは、0 から始まるインデックスによって参照されます。
次の表は、4x MSAA ピクセルを示しています。各ピクセルには、インデックス 0、1、2、3 の 4 つのサンプルがあります。
HLSL セマンティック discard
を粗ピクセル シェーディングで使用すると、粗ピクセルは破棄されます。
粗ピクセル シェーディングを使用している場合、TIR はサポートされません。
ROV インターロックは、細ピクセルの細分性で動作するように指定されています。 サンプルごとにシェーディングが実行されると、インターロックはサンプルの細分性で動作します。
保守的なラスター化は可変レート シェーディングで使用できます。 保守的なラスター化を粗ピクセル シェーディングで使用すると、粗ピクセル内の細ピクセルは、完全なカバレッジが与えられることで保守的にラスター化されます。
保守的なラスター化を使用した場合、カバレッジ セマンティックには、覆われる細ピクセルに対する完全なマスクと、覆われない細ピクセルに対する 0 が含まれます。
可変レート シェーディング API シリーズをバンドルで呼び出すことができます。
可変レート シェーディング API シリーズをレンダー パスで呼び出すことができます。
このセクションでは、Direct3D 12 を介してアプリケーションで可変レート シェーディングを使用する方法について説明します。
アダプターの可変レート シェーディング機能を照会するには、D3D12_FEATURE::D3D12_FEATURE_D3D12_OPTIONS6 を指定して ID3D12Device::CheckFeatureSupport を呼び出し、関数が自動的に値を設定するように D3D12_FEATURE_DATA_D3D12_OPTIONS6 構造体を指定します。 D3D12_FEATURE_DATA_D3D12_OPTIONS6 構造体には、列挙型のメンバー D3D12_VARIABLE_SHADING_RATE_TIER (D3D12_FEATURE_DATA_D3D12_OPTIONS6::VariableShadingRateTier) や、バックグラウンド処理がサポートされているかどうかを示すメンバー (D3D12_FEATURE_DATA_D3D12_OPTIONS6::BackgroundProcessingSupported) など、複数のメンバーが含まれます。
たとえば、階層 1 の機能を照会するには、次を実行できます。
D3D12_FEATURE_DATA_D3D12_OPTIONS6 options;
return
SUCCEEDED(m_device->CheckFeatureSupport(
D3D12_FEATURE_D3D12_OPTIONS6,
&options,
sizeof(options))) &&
options.ShadingRateTier == D3D12_VARIABLE_SHADING_RATE_TIER_1;
D3D12_SHADING_RATE 列挙型の値は、シェーディング レートが 2 つの軸に簡単に分解されるように構成されています。この場合、各軸の値は、D3D12_AXIS_SHADING_RATE 列挙型に従って対数空間でコンパクトに表されます。
次のように 2 つの軸のシェーディング レートを 1 つのシェーディング レートに合成するマクロを作成できます。
#define D3D12_MAKE_COARSE_SHADING_RATE(x,y) ((x) << 2 | (y))
D3D12_MAKE_COARSE_SHADING_RATE(
D3D12_AXIS_SHADING_RATE_2X,
D3D12_AXIS_SHADING_RATE_1X)
また、このプラットフォームには、d3d12.h
で定義されている次のマクロも用意されています。
#define D3D12_GET_COARSE_SHADING_RATE_X_AXIS(x) ((x) >> 2 )
#define D3D12_GET_COARSE_SHADING_RATE_Y_AXIS(y) ((y) & 3 )
これらを使用すると、SV_ShaderRate
を詳細に分析し、理解することができます。
注意
このデータの解釈は、画面領域の画像を記述することを目的としており、シェーダーによって操作できます。 これについては、上のセクションで詳しく説明しています。 ただし、コマンドレベルのシェーディング レートを設定する場合を含め、あらゆる場所で使用される粗ピクセル サイズの一貫した定義がない理由はありません。
シェーディング レートとオプションのコンバイナーは、ID3D12GraphicsCommandList5::RSSetShadingRate メソッドを使用して指定します。 基本シェーディング レートとしての D3D12_SHADING_RATE 値とオプションの D3D12_SHADING_RATE_COMBINER 値の配列を渡します。
使用可能なシェーディング レート画像を指定する読み取り専用のリソース状態は、D3D12_RESOURCE_STATES::D3D12_RESOURCE_STATE_SHADING_RATE_SOURCE として定義されます。
画面領域の画像は、ID3D12GraphicsCommandList5::RSSetShadingRateImage メソッドを使用して指定します。
m_commandList->RSSetShadingRateImage(screenSpaceImage);
タイル サイズは D3D12_FEATURE_DATA_D3D12_OPTIONS6::ShadingRateImageTileSize メンバーから照会できます。 上記の「機能の照会」を参照してください。
水平方向の寸法と垂直方向の寸法は常に同じであるため、取得される寸法は 1 つです。 システムの機能が D3D12_SHADING_RATE_TIER_NOT_SUPPORTED の場合、返されるタイル サイズは 0 です。