ステンシル バッファー テクニック (Direct3D 9)
ステンシル バッファーを使えば、アプリケーションは画像のピクセルをマスクできます。このマスクは、ピクセルを描画するかどうかを制御します。ここでは、頻繁に使われる次のエフェクトについて説明します。
ステンシル バッファーは、レンダー ターゲット サーフェスのピクセル単位の描画を有効または無効にします。このバッファーの最も基本的なレベルでは、アプリケーションがレンダリングした画像の部分をマスクで覆うことが可能になり、その画像が表示されません。アプリケーションはディゾルブ、デカリング、輪郭処理などの特殊効果のためにステンシル バッファーを使うことがよくあります。
ステンシル バッファー情報は、z バッファー データに埋め込まれています。アプリケーションでは、次のコード例に示すように IDirect3D9::CheckDeviceFormat メソッドを使って、ハードウェアがステンシル バッファーをサポートしているかどうかを調べることができます。
// Reject devices that cannot perform 8-bit stencil buffering.
// The following example assumes that pCaps is a valid pointer
// to an initialized D3DCAPS9 structure.
if( FAILED( m_pD3D->CheckDeviceFormat( pCaps->AdapterOrdinal,
pCaps->DeviceType,
Format,
D3DUSAGE_DEPTHSTENCIL,
D3DRTYPE_SURFACE,
D3DFMT_D24S8 ) ) )
return E_FAIL;
IDirect3D9::CheckDeviceFormat では、そのデバイスの能力に基づいて作成するデバイスを選択できます。この場合、8 ビットのステンシル バッファーをサポートしないデバイスは拒否されます。これは IDirect3D9::CheckDeviceFormat の用途の 1 つでしかないことを覚えておいてください。詳細については、「ハードウェア サポートの判定 (Direct3D 9)」を参照してください。
ステンシル バッファーが動作するしくみ
Direct3D は、ステンシル バッファーの内容をピクセル単位でテストします。ステンシル バッファーの対応する値、ステンシル参照値、ステンシル マスク値を使って、ターゲット サーフェスの各ピクセルに対するテストを行います。テストにパスすると、Direct3D はアクションを実行します。このテストは次のステップで実行されます。
- ステンシル参照値とステンシル マスクのビット積 (AND) 演算を実行します。
- カレント ピクセルに対するステンシル バッファー値とステンシル マスクのビット積 (AND) 演算を実行します。
- 比較関数を使って、ステップ 1 とステップ 2 の結果を比較します。
これらの手順を次のコード例に示します。
(StencilRef & StencilMask) CompFunc (StencilBufferValue & StencilMask)
ここで、StencilBufferValue は、カレント ピクセルに対するステンシル バッファーの内容です。このコードでは、アンパサンド (&) 記号はビット積 (AND) 演算を表しています。StencilMask はステンシル マスク値、StencilRef はステンシル参照値を表しています。CompFunc は比較関数です。
このステンシル テストにパスすると、カレント ピクセルはターゲット サーフェスに書き込まれますが、失敗した場合は無視されます。既定の比較処理では、各ビット演算の結果に関係なく、ピクセルが書き込まれます (D3DCMP_ALWAYS)。この動作を変更するには、目的の比較関数を指定する D3DCMPFUNC 列挙型のメンバーを渡して、D3DRS_STENCILFUNC レンダリング ステートの値を変更します。
アプリケーションでは、ステンシル バッファーの処理をカスタマイズできます。アプリケーションでは、比較関数、ステンシル マスク、ステンシル参照値を設定できます。また、ステンシル テストにパスした場合または失敗した場合に実行する Direct3D の処理を制御することもできます。詳細については、「ステンシル バッファーステート (Direct3D 9)」を参照してください。
例
次のコード例は、ステンシル バッファーを設定する方法を示しています。
// Enable stencil testing
pDevice->SetRenderState(D3DRS_STENCILENABLE, TRUE);
// Specify the stencil comparison function
pDevice->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_EQUAL);
// Set the comparison reference value
pDevice->SetRenderState(D3DRS_STENCILREF, 0);
// Specify a stencil mask
pDevice->SetRenderState(D3DRS_STENCILMASK, 0);
既定では、ステンシル参照値はゼロです。整数値はすべて有効です。Direct3D は、ステンシルのテスト前に、ステンシル参照値とステンシル マスク値のビット積 (AND) の演算を実行します。
ステンシルの比較に応じてどのピクセル情報を書き込むかを制御できます。
// A write mask controls what is written
pDevice->SetRenderState(D3DRS_STENCILWRITEMASK, D3DSTENCILOP_KEEP);
// Specify when to write stencil data
pDevice->SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
次の例に示すように、ステンシル バッファーに書き込む値の数式を独自に作成できます。
NewStencilBufferValue = (StencilBufferValue & ~StencilWriteMask) |
(StencilWriteMask & StencilOp(StencilBufferValue))