2

2 つのレンダー ターゲットを作成しています。どちらもバック バッファーの深度バッファーを共有する必要があるため、同じマルチ サンプリング パラメーターを持つように設定することが重要ですが、pDevice->CreateTexture(..) はマルチを設定するためのパラメーターを提供しません。サンプリングの種類。そのため、pDevice->CreateRenderTarget(...) を使用して 2 つのレンダー ターゲット サーフェスを作成し、深度バッファーと同じ値を指定しました。現在、深度バッファーはレンダー ターゲットと連携して機能しますが、画面上で適切にレンダリングすることができません。アルファ ブレンディングは ->StretchRect では機能しません (つまり、私が試したときに機能しないと言われました)。

したがって、この質問のタイトルは基本的に私の質問です。-サーフェスをテクスチャに変換する、または-特定のマルチサンプリングパラメータを使用してテクスチャを作成する、または-アルファレイヤーを使用してサーフェスを適切にレンダリングする

4

2 に答える 2

2

古い質問に対する新しい回答ですが、私はこれに出くわし、この問題に遭遇したときに他の誰かがそれに出くわした場合に備えて回答を提供すると思いました。これは、私のラッパーとその関数の簡素化されたバージョンを使用したソリューションです。

レンダラーに複数のレイヤーがあり、そのうちの 1 つがジオメトリ レイヤーであるゲームがあります。レンダリングするときは、すべてのレイヤーを繰り返し処理し、それらの Draw 関数を呼び出します。各レイヤーには、RenderTarget ラッパーの独自のインスタンスがあります。レイヤーが描画すると、そのレンダー ターゲットが「アクティブ化」され、バッファーがアルファにクリアされ、シーンが描画されてから、そのレンダー ターゲットが「非アクティブ化」されます。すべてのレイヤーがレンダー ターゲットに描画された後、これらのレンダー ターゲットのすべてがバックバッファーに結合され、最終的なイメージが生成されます。

GeometryLayer::Draw
* このレイヤーが使用するレンダー ターゲットをアクティブにする
* 必要なレンダリング ステートを設定する
* バッファーをクリアする
* ジオメトリ
を描画する * このレイヤーが使用するレンダー ターゲットを非アクティブにする

void GeometryLayer::Draw( const math::mat4& viewProjection )
{
    m_pRenderTarget->Activate();

    pDevice->SetRenderState(D3DRS_ALPHABLENDENABLE,TRUE);
    pDevice->SetRenderState(D3DRS_SRCBLEND,D3DBLEND_SRCALPHA);
    pDevice->SetRenderState(D3DRS_DESTBLEND,D3DBLEND_INVSRCALPHA);

    pDevice->Clear(0,0,D3DCLEAR_TARGET,m_clearColor,1.0,0);
    pDevice->BeginScene();
    pDevice->Clear(0,0,D3DCLEAR_ZBUFFER,0,1.0,0);

    for(auto it = m->visibleGeometry.begin(); it != m->visibleGeometry.end(); ++it)
        it->second->Draw(viewProjection);

    pDevice->EndScene();

    m_pRenderTarget->Deactivate();
}

私の RenderTarget ラッパーには、描画先のテクスチャを生成するために D3DXCreateTexture で使用される IDirect3DTexture9* (m_pTexture) が含まれています。また、テクスチャによって提供される IDirect3DSurface9* (m_pSurface) も含まれています。また、別の IDirect3DSurface9* (m_pMSAASurface) も含まれています。

私の RenderTarget の初期化には、マルチサンプリングを有効にするオプションがあります。このオプションがオフの場合、m_pMSAASurface は nullptr に初期化されます。このオプションをオンにすると、IDirect3DDevice9::CreateRenderTarget 関数を使用して m_pMSAASurface が作成され、現在のマルチサンプリング設定が 4 番目と 5 番目の引数として指定されます。

RenderTarget::Init
* テクスチャを作成します
* テクスチャからサーフェスを取得します (サーフェスの参照カウントに追加します)
* MSAA の場合、msaa 対応のサーフェスを作成します

