Hi! Im working on game made on old Ogre3d version.
I want to ask: is manually changed bones with constant position and rotation update every frame performance taking?
I use it for character creation as alternative method of making sliders with animations. With animations I had very bad performance, so I decided to try manual bones instead.
Manual Bones sliders VS Animation sliders
-
- Gnoblar
- Posts: 6
- Joined: Sat Nov 02, 2019 11:10 am
Manual Bones sliders VS Animation sliders
-
- Orc Shaman
- Posts: 724
- Joined: Wed Mar 18, 2009 3:03 am
- x 403
Re: Manual Bones sliders VS Animation sliders
I use a few manually controlled bones on all my characters in my game (to have an upper and a lower body look towards the camera or a look direction), and I don't see why it would take that much more performance.
But I am not exactly sure what you are trying to do here, because animations should have very fast performance, and I would recommend you would use animations instead of moving the bones yourself each frame to create animations. Otherwise, what is the point of having the entire animation system that works?
What is it exactly that made your performance go down? 1000+ animated objects? In that case, moving the bones manually to create animations would not speed things up, in that case it is that your CPU is sending up the vertex buffer to the GPU every frame, and that has nothing to do with the performance of animations, only the performance of sending data.
There need to be more information here to know exactly what you are trying to do and why animations are making your performance bad.
My project: https://imagindar.com/
-
- Gnoblar
- Posts: 6
- Joined: Sat Nov 02, 2019 11:10 am
Re: Manual Bones sliders VS Animation sliders
Url to gif: https://gifyu.com/image/S8D3p
This is what I mean. And when I did all the sizable bones as anims - it had a huuge lag...
Actually when al sizers were anims, all the body parts had its own skeleton (player broken into pieces: Head, Ears, Tail, Eyes, ect, ect). So my guess is that all the skeletons were animated at the same time and it multiplied animation quantity. But now Im using shared instance of skeleton from body. And it should reduce number of animated parts.
Anyway I still worry about lags, when several players could wonder around one map
-
- Orc Shaman
- Posts: 724
- Joined: Wed Mar 18, 2009 3:03 am
- x 403
Re: Manual Bones sliders VS Animation sliders
I wonder if it would be possible to cache it.
When a player character is created, you could first apply all these animations/morphs needed like you are doing right now.
Then, could you not cache the model from the T-pose using those morphs? What I mean with that is that you would get all the details of the vertices in the T-pose and make that the new "normal" mesh, by cloning the mesh and adjusting those vertices (position, normal, tangents, etc).
That way you would probably only have to use one animation (like running) instead of many different animations for the morphs (if that is how you do your current system).
But, as the quote says: "Premature optimization is the root of all evil".
Try with your current system to just place 500 player characters in one scene moving around using different animations, and see if there is actually a bottleneck at all.
If you see a bottleneck, make sure to enable GPU animation for them (needs changes in the shader and the shader program definition), because for my game that makes the FPS go up extremely much with many models (because sending the vertex data to the GPU every frame for each model is very expensive).
If you have GPU animation enabled and it still has performance issues, try the first approach in this post.
My project: https://imagindar.com/
-
- Gnoblar
- Posts: 6
- Joined: Sat Nov 02, 2019 11:10 am
Re: Manual Bones sliders VS Animation sliders
Oh? Gpu animations? Is there anywhere topic about it, in quite novice x)
-
- Orc Shaman
- Posts: 724
- Joined: Wed Mar 18, 2009 3:03 am
- x 403
Re: Manual Bones sliders VS Animation sliders
The GPU animation only requires changes to the vertex shader material and to the vertex shader (not the fragment shader):
Vertex shader material:
Code: Select all
vertex_program SkinningTest_VS hlsl
{
source SkinningTest.hlsl
entry_point main_vs
target vs_3_0
includes_skeletal_animation true
column_major_matrices false
default_params
{
param_named_auto worldMatrix3x4Array world_matrix_array_3x4
param_named_auto viewProjectionMatrix viewproj_matrix
}
}
If your characters do not only use skeletal animation, you might have to add one (or both) of these as well (though I have never used them because I only use skeletal animation with bones and weights):
includes_morph_animation true
includes_pose_animation true
Vertex shader (skip the tangent/bitangent if you are not using it in the fragment shader of course):
Code: Select all
float3x4 worldMatrix3x4Array[23]; // Make sure this is at least equal to the maximum amount of bones in your meshes + 1
float4x4 viewProjectionMatrix;
struct VS_OUTPUT
{
float3 oVertexPos : TEXCOORD0;
float3 oNormal : TEXCOORD1;
float2 oUV : TEXCOORD2;
float3 oTangent : TEXCOORD3;
float3 oBitangent : TEXCOORD4;
};
VS_OUTPUT main_vs( float4 position : POSITION,
out float4 oPosition : POSITION,
float3 normal : NORMAL,
float2 iUV : TEXCOORD0,
float3 iTangent : TANGENT,
float4 blendIdx : BLENDINDICES,
float4 blendWgt : BLENDWEIGHT )
{
VS_OUTPUT Out;
oPosition = float4(0, 0, 0, 0);
Out.oTangent = float3(0, 0, 0);
Out.oNormal = float3(0, 0, 0);
for(int i = 0; i < 3; ++i)
{
oPosition += float4(mul(worldMatrix3x4Array[blendIdx[i]], position).xyz, 1.0) * blendWgt[i];
Out.oNormal += mul((float3x3)worldMatrix3x4Array[blendIdx[i]], normal) * blendWgt[i];
Out.oTangent += mul((float3x3)worldMatrix3x4Array[blendIdx[i]], iTangent) * blendWgt[i];
}
Out.oVertexPos = oPosition.xyz;
oPosition = mul(viewProjectionMatrix, oPosition);
Out.oNormal = Out.oNormal;
Out.oNormal = normalize(Out.oNormal);
Out.oTangent = Out.oTangent;
Out.oTangent = normalize(Out.oTangent);
Out.oUV = iUV;
Out.oBitangent = cross( Out.oTangent, Out.oNormal );
return Out;
}
If animations look strange, alter the for loop to use all 4 instead (I have to do this for certain meshes in my game, some apparently use 3 weights per bone and some uses 4, for some reason, so two different shaders for those):
Code: Select all
for(int i = 0; i < 3; ++i)
to
Code: Select all
for(int i = 0; i < 4; ++i)
BUT
Keep in mind that if a mesh is rendered in two different ways per frame, and that one of those ways are using the above technique (GPU animation) and the other way is using the normal technique (CPU animation), you will get no performance gain.
For example, in my game when a character is rendered, it is first rendered normally and then it is rendered also for the shadow.
So if I add GPU animation to the first normal render, the second (shadow) render still needs to send the vertices to the graphics card each frame if I don't use GPU animation on that.
So the fix to that is to also alter the shadow caster material of the material of the character to also use GPU animation. That way, vertices are no longer sent to the graphics card each frame, which means that you will get a very large performance boost if this is your bottleneck (in my game it increases FPS from around 60 to 200+ if there are many characters out on the scene).
My project: https://imagindar.com/
-
- Gnoblar
- Posts: 6
- Joined: Sat Nov 02, 2019 11:10 am
Re: Manual Bones sliders VS Animation sliders
Oh! It looks awesome! But it brokes my game...
Code: Select all
20:01:08: OGRE EXCEPTION(3:RenderingAPIException): Cannot create D3D9 vertex shader SkinningTest_VS from microcode
in D3D9GpuVertexProgram::loadFromMicrocode at D:\Eternal time\CODE\Eternal-Time-Project\Deps\OgreSrc\RenderSystems\Direct3D9\src\OgreD3D9GpuProgram.cpp (line 258)
So I didn't change anything in code you provided exept number of bones, but i completely donno wats wrong. Maybe there are something wrong with my Ogre project. At least thanks for try to help me
-
- Orc Shaman
- Posts: 724
- Joined: Wed Mar 18, 2009 3:03 am
- x 403
Re: Manual Bones sliders VS Animation sliders
I believe that error message says that it cannot load it from a cached version of the shader, which has nothing to do with the compilation of the shader.
Otherwise it would just tell you what went wrong with the compilation.
Remove your shader cache and then see the real error message instead, when I made the shader I removed a lot of code (my own specific stuff) so it might just be a simple compilation error, which in turn makes the cached version wrong or even non-existent depending on how your user-code works regarding shader caches.
My project: https://imagindar.com/