# Bunch of Questions on Skeletal Animation

## Recommended Posts

##### Share on other sites

Quote:
 Original post by andorI can find no place in it in which it actually uses this effect.

With the sample framework things might be getting done in a way that you cannot see on the surface. I don't use the framework myslef, but maybe sombody else here does.
Quote:
 is it possible to create a pixel shader that does not use a vertex shader at all? If so, what sorts of input parameters would it be able to use?

in your fx fie if you set the PixelShader or the VertexShader (or both) to null th FF is used for that portion of the pipeline. The vertex shader's semantics map back into the FF as you might expect POSITION0 is required, TEXCOORD[0-7] are picked up, COLOR0 is vertex color and COLOR1, I believe, is specular color.
Quote:
 I've only got a vs_1_1 capable card (Radeon 9100), so this 26 palette size limit directly affects me. Is this an absolute max on the number of bones that can be used in a single mesh, or can it be tweaked up slightly?

it probably can be tweaked depending on the number of other constants you need. I have heard of using 2 vectors per bone, 1 for rotation and one for position, instead of using mats(which use 3 or 4 vector registers) and building your mats in the shader to save constant space, don't know how effective it is though.
Quote:
 2. How exactly does one use the SkinInformation.ConvertToIndexedBlendedMesh function and what exactly does it do?

It uses bone combination information to add blend variables to each vert. It should add 4 weight variables and an index variable (4 byte indices) to every vert.

Hope this helps.

##### Share on other sites
Quote:
 Original post by turnpastin your fx fie if you set the PixelShader or the VertexShader (or both) to null th FF is used for that portion of the pipeline. The vertex shader's semantics map back into the FF as you might expect POSITION0 is required, TEXCOORD[0-7] are picked up, COLOR0 is vertex color and COLOR1, I believe, is specular color.

Interesting, I'll have to give that a try. For most of my stuff, I don't particularly care about the vertex shader's capabilities, though I would like to grab normal information out of it.

Quote:
 Original post by turnpastit probably can be tweaked depending on the number of other constants you need. I have heard of using 2 vectors per bone, 1 for rotation and one for position, instead of using mats(which use 3 or 4 vector registers) and building your mats in the shader to save constant space, don't know how effective it is though.

Interesting idea, that would work quite nicely I believe. Since the translation component should be constant for all of the bones, it really only needs to be stored once. Building the transformation matrix in the shader would consume some extra gpu cycles so I'll use that as a last resort if I need to.

Solves some of my questions, so thanks :)

##### Share on other sites
Bizzarly, the SimpleAnimation sample did not seem to use its effect when I last looked at it. I highly recommend going through the C++ SkinnedMesh sample with the docs to understand how it works. That definately does use the shaders and uses several different methods; ff indexed skinning, ff non-indexed skinning, asm skinning and hlsl indexed skinning.

I have got HLDL indexed skinning working, you can have the skinning functions:
Skinning.inc:
// If you want a palette size other than the default (26),// #define MATRIX_PALETTE_SIZE_DEFAULT before your #include Skinning.inc#ifndef SKINNING#define SKINNING//----------------------------------------------------------------------------// Global parameters //----------------------------------------------------------------------------// Declare the 4x3 matrix palette.  This is the array of bone matrices used in// skinning vertices.// The palette size is 26 by default.  This is sufficiently small for most // vs_1_1 shaders.  Shaders targeted at vs_2_0 and above can set this higher// to accommondate more bones in a call.  For example, tiny_anim.x has 35// bones, and so can be rendered in a single call if MATRIX_PALETTE_SIZE is// set to 35 or more.// An HLSL shader can set MATRIX_PALETTE_SIZE_DEFAULT to a different value.// The calling app can also set it in the D3DXMACRO structure when compiling// the shader.  The calling app can query the actual palette size by examining// MATRIX_PALETTE_SIZE (but changing it after compilation will not change the// palette size in the compiled shader, of course).#ifndef MATRIX_PALETTE_SIZE_DEFAULT#define MATRIX_PALETTE_SIZE_DEFAULT 26#endifconst int MATRIX_PALETTE_SIZE = MATRIX_PALETTE_SIZE_DEFAULT;float4x3 amPalette[MATRIX_PALETTE_SIZE_DEFAULT] : WORLDMATRICES;// call this function to skin VB position and normalvoid SkinIndexed(const in float4 position,                 const in float3 blendWeights,                 const in float4 blendIndices,                 const in float3 normal,                 uniform int numBones,                 out float3 skinnedPosition,                 out float3 skinnedNormal){    float lastWeight = 1.0;    float afBlendWeights[3] = (float[3])blendWeights;    int aiIndices[4] = (int[4])D3DCOLORtoUBYTE4(blendIndices);        //First bone    if (numBones == 1) {        skinnedPosition.xyz = mul(position,         amPalette[aiIndices[0]]);        skinnedNormal       = mul(normal, (float3x3)amPalette[aiIndices[0]]);    }    else {        float fWeight = afBlendWeights[0];        lastWeight -= fWeight;        skinnedPosition.xyz = mul(position,         amPalette[aiIndices[0]]) * fWeight;        skinnedNormal      = mul(normal, (float3x3)amPalette[aiIndices[0]]) * fWeight;    }    //Second to third bones    for( int iBone = 1; (iBone < 3) && (iBone < numBones - 1); ++iBone )    {        float fWeight = afBlendWeights[iBone];        lastWeight -= fWeight;        skinnedPosition.xyz += mul(position,         amPalette[aiIndices[iBone]]) * fWeight;        skinnedNormal       += mul(normal, (float3x3)amPalette[aiIndices[iBone]]) * fWeight;    }    //Last bone if not first bone    if (numBones > 1) {        skinnedPosition.xyz += mul(position,         amPalette[aiIndices[numBones - 1]]) * lastWeight;        skinnedNormal       += mul(normal, (float3x3)amPalette[aiIndices[numBones - 1]]) * lastWeight;    }}void SkinIndexedPosOnly(const in float4 position,                        const in float3 blendWeights,                        const in float4 blendIndices,                        uniform int numBones,                        out float3 skinnedPosition){    float lastWeight = 1.0;    float afBlendWeights[3] = (float[3])blendWeights;    int aiIndices[4] = (int[4])D3DCOLORtoUBYTE4(blendIndices);        //First bone    if (numBones == 1) {        skinnedPosition.xyz = mul(position, amPalette[aiIndices[0]]);    }    else {        float fWeight = afBlendWeights[0];        lastWeight -= fWeight;        skinnedPosition.xyz = mul(position, amPalette[aiIndices[0]]) * fWeight;    }    //Second to third bones    for( int iBone = 1; (iBone < 3) && (iBone < numBones - 1); ++iBone )    {        float fWeight = afBlendWeights[iBone];        lastWeight -= fWeight;        skinnedPosition.xyz += mul(position, amPalette[aiIndices[iBone]]) * fWeight;    }    //Last bone if not first bone    if (numBones > 1) {        skinnedPosition.xyz += mul(position, amPalette[aiIndices[numBones - 1]]) * lastWeight;    }}#endif // #ifndef SKINNING

Hope that helps,
Andrew

## Create an account

Register a new account

• ### Forum Statistics

• Total Topics
628354
• Total Posts
2982230

• 10
• 9
• 11
• 24
• 11