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#の適切な値がMatrixHLSLの適切な場所に配置されるようにするだけ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)
    );

modelVertexBufferがクワッドまたはその他のジオメトリであるvboへの行列のリスト

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 に答える