DOTS Animation Options Wiki

DOTS Animation Options Wiki

If you find yourself here, you’re probably getting started with DOTS and trying to figure out how in the bleep you’re supposed to get animation working since it’s one of the top 3 or 4 things people look for in a game engine. And you would be in good company. Every few days someone in forums or on the Turbo Makes Games (TMG) discord drops in and asks the question:

What are my options for animation??

So to increase the speed of answering this question, a few of us decided to make a wiki specifically addressing this topic. I’m far from an animation expert, but I did study the DOTS-animation topic fairly extensively for a few months, so that’s worth something. I’ll update this list as people make suggestions and comments because there’s no doubt that I’ll miss some libraries and make mistakes. So without further ado, here are your options… (At the bottom is some help deciding which technique to choose for your application).

  1. The hybrid approach: In this method, you use regular Unity animation tools and then synchronize them with your entities. Of all the approaches, this is going to be the slowest because it gets bottlenecked in the main thread and can’t benefit from burst, however, it is also the easiest to implement because if you’re already familiar with Unity’s standard animation tools, you have very little extra to learn. One downside is that you have to deal with conversion workflow and game-objects, which can make the workflow awkward. There are lots of threads on this approach in these forums - here is just one example: Current best way to handle animations in ecs? . Also, @WAYNGames has a nice tutorial on the hybrid approach with DOTS 1.0 here: http://y2u.be/vs6h4waQpPA

    • Pure ECS Animation packages: This approach uses a framework for animating meshes using ECS components and systems. It will support a lot of advanced animation techniques and features, and its speed will be very fast compared to traditional game-object based animation - 10k entities is possible in the right circumstances. Several people in these forums and on TMG discord have build their own DOTS animation packages. Let me know if I missed one, but these are the ones I have run across so far:

    • The DOTS animation package: This was the official Unity animation package, however, as of DOTS 0.50 it was abandoned so we could be waiting a year or more for an official version. Or perhaps unity will purchase one of the animation systems here like they did with the Rival Character Controller? The DOTS animation package was always very experimental, but quite a few people have successfully used it. One option for using this package is to use entities 0.17. Another option is that some people in the forums have found hacks to get parts of it working in 1.0. You can read more here: Unity Engine - Unity Discussions

    • Latios Framework’s Kinemation: This is probably the most well known animation package, and it was built by our very own @DreamingImLatios . You will need decent understanding of animation/bones/skinned meshes, and DOTS to use it. It supports lots of badass things like weapon binding, compression, deformations, blending, and more. It will be very fast - not as fast as the GPU approaches, but it is arguably the most flexible and powerful. GitHub - Dreaming381/Latios-Framework: A Unity DOTS framework for my personal projects .

    • Dmotion by @Dechichi01 (dechichi in TMG’s discord). Dmotion uses DreamingImLatios’s Kinemation under the hood. It provides a handy animation graph as well as making the package easier to approach for beginners. The package contains much of the flexibility and feature variety that you would expect from an animation package. It looks very promising. GitHub - gamedev-pro/dmotion: DMotion - A high level Animation Framework for Unity DOTS .

    • Rukhanka ECS Animation System - This is the newest animation system of the bunch. It works by using Unity’s standard animation editing tools (Mechanim) as an authoring workflow and then converting everything into a DOTS compatible animation framework. Because Unity’s traditional tools are used, experienced animators don’t have to learn new tools while still getting the performance benefits of ECS, jobs, and burst. There are a few things that Mechanim supports that the Rukhanka package does not support, but overall most things are supported, including advanced concepts like animation blending, weapon attachments, etc. Rukhanka - ECS Animation System | Animation Tools | Unity Asset Store

  2. GPU Skinning (GPU Bone Animation): This technique involves using skinned meshes and baked bone animation data to perform skinning in the GPU instead of the CPU. It is combined with GPU Instancing. This method is extremely fast and supports 100k+ instances if the circumstances are optimal (such as the use of LODs). The downside to this approach is that it is not easy to get things like weapon binding working and the authoring workflow will be more involved compared to a hybrid approach or a pure ECS package. Also you’re probably not going to find fancy features such as inverse kinematics (IK). There is a discussion of some techniques here: Graphics.DrawMeshInstanced .

    • GPU Skinning Animator - emistro who can be found lurking in TMG’s discord, built an animation package that uses GPU Skinning. It has an graphical animation state controller and a getting-started tutorial. I believe it supports animation blending, but I’m not sure if it can do weapon binding or not. You can download it here: Unity DOTS Animation System by Emistro and it is an offshoot of this GPU skinning project: GitHub - chengkehan/GPUSkinning by chengkehan.

    • Joachim’s tech demo The legendary Joachim @Joachim_Ante_1 was one of the first (if not the first) to build a library via this technique from the Nodeus demo. The repository hasn’t changed in about 3 years, however there is a branch that updates it to 2020.1. It uses a certain API call that has been deprecated so I never got it running, but it is this brilliant idea that sparked off so many other GPU animation repositories. GitHub - joeante/Unity.GPUAnimation: Simple but very fast GPU vertex shader based animation system for Unity.Entities .

    • GPU Instancer - Crowd Animations: You can get this from the asset store. It supports blend animations and can be used with Unity Mecanim Animator. The author told me that it should work in DOTS. GPU Instancer - Crowd Animations | Animation Tools | Unity Asset Store

    • Other assets and repos: There are several other assets on the store that use this technique - just search for GPU animation in the store. Likewise, there are quite a few repositories on GitHub that implement it.

    • GPU ECS Animation Baker (Headfirst Studios): Vertex bone weights are baked into UV channels of the meshes and bone transforms are baked into animation textures. It has some unique features such as blend sampling, animation transitions, and LODs. https://www.headfirststudios.com/theorangecoder

  3. Runtime static mesh replacement: I have only seen one tool that uses this technique and it is an asset in the store called Mesh Animator. I believe it works by baking a bunch of static meshes and then swapping them out really quickly at runtime so you get the benefits of batching and instancing. I suspect this technique is not as fast as the GPU methods, but it would probably work even on ancient mobile devices that are unsupported by GPU techniques. Because it bakes static meshes, it probably uses a decent amount of memory and won’t support a lot of the fancier animation features. Mesh Animator also supports an option for vertex animation baking (see below). Mesh Animator - Animate massive crowds | Animation Tools | Unity Asset Store

  4. Vertex position baking: This approach involves baking vertex positions into a texture (as opposed to GPU skinning which bakes the bone positions). I believe that it will run faster than GPU skinning because with baked positions there are no transform hierarchies to multiply. Even without LODs you can pull off over 100k instances. But as always, there is a tradeoff. Of all the techniques, this one is the least flexible. First of all, the textures are big and use more memory (can be mitigated with compression techniques). Secondly, features like weapon binding, animation blending, etc would require some tricky hacks so they’re not supported by any libraries that I know of. I ran across a handful of repos, so I won’t list them all, but here are a few:

  5. Mathematical Animation: Don’t underestimate the power of simple movement scripts. You’ve all seen the DOTS-rotating-cube demos with millions of entities. With a few simple ECS systems for position/scale/rotation movements and oscillations (using sine and cosine), you can put together some interesting animations. There will be a lot of things you can’t do, but it’s blazing fast, and trivial to setup.

  6. Animated UV material systems - By writing a system that offsets the UV of a texture, you can make a texture appear to move. Props like conveyor belts and wavy laser beams look pretty nifty when animated with this technique.

  7. Particle/VFX Animations - I know very little about this method, but I have heard rumors about ways to get objects within particles or VFX to interact with entities in the light and physics portions of a DOTS game. Most of what I read went over my head and there’s not a lot of information about this approach, but if you’re a VFX expert you might get some mileage out of this idea. :slight_smile:

