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

GPU Instancing

Discussion in '5.4 Beta' started by djarcas, Dec 29, 2015.

  1. elbows

    elbows

    Joined:
    Nov 28, 2009
    Posts:
    2,502
    Oops that last message sounded grumpier than I meant it to. I know there is a lot to do in the 5.4 beta but I just start to get a bit twitchy when there is silence - I don't mind delays but I like to have some vague sense of where we are at.
     
  2. Arowx

    Arowx

    Joined:
    Nov 12, 2009
    Posts:
    8,194
    Well there is a zipped version of the standard shaders with instancing (in thread) and a doc on how to add instancing to other shaders (page 1). So it should be possible to add them to any shader, but they do need the same mesh and material, which could be a problem for speed trees, maybe?

    But as the standard shaders are dynamic, as in you can change their content, e.g. Normal, Heightmap etc and they will be compiled with only the bits you need for that platform it should definitely be a feature to add instancing support via the IDE e.g. an enable instancing check box in the shaders material settings.

    Fingers crossed.
     
  3. elbows

    elbows

    Joined:
    Nov 28, 2009
    Posts:
    2,502
    I would like to beg again for some news on this.
     
    MrEsquire likes this.
  4. Arowx

    Arowx

    Joined:
    Nov 12, 2009
    Posts:
    8,194
    Wow B17 was out fast and with the QA sweepstakes and roadmap for a release date of next month one question?

    Q: UT Will instancing be a standard shading feature, togglable in the IDE?
     
    sqallpl likes this.
  5. Arowx

    Arowx

    Joined:
    Nov 12, 2009
    Posts:
    8,194

    Unity 5.4 Beta 12 results

    Unity 5.4 Beta 17 results. Running 3 x @ 2560 x 1600 full screen on my PC. (DX 12).
     
    MrEsquire likes this.
  6. Riderfan

    Riderfan

    Joined:
    Jan 10, 2013
    Posts:
    514
    Sorry, this is a really old post but needed to ask - Has this been addressed yet?

    Skinned mesh instancing is rather critical to our title and we've been waiting for this to be implemented since GPU instancing was announced.

    We need to render between 20,000 to 30,000 animated skinned meshes. (low poly ones, only about 300 triangles)

    thanks
     
    Roni92pl and hippocoder like this.
  7. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    I too, would love skinned mesh instancing. Not sure what is involved though? what are the reasons for it from Unity's POV? would love to understand why, rather than being told "not planned" so we understand it's a technical issue rather than one of just can't be bothered etc...

    Although I'm not sure 30k skinned meshes would make sense, I would look into animating it via the vertex shader in cases like that.
     
  8. VertexSoup

    VertexSoup

    Joined:
    Nov 25, 2014
    Posts:
    44
    Is this thing supposed to work with LOD groups or am I losing all benefits here?
     
  9. VertexSoup

    VertexSoup

    Joined:
    Nov 25, 2014
    Posts:
    44
    One thing I noticed when I'm using instancing with LOD combo (latest beta b17) LODs are randomly jumping all around and most of them disappear in editor view or just show and hide with each redraw randomly. In play mode all is visible as it should.
    I have question tho. I have material (shader linked here in forum from unity devs) and that material have more assets packed to texture (basically more meshes share same material) what is not clear to me if that prefabs (with that shared material and texture) are used in scene are they all GPU instanced?
    To be more clear:
    Prefab1, Prefab2, Prefab3 etc all using exactly same shared MaterialA with instancing support. All prefabs have different meshes but are used in scene multiple times without any modifications. Do this get GPU instancing support as well? I read about exactly same mesh in doc but it is not clear to me if I'm constrained to use only one mesh with that particular material/shader or I can pack more assets (that means various meshes) to that same material and still reap benefits of instancing... Can anyone shed some light on this? @Unitydevguys maybe? :3
    I'll try to rephrase question:
    Can I use material derived from shader with instancing support shared across multiple assets having packed more assets to same texture atlas and still reap benefits of GPU instancing?
     
  10. Arowx

    Arowx

    Joined:
    Nov 12, 2009
    Posts:
    8,194


    Come on UT we want to be able to do this (video* above) on modern hardware please?

    *Nvidia DX10 Tech Demo circa 2009

    Or this on AMD hardware...

     
    elias_t and VertexSoup like this.
  11. Roni92pl

    Roni92pl

    Joined:
    Jun 2, 2015
    Posts:
    396
    20k skinned meshes? lol, I would be happy if Unity could handle 200 rather low poly skinned meshes with reasonable performance cost, because now rendering and animations already takes ridiculous amount of time for even 100-200 simple skinned meshes(on my o/c i5 4670k animation itself takes 1.3ms for 100 skinned meshes, and combines to 3ms with Unity's navmesh system, even though no agent is moving or finding path).
     
    Last edited: May 13, 2016
  12. Reanimate_L

    Reanimate_L

    Joined:
    Oct 10, 2009
    Posts:
    2,788
  13. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    Yeah it's just the concern about skinned meshes means that Animator needs to have a manual-update property, ie we tell it to .Update() because 30k state machines? that is NOT happening. Period.

    The draw call becomes the least of your problems in that scenario...

    Yes I think its worth skinned mesh instancing (eventually) but Unity needs to add functionality to Animator, otherwise the cost of animating even simple things will outweigh how many things you want. If I understand it there's some form of sharing if things are the same frame but I don't know how to get there. How to force it.
     
  14. Arowx

    Arowx

    Joined:
    Nov 12, 2009
    Posts:
    8,194
    But I only get about 25 FPS when I set it to 100 x 100 ?
     
  15. Arowx

    Arowx

    Joined:
    Nov 12, 2009
    Posts:
    8,194
    The idea is to use this for crowds or armies not player characters or boss battles, so it could really be via a separate animation toolset/system the same way the particle system is separate from the sprite system.
     
  16. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    You're kind of right. But the separate thing shouldn't be a Unity feature, it only needs stuff added to the existing Animator. Things like:

    - update frequency
    - manual updating
    - lod states in Animator - ie a simpler fallback condition (probably can do this yourself)!

    With possible lerping the result, so the visual result is a flat lerp in the distance, or a lower quality update in the distance that's still smooth. This would help animator usage even in the case of not skinning 30,000.

    Right now, instancing is saving you *cpu* for larger numbers, so you adding back 100x the cpu on top with Animator isn't helping.

    @Mecanim.Dev maybe you have insights to such optimisations please? :)
     
  17. Reanimate_L

    Reanimate_L

    Joined:
    Oct 10, 2009
    Posts:
    2,788
    Eh? i'm stable in 60fps
     
  18. Arowx

    Arowx

    Joined:
    Nov 12, 2009
    Posts:
    8,194
    With 100 rows of 100 runners?

    What hardware, browser, OS?
     
  19. Reanimate_L

    Reanimate_L

    Joined:
    Oct 10, 2009
    Posts:
    2,788
    yep, hmm GTX 660TI, firefox, win 8.1
     
  20. Riderfan

    Riderfan

    Joined:
    Jan 10, 2013
    Posts:
    514

    Well, sadly, we need it. Stadium spectators in console sports titles have been animated skinned meshes for about 10 years now. And it's done with GPU Instancing.
     
  21. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    Yes, that's fine. But you need to only run the animator maybe 10 times total, and have the skinned meshes pick one because any gains you get from instancing are otherwise entirely lost under the weight of animator cost.

    I wonder though if you use drawmesh, and you bake a skinned mesh, you can use that baked reference. This would be fast, try it out, since the baked reference would not be a skinned mesh as far as I understand it (http://docs.unity3d.com/ScriptReference/SkinnedMeshRenderer.BakeMesh.html).

    So to clarify:

    1. use BakeMesh on maybe 5 different skinned meshes. These are your source crowd meshes, and are baked to non-skinned meshes on the fly.

    2. now use instancing as usual, but for each crowd person, use a reference from one of the 5 baked meshes shuffled.

    3. update the baked mesh process on different frames. Frame 1 do mesh 1, frame 2 do mesh 2 and so on, this will also be very quick.

    So it is for primitive crowds at least, a solvable thing right now.

    ---

    Those stadium things you see - are a) not simulating animation every frame, and b) are not simulating each one at a different point in the animation, ie the majority are on the same frame of animation, just scattered around so it looks like they're all different frames.

    The instancing is still not the problem you face cpu wise at this point (or until you resolve animator issues).
     
    Last edited: May 14, 2016
    awesomedata likes this.
  22. Riderfan

    Riderfan

    Joined:
    Jan 10, 2013
    Posts:
    514
    Yes, you're right of course, you don't have 30k animators, you probably have only 3 or 4 and they're randomly assigned to each of those 30k skins. Regardless, they are skinned meshes that need to be updated and rendered.

    This is not new tech. As was pointed out above, this dates back to DX10 days. It was invented for the specific purpose of large crowds of spectators. If you're just rendering a lot of static objects (like trees or rocks) you can acheive that with simple billboarding. You don't need GPU Mesh instancing for that.

    Even if we went back to the early 2000s and used billboards for the spectactors, we'd still need to animate their textures so they move. So now you're processing 30,000 movie textures or animating that many sprites. which is actually harder on the processors than GPU Skinned Meshes are.

    Not only is this going to cause a lot of issues for us, but I'm just shocked that the unity techs didn't think this was something that needed to be addressed. What's the point of GPU Mesh instancing if the meshes are static?
     
  23. elbows

    elbows

    Joined:
    Nov 28, 2009
    Posts:
    2,502
    Well, lets not be unnecessarily narrow about it. Trees that are animated by wind are somewhat equivalent to your spectator scenario for example.

    I'm not going to assume they dont think this issue needs addressing. Its just as likely that they know of a long list of improvements required to make instancing useful for all comon cases, but they have to start somwhere. I remain dissapointed that communication from people at Unity regarding instancing progress during the 5.4 beta has fallen off a cliff of late, but that could change at any point. I'm certainly moderating my expectations for instancing for 5.4.0 but I hope it improves over time.
     
    Last edited: May 14, 2016
  24. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    I've just provided a viable solution that probably would be similar if Unity did it in visual and performance that you could use, right now, with minimal effort.

    Like you, I want it built in. But that won't be for months if not the next version of Unity. Until then just convert a few skinned meshes to non skinned meshes, on the fly. It's really not slow if you do it like I suggested.

    I can't agree, but each to their own.
     
  25. Riderfan

    Riderfan

    Joined:
    Jan 10, 2013
    Posts:
    514
    Wouldn't 'updating' the baked mesh at run time, even for 1/4th or 1/5th of the 30,000 meshes cause horrible performance problems?
     
  26. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    Should be instant ish. Probably the cost of a draw call or just over. It's only done for a couple of meshes. Try it?

    Probably misunderstanding me? in those tech demos for crowds they do this. They update at most 3-5 models (the sources). The rest are instanced from that core set. They probably only need to update one model of the source pool per frame so it's even less a hit. You can tell if you pause, that quite a few are on the same frame and are the same mesh.



    It's not perfect. Unity needs to work out standard instancing best it can before upgrading all it's skinned stuff, this would eventually be a great thing, but you would still be capped by animator performance. The above technique is not capped by animator performance. So the Unity solution is still very far away for most people.
     
    Last edited: May 15, 2016
  27. Reanimate_L

    Reanimate_L

    Joined:
    Oct 10, 2009
    Posts:
    2,788
    Oh btw and bakemesh still suffer performance problem if they cast/receive shadow. already tried bakemesh before to instance 5 character. not sure if they improve it now
     
  28. TJHeuvel-net

    TJHeuvel-net

    Joined:
    Jul 31, 2012
    Posts:
    838
    Cant wait till we switch to 5.4, i'd love to use this for our deferred decal renderer. Its a bit unclear how to properly do a fallback for unsupported platforms though, guess we'll have to figure it out.
     
  29. dreamerflyer

    dreamerflyer

    Joined:
    Jun 11, 2011
    Posts:
    927
    Can only replacewithshader render depthtexture for special instance_id mesh ?------I meant how can i only render some instance_id object on camera postrender?
     
    Last edited: May 19, 2016
  30. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    Bakemesh has nothing to do with rendering. I think you meant shadows on any instanced mesh.
     
  31. VertexSoup

    VertexSoup

    Joined:
    Nov 25, 2014
    Posts:
    44
    BUMP :) Does anyone know more in regard I asked couple posts above? TY for any insight into that matter.
     
  32. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    You can't instance unless you use the exact same mesh. By using property groups you can vary the input properties in a material/shader enabling instancing to still work but slightly slower than regular instancing.
     
  33. Reanimate_L

    Reanimate_L

    Joined:
    Oct 10, 2009
    Posts:
    2,788
    Yep, that's what i mean :)
     
  34. VertexSoup

    VertexSoup

    Joined:
    Nov 25, 2014
    Posts:
    44
    @hippocoder that was for me or for the other guy? In my case I'm using exactly same mesh with same material with same shader, that's why I ask it. Nature of prefabs. In my case there should be some advantage of using texture atlas with all mentioned things shared among them so if you have time can you elaborate why it should not work? Does not unity internally take them as same as they all point to exactly same resources.. I do not get it.
     
  35. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    If you are changing texture via atlas you are changing the mesh (uv attributes), so you would if using an atlas probably need to shift the cell the texture is on via property block ie 1 for set 1, 2 for set 2 and a slight mod to the uvs in a customised shader

    have to test, this is only theory from my end sorry.
     
    Last edited: May 18, 2016
  36. VertexSoup

    VertexSoup

    Joined:
    Nov 25, 2014
    Posts:
    44
    No no no, I'm not changing anything at all. Thy are all prefabs and all point to exactly same single shared material. As I'm not altering them during runtime in any way I would expect Unity to treat them internally as GPU instanced objects because material they use is made with instancing support. So basically there is more prefabs in scene all sharing this ONE material (which is made of shader linked in this forum).
    maybe some unity devs should chime in and tell us how it all work and why this in my case won't work. And if there is something they can do about it in cases like this as I see lot's of benefits using this technique. I won't mind if they are rendered out in sequences as per "unique" mesh, I just want to be sure I'm not doing something that goes against system (eg, creating additional workload)...
     
  37. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    You have to modify the standard shader, it's not automatic. Did you do that? Instancing doesn't care if it's a prefab or not. It only cares that a) it's the same material* and b) its an identical mesh.

    The renderer, prefab etc can all be different. Instancing is a shader / GPU feature so it will only be applied via a shader / material.

    *Be aware if you access a material in code, you will create a different material and break instancing, you should access .sharedMaterial in cases like this.
     
  38. VertexSoup

    VertexSoup

    Joined:
    Nov 25, 2014
    Posts:
    44
    Yep ty for pointing to noob stuff ;) I'm using unity since v2.1 or so. But I did not worked with this instancing thingy that's why this "weird" questions :)) I did all the shader mods required even successfully add instancing support to my own shaders as by instructions, that's not an issue. I'm asking about this old skool way of helping engine draw more with less work that's why I'm asking about this presumably old tricks.
    I would REALLY APPRECIATE Unity3D devs shedding some light and giving us some wisdom about how this behaves internally as they still did not opened up their code base for everyone to improve this engine.
    If there would be access to sources I won't be posting here this obviously simple questions that only the ones that see the source can answer me :)
     
  39. elbows

    elbows

    Joined:
    Nov 28, 2009
    Posts:
    2,502
    I'm presuming that lack of forum activity by Unity staff in general in recent weeks is because lots of them are crunching stuff for Unite Europe, but thats only a guess.
     
    VertexSoup likes this.
  40. VertexSoup

    VertexSoup

    Joined:
    Nov 25, 2014
    Posts:
    44
    Let's assume here: You want to use instancing so you use shader that support it. With current limited informations about how this thing works you need to assume that for each mesh you would need it's own copy of material. That mean you are forcing GPu to switch state if you want to render other object as instanced. With all my questions I'm trying to point to thing that you would like to avoid this extra work on GPU to force it to switch texture or shader as when using atlas you can pack more to same texture and thus avoid this "slow" operation.
    Is Unity3D intelligent enough under the hood to notice your intentions to help it with rendering or it will force extra "instance" of material for prefab that is different only in mesh and not material or any other thing.
    I assume we all know what are benefits of using texture atlases and benefits of this shared resource.
     
  41. VertexSoup

    VertexSoup

    Joined:
    Nov 25, 2014
    Posts:
    44
    Let's hope to be it this case ;) I assume they will eventually chime in and enlighten us with this missing info.

    One can only do that good decisions as good his information is.
     
  42. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    Instancing merely instructs the gpu to draw again, what it already has. It's a feature from 2001 or something. In Unity's case, it will instance dumb, and if it cannot instance (sorting says no, material says no, mesh says no) then it will split it automatically to another draw call.

    If you want manual control, use drawmesh and friends, they should do it.

    Unity will create a new batch if the material, mesh or sorting requires it.
     
  43. VertexSoup

    VertexSoup

    Joined:
    Nov 25, 2014
    Posts:
    44
    Yep that is the other way around but I would welcome some kind of component that I can specify prefabs that are all sets in a way they do not need to force GPU to switch state thus rendering them all out in sequence in same draw operation. I'm perfectly able to this myself I was just wondering if I won't (by doing this) break unity rendering internally and thus creating some unwanted overhead. This is why I need answer from them as I can only guess here how it works internally with instancing. And as technique from ~2001 I'm happy we finally starting to have this option to chose :D Just look at input class... Core feature of any game engine addressed only recently after years of developer cry and litres of booze they was forced to consume to live with it as it was till now.. :p

    From user friendly point of view it would be super nice for us, users and even for power-users be able to specify this case as in most productions this is probably most common optimization technique not some edge case scenario.
     
  44. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    You do the manual way with Drawmesh, you pass an array to it
     
  45. pixelsplit

    pixelsplit

    Joined:
    Sep 16, 2013
    Posts:
    173
    Will GPU instancing be released for mobile devices with 5.4? Wouldn't these be the platforms that would really benefit from instancing?

    Furthermore i'd like to know if someone already tried using a instanced emission property. I tried it and it behaves very strange. Only some of the meshes are actually using the property - when i zoom in / out the subset that uses the emission property changes.
     
    Last edited: May 22, 2016
  46. joergzdarsky

    joergzdarsky

    Joined:
    Sep 25, 2013
    Posts:
    56
    Well I can add a usecase to that question.

    I am intensively using ComputeShaders (love them) to procedurally draw surfaces of any kind for a space game. E.g. the terrain of a planet surface, an asteroid surface etc.

    To draw the surfaces I use a one time created flat simple plane mesh on the CPU, which's vertices are being displaced (to add terrain height) in the vertex shader and textured in the surface shader of my single material.

    The process is that for each individual terrain segement the height (stored in a computebuffer) and texture is calculated once in the computeshader, both is added to a MaterialPropertyBlock.
    I use
    - the same one time created mesh
    - the same material
    - an individually filled MaterialPropertyBlock (different SetTexture() and SetBuffer() commands) to draw each segement of the terrain.

    I consider this very efficient as all the performance critical operation (the terrain height) is only one time calculcated on the GPU in the compute shader. I need only one single mesh once created on the GPU, and only one material.
    Its basically pretty pretty quick, however I require individual MaterialPropertyBlocks for the buffer and texture, so it breaks batching and results in a lot of draw calls in the end.

    GPU instancing could be my way out, but as long as different MaterialPropertyBlocks block that I could be stuck. Which is sad, because the only difference between each surface segement is a different reference to a memory location for the ComputeBuffer and Texture information, everything else (the mesh and the material) is the same.
     
  47. elbows

    elbows

    Joined:
    Nov 28, 2009
    Posts:
    2,502
    Is this still true? Because I'm really bored of asking about this and receiving no reply from anyone at Unity here.
     
  48. zeroyao

    zeroyao

    Unity Technologies

    Joined:
    Mar 28, 2013
    Posts:
    169
    You need to copy Standard.shader from the built-in shader package to your project folder, and add #pragma multi_compile_instancing to it. You don't need to add other instancing macros described in the document unless you start to add more custom instanced properties.
     
  49. pixelsplit

    pixelsplit

    Joined:
    Sep 16, 2013
    Posts:
    173
    You could also just go into your project explorer and choose "Create" -> "Standard Surface Shader (Instanced)" :)
     
  50. zeroyao

    zeroyao

    Unity Technologies

    Joined:
    Mar 28, 2013
    Posts:
    169
    Hey,

    Firstly I'm sorry that the previously mentioned DrawMeshInstanced API has been postponed for 5.5. There was some interdependencies to the other team's work and after we came back from HackWeek it was too late for 5.4.

    And for your particular problem I think the best way to do is to set the big ComputeBuffer and the texture to your shared material, and have some instanced properties in each MaterialPropertyBlock for reference different location for the buffer and texture (e.g. a UV offset for the texture).

    Currently textures and computebuffers can't be instanced automatically. Only float values (scalar, vector or matrix) There is this new TextureArray API you can try out, but some manually texture packing code is required. ComputeBuffers can never be an array. Use a big combined buffer and use instanced properties for location as mentioned above.