shader not working for animated model

Started by
3 comments, last by RyuMaster 14 years, 11 months ago
Hi! I'm using Flat Red Ball engine with XNA 3.0, and it has this test shader for 3d models, which works as it should: // View and world variables - set by engine shared float4x4 View : VIEW; shared float4x4 Projection : PROJECTION; float4x4 World; // Vertex Shader void vs_default(in float4 inpos : POSITION0, out float4 position : POSITION0, out float3 texcoord : TEXCOORD0) { // Pass position as Position and a Texcoord position = mul(inpos, mul(World, mul( View, Projection ))); texcoord = mul(inpos, World); } // Pixel Shader float4 ps_default(in float3 texcoord : TEXCOORD0) : COLOR { float period = 3.14f * 7.0f; float secondaryPeriod = 3.14f * 7.0f; float4 finalColor = float4( sin(texcoord.x * period + cos(texcoord.y * secondaryPeriod)), // red cos(texcoord.y * period), // green sin(texcoord.z * period), // blue 1.0f); // alpha return finalColor; } // Technique technique Default { pass Pass0 { VertexShader = compile vs_2_0 vs_default(); PixelShader = compile ps_2_0 ps_default(); } } But when I use .X file with skinned animation, application crashes. What kinds of differences are between shader for static model and skinned one? Where can I read it, or how to I have to change this shader? Regards, Konstantin.
Advertisement
Hi,

I know nothing about XNA but I can tell how can I use shaders with my animated models in D3D.

I'm not working on skeletal animation for now; but I'm working on hierarchical meshes. You know a hierarchical mesh has a frame hierarchy. Each frame has a pMeshContainer object and there's a (MeshData.pMesh) object in it.

I create a frame array separately. And each time I want to render the entire hierarchical mesh with my shaders, for example, first I pass View and Projection matrices, then I pass TransformationMatrix of frame as WorldMatrix and other parameters to shader. And I render (MeshData.pMesh) object of each frame.

Hope this helps.

Regards,
Rohat.
There's no "hard", and "the impossible" takes just a little time.
As programci_84 i nor know anything of XNA.

But is deep than pass "World Matrix", i hope you understand all the
"big deal" behind animate a Mesh with bones... You'll need to pass
to the shader a Matrices Array for each frame(directx call thems frames,
but they are Matrices) of the hierarchy, additionally you'll need to pass
the vertex weights to blend...

Take a look the SDK, see the skinned mesh sample, there are a .fx for the
job, i'm sure you will get error when you try to load it just like that,
first understand all the theory that not going to put here, or any user,
because its bigger and harder to understand the first time, i only don't
figure out how you are drawing your animated meshes O_o
yo ;)


you should check out frank d lunas site. He has source code for animation. And if you really want to learn that stuff, buy that book. it really explains it very good. His implementation has some flaws (only loading one container, ...)
but its very good to start.
http://www.d3dcoder.net/d3d9c.aspx



There is a LOT of stuff you have to change, because your animated mesh has several matrices you must think about. You have a hierarchy in your XFiles, that are HierarchyMatrices. You can get them from the function D3DXLoadMeshHierarchyFromX, the RootFrame contains the matrices + the connection. This way you can setup Matrices for every Bone. That is a combined matrix from the bone itself and its parent matrix (you must calc the parent matrix of couse thats own matrix * parent * parentParent ....^^). every Frame can have childrens and/or Siblings.


For every Container of your XFile, you will also have a CSkinInfo*, that structure can give you BoneOffsetMatrices, if you multiply that given matrix
for a bone, with the above toRoot Matrix (from CurrentFrame to the Root Frame)
you have the given Matrices for every bone.

in your shader you will then multiply your localPosition by that given matrix (you can also apply weights and use more matrices), because every localPos has a boneIndex which tells by which (can be more then one) bone your pos will be influenced. you should get good results with 1 bone too. and here you see you must change your input structure its not pos/norm/tex anymore you must know which to use.



That given pos is then 'LocalBoneSpace' and by multiply it with your Rotate*Scale*World Matrix and After that with your ViewProj it should be on the screen.

(Btw do the Matrix stuff on CPU you cant do a WorldViewProj multiply on GPU that are 3 multiplications for every vertex!, actually you can get the WorldMatrix into the FrameHierarchy by multiply your boss Transformation Matrix (m_Root from D3DXLoadFrameHierarchy with your World Matrix, but you can also do this on GPU), but if you have World in Hierarchy you can set the ViewProj for every skinned mesh only once other way you have to recalc WorldViewProj for every mesh and set it for every mesh :D^^)


I hope everything here is correct, if you buy the book or use his code you will be able to fully understand it.


and you must be sure to load that mesh with the right function! D3DXLoadMeshFromX wont work, it just puts the frame into one object, your bones and everything gets lost then.
Everyone, thanks for answering! Looks like it is not a simple matter of passing correct parameters. I'll take my time then I dive into the subject, looks like there is no magic workaround.

This topic is closed to new replies.

Advertisement