Sign in to follow this  

XNAnimation shader problem (calc problem)

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

If you intended to correct an error in the post then please contact us.

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;   
    AddressU = Clamp;   
    AddressV = Clamp;   
};   
  
  
//---------------------   
// Structures   
//---------------------   
  
struct VertexShaderInput   
{   
    float4 Position             : POSITION0;   
    float4 Color                : COLOR0;   
    float3 Normal               : NORMAL0;   
    float2 TextureCoordinate    : TEXCOORD0;   
};   
  
struct LightingVertexShaderOutput   
{   
    float4 Position             : POSITION0;   
    float4 Color                : COLOR0;   
    float2 TextureCoordinate    : TEXCOORD0;   
    float LightAmount           : TEXCOORD1;   
};   
  
struct LightingPixelShaderInput   
{   
    float4 Color                : COLOR0;   
    float2 TextureCoordinate    : TEXCOORD0;   
    float LightAmount           : TEXCOORD1;   
};   
  
//---------------------   
// Vertex shader   
//---------------------   
  
LightingVertexShaderOutput LightingVertexShader(VertexShaderInput input, float4 inBoneIndex :BLENDINDICES0, float4 inBoneWeight :BLENDWEIGHT0)   
{   
    LightingVertexShaderOutput output;   
    // 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;   
       
       
}   
  
//---------------------   
// Pixel shader   
//---------------------   
  
  
float4 ToonPixelShader(LightingPixelShaderInput input) : COLOR0   
{   
    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   
    {   
        VertexShader = compile vs_1_1 LightingVertexShader();   
        PixelShader = compile ps_2_0 ToonPixelShader();   
    }   
}   


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 this post


Link to post
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 :)

Share this post


Link to post
Share on other sites

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

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this