Original Post
hello, I have this issue. Recently I ported my engine from ogl to dx. I had a ogl skinning shader. I rewrote the shader to HLSL. But with the HLSL version I get a strange artifact. The mesh gets animated but some verticies animate differently, some verticies animate properly. I can tell I get about 70% of verticies animating well, the rest of them absolutely unexpectedly animating. I thought the problem might be weights or indicies I send by the stream but my CPU code for stream data creation is just the same like in ogl version. I work with the same mesh file format (arbitrary one). I feed the stream with the same data as in ogl version but there might by some problem with vertex declaration. Here is my vertex declaration in dx. As you can see stream 2 is associated with bones info. Here is how I feed the stream the BoneVertex structure is defined as follows Matricies data are fed to the shader the same way like in ogl version. They are column major matricies. I bind the stream when rendering. I think I have the stucky in the HLSL shader Here is ogl version of the skinning shader and here is the HLSL one What possibly coild couse some verticies to animate unexpectedly, some correctly? matricies data are the same like in ogl version.
D3DVERTEXELEMENT9 decl[] =
{
{ 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
{ 0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0 },
{ 0, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },
{ 2, 32, D3DDECLTYPE_UBYTE4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES, 0 },
{ 2, 36, D3DDECLTYPE_UBYTE4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 0 },
D3DDECL_END()
};
char* boneIDs = new char[vert*4];
char* boneWeights = new char[vert*4];
inputf.read((char*)boneWeights,vert*4*sizeof(char));
inputf.read((char*)boneIDs,vert*4*sizeof(char));
IDirect3DVertexBuffer9* bonebuff = m_pVerBuff->GetBonesBuffer();
GetScene()->GetDevice()->GetD3DDevice()->CreateVertexBuffer(
m_iNumOfVerticies*sizeof(BoneVertex),
0 /*Usage*/, 0, D3DPOOL_DEFAULT, &bonebuff, NULL
);
BoneVertex* data;
bonebuff->Lock(0,0,(void**)&data,D3DLOCK_DISCARD);
for (long i=0;i<m_iNumOfVerticies;i++)
{
(data+i)->id1 = *(boneIDs+i*4);
(data+i)->id2 = *(boneIDs+i*4+1);
(data+i)->id3 = *(boneIDs+i*4+2);
(data+i)->id4 = *(boneIDs+i*4+3);
(data+i)->w1 = *(boneWeights+i*4+0);
(data+i)->w2 = *(boneWeights+i*4+1);
(data+i)->w3 = *(boneWeights+i*4+2);
(data+i)->w4 = *(boneWeights+i*4+3);
}
bonebuff->Unlock();
struct BoneVertex {
unsigned char id1,id2,id3,id4;
unsigned char w1,w2,w3,w4;
};
uniform vec3 u_direction;
uniform mat4 u_modelmatrix;
uniform mat4 u_identitymatrix;
uniform mat4 u_modelmatrixinverse;
uniform mat4 u_model_view_proj_matrix;
uniform mat4 u_pose[32];
varying vec3 normal;
varying vec3 lightDir;
varying vec2 Texcoord;
varying float matid;
attribute vec4 BoneWeight;
attribute vec4 BoneID;
attribute int BoneID1;
attribute int BoneID2;
attribute int BoneID3;
attribute int BoneID4;
/*attribute float MaterialID;*/
void main()
{
mat4 mat = u_pose[BoneID1] * BoneWeight[0];
mat += u_pose[BoneID2] * BoneWeight[1];
mat += u_pose[BoneID3] * BoneWeight[2];
mat += u_pose[BoneID4] * BoneWeight[3];
if (mat[0]==0.0)
mat = u_identitymatrix;
gl_Position = u_model_view_proj_matrix * mat * gl_Vertex;
static const int MAX_MATRICES = 16;
float3 u_direction;
float4x4 u_modelmatrix;
float4x4 u_identitymatrix;
float4x4 u_modelmatrixinverse;
float4x4 u_model_view_proj_matrix;
float4x4 u_pose[MAX_MATRICES] : WORLDMATRIXARRAY;
bool haslayer2;
bool haslayer3;
bool u_light1;
bool u_light2;
texture baseMap;
texture baseMapB;
texture baseMapC;
texture baseMapD;
sampler2D sTex0A = sampler_state {
Texture = <baseMap>;
MinFilter = Linear;
MagFilter = Linear;
MipFilter = Linear;
};
struct VS_OUTPUT_BASE
{
float4 Pos : POSITION;
float3 normal : TEXCOORD0;
float3 lightDir : TEXCOORD1;
float2 Texcoord : TEXCOORD2;
};
VS_OUTPUT_BASE mainV(
float4 inPos : POSITION,
float3 inNorm : NORMAL,
float2 inTex : TEXCOORD0,
float4 indicies : BLENDINDICES,
float4 weights : BLENDWEIGHT
)
{
VS_OUTPUT_BASE Out = (VS_OUTPUT_BASE) 0;
float3 Pos = 0.0f;
float4 src = float4(inPos.xyz,1.0f);
Pos += mul(u_pose[int(indicies.x)] ,src) * weights.x/255;
Pos += mul(u_pose[int(indicies.y)] ,src) * weights.y/255;
Pos += mul(u_pose[int(indicies.z)] ,src) * weights.z/255;
Pos += mul(u_pose[int(indicies.w)] ,src) * weights.w/255;
Out.Pos = mul(u_model_view_proj_matrix,float4(Pos,1.0f) );