Jump to content
  • Advertisement
Sign in to follow this  
8up tuotlo

Help with Skinned Mesh shader

This topic is 1346 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 am use this HLSL D3DXEFFECT shader to draw my animated model in my application.

Shader model 3.0.




//-- Lighting ------
struct Direct
float3 pos;
float3 col;
Direct Dl[2];
float3 Al;
float3 eye;
float Sp;
float4x4 BM[60];
float4x4 Gm;
float4x4 Wm;
struct VS_in
float4 Pos  : POSITION;
float3 Norm : NORMAL;
float2 Tex  : TEXCOORD0;
float4 bi   : BLENDINDICES0;
float4 bw : BLENDWEIGHT0;
struct VS_out
float4 Pos  : POSITION;
float3 Norm : TEXCOORD1;
float2 Tex  : TEXCOORD0;
float3 wPos : TEXCOORD2;
float3 v    : TEXCOORD3;
VS_out vs(VS_in In)
VS_out Out;
float4x4 blend = BM[In.bi.x]*In.bw.x + BM[In.bi.y]*In.bw.y + BM[In.bi.z]*In.bw.z + BM[In.bi.w]*In.bw.w;
float4 SkinPos, SkinNorm;
SkinPos.x = (In.Pos.x * blend._11)+(In.Pos.z * blend._21)+(In.Pos.y * blend._31)+(blend._41);
SkinPos.z = (In.Pos.x * blend._12)+(In.Pos.z * blend._22)+(In.Pos.y * blend._32)+(blend._42);
SkinPos.y = (In.Pos.x * blend._13)+(In.Pos.z * blend._23)+(In.Pos.y * blend._33)+(blend._43);
SkinPos.w = 1.0f;
SkinNorm.x = (In.Norm.x * blend._11)+(In.Norm.z * blend._21)+(In.Norm.y * blend._31);
SkinNorm.z = (In.Norm.x * blend._12)+(In.Norm.z * blend._22)+(In.Norm.y * blend._32);
SkinNorm.y = (In.Norm.x * blend._13)+(In.Norm.z * blend._23)+(In.Norm.y * blend._33);
SkinNorm.w = 1.0f;
Out.Pos = mul(SkinPos, Gm);
Out.Tex = In.Tex;
Out.Norm = normalize(mul(SkinNorm, (float3x3)Wm));
Out.wPos = mul(SkinPos, Wm);
Out.v = eye.xyz - Out.wPos;
return Out;
float3 light(float3 n, float3 v)
float  nDotL[2];
nDotL[0] = saturate(dot(n, normalize(Dl[0].pos)));
nDotL[1] = saturate(dot(n, normalize(Dl[1].pos)));
float3 ret = Dl[0].col * nDotL[0] + Dl[1].col * nDotL[1] + Al;
/*+ (Dl[0].col * ((nDotL[0] == 0.0f) ? 0.0f : pow((saturate(dot(n, normalize(Dl[0].pos + v)))), Sp)));*/
return ret;
float4 ps(VS_out In) : COLOR0
return float4(light(normalize(In.Norm), normalize(In.v)), 1);
technique Standart
    pass P0
        VertexShader = compile vs_3_0 vs();
PixelShader  = compile ps_3_0 ps();



it is maximum of 60 bones by:


float4x4 BM[60];


when i try to set it to:


float4x4 BM[120];


shader not works.


Who knows why?

Can it be set to 120, and how if it is possible?

Edited by 8up tuotlo

Share this post

Link to post
Share on other sites

You're limited to 256 registers (float4) for constants. 60 * 4 = 240, which is okay. 120 * 4 > 256.


EDIT: For clarity - float4x4 is float4 times 4 = 4 registers. Also, beware, with 60 matrices taking up 240 registers, you're limited to just 16 additional constants.


float3 eye; // 1 register
float Sp; // 1 register
float4x4 BM[60]; // 240 registers
float4x4 Gm; // 4 registers
float4x4 Wm; // 4 registers


for 250 registers (of 256 available).

Edited by Buckeye

Share this post

Link to post
Share on other sites

Yup, up to 1024 bones if you do it naively. "Limitless" if you're doing it smart wink.png


But since you use SM3 you could use vertex texture fetch: Using a texture to hold your bone matrices and use several tex2Dlod in the vertex shader to load them.


There are other ways to address this limit: Split the mesh, use affine transformations (3x4 matrices), quaternions... Here's a recent discussion.



Share this post

Link to post
Share on other sites
Sign in to follow this  

  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!