Search Unity

Graphics.DrawMeshInstanced

Discussion in 'Data Oriented Technology Stack' started by Arathorn_J, Jun 26, 2018.

  1. Arathorn_J

    Arathorn_J

    Joined:
    Jan 13, 2018
    Posts:
    24
    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?
     
    Last edited: Jun 26, 2018
  2. zulfajuniadi

    zulfajuniadi

    Joined:
    Nov 18, 2017
    Posts:
    117
    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.
     
  3. Arathorn_J

    Arathorn_J

    Joined:
    Jan 13, 2018
    Posts:
    24
    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?
     
  4. zulfajuniadi

    zulfajuniadi

    Joined:
    Nov 18, 2017
    Posts:
    117
    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.
     
  5. Arathorn_J

    Arathorn_J

    Joined:
    Jan 13, 2018
    Posts:
    24
    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.
     
  6. zulfajuniadi

    zulfajuniadi

    Joined:
    Nov 18, 2017
    Posts:
    117
    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.
     
    NathanJSmith likes this.
  7. Arathorn_J

    Arathorn_J

    Joined:
    Jan 13, 2018
    Posts:
    24
    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.
     
    zulfajuniadi likes this.
  8. Arathorn_J

    Arathorn_J

    Joined:
    Jan 13, 2018
    Posts:
    24
    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.
     
    Babiole and zulfajuniadi like this.
  9. zulfajuniadi

    zulfajuniadi

    Joined:
    Nov 18, 2017
    Posts:
    117
  10. Soaryn

    Soaryn

    Joined:
    Apr 17, 2015
    Posts:
    244
    How would you animate them say separately. Say one is running the others are idle.
     
  11. zulfajuniadi

    zulfajuniadi

    Joined:
    Nov 18, 2017
    Posts:
    117
    @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
     
  12. Arathorn_J

    Arathorn_J

    Joined:
    Jan 13, 2018
    Posts:
    24
    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.
     
  13. zulfajuniadi

    zulfajuniadi

    Joined:
    Nov 18, 2017
    Posts:
    117
    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
     
    Arathorn_J likes this.
  14. zulfajuniadi

    zulfajuniadi

    Joined:
    Nov 18, 2017
    Posts:
    117
    I've updated the repo. Now you can set each individual animation for each entity:

    upload_2018-7-6_9-57-15.png

    [Video]

    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.

    upload_2018-7-6_9-49-46.png

    The tool will merge all selected animation and bake the vertices and normal data into two textures:

    upload_2018-7-6_9-52-33.png

    Github: https://github.com/zulfajuniadi/Animation-Texture-Baker
     
    PixelMind, racer161, Rewaken and 11 others like this.
  15. tertle

    tertle

    Joined:
    Jan 25, 2011
    Posts:
    1,958
    Ok. That's cool.
     
    zulfajuniadi likes this.
  16. Arathorn_J

    Arathorn_J

    Joined:
    Jan 13, 2018
    Posts:
    24
    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!
     
    zulfajuniadi likes this.
  17. zyc_dc

    zyc_dc

    Joined:
    May 11, 2018
    Posts:
    40
    Hey! Just tried your demo on 2018.2.0f2. It does not show anything except particle effects
     
  18. zulfajuniadi

    zulfajuniadi

    Joined:
    Nov 18, 2017
    Posts:
    117
    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.
     
    Last edited: Jul 13, 2018
  19. zyc_dc

    zyc_dc

    Joined:
    May 11, 2018
    Posts:
    40
    It seems like a shader issue. My platform is Windows 7. BTW, will it work on mobile?
     
  20. zulfajuniadi

    zulfajuniadi

    Joined:
    Nov 18, 2017
    Posts:
    117
    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.
     
  21. zyc_dc

    zyc_dc

    Joined:
    May 11, 2018
    Posts:
    40
    Cool! Look forward to it!
     
  22. drallcom3

    drallcom3

    Joined:
    Feb 12, 2017
    Posts:
    21
    I would love to see that.
     
    zulfajuniadi likes this.
  23. Spy-Shifty

    Spy-Shifty

    Joined:
    May 5, 2011
    Posts:
    535
    How many animation does your tool support and how long can each animation be?
    There is no blending between animations or?
     
  24. zulfajuniadi

    zulfajuniadi

    Joined:
    Nov 18, 2017
    Posts:
    117
    AS of now it's limited by the number of vertices of the model and the duration of the animation * animation frame rate. As the data is stored inside a texture, it is also limited to the supported texture size. For a low poly character of around 800 vertices, you can store all the basic animations such as idle, walk, get hit, attack, die in a 1024x1024 px texture.

    No, there isn't any blending between animations yet. Though it is technically possible.
     
    racer161 and Spy-Shifty like this.
  25. wechat_os_Qy0_X1ITy6VrZHYPJFd58JGlA

    wechat_os_Qy0_X1ITy6VrZHYPJFd58JGlA

    Joined:
    Nov 15, 2018
    Posts:
    59
  26. Ylly

    Ylly

    Joined:
    May 15, 2015
    Posts:
    17
    I downloaded your project and it seems to be old and there is no functional that you described
     
  27. tylo

    tylo

    Joined:
    Dec 7, 2009
    Posts:
    132
  28. wechat_os_Qy01WAFRlw4wvZ2d6iTLnAfVk

    wechat_os_Qy01WAFRlw4wvZ2d6iTLnAfVk

    Joined:
    Jan 10, 2020
    Posts:
    1
    I Use Graphics.DrawMeshInstanced With a Problem that the Direction Light can't be Enable. How can I Use Graphics.DrawMeshInstanced With a realtime light?
     
  29. Arathorn_J

    Arathorn_J

    Joined:
    Jan 13, 2018
    Posts:
    24
    I'm not precisely sure what the issue would be, I used mixed lighting usually and bake the directional light, but I've used realtime lighting as well and haven't had an issue using DrawMeshInstanced. It could be an issue with the particular shader you are using? My suggestion would be to create a clean scene, setup realtime lighting and make sure a simple script that draws a couple instances of a mesh is working as expected.
     
unityunity