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
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?
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?
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).
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.
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
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 ;-)
euhw sorry it's a dutch expression, it's like saying you don't want to blame or bring up something old, nvm
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 ?
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
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 ?
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
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 ?
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
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.
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)
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?
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.
Is there something new about gpu mesh instancing in Unity? It would very very helpful in the architecture and urban planning visualisation field.
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.
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?
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.
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.
This is something I'm looking forward to. I had held off while Mac and OpenGL was not supported but now that it is...let's instance it up! Coming from a XNA/SunBurn background...I'm excited for this in Unity. http://www.synapsegaming.com/downloads/resource.aspx?guid=a6d20942-7ce0-4030-a121-a1110affdcce
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.
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.
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
@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!
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.
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.
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.
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?
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?