4

OpenGL で記述されたレンダリング コードがいくつかあります。ステンシル バッファーを使用してクリッピングを実装します。


    //Let's assume this is done in render loop.

    if(!already_created())
    {
      create_stencil_attachment_and_bind_to_FB_as_depth_stencil_attachment();
    }

    glEnable(GL_STENCIL_TEST);
    glColorMask(0,0,0,0);
    glDepthMask(0);
    glClearStencil(0);
    glClear(GL_STENCIL_BUFFER_BIT);
    glStencilFunc(GL_ALWAYS,1,1);
    glStencilOp(GL_REPLACE,GL_REPLACE,GL_REPLACE);

    render_to_stencil();

    glColorMask(1,1,1,1);
    glDepthMask(1);
    glStencilFunc(GL_EQUAL,1,1);
    glStencilOp(GL_KEEP,GL_KEEP,GL_KEEP);

    render_with_clipping();

    glDisable(GL_STENCIL_TEST);

問題は、このコードを DX11 に移植する必要があることです。MSDN の例といくつかの素晴らしいチュートリアルを見ました。私はこのロジックで終わります:

1. ID3D11Texture2D をフォーマット = DXGI_FORMAT_D32_FLOAT_S8X24_UINT で作成します。
2. ステンシルにレンダリングするための ID3D11DepthStencilState を作成します。 // DS_RENDER と呼びましょう。
   - 前面と背面の両方の場合:
     - op = 3 つのケースすべてで D3D11_STENCIL_OP_REPLACE
     - func = D3D11_COMPARISON_ALWAYS
   - DepthEnable = FALSE
   - StencilEnable = TRUE
   - StencilReadMask = 0xFF
   - StencilWriteMask = 0xFF
3. 以前に作成した状態とテクスチャの ID3D11DepthStencilView を作成します。//DSVとしましょう
4. ステンシルを「入力」として使用するための ID3D11DepthStencilState を作成します。 //これを DS_CLIP と呼びましょう。
   - 前面と背面の両方の場合:
     - op = 3 つのケースすべてで D3D11_STENCIL_OP_KEEP
     - func = D3D11_COMPARISON_EQUAL
   - DepthEnable = FALSE
   - StencilEnable = TRUE
   - StencilReadMask = 0xFF
   - StencilWriteMask = 0xFF

さて、ステンシルをターゲットまたは入力として設定する方法がわかりません。

MSDN は次のように述べています。

`pDevice->OMSetDepthStencilState(pDSState, 1);`

`pd3dDeviceContext->OMSetRenderTargets(1, &pRTV, pDSV);`

これらの呼び出しを正しく理解していれば、最初の呼び出しでステンシル状態を設定し、2 番目の呼び出しで pDSV を追加の「アタッチメント」としてレンダー ターゲットにバインドします。あれは正しいですか?

もしそうなら、これは私が期待するように機能しますか?



    pDevice->OMSetDepthStencilState(DS_RENDER, 1);
    pd3dDeviceContext->OMSetRenderTargets(1, &pRTV, DSV);

    render_geometry_to_stencil_buffer();

    pDevice->OMSetDepthStencilState(DS_CLIP, 1);

    render_geometry_with_clipping();

    pd3dDeviceContext->OMSetRenderTargets(1, &pRTV, NULL); //Does this disable stencil testing?

すべてのヘルプまたは有用なヒントを前もって感謝します。

4

1 に答える 1

1

ステンシルにのみレンダリングする場合は、次を使用します (書き込み状態を設定します):

pd3dDeviceContext->OMSetRenderTargets(0, NULL, DSV);

カラー バッファにレンダリングする必要がないため、バインドする必要はありません。

次に、ターゲットにレンダリングしてステンシル テストを有効にするには、次を使用します。

pd3dDeviceContext->OMSetRenderTargets(1, &pRTV, DSV);

入力としてステンシルを使用する場合、非常に簡単なことは、StencilWriteMask = 0; を設定することです。そのため、それに書き込むことはありません (これは、クリップされたジオメトリをレンダリングしたいものです)。

使用する場合:

pd3dDeviceContext->OMSetRenderTargets(1, &pRTV, NULL); 

確かに、あらゆる形式の深度/ステンシル テストを無効にします (これ以上の深度制限がないため、DepthStencilState はまったく効果がありません)。

また、深度形式 (個人的な好み) には DXGI_FORMAT_D24_UNORM_S8_UINT を使用します。ユースケースに完全に適合し、メモリの消費量が少なくなります。

それが役立つことを願っています。

于 2013-10-11T16:08:57.520 に答える