   Problem of animation shadow volume
  here is the situation...I want using shadow volume with animation,and after I tried get some informationabout this... I known I have to do these steps*prepare workgenerate the shadow meshes by animation model*for updateskinned the default mesh and apply all frame transform to the shadow mesh*for render1.render default animatio mesh only ambient2.enable stencil and write stencil value with the extruding the vertices of shadow mesh in the vertex shader3.render animation mesh with light and compare stencil to implement last step for shadow volumehere's the problem the the extruding vertex seems get some troublehttp://farm2.static.flickr.com/1424/1312875272_976e2018ef.jpg?v=0http://farm2.static.flickr.com/1424/1312875272_976e2018ef.jpg?v=0below is my shader codeplease give some advice,I am confused this for a long timeor should I instead shadow mao to shadow volume?// Matrix Pallettestatic const int MAX_MATRICES = 26;float4x4    mWorldViewMatrixArray[MAX_MATRICES];//world * cameraViewfloat4x4    g_mProj;texture  g_txScene;  // texture for scene renderingfloat    g_fFarClip; // Z of far clip planefloat3   g_vLightWorldViewPos;    // View space light position/directionfloat3   g_vLightDir;    // View space light position/directionfloat4   g_vLightColor;   // Light colorfloat4   g_vAmbient;float4   g_vShadowColor;  // Shadow volume color (for visualization)float4   g_vMatColor;// Color of the materialint    MaterialSpecularPower    = 32;   // powerfloat3 CameraPos : CAMERAPOSITION;/////////////////////////////////////////////////////////-----------------------------------------------------------------------------// Texture samplers//-----------------------------------------------------------------------------sampler g_samScene =sampler_state{    Texture = &lt;g_txScene&gt;;    MinFilter = Linear;    MagFilter = Linear;    MipFilter = Linear;};struct VS_INPUT{    float4  Pos   : POSITION;    float4  BlendWeights    : BLENDWEIGHT;    float4  BlendIndices    : BLENDINDICES;    float3  Normal: NORMAL;    float3  Tex0  : TEXCOORD0;};struct VS_OUTPUT{    float4  Pos: POSITION;    float2  Tex0    : TEXCOORD0;};//-----------------------------------------------------------------------------// Name: CalcDiffuse// Type: Helper function// Desc: Calculates the diffuse lighting term//-----------------------------------------------------------------------------float4 CalcDiffuse(float3 Normal, float3 DirToLight){    return g_vMatColor * max(0, dot(Normal, DirToLight));}//-----------------------------------------------------------------------------// Name: CalcAmbient// Type: Helper function// Desc: Calculates the ambient lighting term//-----------------------------------------------------------------------------float4 CalcAmbient(){    return g_vLightColor * g_vMatColor * g_vAmbient;;}//-----------------------------------------------------------------------------// Name: CalcSpecular// Type: Helper function// Desc: Calculates the specular lighting term//-----------------------------------------------------------------------------float4 CalcSpecular(float3 Normal, float3 DirFromLight, float3 EyeToVertex){    float3 R = normalize(reflect(DirFromLight, Normal));    return pow(max(0, dot(R, -EyeToVertex)), MaterialSpecularPower/4);}VS_OUTPUT VertSceneAmbient(VS_INPUT i, uniform int NumBones){    VS_OUTPUT   o;    float4 Pos = 0.0f;    float  LastWeight = 0.0f;    // Compensate for lack of UBYTE4 on Geforce3    int4 IndexVector = D3DCOLORtoUBYTE4(i.BlendIndices);    // cast the vectors to arrays for use in the for loop below    float BlendWeightsArray[4] = (float[4])i.BlendWeights;    int   IndexArray[4]   = (int[4])IndexVector;   // calculate the pos/normal using the "normal" weights//   and accumulate the weights to calculate the last weight    for (int iBone = 0; iBone &lt; NumBones-1; iBone++)    {   LastWeight = LastWeight + BlendWeightsArray[iBone]; Pos += mul(i.Pos, mWorldViewMatrixArray[IndexArray[iBone]]) * BlendWeightsArray[iBone];    }    LastWeight = 1.0f - LastWeight;// Now that we have the calculated weight, add in the final influence    Pos += (mul(i.Pos, mWorldViewMatrixArray[IndexArray[NumBones-1]]) * LastWeight);   // transform position from world space into view and then projection space    o.Pos = mul(Pos,g_mProj);    // copy the input texture coordinate through    o.Tex0  = i.Tex0.xy;    return o;}float4 PixSceneAmbient( float2 Tex0 : TEXCOORD0 ) : COLOR0{    // Lookup mesh texture and modulate it with material and ambient amount    return g_vAmbient * tex2D( g_samScene, Tex0 * g_vMatColor);}void VertShadowVolume( VS_INPUT i, uniform int NumBones,   out float4 oPos : POSITION ){    float4 Pos = 0.0f;    float3 Normal = 0.0f;   float  LastWeight = 0.0f;    // Compensate for lack of UBYTE4 on Geforce3    int4 IndexVector = D3DCOLORtoUBYTE4(i.BlendIndices);    // cast the vectors to arrays for use in the for loop below    float BlendWeightsArray[4] = (float[4])i.BlendWeights;    int   IndexArray[4]   = (int[4])IndexVector;   // calculate the pos/normal using the "normal" weights//   and accumulate the weights to calculate the last weight    for (int iBone = 0; iBone &lt; NumBones-1; iBone++)    {   LastWeight = LastWeight + BlendWeightsArray[iBone]; Pos += mul(i.Pos, mWorldViewMatrixArray[IndexArray[iBone]]) * BlendWeightsArray[iBone];   Normal += mul(i.Normal, mWorldViewMatrixArray[IndexArray[iBone]]) * BlendWeightsArray[iBone];    }    LastWeight = 1.0f - LastWeight;// Now that we have the calculated weight, add in the final influence    Pos += (mul(i.Pos, mWorldViewMatrixArray[IndexArray[NumBones-1]]) * LastWeight);    Normal += (mul(i.Normal, mWorldViewMatrixArray[IndexArray[NumBones-1]]) * LastWeight);Normal = normalize(Normal);    float4 PosView = Pos;    float3 N = Normal;    float3 LightVecView = PosView - g_vLightWorldViewPos;    // Perform reverse vertex extrusion    // Extrude the vertex away from light if it's facing away from the light.    if( dot( N, -LightVecView ) &lt; 0.0f )    {   if( PosView.z &gt; g_vLightWorldViewPos.z )  PosView.xyz += LightVecView * ( g_fFarClip - PosView.z ) / LightVecView.z;   else  PosView = float4( LightVecView, 0.0f );   // Transform the position from view space to homogeneous projection space   oPos = mul( PosView, g_mProj );    } elseoPos = mul(Pos, g_mProj);}float4 PixShadowVolume() : COLOR0{    return float4( g_vShadowColor.xyz, 0.1f );}voidVertScene(VS_INPUT i,uniform int NumBones,uniform bool bSpecular,uniform bool bDiffuse, out float4 oPos : POSITION, out float4 ViewPos : TEXCOORD0, out float3 ViewNormal : TEXCOORD1, out float2 oTex0 : TEXCOORD2, out float4 oDiffuse : TEXCOORD3,out float4 oSpec: TEXCOORD4){    float4 Pos = 0.0f;    float3 Normal = 0.0f;   float  LastWeight = 0.0f;    // Compensate for lack of UBYTE4 on Geforce3    int4 IndexVector = D3DCOLORtoUBYTE4(i.BlendIndices);    // cast the vectors to arrays for use in the for loop below    float BlendWeightsArray[4] = (float[4])i.BlendWeights;    int   IndexArray[4]   = (int[4])IndexVector;   // calculate the pos/normal using the "normal" weights//   and accumulate the weights to calculate the last weight    for (int iBone = 0; iBone &lt; NumBones-1; iBone++)    {   LastWeight = LastWeight + BlendWeightsArray[iBone]; Pos += mul(i.Pos, mWorldViewMatrixArray[IndexArray[iBone]]) * BlendWeightsArray[iBone];   Normal += mul(i.Normal, mWorldViewMatrixArray[IndexArray[iBone]]) * BlendWeightsArray[iBone];    }    LastWeight = 1.0f - LastWeight;// Now that we have the calculated weight, add in the final influence    Pos += (mul(i.Pos, mWorldViewMatrixArray[IndexArray[NumBones-1]]) * LastWeight);    Normal += (mul(i.Normal, mWorldViewMatrixArray[IndexArray[NumBones-1]]) * LastWeight);    // transform position from world space into view and then projection space    oPos = mul(Pos,g_mProj);    // normalize normals    Normal = normalize(Normal);    // Compute view space position    ViewPos = Pos;    // Compute world space normal    ViewNormal = Normal;    oDiffuse = CalcAmbient();    float3 EyeToVertex = normalize(oPos - CameraPos);   // vector from vertex towards eye    // Modulate material with light to obtain diffuse    oSpec = 0;    if( bSpecular )oSpec = CalcSpecular(ViewNormal, g_vLightDir, EyeToVertex);    if( bDiffuse )oDiffuse += CalcDiffuse(ViewNormal, -g_vLightDir);    // Just copy the texture coordinate through    oTex0 = i.Tex0;}void PixScene( float4 ViewPos : TEXCOORD0,  float3 ViewNormal : TEXCOORD1,  float2 Tex0 : TEXCOORD2,  float4 Diffuse :TEXCOORD3,  float4 Spec:TEXCOORD4,  out float4 oCol : COLOR0,  out float4 oNormal : COLOR1,  out float4 oPos : COLOR2 ){    //Lookup mesh texture and modulate it with diffuse    oCol = float4( tex2D( g_samScene, Tex0 ).xyz, 1.0f );// * I;    oCol +=  Spec;    oNormal = float4(ViewNormal,1.0f);    oPos = ViewPos;}float4 ShowDirtyStencil() : COLOR0{    return g_vShadowColor;}float4 PixComplexity( uniform float4 Color ) : COLOR0{    return Color;}int CurNumBones = 2;//////////////////////////////////////// Techniques specs follow//////////////////////////////////////technique RenderSceneAmbient{    pass p0    {   VertexShader = compile vs_2_0 VertSceneAmbient(CurNumBones);   PixelShader  = compile ps_2_0 PixSceneAmbient();   StencilEnable = false;   ZFunc = LessEqual;    }}technique RenderShadowVolume2Sided{    pass P0    {   VertexShader = compile vs_2_0 VertShadowVolume(CurNumBones);   PixelShader  = compile ps_2_0 PixShadowVolume();   CullMode = None;   // Disable writing to the frame buffer   AlphaBlendEnable = true;   SrcBlend = Zero;   DestBlend = One;   // Disable writing to depth buffer   ZWriteEnable = false;   ZFunc = Less;   // Setup stencil states   TwoSidedStencilMode = true;   StencilEnable = true;   StencilRef = 1;   StencilMask = 0xFFFFFFFF;   StencilWriteMask = 0xFFFFFFFF;   Ccw_StencilFunc = Always;   Ccw_StencilZFail = Incr;   Ccw_StencilPass = Keep;   StencilFunc = Always;   StencilZFail = Decr;   StencilPass = Keep;    }}technique RenderShadowVolume{    pass P0    {   VertexShader = compile vs_2_0 VertShadowVolume(CurNumBones);   PixelShader  = compile ps_2_0 PixShadowVolume();   CullMode = Ccw;   // Disable writing to the frame buffer   AlphaBlendEnable = true;   SrcBlend = Zero;   DestBlend = One;   // Disable writing to depth buffer   ZWriteEnable = false;   ZFunc = Less;   // Setup stencil states   StencilEnable = true;   StencilRef = 1;   StencilMask = 0xFFFFFFFF;   StencilWriteMask = 0xFFFFFFFF;   StencilFunc = Always;   StencilZFail = Decr;   StencilPass = Keep;    }    pass P1    {   VertexShader = compile vs_2_0 VertShadowVolume(CurNumBones);   PixelShader  = compile ps_2_0 PixShadowVolume();   CullMode = Cw;   StencilZFail = Incr;    }}technique ShowShadowVolume2Sided{    pass P0    {   VertexShader = compile vs_2_0 VertShadowVolume(CurNumBones);   PixelShader  = compile ps_2_0 PixShadowVolume();   CullMode = None;   AlphaBlendEnable = true;   SrcBlend = SrcAlpha;   DestBlend = InvSrcAlpha;   // Disable writing to depth buffer   ZWriteEnable = false;   ZFunc = Less;   // Setup stencil states   TwoSidedStencilMode = true;   StencilEnable = true;   StencilRef = 1;   StencilMask = 0xFFFFFFFF;   StencilWriteMask = 0xFFFFFFFF;   Ccw_StencilFunc = Always;   Ccw_StencilZFail = Incr;   Ccw_StencilPass = Keep;   StencilFunc = Always;   StencilZFail = Decr;   StencilPass = Keep;    }}technique RenderScene{    pass P0    {   VertexShader = compile vs_2_0 VertScene(CurNumBones,true,true);   PixelShader  = compile ps_2_0 PixScene();   ZEnable = true;   ZFunc = LessEqual;   StencilEnable = true;   AlphaBlendEnable = true;   BlendOp = Add;   SrcBlend = One;   DestBlend = One;   StencilRef = 1;   StencilFunc = Greater;   StencilPass = Keep;    }}EDIT: Please do not just dump large blocks of code into posts. Use the 'source' tags in future. Thanks![Edited by - jollyjeffers on September 9, 2007 8:52:13 AM]