matBones
If a matrix array with this name appears in a shader, the engine calculates the bones animation on the GPU, rather than on the CPU. This way animated actors are rendered up to 10 times faster, especially when they have many bones or bone weights.
Type:
float4x3
Remarks:
- Functions that rely on vertex positions - such as vec_for_vertex, decals, mouse picking, polygonal collisions, traces etc. - can't be used when bones animation is calculated on the GPU.
- The array size must be the same or greater than the number of bones of the model. As the number of shader variables, including bones matrices, is limited, don't use models with more than about
70 bones. The DoBones function of the default.fx shader code library allocates 72 bones matrices. If this limits other shader variables, reduce this number.
- A8.11
The array size can be read by script from the maxbones variable of the material struct. This variable can also be used to determine if a material contains a GPU bones shader.
-
The model must not use more than 4 bones per vertex, and the bones with the highest weight must come first. Otherwise, distortion will be visible in the GPU bones animation.
- An example shader bones.fx is included in the code folder. The shader can be combined with other shaders f.i. for surface bumpmapping. The crowd.c sample uses GPU bones animation.
- If a shader variable iWeights exists, it is preset to the number of weights (0..3) of the model.
Edition:
A8
P
Example:
// bones animation shader
#include <transform>
#include <fog>
#include <pos>
#include <normal>
#include <lights>
#include <texture>
#include <color>
float4x3 matBones[72];
int iWeights;
struct vsOut
{
float4 Pos: POSITION;
float Fog: FOG;
float4 Ambient:COLOR;
float2 Tex: TEXCOORD0;
};
vsOut bones_VS (
in float4 inPos: POSITION,
in float3 inNormal: NORMAL,
in float2 inTex: TEXCOORD0,
in int4 inBoneIndices: BLENDINDICES,
in float4 inBoneWeights: BLENDWEIGHT
)
{
vsOut Out;
Out.Tex = DoTexture(inTex);
Out.Fog = DoFog(inPos);
Out.Ambient = DoAmbient();
float3 P = DoPos(inPos);
float3 N = DoNormal(inNormal);
for (int i=0; i<iLights; i++) // Add 8 dynamic lights
Out.Ambient.xyz += DoLight(P,N,i)*0.5*vecDiffuse;
float3 WorldPos = 0;
for (int i=0; i<iWeights; i++)
WorldPos += mul(inPos.xzyw,matBones[inBoneIndices[i]])*inBoneWeights[i];
Out.Pos = DoTransform(float4(WorldPos.xzy,1.0));
return Out;
}
technique bones
{
pass { VertexShader = compile vs_2_0 bones_VS(); }
}
See also:
Shader variables, matTangent
► latest
version online