Instancing Problems

Started by
1 comment, last by jischneider 12 years ago
Hi guys,

at the moment im writing a little editor in XNA 4.0. Lately i implemented loading & managing models, but when it comes to drawing them instanced, they look kind of weird.
Heres a screenshot of the problem:

screenjql.png

The strange thing is, that the modelpreview renders correctly, so a broken model is out of topic, shaders and code are almost the same. Have a look here...

ShaderCode:

float4x4 View;
float4x4 Projection;
texture2D Texture;
sampler2D Sampler = sampler_state
{
Texture = <Texture>;
AddressU = Wrap;
AddressV = Wrap;
MinFilter = anisotropic;
MagFilter = anisotropic;
};
float3 Color = float3(1, 1, 1);
float3 Ambient;
float3 LightDirection;
float3 LightColor;
float AlphaClip;
struct VertexShaderInput
{
float4 Position : POSITION0;
float2 UV : TEXCOORD0;
float3 Normal : NORMAL0;
float4x4 World : TEXCOORD2;
};
struct VertexShaderOutput
{
float4 Position : POSITION0;
float2 UV : TEXCOORD0;
float3 Normal : TEXCOORD1;
};
VertexShaderOutput VertexShaderFunction(VertexShaderInput input)
{
VertexShaderOutput output;
float4 worldPosition = mul(input.Position, transpose(input.World));
float4 viewPosition = mul(worldPosition, View);
output.Position = mul(viewPosition, Projection);
output.UV = input.UV;
output.Normal = input.Normal;
return output;
}
float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0
{
float4 tex = tex2D(Sampler, input.UV);
clip(tex.a - AlphaClip);
float3 light = Ambient;
float3 lightDir = normalize(LightDirection);
float3 normal = normalize(input.Normal);
light += saturate(dot(lightDir, normal)) * LightColor;
float4 finallight = float4(light, 1);
float4 output = saturate(finallight) * tex;
return output;
}


And my XNA drawing-code:

foreach (ModelMesh mesh in DefaultModel.Meshes)
{
device.SetVertexBuffers(null);
for (int i = 0; i < NumberOfInstances; i++)
transformedData = new InstanceData(Transforms[mesh.ParentBone.Index] * Instances.World);
InstanceBuffer.SetData<InstanceData>(transformedData);
foreach (ModelMeshPart part in mesh.MeshParts)
{
Effect effect = EngineManager.CurrentProject.AssetManager.InstanceModelEffect;

//... Set Effect Parameters

device.SetVertexBuffers(part.VertexBuffer, new VertexBufferBinding(InstanceBuffer, 0, 1));
device.Indices = part.IndexBuffer;
effect.CurrentTechnique = effect.Techniques[0];
effect.CurrentTechnique.Passes[0].Apply();
device.DrawInstancedPrimitives(PrimitiveType.TriangleList, 0, 0, part.NumVertices, part.StartIndex, part.PrimitiveCount, NumberOfInstances);
}
}


Last but not least the code for generating the worldmatrix (Instances[...].World):

public InstanceData(Vector3 Position, Vector3 Rotation, float Scale)
{
World = Matrix.CreateScale(Scale) *
Matrix.CreateFromYawPitchRoll(Rotation.X, Rotation.Y, Rotation.Z) *
Matrix.CreateTranslation(Position);
}


The code for drawing the preview uses mesh.Draw(), everything else is essentially the same.

Does anybody have an idea, whats going wrong?
Thanks in advance,
majorbrot
Advertisement
float4x4 World : TEXCOORD2; Why TEXCOORD2 and not 1?

[size=1]Project page: [size=1]<

[size=1] XNA FINAL Engine[size=1] [size=1]>
One more thing. Look at the Instanced example from App Hub:
http://create.msdn.com/en-US/education/catalog/sample/mesh_instancing
They pass the vertex information only one time for all instances and then they pass the matrices.

// Tell the GPU to read from both the model vertex buffer plus our instanceVertexBuffer.
GraphicsDevice.SetVertexBuffers(
new VertexBufferBinding(meshPart.VertexBuffer, meshPart.VertexOffset, 0),
new VertexBufferBinding(instanceVertexBuffer, 0, 1)
);


And in the vertex shader:

VertexShaderOutput VertexShaderCommon(VertexShaderInput input, float4x4 instanceTransform)

[size=1]Project page: [size=1]<

[size=1] XNA FINAL Engine[size=1] [size=1]>

This topic is closed to new replies.

Advertisement