Quick Q for Epic, do you support performance saving instanced rendering for identical meshes? I want to know if identical assets will affect my total draw count or not now before I start planning my building blocks to create worlds.
They are instanced, but that only ever helps with memory management (in any game engine or 3D program). It means it only has to store one object in memory.
The number of objects will greatly affect the performance, each object is a draw call.
I don’t believe that’s actually correct. Isn’t performance kind of the whole point of instancing? I couldn’t find any docs on instanced static meshes, but there’s a comment in InstancedStaticMeshComponent.h that says:
/** A component that efficiently renders multiple instances of the same StaticMesh. */
“Efficiently” pretty clearly implies a performance improvement, not just memory savings.
@Mothership.Entertainment, I think you’re right - I think that InstancedStaticMeshes give you instanced rendering, so it basically just has the one vert/index buffer with different transforms (or whatever - don’t know how it’s handled precisely in UE4).
That said, overall it’s still going to be way faster for what you’re doing to simply write a custom actor class that sets up your mesh dynamically (if I’m guessing right that you’re interested in the instanced behavior to fix your performance issue from your other thread). This type of instancing behavior is mostly useful for cases like foliage where you have a ton of one mesh being drawn and the only thing that is really different is the transform/scale.
It will have a lot fewer verts to send, only one transform, etc. if you do it by building a custom mesh, and if it doesn’t rebuild super often the performance impact should be minimal (you could also set it up with a static index buffer I’m guessing, though that may complicate things).
I can understand the reluctance to do that, setting up custom meshes in code tends to be a pain.
There are lots of different ways of batching things together for rendering but from what I remember in UE3, it was there for particles, but not meshes so it worked with 2D foliage, but not common meshes such as wall sections.
Depending on how you handle things you can get groups of identical meshes to draw for the same price as just one instance of that mesh and draw calls are still one of the biggest issues for PC gaming (roll on DX12!!!).
Instancing is all about improving memory performance, that’s why things are reused as much as possible, it still has to process all of the geometry like anything else and there’s a limit to how fast it can render the geometry. For something like a particle system, it may perform better because it’s a single draw call, rather than many separate objects.
It needs bit more explanation.
It will indeed improve performance, if you are locked on draw calls (on CPU), by batching geometry together into single call and sending it to GPU, where with “normal” meshes you have to make call for each mesh individually.
But it will of course doesn’t improve raw rendering performance. You still have to render all the geometry and do all the shading.
It actually should be called batching, not instancing.
It’s not about memory performance, it’s about the fact that issuing drawcalls is slow in (current implementations) DirectX and OpenGL.
Instancing doesn’t reduce drawcalls, if you’re talking about batching, then like the post before yours then that’s something different.
Ah, sorry, I didn’t realise, I was talking about batching then and will hunt down that post.
[EDIT] Darth, could you link to the specific post please? I’m searching the forum for recent threads on Batching and can’t find any relevent to what is being discussed here.
It’s a couple posts above: https://forums.unrealengine.com/showthread.php?13107-Instanced-Rendering&p=84119&viewfull=1#post84119
Sorry, I completely misread your initial post, thought you was talking abou a whole new thread on the topic.
You can call it whatever you want and I’m well aware of batching, but Epic calls it instancing in their tools:
and that’s what we’re all (presumably) using and discussing. It’s quite clear which one of the two that the OP was asking about, too.
So are instanced meshes batched or not?
My assumption would be yes, as there doesn’t seem to be a whole lot of point otherwise, and it’s also a very common engine feature in modern engines.
No, that’s foliage, and the OP wasn’t asking about foliage. Foliage is batched because otherwise you wouldn’t be able to do it. If you placed the foliage by hand instead of using the foliage system then it wouldn’t be batched and you would have a significantly lower performance. You could batch things together and it will reduce the draw calls, and if they are simple objects then they won’t be much of a strain, but you wouldn’t be able to do that with everything.
Sadly the term ‘instancing’ is being used in two ways in UE4.
Instancing of components like UStaticMeshComponent: this means the components are all sharing the same resource, which is the UStaticMesh vertex and index data. This saves memory. As far as draw calls go, each element of a UStaticMeshComponent will issue a draw call in each mesh pass it is in (depth only, base pass, shadow depth pass, etc). Even though every element of every instance/component is a draw call, there’s a lot less state setup for UStaticMeshComponent’s of the same mesh and material and they can cost ~3x less than if every UStaticMeshComponent had a different mesh and material.
Instancing as in UInstancedStaticMeshComponent: this is referring to hardware instancing, which is the GPU feature that you issue one draw call and a bunch of per-instance work is done in the vertex shader. It typically reduces rendering thread overhead, but increases GPU vertex cost and has a very limited feature set, because any per-instance features (all the rendering flags on UPrimitiveComponent) have to be done in the vertex shader. By rendering meshes with low poly counts, you can get huge performance savings with this. UE4 does not yet support lightmaps on UInstancedStaticMeshComponent, but they are coming.
Thanks for the explanation Daniel, that makes sense.