ガンマ (Direct3D 9)
テクスチャー コンテンツは sRGB フォーマットで保存することがよくあります。従来、ピクセル パイプラインでは、色は線形であるとの前提に基づいて、ブレンディング処理を線形空間で実行していました。しかし、sRGB コンテンツはガンマ補正されているため、線形空間でブレンディング処理を行うと正しい結果が得られません。現在は、ビデオ カードで、sRGB コンテンツを読み込むときにガンマ補正を元に戻すことによってこの問題を修正し、ピクセルを書き出すときにピクセル データを sRGB フォーマットに変換できます。この場合、ピクセル パイプライン内での処理はすべて線形空間で行われます。
ガンマ補正
Direct3D 9 では次のことが可能です。
- テクスチャーがガンマ 2.2 で補正されているかどうか (sRGB かどうか) を示します。これに従って、ドライバーが SetTexture 時にブレンディング処理のために線形ガンマに変換するか、サンプラーが参照時に線形データに変換します。
- ピクセル パイプラインがレンダー ターゲットを書き出すときにガンマ補正を実行して sRGB 空間に戻す必要があるかどうかを示します。
その他のすべての色 (クリア カラー、マテリアル カラー、頂点カラーなど) は線形空間にあると見なされます。アプリケーションは、ピクセル シェーダーの命令を使って、フレーム バッファーに書き込まれた色をガンマ補正できます。線形化は RGB チャンネルだけに適用し、アルファ チャンネルには適用しないでください。
すべてのサーフェス フォーマットを線形化できるわけではありません。線形化できるのは、D3DUSAGE_SRGBREAD を使ってIDirect3D9::CheckDeviceFormat を渡すフォーマットだけです。その他のフォーマットでは、サンプラー ステート D3DSAMP_SRGBTEXTURE は無視されます。通常、この変換をサポートしているのは符号なしのテクスチャー フォーマットだけです。符号なしのテクスチャー フォーマットは、R、G、B、L の成分だけを含んでいます。アルファ チャンネルが存在する場合は無視されます。混在するフォーマットが sRGB の線形化をサポートしている場合は、符号なしのチャンネルだけが影響を受けます。理想的には、フィルターリング前にハードウェアによる線形化を実行した方がよいですが、Direct3D 9 では、フィルターリング後にハードウェアによる線形化を実行することもできます。
すべてのサーフェス フォーマットを sRGB 空間に書き込めるわけではありません。線形化できるのは、利用フラグ D3DUSAGE_SRGBWRITE を使って IDirect3D9::CheckDeviceFormat を渡すフォーマットだけです。その他のフォーマットでは、レンダリング ステート D3DRS_SRGBWRITEENABLE は無視されます。チャンネルあたり 8 ビットの RGB 符号なしフォーマットは、この能力を公開しなければなりません。
理想的には、線形空間でハードウェアによるフレーム バッファー ブレンディング処理を実行した方がよいですが、ピクセル シェーダーの後、フレーム バッファー ブレンダーの前にハードウェアでこれを実行することもできます。これは、sRGB 空間でフレーム バッファー- ブレンディング処理を行うと正しい結果が得られないことを意味します。レンダー ターゲットのクリアを実行している間は、D3DRS_SRGBWRITEENABLE が有効になっています。複数の 複数のレンダー ターゲット (Direct3D 9) または 複数の要素テクスチャー (Direct3D 9) をサポートしているハードウェアでは、最初のレンダー ターゲットまたは要素だけが書き込まれます。
API の変更
// 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 では、新しいフラグ D3DPRESENT_LINEAR_CONTENT を IDirect3DSwapChain9::Present に使用することができます。このフラグが設定されていると、線形空間から sRGB/ガンマ 2.2 に非明示的に変換するプレゼンテーションが可能です。全画面のガンマ動作と一致するウィンドウ モード表示とするために、バックバッファー フォーマットが 16 ビット浮動小数点である場合は、アプリケーションでこのフラグを指定する必要があります。ただし、IDirect3DDevice9::GetDeviceCaps をからデバイス機能として D3DCAPS3_LINEAR_TO_SRGB_PRESENTATION が返される場合に限ります。