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 デバイスを処理するクラスです。CPolyIndices はインデックス配列です。CPolyVerts は頂点配列です。CPolyTriangles は、レンダリングする三角形の数です。
ご覧のとおり、レンダリングする前に、デバイスに既に割り当てられているマトリックスに WorldViewProj を設定するため、デフォルト シェーダーとカスタム シェーダーは同じ変換マトリックスを使用する必要があります。実際、間違った場所にレンダリングされるわけではなく、数フレーム前にあるはずだった場所にレンダリングされるだけです (何フレーム遅れているかを正確に判断するのは困難ですが、約 3 フレームのように見えます)。
描画の間にカスタム シェーダーのオンとオフを切り替える行をコメント アウトするだけで、問題は解決します。カスタム シェーダーとデフォルト シェーダーを同じレンダリング サイクルで使用するのはこれが初めてなので、気付いていなかった何かを見落としている可能性があります。誰もこれを前に聞いたことがありますか?