Search Unity

  1. Unity Asset Manager is now available in public beta. Try it out now and join the conversation here in the forums.
    Dismiss Notice

Other DOTS Animation Options Wiki

Discussion in 'DOTS Animation' started by lclemens, Sep 21, 2022.

  1. lclemens

    lclemens

    Joined:
    Feb 15, 2020
    Posts:
    761
    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: https://forum.unity.com/threads/current-best-way-to-handle-animations-in-ecs.903824/ . Also, @WAYN_Games has a nice tutorial on the hybrid approach with DOTS 1.0 here: http://y2u.be/vs6h4waQpPA

    2. 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:
      1. 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: https://forum.unity.com/forums/dots-animation.583/
      2. 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. https://github.com/Dreaming381/Latios-Framework .
      3. 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. https://github.com/gamedev-pro/dmotion .
      4. 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. https://assetstore.unity.com/packages/tools/animation/rukhanka-ecs-animation-system-241472

    3. 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).
      1. 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 free from his Patreon page: https://www.patreon.com/itsEmistro and it is an offshoot of this GPU skinning project: https://github.com/chengkehan/GPUSkinning by chengkehan. I will have to test this one when I have some free time!
      2. Joachim's tech demo The legendary Joachim @Joachim_Ante 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. https://github.com/joeante/Unity.GPUAnimation .
      3. 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. https://assetstore.unity.com/packages/tools/animation/gpu-instancer-crowd-animations-145114
      4. 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.
      5. 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

    4. 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 skinned 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 on older 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). https://assetstore.unity.com/packages/tools/animation/mesh-animator-animate-massive-crowds-26009

    5. 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:
      1. @zulfajuniadi has a repo that has a cool animation graph tool, but it's pretty old and probably won't work with DOTS 1.0. https://github.com/zulfajuniadi/Animation-Texture-Baker/tree/dev
      2. Mesh Animator - listed above (it's in the asset store and supports this as a second technique).
      3. Animation Texture Baker - https://github.com/sugi-cho/Animation-Texture-Baker was on of the original repos and I think it's still used by some people.
      4. Animation Cooker - This is my repo made specifically for DOTS. I used code and inspiration from a lot of repos and articles and I listed those authors in the credits at the bottom of the readme. I put quite a bit of work into it and added a few unique features that I'm quite proud of (especially the compression). I'm using it in my game workflow so it's fairly user-friendly and I'll be updating it for at least a couple of years until my game either flops or succeeds. https://gitlab.com/lclemens/animationcooker
      5. Other: Like with GPU skinning, there are a few of branches and offshoots in GitHub.
      6. maxartz15 VertexAnimation - The maker of The Golden Hoard published a repo for vertex animation baking that is made for DOTS that provides a nice interface. https://github.com/maxartz15/VertexAnimation .

    6. 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.

    7. 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.

    8. 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. :)
    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.

    https://forum.unity.com/threads/graphics-drawmeshinstanced.537927/
     
    Last edited: May 22, 2023
  2. Lance-Huang

    Lance-Huang

    Joined:
    Apr 7, 2013
    Posts:
    9
    Thank you for the information. It was very helpful.
     
    lclemens likes this.
  3. kite3h

    kite3h

    Joined:
    Aug 27, 2012
    Posts:
    197
    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.
     
    carl010010 and ThynkTekStudio like this.
  4. Rukhanka

    Rukhanka

    Joined:
    Dec 14, 2022
    Posts:
    204
    Now I can add Rukhanka Animation System to the "Pure ECS Animation packages" section.
     
    lclemens and Opeth001 like this.
  5. Opeth001

    Opeth001

    Joined:
    Jan 28, 2017
    Posts:
    1,117
    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.
     
    Walter_Hulsebos and lclemens like this.
  6. Rukhanka

    Rukhanka

    Joined:
    Dec 14, 2022
    Posts:
    204
    Humanoid animation is most requested feature. It has highest priority now
     
    lclemens, JesOb and Opeth001 like this.
  7. lclemens

    lclemens

    Joined:
    Feb 15, 2020
    Posts:
    761
    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.
     
    Rukhanka likes this.
  8. Endlesser

    Endlesser

    Joined:
    Nov 11, 2015
    Posts:
    89
    Wow! now that's an option for me to get rid of jammed package and Unity 2020, finally.
     
    Rukhanka likes this.
  9. Epineurien

    Epineurien

    Joined:
    Mar 9, 2013
    Posts:
    45
    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.
     
    Last edited: Mar 24, 2023
  10. Rukhanka

    Rukhanka

    Joined:
    Dec 14, 2022
    Posts:
    204
    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.
     
    lclemens likes this.
  11. Epineurien

    Epineurien

    Joined:
    Mar 9, 2013
    Posts:
    45
    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.
     
    Last edited: Mar 25, 2023
  12. lclemens

    lclemens

    Joined:
    Feb 15, 2020
    Posts:
    761
    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:

    upload_2023-3-24_19-51-25.png

    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.
     
    Last edited: Mar 25, 2023
    DungDajHjep, JelaMiraj and Opeth001 like this.
  13. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    4,264
    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.
     
  14. Epineurien

    Epineurien

    Joined:
    Mar 9, 2013
    Posts:
    45
    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.
     
  15. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    4,264
    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.
     
    lclemens likes this.
  16. luongnd05

    luongnd05

    Joined:
    Jul 9, 2023
    Posts:
    1
    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?
     
    lclemens likes this.
  17. lclemens

    lclemens

    Joined:
    Feb 15, 2020
    Posts:
    761
    Sure, I added a license section at the bottom of the readme.
     
    DungDajHjep likes this.