Skinned models not animating in migrated project

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

I am trying to debug the vertex shader using Intel GPA. Unfortunately the HLSL code is not available… it says the code is only available if the game has supplied the shader at runtime.

It looks like I will have to output debug values in the pixel shader if I want to figure out what isn’t working. First I have to pass them from the vertex shader through the modified output struct.

I’m sorry I can’t help, I have not used skinned yet - but maybe check out this thread

The code originally came from the XNA Animation Component library:

There is animation on the root bone. The entire model is in the bind pose but it moves in rhythm with the animation…

As a first step in debugging, I am trying to output the blend indices from the vertex shader input in a color. The result is black - so either they are all 0, or I am not doing it correctly.

The weights seem to have appropriate values:

When I output the blend indices in the original project, I see varying colors as expected. But in the migrated project they are all black, which means their values are lost somewhere going into the vertex shader.

It looks like the vertex buffer contains data at the spot where the blend indices are supposed to be, right before calling device.SetVertexBuffer(currentPart.VertexBuffer);

I checked with my original xna project and the data looks to be the same.

Could it be that the half4 type is causing problems in the later shader model? Since this used to be SM 2 code.
half4 indices : BLENDINDICES0;

“half - 16-bit floating point value. This data type is provided only for language compatibility. Direct3D 10 shader targets map all half data types to float data types.”

The C# code packs the indices into Byte4 structures. So 4 bytes have to be mapped to a vector with 4 16-bit types.

I finally got it working, by changing half4 to int4.

I had the XNA skinned animation sample working in MonoGame a couple of years ago. I should dig it out, update it and make it an official sample.

You have done a great job for all us who have stranded XNA projects. I was nervous when I started migrating, but now I feel I’m out of the woods.

Perhaps the forum should have a “Migrating” tag or label to put on posts, or a FAQ for the most common issues.