Gamma (Direct3D 9)
テクスチャ コンテンツは、多くの場合、sRGB 形式で格納されます。 従来、ピクセル パイプラインでは色が線形であると想定されていたため、ブレンド操作は線形空間内で実行されていました。 ただし、sRGB コンテンツはガンマ補正されるため、線形空間内でのブレンド操作では正しくない結果が生成されます。 ビデオ カードは、sRGB コンテンツを読み取る際にガンマ補正を元に戻し、ピクセルを書き出す際にピクセル データを sRGB 形式に変換し直すことで、この問題を解決できるようになりました。 この場合、このピクセル パイプライン内のすべての操作は、線形空間内で実行されます。
Direct3D 9 では次のことができます。
- テクスチャがガンマ 2.2 補正されているかどうか (sRGB かどうか) を示します。 ドライバーが SetTexture 実行時にブレンド操作用の線形ガンマに変換する、またはサンプラーが参照時にそれを線形データに変換します。
- レンダー ターゲットに書き出す際に、ピクセル パイプラインを sRGB 空間にガンマ補正し直す必要があるかどうかを示します。
その他すべての色 (クリア カラー、マテリアルカラー、頂点カラーなど) は、線形空間内にあると想定されます。 アプリケーションでは、ピクセル シェーダー命令を使用して、フレーム バッファー内に書き込まれた色をガンマ補正することができます。 線形化は、アルファ チャネルに対してではなく、RGB チャネルに対してのみ適用する必要があります。
すべてのサーフェス形式を線形化することができるわけではありません。 D3DUSAGE_QUERY_SRGBREAD で CheckDeviceFormat に合格した形式のみを線形化することができます。 サンプラーの状態 D3DSAMP_SRGBTEXTURE は、残りの部分では無視されます。 この変換をサポートするには、符号なしテクスチャ形式のみが要求されます。 符号なしテクスチャ形式には、R、G、B、L コンポーネントのみが含まれます。 アルファ チャネルが存在する場合、それは無視されます。 混合形式で sRGB 線形化がサポートされている場合は、符号なしチャネルのみが影響を受けます。 理想的には、フィルター処理の前にハードウェアが線形化を実行する必要がありますが、Direct3D 9 内では、フィルター処理後にハードウェアが線形化を実行することができます。
すべてのサーフェス形式を sRGB 空間内に書き込むことができるわけではありません。 使用フラグ D3DUSAGE_QUERY_SRGBWRITE を使用して CheckDeviceFormat に合格した形式のみを線形化することができます。 レンダー状態 D3DRS_SRGBWRITEENABLE は、残りの部分では無視されます。 この機能を公開するには、チャネルあたり 8 ビットの RGB 符号なし形式が要求されます。
理想的には、ハードウェアは線形空間内でフレーム バッファー ブレンド操作を実行する必要がありますが、ハードウェアはピクセル シェーダーの後、フレーム バッファー ブレンダーの前にそれを実行することができます。 つまり、sRGB 空間内で行われるフレーム バッファー ブレンド操作では、正しくない結果が生成されます。 D3DRS_SRGBWRITEENABLE は、レンダー ターゲットのクリアを実行する間に受け入れられます。 複数のレンダー ターゲット (Direct3D 9) または複数要素テクスチャ (Direct3D 9) をサポートするハードウェアの場合、最初のレンダー ターゲットまたは要素のみが書き込まれます。
// New sampler state (DWORD)
// If this is nonzero, the texture is linearized on lookup.
D3DSAMP_SRGBTEXTURE // Default FALSE
// New render state (DWORD)
D3DRS_SRGBWRITEENABLE // Default FALSE
// New usage flags
D3DUSAGE_QUERY_SRGBWRITE
D3DUSAGE_QUERY_SRGBREAD
アプリケーションでは、正しいブレンド操作を可能にするために、スワップ チェーンのバック バッファーを線形空間内に保持することが重要です。 デスクトップは通常、線形空間内にないため、バック バッファーのコンテンツを表示する前にガンマ補正が必要です。 アプリケーションは、追加のバッファーを割り当て、線形バッファーからバック バッファーへの独自の補正コピーを実行することで、この補正自体に影響を与える場合があります。 これにより、ドライバーがプレゼンテーションのビット ブロック転送の一環としてガンマ補正を実行する場合であれば回避することができる、追加のコピーが必要になります。
Direct3D 9 内では、プレゼンテーションが線形空間から sRGB/ガンマ 2.2 へ暗黙的に変換することができるようにする新しいフラグ (D3DPRESENT_LINEAR_CONTENT) が、Present で使用可能です。 GetDeviceCaps を経由して取得されたデバイス機能に対して D3DCAPS3_LINEAR_TO_SRGB_PRESENTATION が返されるという条件で、バックバッファー形式が 16 ビット浮動小数点の場合は、ウィンドウ モードの存在を全画面表示のガンマ動作に一致させるために、アプリケーションはこのフラグを指定する必要があります。