0

C# マネージ DirectX で台形 (遠近法から見たように片側が小さいクワッド) にテクスチャを適切に表示するのに問題がありました。カスタムシェーダーで解決しました(探していたソリューションではありませんが、これまでのところ機能する唯一のソリューションです)。ただし、問題は、カスタム シェーダでレンダリングされたすべてのプリミティブが、他のプリミティブより 1 フレームまたは数フレーム遅れることです。コードの主要セクションの概要を以下に示します。

頂点シェーダー:

float4x4 WorldViewProj;

struct VSData
{
    float4 Position : POSITION0;
    float2 TexCoord : TEXCOORD0;
};    

void Raw_VertexShader(in VSData IN, out VSData OUT)
{
    OUT.Position = mul(IN.Position, WorldViewProj);
    OUT.TexCoord = float2(IN.Position.x, IN.Position.z);
}

technique StretchTexture
{
    pass
    {
        VertexShader = compile vs_3_0 Raw_VertexShader();
    }
}

与える():

//apply shader
manager.CPolyVertexShader.Technique = "StretchTexture";
manager.CPolyVertexShader.Begin(0);
manager.CPolyVertexShader.BeginPass();
//set shader's transformation matrix
manager.CPolyVertexShader.SetValue(manager.hWorldViewProj, device.Transform.World * device.Transform.View * device.Transform.Projection);
//draw the triangles
device.DrawIndexedUserPrimitives(PrimitiveType.TriangleList, 0, CPolyIndices.Length, CPolyTriangles, CPolyIndices, true, CPolyVerts);
//deapply the shader
manager.CPolyVertexShader.EndPass();
manager.CPolyVertexShader.End();

manager は、Direct3D デバイスを処理するクラスです。CPolyIndi​​ces はインデックス配列です。CPolyVerts は頂点配列です。CPolyTriangles は、レンダリングする三角形の数です。

ご覧のとおり、レンダリングする前に、デバイスに既に割り当てられているマトリックスに WorldViewProj を設定するため、デフォルト シェーダーとカスタム シェーダーは同じ変換マトリックスを使用する必要があります。実際、間違った場所にレンダリングされるわけではなく、数フレーム前にあるはずだった場所にレンダリングされるだけです (何フレーム遅れているかを正確に判断するのは困難ですが、約 3 フレームのように見えます)。

描画の間にカスタム シェーダーのオンとオフを切り替える行をコメント アウトするだけで、問題は解決します。カスタム シェーダーとデフォルト シェーダーを同じレンダリング サイクルで使用するのはこれが初めてなので、気付いていなかった何かを見落としている可能性があります。誰もこれを前に聞いたことがありますか?


4

1 に答える 1

2

あなたの問題は、Begin および BeginPass スコープ内に値を設定することだと思います。Begin は、CPU がパイプラインの現在の状態を適用することを意味します。シェーダー変数を含みます。

begineffect の前に setvalue を移動するか、yourshader.Apply() のようなものを呼び出す必要があります。

于 2013-03-30T13:52:38.630 に答える