Search Unity

GPU Mesh Instancing

Discussion in 'Shaders' started by nafonso, Mar 23, 2009.

  1. nafonso

    nafonso

    Joined:
    Aug 10, 2006
    Posts:
    376
    Is there a way to render multiple mesh instances with only one draw call (i.e. pass the mesh once and multiple matrixes, e.g. to get multiple trees)?

    Can we use the MaterialPropertyBlock to attain such a functionality?

    We want to have something like XNA's Mesh Instancing (http://creators.xna.com/en-US/sample/meshinstancing).

    Regards,
    Afonso
     
  2. Aras

    Aras

    Unity Technologies

    Joined:
    Nov 7, 2005
    Posts:
    4,536
    No.

    The big question with instancing is: how would one do instancing in real-life cases? Where multiple instances are affected by different lights, for example?
     
  3. Scrat

    Scrat

    Joined:
    Apr 20, 2008
    Posts:
    316
    You usually use geometry instancing in outdoor environments (where the lighting isn't really a problem). I think there is an article on how Lionhead used that technology in Black&White 2 on GPU Gems 2.

    Besides, I think, in this case, there is trade off to be made between the individual quality of each instance and the overall effect you convey by drawing hundreds of characters on screen...

    Small question though, I don't have all the details on how to implement GPU instancing in mind but, technically, why wouldn't this be possible to do inside Unity?
     
  4. Aras

    Aras

    Unity Technologies

    Joined:
    Nov 7, 2005
    Posts:
    4,536
    There are platform specific difficulties (e.g. instancing does not exist in OpenGL on OS X, at least right now).

    Then there are integration difficulties, like the lighting issue I mentioned. Adopting an approach from some particular game can be hard, because in that game they can optimize everything based on their own usage pattern, whereas doing the same in "a generic way" can be next to impossible.

    I'm not saying Unity won't ever have instancing, just in my view it's not a very useful feature to have in a generic engine. Also, on a lot of hardware instancing is actually slower than no instancing (again, depending on a lot of factors).
     
  5. snicholls

    snicholls

    Joined:
    Mar 19, 2009
    Posts:
    229
    You got it all wrong.
     
  6. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,603
    Doubt that
    Mesh instancing is no shader thing, its an engine thing and the engine does not support it.

    If you were talking more about geometry shaders and instancing of algorithmic geometry through the shader at realtime: Unity is strictly shader Model 3 and lower, so no SM4 features like Geometry Shaders.
     
  7. Aras

    Aras

    Unity Technologies

    Joined:
    Nov 7, 2005
    Posts:
    4,536
    wat?

    In other words, what did I get wrong?
     
  8. snicholls

    snicholls

    Joined:
    Mar 19, 2009
    Posts:
    229
    Oh how odd, that post was meant for a different topic, the funny bit? the topic is on a completely different forum! epic posting fail
     
  9. jeremyace

    jeremyace

    Joined:
    Oct 12, 2005
    Posts:
    1,661
    /me sends snicholls 7 pounds of fresh coffee and an IV rig.

    -Jeremy
     
  10. AngryAnt

    AngryAnt

    Keyboard Operator Moderator

    Joined:
    Oct 25, 2005
    Posts:
    3,042
    Thats gotta go on some forum mispost record. Epic!
     
  11. JanHelleman

    JanHelleman

    Joined:
    Oct 11, 2009
    Posts:
    116
    Not to get old cows out of the water, but instancing can be very helpfull in case of a deferred rendering setup. But my guess is that unity has forward rendering ;-)
     
  12. Daniel_Brauer

    Daniel_Brauer

    Unity Technologies

    Joined:
    Aug 11, 2006
    Posts:
    3,355
    Unity does forward rendering.
     
  13. andeeeee

    andeeeee

    Joined:
    Jul 19, 2005
    Posts:
    8,768
    :?:
     
  14. JanHelleman

    JanHelleman

    Joined:
    Oct 11, 2009
    Posts:
    116
    euhw sorry it's a dutch expression, it's like saying you don't want to blame or bring up something old, nvm :)
     
  15. nawash

    nawash

    Joined:
    Jan 29, 2010
    Posts:
    161
    Mes instanciation can be also very useful to reduce file size, especially in case of Web or iPhone publishing
    I got a scene with trees and mesh instanciation would have been useful

    perhaps in Unity 3.0 ?
     
  16. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,123
    That won't reduce file size. If all your trees use the same mesh, then Unity's already just using one mesh, so there's nothing to reduce.

    --Eric
     
  17. nawash

    nawash

    Joined:
    Jan 29, 2010
    Posts:
    161
    Eric,
    Thank you for that information. As I have not seen that feature in the documentation (I am rather new to Unity) I did not know that.
    I assume that it is supported via the "instance" feature of the DCC via fbx file format ?
     
  18. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,123
    No, that's not used, but you don't need anything special. If you have a mesh, then any number of objects can use that mesh. If you duplicated all the trees in a 3D app and imported them as a group, then each one will be unique and it will result in large files, but that's usually a poor way to work unless you need all the meshes to be unique for some reason.

    --Eric
     
  19. nawash

    nawash

    Joined:
    Jan 29, 2010
    Posts:
    161
    Sorry, I do not mean to be annoying but I do not get it .
    In a DCC, IMHO, there are 2 ways to duplicate : either using "copy" or "create instance".
    If I understood correctly (which is not obviously the case :) ) if I use copy the mesh will not be shared, but I do not have to use "create instance" either.

    Do you mean unity parses all the meshes and compare them to "build" the mesh sharing in the scene ?
     
  20. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,603
    you can just try it.
    export it, import into unity and select the mesh on the mesh renderers. if it goes to the same its the same otherwise not :)

    and there is never hardware instancing. you can only get "mesh data sharing" so the mesh data isn't multiple times in RAM but it will always be a distinct mesh with own render request etc, so all you can get is a reduced size for the mesh data in ram
     
  21. Daniel_Brauer

    Daniel_Brauer

    Unity Technologies

    Joined:
    Aug 11, 2006
    Posts:
    3,355
    Unfortunately, there are three types of mesh instancing being discussed in this thread now:

    Hardware instancing:
    This is a method supplied by Direct3D which allows you to draw multiple instances of a mesh in a single draw call. This is what the OP was asking about, and what Aras said would be difficult or impossible to implement in a generic way.

    FBX Instancing:
    This is a method that the FBX format allows you to use for models that contain multiple instances of the same mesh. It reduces the size of the FBX, but does not inherently improve rendering performance. As far as I know, Unity does not support FBX instancing. Each instance will be imported as a unique mesh. I'm not sure whether Unity's mesh asset format could easily be modified to support instancing, but it's something to ask about either way.

    Unity's mesh instancing:
    If you have two MeshFilters (or MeshColliders, or MeshParticleEmitters) pointing to the same Mesh asset, Unity will not duplicate that asset other than storing it both in video memory and main memory, as necessary. This is the standard behaviour for Unity, and (as I understand it) works automatically as long as you don't apply different non-uniform scales to your MeshRenderers. If you do this, then multiple copies are kept in memory due to the way Unity handles mesh scaling. I could be wrong, and it might just be that different scales create different VBOs, whether they are uniform or not.
     
  22. nawash

    nawash

    Joined:
    Jan 29, 2010
    Posts:
    161
    Thank you for the clarification
     
  23. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,603
    Unless unity is doing something stupid, not even that should be the case for transforms as you can take the same mesh and process it with different transform matrices. That has worked since DX6 and I would be a bit puzzled if unity decided to break this for some reason. (with HW mesh instancing, it would be a different story)
     
  24. mulova

    mulova

    Joined:
    Apr 14, 2011
    Posts:
    52
    Unity3D doesn't offer the way to access DX context
    then I can't implement hardware instancing even on DX specific hardware?
    Do I have to wait until Unity3D engine support it?
     
  25. ZJP

    ZJP

    Joined:
    Jan 22, 2010
    Posts:
    2,646
    Possible with 3.5 ;)
     
  26. duke

    duke

    Joined:
    Jan 10, 2007
    Posts:
    762
    OpenGL supports hw instancing as well. I fail to see the difficulty in implementing such a thing.
     
  27. kaiwegner

    kaiwegner

    Joined:
    Aug 5, 2010
    Posts:
    9
    *Bump* I would like to see that feature too!!! This would reduce the draw calls on my games a lot!
     
  28. Owen

    Owen

    Joined:
    Apr 20, 2011
    Posts:
    79
    Don't really need it to work in a generic way. Its a special purpose solution. I think it would be fine if the additive forward passes ignored it, as long as the base render pass and any depth-normal passes used it. Should also be easy in deferred lighting mode, and thats where it would see the most benefit anyway.

    Even if its not done automatically using renderers, making it an option for Graphics.DrawMesh would be extremely useful. Let us pass in a list of world matrices and maybe material property blocks if possible.
     
  29. romaing

    romaing

    Joined:
    Feb 11, 2010
    Posts:
    24
    Is there something new about gpu mesh instancing in Unity?
    It would very very helpful in the architecture and urban planning visualisation field.
     
  30. KarelA

    KarelA

    Joined:
    Dec 30, 2008
    Posts:
    412
    I guess there is no point on creating a new thread about this. Since we are going to have mesh instancing in Unity4 then we could discuss about this in this topic.
     
  31. romaing

    romaing

    Joined:
    Feb 11, 2010
    Posts:
    24
    I am not sure skinned mesh instancing is exactly the same thing we are talking in this topic ; we are going to have mesh instancing in Unity 4?
     
  32. djarcas

    djarcas

    Joined:
    Nov 15, 2012
    Posts:
    154
    Posted: 11:17 AM 04-01-2009
    Well, it's 2013 now. Is this somewhere on the horizon?
     
  33. SL-Paul

    SL-Paul

    Joined:
    Sep 20, 2012
    Posts:
    8
    hardware instancing :) will Unity support this anytime soon?
     
  34. duke

    duke

    Joined:
    Jan 10, 2007
    Posts:
    762
    Can't this be done in the (dx11) geometry shader?
     
  35. Velo222

    Velo222

    Joined:
    Apr 29, 2012
    Posts:
    1,281
    I would like to see this happen. If it is possible, I hope someone that knows how would actually make an asset that could do this.
     
  36. Aras

    Aras

    Unity Technologies

    Joined:
    Nov 7, 2005
    Posts:
    4,536
    Sometime, yes. "soon", well depends on your definition of soon. It's "on our radar", for whatever that's worth.

    Not really. Or, well, that would be a really, really bad way at doing it. General rule with geometry shaders is: "if you can do something without a geometry shader, do that". Geometry shaders are really, really bad for performance; and should only be used when there's really no other way at achieving something.
     
  37. CommunityUS

    CommunityUS

    Joined:
    Sep 2, 2011
    Posts:
    181
  38. stevesan

    stevesan

    Joined:
    Aug 14, 2011
    Posts:
    64
    Just wanna post here to revive the call for instancing. I'm working on a highly dynamic open world game right now, and instancing would help sooooo much to have more detail in the world.
     
  39. BBeck

    BBeck

    Joined:
    Jan 12, 2014
    Posts:
    57
    Wow. It does make a pretty big difference. I just ran the XNA example and on my hardware I'm either getting 5 to 6 times as many models or 5 to 6 times the frame rate depending on whether I go with more instances or better frame rate.

    I had about 15,000 instances that could barely hold 30 frames per second. I found I could either bump the frame rate up to almost 180fps with hardware instancing or increase the number of instances to about 80,000 instances and still hold above 30fps.

    It seems like that might be really useful for billboards and highly repetitive background details like plants.

    But the Microsoft documentation that comes with the example says that it can actually decrease performance if you have objects with over about 1,000 triangles. And it also says the technique is extremely hardware dependent even so much so that they wrote separate code for Shader Model 2 and 3 as well as separate code to make it work on the Xbox 360 as opposed to PC.

    It sounds like something that really should be done at the engine level, and with an engine that supports a wide range of platforms, I can see why it might not really be a viable option especially if its not even an option on OpenGL which is what you're going to have to use for most of the platforms the engine runs on.
     
  40. Cynicat

    Cynicat

    Joined:
    Jun 12, 2013
    Posts:
    255
    could still use instancing. great for foliage and deffered rendering deals with the lighting problem nicely. could still have problems with things such as light and reflection probes but still. for things like grass this is necessary, even if it has to use a single light/reflection probe. =3
     
  41. hicks

    hicks

    Joined:
    Nov 24, 2013
    Posts:
    13
    @Aras I was experimenting with Graphics.DrawProcedural a lot.
    I already managed to draw thousands of animated skinned instances with a single reference animation object:

    However, I didn't manage to get it lit by Unity. I always needed to fake the shading in the fragment shader. Is there a way to get stuff lit that was drawn by Graphics.DrawProcedural?
    Bonus: Is there some way to use the Unity Standard shader for those drawcalls?

    Thanks in advance and keep up the good work!
     
    Pecek and Voxel-Busters like this.
  42. hicks

    hicks

    Joined:
    Nov 24, 2013
    Posts:
    13
    Good news!
    Working on a different project now, I gave it another try. This time with a deferred shader. Calling DrawProcedural in OnRenderObject results in no lighting. However, if you use a CommandBuffer scheduled for AfterGBuffer Unity lights it correctly! The frame debugger was really helpful on this one as you can see exactly when the drawcall is executed and what the shader writes to the render targets.
     
  43. Arycama

    Arycama

    Joined:
    May 25, 2014
    Posts:
    81
    What do you have going on in your shader to get it to work with Unity's lighting? I currently have procedurally generated meshes with arbitary amounts of vertices, being drawn with Graphics.DrawProceduralIndireect. I can get them to render through a command buffer, but the surface appears black unless I render it after lighting, in which case it just uses the shader without any lighting.
     
  44. Aras

    Aras

    Unity Technologies

    Joined:
    Nov 7, 2005
    Posts:
    4,536
    Yes, DrawProcedural right now is just like Graphics.DrawMeshNow; it just draws the mesh immediately, without setting up any lighting or making it render into shadow maps etc. So yeah that's not ideal.

    About the only way to work around this right now would be using deferred shading, so that it does not need to interact with lighting much, just need to write into the g-buffer.
     
  45. BSz

    BSz

    Joined:
    Jun 11, 2016
    Posts:
    4
    That's interesting. Are there any plans to change that so DrawMesh or DrawProcedural would have light and shadow set up? This would be a great improvement for the projects I am working on in my job, since both heavily rely on procedural mesh generation using those commands.

    Besides, and to get back to the spirit of the OP now that GPU instancing is indeed available in Unity 5.4, do GPU-instantiated instances have lighting and shadowing all set up from start or do they suffer from the same problems?
     
  46. dreamerflyer

    dreamerflyer

    Joined:
    Jun 11, 2011
    Posts:
    901
    if can draw gameobject in gpu ,that is the most ideal~
     
  47. hippocoder

    hippocoder

    Digital Ape Moderator

    Joined:
    Apr 11, 2010
    Posts:
    25,354
    I guess we could do vertex lighting in shader, or maybe forward+ will come? :)
     
  48. TheRenalicious

    TheRenalicious

    Joined:
    Oct 22, 2014
    Posts:
    1
    I've been researching this for a while, but I'm still having a hard time understanding the major performance differences and advantages between static batching, and gpu instancing in Unity 5.4.

    I'm still using 5.4.0p1, so I haven't had a chance to see if the changes to batching and instancing in p2 do anything different, but as of now I have a hard time seeing the performance difference.

    I'm working with a relatively high end PC (Intel 4790 (non K cpu), GTX 960), and in an open world game it's not unusual to see ~2500 SetPass calls, ~3000 total drawcalls, and ~3000 total batches.
    What would be the major gains between seeing 2000 batched draw calls and 1000 batches that are instanced, over 2000 batched draw calls and 1000 batches that are static?