hey there. i guess this is just some kind of small error but idk.
I'm currently programing a small game in XNA and so far I've implemented a Toon Shader and wanted to add animations.
After some trouble I found some help on a website and edited the Shader to this
Code
//--------------------------- BASIC PROPERTIES ------------------------------
#define MaxBones 60
float4x3 Bones[MaxBones];
// The world transformation
float4x4 World;
// The view transformation
float4x4 View;
// The projection transformation
float4x4 Projection;
// The transpose of the inverse of the world transformation,
// used for transforming the vertex's normal
float4x4 WorldInverseTranspose;
//--------------------------- DIFFUSE LIGHT PROPERTIES ------------------------------
// The direction of the diffuse light
float3 DiffuseLightDirection = float3(0, 0.5, 0.5);
// The color of the diffuse light
float4 DiffuseColor = float4(1, 1, 1, 1);
// The intensity of the diffuse light
float DiffuseIntensity = 5.7;
//--------------------------- TOON SHADER PROPERTIES ------------------------------
// The color to draw the lines in. Black is a good default.
float4 LineColor = float4(0, 0, 0, 1);
// The thickness of the lines. This may need to change, depending on the scale of
// the objects you are drawing.
float4 LineThickness = 0.12;
//--------------------------- TEXTURE PROPERTIES ------------------------------
// The texture being used for the object
texture Texture;
// The texture sampler, which will get the texture color
sampler2D textureSampler = sampler_state
{
Texture = (Texture);
MinFilter = Linear;
MagFilter = Linear;
AddressU = Clamp;
AddressV = Clamp;
};
//--------------------------- DATA STRUCTURES ------------------------------
// The structure used to store information between the application and the
// vertex shader
struct AppToVertex
{
float4 Position : SV_Position;
float3 Normal : NORMAL;
float2 TexCoord : TEXCOORD0;
int4 Indices : BLENDINDICES0;
float4 Weights : BLENDWEIGHT0;
};
// The structure used to store information between the vertex shader and the
// pixel shader
struct VertexToPixel
{
float4 Position : POSITION0;
float2 TextureCoordinate : TEXCOORD0;
float3 Normal : TEXCOORD1;
};
//SKIN Metod
void Skin(inout AppToVertex vin, uniform int boneCount)
{
float4x3 skinning = 0;
[unroll]
for (int i = 0; i < boneCount; i++)
{
skinning += Bones[vin.Indices[i]] * vin.Weights[i];
}
vin.Position.xyz = mul(vin.Position, skinning);
vin.Normal = mul(vin.Normal, (float3x3)skinning);
}
//--------------------------- SHADERS ------------------------------
// The vertex shader that does cel shading.
// It really only does the basic transformation of the vertex location,
// and normal, and copies the texture coordinate over.
VertexToPixel CelVertexShader(AppToVertex input)
{
VertexToPixel output;
Skin(input, 4);
// Transform the position
float4 worldPosition = mul(input.Position, World);
float4 viewPosition = mul(worldPosition, View);
output.Position = mul(viewPosition, Projection);
// Transform the normal
output.Normal = normalize(mul(input.Normal, WorldInverseTranspose));
// Copy over the texture coordinate
output.TextureCoordinate = input.TexCoord;
return output;
}
// The pixel shader that does cel shading. Basically, it calculates
// the color like is should, and then it discretizes the color into
// one of four colors.
float4 CelPixelShader(VertexToPixel input) : COLOR0
{
// Calculate diffuse light amount
float intensity = dot(normalize(DiffuseLightDirection), input.Normal);
if(intensity < 0)
intensity = 0;
// Calculate what would normally be the final color, including texturing and diffuse lighting
float4 color = tex2D(textureSampler, input.TextureCoordinate) * DiffuseColor * DiffuseIntensity;
color.a = 1;
// Discretize the intensity, based on a few cutoff points
if (intensity > 0.95)
color = float4(1.0,1,1,1.0) * color;
else if (intensity > 0.5)
color = float4(0.7,0.7,0.7,1.0) * color;
else if (intensity > 0.05)
color = float4(0.35,0.35,0.35,1.0) * color;
else
color = float4(0.1,0.1,0.1,1.0) * color;
return color;
}
// The vertex shader that does the outlines
VertexToPixel OutlineVertexShader(AppToVertex input)
{
VertexToPixel output = (VertexToPixel)0;
Skin(input, 4);
// Calculate where the vertex ought to be. This line is equivalent
// to the transformations in the CelVertexShader.
float4 original = mul(mul(mul(input.Position, World), View), Projection);
// Calculates the normal of the vertex like it ought to be.
float4 normal = mul(mul(mul(input.Normal, World), View), Projection);
// Take the correct "original" location and translate the vertex a little
// bit in the direction of the normal to draw a slightly expanded object.
// Later, we will draw over most of this with the right color, except the expanded
// part, which will leave the outline that we want.
output.Position = original + (mul(LineThickness, normal));
return output;
}
// The pixel shader for the outline. It is pretty simple: draw everything with the
// correct line color.
float4 OutlinePixelShader(VertexToPixel input) : COLOR0
{
return LineColor;
}
// The entire technique for doing toon shading
technique Toon
{
// The first pass will go through and draw the back-facing triangles with the outline shader,
// which will draw a slightly larger version of the model with the outline color. Later, the
// model will get drawn normally, and draw over the top most of this, leaving only an outline.
pass Pass1
{
VertexShader = compile vs_1_1 OutlineVertexShader();
PixelShader = compile ps_2_0 OutlinePixelShader();
CullMode = CW;
}
// The second pass will draw the model like normal, but with the cel pixel shader, which will
// color the model with certain colors, giving us the cel/toon effect that we are looking for.
pass Pass2
{
VertexShader = compile vs_1_1 CelVertexShader();
PixelShader = compile ps_2_0 CelPixelShader();
CullMode = CCW;
}
}
also my current draw method looks like this
Code
public override void draw()
{
Matrix view = m_updateInfo.viewMatrix;
Matrix projection = m_updateInfo.projectionMatrix;
// Copy any parent transforms.
Matrix[] transforms = new Matrix[m_model.Bones.Count];
m_model.CopyAbsoluteBoneTransformsTo(transforms);
Matrix[] bones = animationPlayer.GetSkinTransforms();
Matrix translateMatrix = Matrix.CreateTranslation(m_position);
Matrix worldMatrix = translateMatrix;
Matrix rotation;
if (direction.X > 0)
{
rotation = Matrix.CreateRotationY((float)Math.Acos(direction.Z));
}
else
{
rotation = Matrix.CreateRotationY((float)-Math.Acos(direction.Z));
}
// Draw the model. A model can have multiple meshes, so loop.
foreach (ModelMesh mesh in m_model.Meshes)
{
foreach (ModelMeshPart part in mesh.MeshParts)
{
part.Effect = effect;
effect.Parameters["Bones"].SetValue(bones);
effect.Parameters["World"].SetValue(rotation * worldMatrix * mesh.ParentBone.Transform);
effect.Parameters["DiffuseLightDirection"].SetValue(new Vector3(rotation.M13, rotation.M23, rotation.M33));
effect.Parameters["View"].SetValue(view);
effect.Parameters["Projection"].SetValue(projection);
effect.Parameters["WorldInverseTranspose"].SetValue(
Matrix.Transpose(Matrix.Invert(worldMatrix * mesh.ParentBone.Transform)));
effect.Parameters["Texture"].SetValue(texture);
}
// Draw the mesh, using the effects set above.
mesh.Draw();
BoundingBoxRenderer.Render(this.m_boundingBox, m_updateInfo.graphics, view, projection, Color.White);
}
}
the problem I got now is the following:

For some reason the model and/or the texture gets kinda deformed... except for the hand everything's fine on the normal model but the Outline of the Shader is completely wrong!? it's kind of distorted in another direction and I have no idea why..
Is there some kind of mistake in my code or am I missing something!?
Already checked it with another test-animation, result was the same.
I appreciate any help.
/e: the animation only moves the feet a little btw
This post was edited by KillerApfel on Aug 13 2013 07:54am