0

我在 XNA 4.0 中使用模型实例化,并在并行流中发送我的模型实例转换。我正在关注教程。然而,当我想要一个矩阵作为我的着色器的输入时,我得到一个看起来像损坏的矩阵的东西,因为我得到了奇怪的投影结果。

有谁知道问题的根源以及为什么当其他人建议时我不能通过矩阵?

问题:

struct VertexShaderInput
{
    float4 Position : POSITION0;    
    float3 Normal : NORMAL0;
    float3 UV : TEXCOORD0;
    float3 Color : COLOR0;
    float3 Tangent : TANGENT0;
    float3 Binormal : BINORMAL0;
    float4x4 World : TEXCOORD3; //Problem 
};

将顶点着色器函数更改为以下也无济于事:

VertexShaderOutput VertexShaderFunction(VertexShaderInput input, float4x4 World : TEXCOORD3)
{

}

如果我只用向量构建矩阵,这可行,我不知道为什么。我丢失数据了吗?

struct VertexShaderInput
{
    float4 Position : POSITION0;    
    float3 Normal : NORMAL0;
    float3 UV : TEXCOORD0;
    float3 Color : COLOR0;
    float3 Tangent : TANGENT0;
    float3 Binormal : BINORMAL0;
    float4 World1 : TEXCOORD3;
    float4 World2 : TEXCOORD4;
    float4 World3 : TEXCOORD5;
    float4 World4 : TEXCOORD6;
};

顶点格式:

internal struct InstanceDataVertex   
{
        public Matrix World;

        public InstanceDataVertex(Matrix World)
        {
            this.World = World;
        }

        public readonly static VertexDeclaration VertexDeclaration = new VertexDeclaration
        (
            new VertexElement(0, VertexElementFormat.Vector4, VertexElementUsage.TextureCoordinate, 3),
            new VertexElement(sizeof(float) * 4, VertexElementFormat.Vector4, VertexElementUsage.TextureCoordinate, 4),
            new VertexElement(sizeof(float) * 8, VertexElementFormat.Vector4, VertexElementUsage.TextureCoordinate, 5),
            new VertexElement(sizeof(float) * 12, VertexElementFormat.Vector4, VertexElementUsage.TextureCoordinate, 6)
        );
    }
4

2 回答 2

1

GPU 上的输入寄存器的大小是有限的。的大小TEXCOORDn是(如此float4所列)。没有输入。float4x4

将矩阵拆分到多个输入寄存器然后重建它应该可以正常工作。只需确保 C# 中的正确值Matrix最终出现在 HLSL 中的正确位置即可float4x4。我怀疑映射是微不足道的,但我不确定。

于 2012-11-25T14:34:51.737 回答
1

这是我在项目中使用的代码

 public Instance(Instancer instancer, float scale, Vector3 translate, Vector3 information)
    {
        ID++;
        id = ID;
        this.Scale(scale); 
        this.Translate(translate);
        this.Update(); //update the model matrix modelMatrix=scale*rotate*translate ma!

        Instancer = instancer;

        modelMatrix.M12 = information.X; //additional info unique for each instance
        modelMatrix.M23 = information.Y;
        modelMatrix.M34 = information.Z;
        Instancer.instanceTransformMatrices.Add(this, ModelMatrix);
    }

每个实例的模型矩阵

  protected static VertexDeclaration instanceVertexDeclaration = new VertexDeclaration
    (
        new VertexElement(0, VertexElementFormat.Vector4, VertexElementUsage.BlendWeight, 0),
        new VertexElement(16, VertexElementFormat.Vector4, VertexElementUsage.BlendWeight, 1),
        new VertexElement(32, VertexElementFormat.Vector4, VertexElementUsage.BlendWeight, 2),
        new VertexElement(48, VertexElementFormat.Vector4, VertexElementUsage.BlendWeight, 3)
    );

vbo 的矩阵列表,其中 modelVertexBuffer 是四边形或任何其他几何图形

instanceVertexBuffer = new DynamicVertexBuffer(BaseClass.Device, instanceVertexDeclaration, instanceTransformMatrices.Count, BufferUsage.WriteOnly);
            instanceVertexBuffer.SetData(instanceTransformMatrices.Values.ToArray(), 0, instanceTransformMatrices.Count, SetDataOptions.Discard);

绘制函数

BaseClass.Device.SetVertexBuffers(
                       new VertexBufferBinding(modelVertexBuffer, 0, 0),
                       new VertexBufferBinding(instanceVertexBuffer, 0, 1)
                   );

BaseClass.Device.Indices = indexBuffer;
BaseClass.Device.DrawInstancedPrimitives(PrimitiveType.TriangleList, 0, 0,modelVertexBuffer.VertexCount, 0,2,instanceTransformMatrices.Count);

顶点着色器示例

 VertexOut VS(VertexIn input, float4x4 instanceTransform : BLENDWEIGHT)
 {
    VertexOut Out = (VertexOut)0;

  float4x4 world = transpose(instanceTransform);
  input.Position.xyz = float3(world._41,world._42,world._43);
于 2012-11-25T15:10:03.023 回答