So in summary, the tradeoff space is mainly down to flexibility vs dev-time vs speed. If you need something up and running within a day, the hybrid approach is the way to go for that, but realize that it won’t be much more efficient than standard Unity animation. If you want a technique that’s way faster than Mecanim but is still flexible and powerful, use one of the pure ECS approaches. If you don’t need super sophisticated animations and all you care about is having a bazillion zombies running around, then go with either GPU skinning or Vertex Animation. You can always throw in mathematical and UV animations on the side to spice things up.

Of course, there’s no law against combining multiple techniques, but be aware that the pure ECS and GPU techniques will require significant time investments to both learn the them and tweak your models to support them.

60 Likes

Thank you for the information. It was very helpful.

1 Like

Most of the ones mentioned above were made before DOTS came out or for very limited uses.
Even if Unity obtained the skin matrices, there was no way to pass them to the shader, so vertex-based baking was performed.

DOTS no longer needs a bone instance if it can only update skinmatrices.

So for now, baking the movement of bones is most effective, and curve to texture already exists in Unity DOTS. Although it is hidden.
Curve To Texture is mainly used to adjust properties with curves in the shader inspector.
Anyway, this baking method has one problem.
The reason why we use skeletal skinning is not simply because of the size of animation assets, but also because human movement is based on rotation, not transition.
That’s why you shouldn’t linearly interpolate the baked data.
However, you cannot do SLERP without knowing the pivot.
So, this error may cause the motion to become strange.

