0

テクセルとピクセルの間の正しいマッピングを取得するために、テクスチャを頂点位置の0.5単位移動する必要性について説明している記事をいくつか読みました。その背後にある理論は理解していると思いますが、ソリューションを実装しようとすると(半分の単位を左に移動)、レンダリングされた画像の反対側に黒い線が表示されるだけです。

正しいxおよびyパラメーターを調整していないか、これが私の特定のシナリオに当てはまらないという印象を受けます。線形フィルタリングでdirect3d9を使用し、画面全体をカバーする画像をレンダリングします。テクスチャの実際のサイズと-1から+1の両方で試しました(つまり、2つのリンクされた記事の異なる解決策による)。どちらのアプローチでも同じ効果が得られます。

私の質問は、この修正が必要なのはいつですか、そして私が見逃しているこれを行う正しい方法はありますか?

4

1 に答える 1

1

DirectXのドキュメントによると、0.5ピクセルのオフセットは、「事前に変換された頂点を使用して2D出力をレンダリングする場合」にのみ必要です。事前に変換された頂点は、呼び出しD3DFVF_XYZRHWで指定されたフラグを持つ頂点です。IDirect3DDevice9::SetFVF変換された頂点を正しく描画するには、その位置を頂点の画面空間座標(ピクセル単位)に設定する必要が(posx - 0.5, posy - 0.5, 0, 1)あり(posx, posy)ます。

フルスクリーンのテクスチャクワッドをレンダリングするためのコードは次のとおりです。

struct TRANSFORMED_VERTEX
{
    D3DXVECTOR4 pos;
    D3DXVECTOR2 tex;
    static const DWORD FVF;
};
const DWORD TRANSFORMED_VERTEX::FVF = D3DFVF_XYZRHW | D3DFVF_TEX1;



void RenderFullScreenQuad()
{
    D3DSURFACE_DESC desc;
    LPDIRECT3DSURFACE9 pSurf;

    g_pd3dDevice->GetRenderTarget(0, &pSurf);
    pSurf->GetDesc(&desc);
    pSurf->Release();

    float width = (float)desc.Width - 0.5f;
    float height = (float)desc.Height - 0.5f;

    TRANSFORMED_VERTEX v[4];
    v[0].pos = D3DXVECTOR4(-0.5f, -0.5f, 0.0f, 1.0f);
    v[1].pos = D3DXVECTOR4(width, -0.5f, 0.0f, 1.0f);
    v[2].pos = D3DXVECTOR4(-0.5f, height, 0.0f, 1.0f);
    v[3].pos = D3DXVECTOR4(width, height, 0.0f, 1.0f);

    v[0].tex = D3DXVECTOR2(0.0f, 0.0f);
    v[1].tex = D3DXVECTOR2(1.0f, 0.0f);
    v[2].tex = D3DXVECTOR2(0.0f, 1.0f);
    v[3].tex = D3DXVECTOR2(1.0f, 1.0f);

    g_pd3dDevice->SetFVF(TRANSFORMED_VERTEX::FVF);
    g_pd3dDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, v, sizeof(TRANSFORMED_VERTEX));
}

もちろん、との間でこの関数を呼び出す必要がありBeginScene()ますEndScene()。また、テクスチャとサンプラーの状態(またはシェーダー定数)を適切に設定する必要があります。

于 2012-05-15T13:50:44.720 に答える