2012-11-25 60 views
0

我在XNA 4.0中使用模型實例,並在並行流中發送模型實例轉換。我遵循this教程。然而,當我想要一個矩陣作爲我的着色器的輸入時,我會看到一個看起來像是受損矩陣,因爲我得到了奇怪的投影結果。XNA着色器矩陣參數損壞

有沒有人知道問題的根源,爲什麼我不能通過矩陣當別人提出這樣的?

問題:

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) 
     ); 
    } 

回答

1

輸入在GPU寄存器的大小是有限的。 TEXCOORDn的大小是float4(如列出的here)。沒有float4x4輸入。

將你的矩陣分割成幾個輸入寄存器,然後重建它應該可以正常工作。這只是確保您的C#Matrix中的正確值最終在HLSL float4x4的正確位置。我懷疑映射是微不足道的,但我不確定。

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); 

樣品的Vertex Shader

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);