void    RenderTarget::Init(const int width,const int height,const bool enableMSAA)
{
    m_bEnableMSAA = enableMSAA;
    D3DXCreateTexture(pDevice,
        width,
        height,
        1,
        D3DUSAGE_RENDERTARGET,
        D3DFMT_A8R8G8B8,
        D3DPOOL_DEFAULT,
        &m_pTexture;
    );
    m_pTexture->GetSurfaceLevel(0,&m_pSurface);

    if(enableMSAA)
    {
        Renderer::GetInstance()->GetDevice()->CreateRenderTarget(
            width,
            height,
            D3DFMT_A8R8G8B8,
            d3dpp.MultiSampleType,
            d3dpp.MultiSampleQuality,
            false,
            &m_pMSAAsurface,
            NULL
        );
    }
}

この MSAA 設定がオフの場合、RenderTarget::Activate は m_pSurface をレンダー ターゲットとして設定します。この MSAA 設定がオンの場合、RenderTarget::Activate は m_pMSAASurface をレンダー ターゲットとして設定し、マルチサンプリング レンダー ステートを有効にします。

RenderTarget::Activate
* 現在のレンダー ターゲットを格納します (そのサーフェスの参照カウントに追加します)
* MSAA でない場合、サーフェスを新しいレンダー ターゲットとして
設定します * MSAA の場合、msaa サーフェスを新しいレンダー ターゲットとして設定し、msaa レンダリング ステートを有効にします

void    RenderTarget::Activate()
{
    pDevice->GetRenderTarget(0,&m_pOldSurface);

    if(!m_bEnableMSAA)
    {
        pDevice->SetRenderTarget(0,m_pSurface);
    }
    else
    {
        pDevice->SetRenderTarget(0,m_pMSAAsurface);
        pDevice->SetRenderState(D3DRS_MULTISAMPLEANTIALIAS,true);
    }
}

この MSAA 設定がオフの場合、RenderTarget::Deactivate は単に元のレンダー ターゲットを復元します。この MSAA 設定がオンの場合、RenderTarget::Deactivate は元のレンダー ターゲットも復元しますが、m_pMSAASurface を m_pSurface にコピーします。

RenderTarget::Deactivate
* MSAA の場合、MSAA レンダリング ステートを無効にする
* 以前のレンダー ターゲットを復元する
* 以前のレンダー ターゲットの参照カウントを削除する

void    RenderTarget::Deactivate()
{
    if(m_bEnableMSAA)
    {
        pDevice->SetRenderState(D3DRS_MULTISAMPLEANTIALIAS,false);
        pDevice->StretchRect(m_pMSAAsurface,NULL,m_pSurface,NULL,D3DTEXF_NONE);
    }
    pDevice->SetRenderTarget(0,m_pOldSurface);

    m_pOldSurface->Release();
    m->pOldSurface = nullptr;
}

後でレンダラーがジオメトリ レイヤーに RenderTarget テクスチャを要求して、他のレイヤーと組み合わせると、そのテクスチャには m_pMSAASurface からコピーされた画像が含まれます。アルファ チャネルを容易にするフォーマットを使用していると仮定すると、このテクスチャは、複数のレイヤーのレンダー ターゲットで行っているように、他のテクスチャとブレンドできます。

于 2013-12-13T06:30:11.177 に答える
2

StretchRectのドキュメントでは、これを行う方法が具体的に説明されています。

StretchRect を使用して Multisample Rendertarget をダウンサンプリングする

StretchRect を使用して、あるレンダー ターゲットから別のレンダー ターゲットにコピーできます。ソース レンダー ターゲットがマルチサンプリングされている場合、ソース レンダー ターゲットがダウンサンプリングされます。たとえば、次のことができます。

  • マルチサンプリングされたレンダー ターゲットを作成します。
  • マルチサンプリングされていない、同じサイズの 2 番目のレンダー ターゲットを作成します。
  • (StretchRect を使用して、マルチサンプル レンダー ターゲットを 2 番目のレンダー ターゲットにコピーします。

Multisample Rendertarget をダウンサンプリングするために StretchRect を使用する際に余分なサーフェスを使用すると、パフォーマンスが低下することに注意してください。

于 2011-03-30T21:43:05.767 に答える