Do we have an ETA or is there a plan to allow calls to Graphics.DrawMeshInstanced from inside of a job or at least being able to pass a native array of Matrix4x4 to the DrawMeshInstanced method?
You can keep a class property of Matrix4x4[1023] ready and just copy over the values on each update. During the DrawMeshInstanced calls, you have to pass in the actual length of the data so its fine to have a larger array.
Thanks for the reply. I’m doing that precisely in my code. The problem is I’ve created a batched mesh animation system that allows me to animate thousands of characters but the bottleneck right now is the call to draw meshed instance which has to be called outside the job and copying from native arrays to my matrix array for the next frame takes a lot of time… I’m still able to get 30 FPS even with a 100 thousand animated characters but that’s with really minimizing draw calls which limits variety and realism of the characters. I saw in the examples for ECS and from other posts that Unity was hinting at allowing passing native array or allowing Graphics methods from inside the job system but I haven’t seen anything for certain on when or if this is going to happen?
You can try looking into DrawMeshInstancedIndirect. That API is a beast and can happily draw a hundred thousand agents without hurting the CPU. I drew 20,000 trees in one batch and it took less than 0.3ms every frame. Of course they were static so I only updated the cached tree transform when it is cut down.
Oh yes, I played around with that a bit, but I’m not familiar enough with shaders and most of the examples for using with animations were not friendly to the job system at all. So as an example I have 30 statically baked meshes for my walk animation cycle, to create variety I have that broken up into 20 different cycles with 5 draw calls per cycle so for my 100K example I have about 100 draw calls (DrawMeshInstanced), which makes them look non-uniform for their walk cycle. The drawing part of that takes between 1-2 MS, but getting the data ready to pass to that system takes about 6 ms, if I can make the calls inside a job or just pass a native array I’m betting I can totally eliminate the 6ms it takes to prep the data. You can imagine once these characters have LOD cycles with different animations, walk, run, attack, death, plus different materials for more variety that it will slow down exponentially if I can’t quickly pass data to the DrawMeshInstanced calls.
Another way to go about it is by baking the animations into textures rather than the meshes. And then setting the animation index via material property blocks on the DrawMeshInstanced calls. In theory it should work though i’m not too sure.
So far I’ve only looked into the Austin Tech Demo and the Unity Animation Instancing repo to tackle the animation problem in ECS. But have yet to fully test both methods to see which one works best.
But I totally understand what you are going through.
Thanks for the great replies! Yes, so the Austin Tech Demo basically is licensed in such a way you can’t use anything in there other than for inspiration, but its a good reference. The Unity Animation Instancing Repo demo you linked to was the one I had the most success with, though once I hit about 20,000 animations the frame rate plummeted as it just does so much work on the CPU that it bogs the whole thing down, it was taking nearly 30 ms to finish doing the work it needed to do for the bones. It was still really impressive, but considering my baked plan I can get higher framerate with 5x the number of characters I decided against it. The nice thing about that static batching is performance is pretty amazing, you are doing no additional calculations on the GPU or CPU for skinning (since you pre-bake the animations), the downside is you really have to plan and have a tight budget for the number of different units and animations you allow on screen at once or you might find yourself with no memory left. I’m hoping we get some additional options here soon, I’ve been following your work on the nav agent system and that is really great, I think we can see some outstanding simulations coming out of this software if we have all these tools made available even with some of the headaches it takes with getting your mind working in a more ECS thinking approach. I’m really hopeful we see NativeArray options for the DrawMeshInstanced call (better yet just call it from a job) so we can plan accordingly for future work, right now my project probably won’t see beta till the end of the year so I’m not too worried about timeline but its nice to know for architecture decisions as to whether it will be an option.
This thread helped a lot in case anyone else was looking, though the issues should be resolved without hacking things together when drawmeshinstanced can be called from a job with a nativearray.
Hey Arathorn_J, I got 100,000 animated swordsman at 60 fps. I’m using animations baked into the textures.
https://i.gyazo.com/cef50f2a589c75b837c1ef978a49f9eb.gif
Here’s the code:
How would you animate them say separately. Say one is running the others are idle.
@Soaryn I was planning to set the animation index via the material property group. It seems that the Graphics.MeshInstancedRenderer does accept that as one of the properties
Wow, that’s fantastic. I was able to hit about 50 FPS before I left for summer vacation, but this might be a better example for getting the diversity I need, also packing to the 2d textures uses less memory and fewer draw calls than my texture baking does.
I’ll be tinkering over the night. I’ll push the code and share the result afterwards. Right now its not very user friendly. I imagine something where you reference a prefab and it does the pre-processing automatically. I might even attempt to make it render via instancedindirect to get better performance
I’ve updated the repo. Now you can set each individual animation for each entity:
[[/URL]
The project now has a window where you can drag in skinned mesh prefab and it will generate the animation textures. Conversion is pretty slow but I guess it’s okay since you only have to do it once. Plus it does some nifty stuff like fix the model’s scale, rotation and pivot point.
The tool will merge all selected animation and bake the vertices and normal data into two textures:
Github: GitHub - zulfajuniadi/Animation-Texture-Baker: Bake Legacy Animations into Textures. Targeting ECS](https://i.gyazo.com/cb50d23c29482b18d0573d01da9e33d3.mp4)
Ok. That’s cool.
That looks great! Good job! I won’t be able to get back to work for a few days but I really Can’t wait to dig into the details!
Hey! Just tried your demo on 2018.2.0f2. It does not show anything except particle effects
Sounds like a shader issue. What platform are you on? Tested on 2018.2.0f1 on Windows 10 works fine.
Yeah doesn’t work on OSX. Like I suspected it’s a shader issue. I’m in the middle of a large upgrade for the system (adding state machines to the baked agents) and will look into getting the shaders compatible with opengl & metal.
It seems like a shader issue. My platform is Windows 7. BTW, will it work on mobile?
Right now it doesn’t as the shaders uses compute buffers to store the state. I’m working to get that remove so that it can be compatible with lower shader targets.