In fact, you should seriously consider using dual quaternion now.
I think dual quaternions are actually more suitable for baking.

For now, instead of 3x4, you only need 4x2. 4x2 is also easy to put into a texture.

Anyway, I think the best way at this point is hybrid. Proximity characters are treated as hybrid, and farther characters are processed through GPU vertex animation. Other methods are inflexible and too cumbersome to use.

I think it is difficult to handle more than 200 instances with a hybrid method. But… it’s rare that there will be more melee characters than that.

2 Likes

Now I can add Rukhanka Animation System to the "Pure ECS Animation packages" section.

2 Likes

amazing!!
I was thinking of making a package like this but it will take me a lot of time.
Unfortunately it does not support humanoid animations and my project relies on it.
hopefully it will be added soon.

2 Likes

Humanoid animation is most requested feature. It has highest priority now

3 Likes

I saw this a couple of days ago and was going to add it but I was traveling. Very cool!!! I added it to the wiki just now.

1 Like

Wow! now that’s an option for me to get rid of jammed package and Unity 2020, finally.

1 Like

How realistic are all those estimates in practice and/or for which gpu?
I’m toying around with the goal of making a GPU Skinning solution (as Hybrid Rendering is buggy for me, with some Animators staying frozen for unknown reasons), but even with a low-poly static mesh and Graphics.DrawMeshInstanced I can barely break past 20k instances (for 60FPS on a RTX2060). I’m not sure which method to use that could achieve 5x more with skinning on top of it.

There is a practical example for you. I have highly optimized grass rendering system. It uses DrawMeshInstancedIndirect and meshes (them are not just blades, but small meshes ~50-100 polygons each) are GPU animated. Not exact coincidence to the skin matrices application, but for rough estimation will fit. I have made a stress test scene for measurements. It has ~500K meshes (instances), no frustum and occlusion culling. All meshes rendered by one draw call. Pixel shader takes almost nothing because most of the instances not visible in camera.
There are two passes: “ForwardToDepth”, and “Forward”, so number of rendered meshes is doubled. I have RTX 3070Ti, and have ~110FPS in editor (!). As you can calculate there are ~70M vertices transformed and rendered per frame.

Can you tell please paremeters of your test mesh (vertex and tri count)? I am pretty sure that you either vertex bound or not GPU bound at all, because you have issue somewhere else.

1 Like

Ah, everything is normal then. I was doing my tests with low-poly critters at 1.4K vertices.
Keeping the 60FPS target:
With shadows casting enabled, I can display up to 20K of them for 81M ver / 171M tri.
Without shadows it can be pushed up to 46K instances for 74M/137M.

This seems to be in the same ballpark as what you have, so I suppose the “100k” estimate above is just for very simple objects, and not for classic characters&mobs - even low-poly ones.
In both case profiler show “Gfx.WaitForPresentOnGfx” (and editor loop) as being the limiting factor by a large margin, which, as far I understand from the confusing info on the net about it, should indicate that the system is GPU-bound.

Guess I can start working on the actual skinning part then, thanks.

