私のアプリケーションでは、ワールド、ビュー、および投影マトリックスをシェーダーに渡す際に問題があります。これらのタスクを実行するための小さなエンジンをセットアップしました。出力として得られるものをデバッグするために PIX とビジュアル スタジオを使用しています。
まず、頂点とインデックスに関連するコードを投稿します。
Rendering.Geometry.MeshGeometry<uint> geom = Rendering.Geometry.MeshGeometry<uint>.Create(device);
var elem = Rendering.Geometry.VertexElement.CreatePosition3D(device);
float[] vertices = new float[9]
{
0, 0, -3,
0, 0, 3,
0, 5, 0,
};
elem.DataStream.WriteRange(vertices);
geom.AddVertexElement(elem);
var triangle = geom.Triangles.AddFace();
triangle.P1 = 0;
triangle.P2 = 1;
triangle.P3 = 2;
PIX で描画呼び出しをデバッグすると、頂点 (0/0/-3)/(0/0/3)/(0/5/0) の正しい値が得られるため、ジオメトリは正しいようです。インデックス バッファ、頂点バッファ、入力レイアウト、およびポリゴン トポロジがすべて正しく設定されています。
現在、PIX には興味深い Pre-VS、Post-VS ビューがあります。すべてがうまく見えると言ったように、VS前は、頂点は正しい順序で正しいです。Post-VS に移動して頂点をデバッグすると、最終的にはシェーダーに入り、そこで指示を実行できます。
ここで正しくないのは、定数バッファーで渡された行列です。ここに私のシェーダーがあります:
cbuffer MatrixBuffer
{
float4x4 worldMatrix;
float4x4 viewMatrix;
float4x4 projectionMatrix;
};
struct VertexInputType
{
float4 position : POSITION;
};
struct PixelInputType
{
float4 position : SV_POSITION;
};
PixelInputType BasicEffectVS(VertexInputType input)
{
PixelInputType output = (PixelInputType)0;
float4x4 worldViewProj = worldMatrix * viewMatrix * projectionMatrix;
output.position = mul(input.position, worldViewProj);
output.position.w = 1.0f;
return output;
}
PIX で 3 つの行列を確認すると、worldMatrix を除いて、viewMatrix と projectMatrix の値が完全に間違っていることがわかります (NaN が含まれていても)。アプリケーションで行列を設定する方法は次のとおりです。
basicEffect.WorldMatrix = SlimDX.Matrix.Identity;
basicEffect.ViewMatrix = SlimDX.Matrix.Transpose(SlimDX.Matrix.LookAtLH(new SlimDX.Vector3(20, 5, 0), new SlimDX.Vector3(0, 5, 0), new SlimDX.Vector3(0, 1, 0)));
basicEffect.ProjectionMatrix = SlimDX.Matrix.Transpose(SlimDX.Matrix.PerspectiveFovLH((float)Math.PI / 4, ((float)f.ClientSize.Width / f.ClientSize.Height), 1.0f, 100.0f));
VS でそれらをデバッグすると、正しい値が得られます。次に、実際のバイトの書き込みに到達するまで、シェーダーで SetValue 呼び出しに従います。そこではすべて大丈夫です!
バッファは次の方法で作成されます。
holder.buffer = new SlimDX.Direct3D11.Buffer(mShader.Device, new BufferDescription()
{
BindFlags = BindFlags.ConstantBuffer,
SizeInBytes = buffer.Description.Size,
Usage = ResourceUsage.Dynamic,
CpuAccessFlags = CpuAccessFlags.Write
});
さらに悪いことに、シェーダーに別のマトリックス パラメーターを追加し、その値にハードコードされたマトリックスを設定すると、次のようになります。
Matrix mat = new Matrix()
{
M11 = 1,
M12 = 2,
...
};
PIX では、期待どおりの値が得られます。したがって、シェーダーへの関数設定値は正しくなければなりません。
誰がこれがどこから来たのか考えていますか?