I am almost done with migrating my XNA project, thanks to this great forum. I only have one major issue left: Skinned models do not animate. I have unskinned models that work as they should, and both types of models use common code for the animations, bone transforms and so on. So I suspect the error is in the skinned shader effect. I cannot debug the shader so I’m hoping for some troubleshooting ideas or other input.
technique SkinnedRender
{
pass P0
{
VertexShader = compile vs_4_0 TransformVertex();
PixelShader = compile ps_4_0 TransformPixel();
}
}
// This is the output from our skinning method
struct SKIN_OUTPUT
{
float4 position;
float4 normal;
};
// This method takes in a vertex and applies the bone transforms to it.
SKIN_OUTPUT Skin4(const VS_INPUT input)
{
SKIN_OUTPUT output = (SKIN_OUTPUT)0;
// Since the weights need to add up to one, store 1.0 - (sum of the weights)
float lastWeight = 1.0;
float weight = 0;
// Apply the transforms for the first 3 weights
for (int i = 0; i < 3; ++i)
{
weight = input.weights[i];
lastWeight -= weight;
output.position += mul(input.position, MatrixPalette[input.indices[i]]) * weight;
output.normal += mul(input.normal, MatrixPalette[input.indices[i]]) * weight;
}
// Apply the transform for the last weight
output.position += mul(input.position, MatrixPalette[input.indices[3]]) * lastWeight;
output.normal += mul(input.normal, MatrixPalette[input.indices[3]]) * lastWeight;
return output;
};
// This is passed into our pixel shader
struct VertexShaderOutput
{
float4 PositionPS : POSITION; // Position in projection space
float2 TexCoord : TEXCOORD0;
float4 PositionWS : TEXCOORD1;
float3 NormalWS : TEXCOORD2;
float2 DistanceFromViewer : TEXCOORD3; // NEW: for correct light occlusion!
float4 ScreenPosition : TEXCOORD4;
};
VertexShaderOutput TransformVertex(in VS_INPUT input)
{
VertexShaderOutput output = (VertexShaderOutput)0;
// Calculate the skinned position
SKIN_OUTPUT skin = Skin4(input);
// This is the final position of the vertex, and where it will be drawn on the screen
float4x4 WorldViewProjection = mul(World, mul(View, Projection));
output.PositionPS = mul(skin.position, WorldViewProjection);
float4 worldNormal = mul(skin.normal, World);
output.TexCoord = input.texcoord;
output.NormalWS = worldNormal;
output.PositionWS = mul(skin.position, World);
output.ScreenPosition = output.PositionPS; //pos_ps; /* for overlay rendering */
float4 uncorrectedPositionWS = mul(skin.position, UncorrectedWorld);
// use the uncorrected world matrix when computing the distance from the viewer. verify by comparing with billboards on the same line near the top/bottom parts of the screen.
float distanceFromViewer = saturate(1 - (uncorrectedPositionWS.y - WindowPosition.y) / ViewportSize.y);
output.DistanceFromViewer.x = distanceFromViewer;
return output;
}