• 10
• 9
• 13
• 10
• 18

# XNAnimation shader problem (calc problem)

This topic is 2910 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I'm struggling with XNAnimation (a skeletal animation library for XNA). I want to apply a Toon shader effect to a SkinnedModel, but for some reason i don't see the effect... If you know XNAnimation then you probably know it uses his own 'basic' fx file in which he calculates the bone transformations. So i copied that part out and pasted that in my Toon shader file. My character does animate, but for some reason the Toon shader isn't applied, eventhough the code in the VertexShader part (where the bone transformations are done) DO work. I'm hoping anyone here has any idea what the problem might be. Cause i'm all out of ideas :-( This is my Toon shader:
float4x4 World;
float4x4 View;
float4x4 Projection;

float4x3 matBones[80];

float3 LightDirection = normalize(float3(1, 1, 1));

// Settings controlling the Toon lighting technique.
float ToonThresholds[2] = { 0.8, 0.4 };
float ToonBrightnessLevels[3] = { 1.3, 0.9, 0.5 };

texture Texture;

sampler ModelTextureSampler = sampler_state
{
Texture = <Texture>;

MinFilter = Linear;
MagFilter = Linear;
MipFilter = Linear;
};

//---------------------
// Structures
//---------------------

{
float4 Position             : POSITION0;
float4 Color                : COLOR0;
float3 Normal               : NORMAL0;
float2 TextureCoordinate    : TEXCOORD0;
};

{
float4 Position             : POSITION0;
float4 Color                : COLOR0;
float2 TextureCoordinate    : TEXCOORD0;
float LightAmount           : TEXCOORD1;
};

{
float4 Color                : COLOR0;
float2 TextureCoordinate    : TEXCOORD0;
float LightAmount           : TEXCOORD1;
};

//---------------------
//---------------------

{
// Calculate the final bone transformation matrix
float4x3 matSmoothSkin = 0;
matSmoothSkin += matBones[inBoneIndex.x] * inBoneWeight.x;
matSmoothSkin += matBones[inBoneIndex.y] * inBoneWeight.y;
matSmoothSkin += matBones[inBoneIndex.z] * inBoneWeight.z;
matSmoothSkin += matBones[inBoneIndex.w] * inBoneWeight.w;

// Combine skin and world transformations
float4x4 matSmoothSkinWorld = 0;
matSmoothSkinWorld[0] = float4(matSmoothSkin[0], 0);
matSmoothSkinWorld[1] = float4(matSmoothSkin[1], 0);
matSmoothSkinWorld[2] = float4(matSmoothSkin[2], 0);
matSmoothSkinWorld[3] = float4(matSmoothSkin[3], 1);
matSmoothSkinWorld = mul(matSmoothSkinWorld, World);

// Apply camera matrices to the input position.
// Original: output.Position = mul(mul(mul(input.Position, World), View), Projection);
output.Position = mul(mul(mul(input.Position, matSmoothSkinWorld), View), Projection);

output.TextureCoordinate = input.TextureCoordinate;

float3 worldNormal = mul(input.Normal, World);

output.LightAmount = dot(worldNormal, LightDirection);

output.Color = input.Color;

return output;

}

//---------------------
//---------------------

{
float4 color = tex2D(ModelTextureSampler, input.TextureCoordinate);

float light;

if (input.LightAmount > ToonThresholds[0])
light = ToonBrightnessLevels[0];
else if (input.LightAmount > ToonThresholds[1])
light = ToonBrightnessLevels[1];
else
light = ToonBrightnessLevels[2];

color.rgb *= light;

return color;
}

//---------------------
// Technique
//---------------------

technique Toon
{
pass P0
{
}
}


This is what i have in my draw loop:
            Toon.Parameters["World"].SetValue(world);
Toon.Parameters["View"].SetValue(camera.View);
Toon.Parameters["Projection"].SetValue(camera.Projection);
Toon.CurrentTechnique = Toon.Techniques["Toon"];

foreach (ModelMesh meshes in model.Meshes)
{
foreach (ModelMeshPart parts in meshes.MeshParts)
{
Toon.Parameters["matBones"].SetValue(animationController.SkinnedBoneTransforms);
Toon.Parameters["Texture"].SetValue(Materials[parts].Texture);
parts.Effect = Toon;
}
meshes.Draw();
}


[Edited by - vivendi on April 1, 2010 7:48:51 AM]

##### Share on other sites
Just checked it out with PIX. I have an original sample, which just uses the Model of XNA Framework which i debuged in PIX and next to that the game i have now with XNAnimation.

I noticed that for some reason the value of 'worldNormal' was much higher in the original than in my current game. In the original the values were approximately: (0.400, 0.200, 0.800). But in my current game the value was: (0.003, 0.020, 0.046). So like a hundred times smaller.

So i changed the following line:

float3 worldNormal = mul(input.Normal, World);

To:

float3 worldNormal = mul(mul(input.Normal, World), 100);

Now i do see the Toon effect appear. But not 100% correctly yet. Please take a look at the image:

http://i39.tinypic.com/6p9b8m.jpg

As you can see in that image, my current game shows only two colors of the Toon effect, while the original version shows 3 colors of the Toon effect. So it obviously has something to do with my shader. Guess some other values need to be altered aswell. If you have any idea what it might be please let me know :)