2

在我的应用程序中,我无法将我的世界、视图和投影矩阵传递给着色器。我已经设置了一个小引擎来执行这些任务,并且我正在使用 PIX 和 Visual Studio 来调试我得到的输出。

首先,我发布与顶点和索引相关的代码:

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 视图。正如我所说的,Pre-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 中查看三个矩阵时,我发现除了 worldMatrix 之外,对于 viewMatrix 和 projectionMatrix,它们的值完全错误(甚至包含 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 中,我得到了我期望的值。所以我对着色器的函数设置值必须是正确的。

有人知道这是从哪里来的吗?

4

1 回答 1

0

确保删除此行: output.position.w = 1.0f;

这是投影组件,因为您已经乘以投影矩阵,您需要将其原样发送到像素着色器。

此外,我会对所有转置非常小心,我不确定它们是否真的需要。

于 2012-09-21T13:44:47.043 回答