I'm currently working on a hardware skinning shader in my project and I have it working, but only with a weird limitation.
This is the working shader:
Code: Select all
float4x4 World;
float4x4 View;
float4x4 Projection;
float4x4 WorldViewProjection;
// max. number of bones
static const int MAX_MATRICES = 64;
float4x4 BonesMatrix[MAX_MATRICES];
// input for the vertex shader
struct VS_INPUT
{
float4 Position : POSITION0;
float4 Normal : NORMAL0;
float4 Color : COLOR0;
float2 TexCoord : TEXCOORD0;
float4 BlendIndices : BLENDINDICES0;
float4 BlendWeights : BLENDWEIGHT0;
float4 Tangent : TANGENT0;
float4 Binormal : BINORMAL0;
};
struct VS_OUTPUT
{
float4 Position : POSITION0;
float4 Color : COLOR0;
float2 TexCoord : TEXCOORD0;
};
VS_OUTPUT main(VS_INPUT input)
{
VS_OUTPUT output = (VS_OUTPUT)0;
output.Color = float4(0.0, 0.2, 0.4, 1);
float4 worldPos = mul(input.Position, World);
float4 viewPos = mul(worldPos, View);
// calculate the pos/normal using the "normal" weights and accumulate the weights to calculate the last weight
int NumBones = 4;
int BoneIndex = 1;
float Weight = 0;
float LastWeight = 1;
float4 Position = 0;
// Blend between the weighted bone matrices.
for(int iBone = 0; iBone < NumBones -1; iBone++)
{
BoneIndex = int(input.BlendIndices[iBone]);
Weight = float(input.BlendWeights[iBone]);
LastWeight = LastWeight - Weight;
if (BoneIndex < 61)
{
float4 difference = mul(input.Position, BonesMatrix[BoneIndex]) * Weight;
Position.xyz += difference.xyz;
}
}
BoneIndex = int(input.BlendIndices[NumBones-1]);
if (BoneIndex < 61)
{
float4 difference = mul(input.Position, BonesMatrix[BoneIndex]) * LastWeight;
Position.xyz += difference.xyz;
}
output.Position = mul(float4(Position.xyz, 1.0f), WorldViewProjection);
output.Color.rgba = input.Color;
output.TexCoord = input.TexCoord;
return output;
}
Code: Select all
...
if(BoneIndex < 61)
...
"Could not create hlsl vertex shader."
This is how I load my shader:
Code: Select all
// Setup the skin shader
irr::s32 material = irr::video::EMT_SOLID;
irr::scene::ISceneManager* smgr = m_device->getSceneManager();
irr::video::IVideoDriver* driver = m_device->getVideoDriver();
m_callback = std::make_shared<SkinShaderCallback>();
if (driver->queryFeature(irr::video::EVDF_VERTEX_SHADER_2_0)) {
irr::video::IGPUProgrammingServices* gpu = driver->getGPUProgrammingServices();
if (gpu) {
// DirectX 9
if (driver->getDriverType() == irr::video::EDT_DIRECT3D9) {
material = gpu->addHighLevelShaderMaterialFromFiles("data/skin_vs.hlsl", "main", irr::video::EVST_VS_1_1, "", "", irr::video::EPST_PS_2_0, m_callback.get(), irr::video::EMT_SOLID);
}
}
}
We are using the shader-pipeline branch:
svn://svn.code.sf.net/p/irrlicht/code/branches/shader-pipeline
Thanks in advance,
Erelas