I haven’t done the GPU Skinning technique myself, but I remember seeing a guy in the forum getting GPU skinning working with >100k instances by using LODs. Without LODs, and 1.4k vert models I don’t think you’d hit that without a really impressive GPU.

I have tested the baked vertex animation technique with a 660 vert character and hit 40fps with 100k instances on a Mobile RTX 2060 in the editor. I’m pretty sure that with LODs it could perform much better, but I haven’t gotten around to setting up an LOD system yet.

When you start getting into instance numbers that high, it makes sense to do LODs because when you’re looking at a 100k hoard like this:

8901714--1218027--upload_2023-3-24_19-51-25.jpg

The player has almost no chance of noticing if the far away instances are not animated, and they definitely won’t notice if those instances aren’t showing all 660 verts.

3 Likes

Please at the very least use DrawMeshInstancedProcedural. However, I can tell you right now that using a technique involving BatchRendererGroup (Just leveraging Entities.Graphics is sufficient) will be even faster.

And definitely use LODs because you are GPU-bound. Generally for desktop you want to be under at least 20 million vertices. Preferably under 10 million.

3 Likes

Thanks, toyed with it and it’s indeed faster, but I can’t get it to work on mobile which is a wrench in my plans - and I don’t see an ETA or even roadmap on making BRG work for OpenGL/GLES/WebGL.
It’s a shame because being able to send arbitrary data to each instances via GraphicsBuffer.SetData & CreateMetadataValue mean shared textures shenanigans aren’t needed. I’m half tempted to give up on non-PC platforms just for that, and pray they actually finish the api one day.

The 2022.2 version works with GLES 3.0. Under the hood I think they are using GraphicsBuffer as a source for a UniformBlockBinding. I’m not aware of any platforms that support modern desktop OpenGL but don’t support Vulkan. I’m not sure what is up with WebGL.

1 Like

I tried your AnimationCooker. It works very well , i want to try it in my project but i dont see license in your gitlab. Can you add it?

1 Like

Sure, I added a license section at the bottom of the readme.

1 Like

Hi @lclemens ,
just started experimenting with your DOTS Animation tool, which seems perfect for a project I’m working on. Really sterling work on the tool itself, on the very detailed documentation, and on this thread exploring the different options available.

I found that the LODs are behaving differently in the original model and in the baked version. I can reproduce this with the provided spider model. At the same camera distance the original one is getting culled, while the baked one is at LOD2. The original model only reappears after I increase the LOD2 distance to more than double the baked one. I tried changing LOD bias in settings just to check, but it doesn’t seem to make a difference.
Is this expected behavior?

How did you manage to get the pivot correct in your baked model? Starting from the prefab in the example scene I’m able to get center and outline correct, but the pivot is off far to one side. I tried all “b4 bake” options.
EDIT: I think I figured it out, you need to bake models at world position 0,0,0 to get correct pivot, is that right?

It might be worth it to add a warning and stop the baking process if the prefab has spaces in the name, as that will mess up the generated scripts. Also if the baking process has errors the “hold on” progress bar stays open without a way to close it.

1 Like

Sorry for the late reply - I was traveling this week. Not too many people are using vertex position baking - mainly because GPU bone animation is only a hair slower and supports more features (like animation blending, etc). When you get into the 100k+ entity territory, the triangle count (hundreds of millions) just swamps the GPU and the actual animation is like 1 percent of the equation. That’s when LODs become extremely important.

To be honest I didn’t really compare the LOD distances between the baked and non-baked ones. Originally I just used distance-to-camera, which worked great except in theory it would break if you changed FOV at runtime (like using a rifle scope or something) so that’s why I changed it to account for FOV. If the difference factor is exactly 2x, maybe I could just change the equation by 2x? I’ll look into it and see if I can get them to match up.

I have been baking at 0,0,0 so I didn’t notice the problem, but in theory it shouldn’t matter - I will look into that as well.

As for spaces in the prefab name - that’s a good point. I could probably clean up the string. I knew about the progress bar staying open - I just didn’t get around to figuring out how to fix it. It should be an easy fix.

1 Like

GPU Skinning New Link: Unity DOTS Animation System by Emistro
or
DOTS Animation System | Utilities Tools | Unity Asset Store

1 Like