Home Unreal Engine

Unreal Engine, StaticMesh and InstancedStaticMesh, doubt realistic use

polycounter lvl 3
Offline / Send Message
orangesky polycounter lvl 3
I have observed that the difference between using StaticMesh and InstancedStaticMesh lies in the fact that, in the former, every time a 3D object is drawn on the screen, it generates 1 drawcall (not counting the textures associated with the model). For example, if a wall that is part of a modular kit appears 30 times in a corridor, 30 drawcalls will be generated (only if all 30 wall sections are visible at once).

On the other hand, when using InstancedStaticMesh, a single Blueprint configured with ISM and the same wall module as in the previous case will generate only 1 drawcall, regardless of whether that module is instantiated 1 or 100 times.

Now, the following question arises:

Does it make sense in terms of performance to exclusively use StaticMesh in a modular kit if an excessive number of modules will never be visible on the screen simultaneously?

Using only StaticMesh, these will not be rendered until the camera has them within its frustum. I believe that the performance difference is insignificant when choosing either method (PC, Console). For instance, if my player is inside a room, only the models they can see will be rendered, which might be 4 or 5 walls of the modular kit at a time, and the rest will be omitted until they enter the camera's field of view. In this case, there would be 4 or 5 drawcalls depending on the number of visible modules.

I find it more useful to use the InstancedStaticMesh method when viewing a landscape from a certain height and thousands of objects can be seen on the screen at once (or perhaps in this case, it would be better to use Hierarchical Instanced Static Mesh).

(The information I provide here is based on my understanding of how these systems work in Unreal; if I am mistaken at any point, I would appreciate your correction to ensure a correct approach).

I have noticed that many artists do not use any system other than the basic StaticMesh and usually do not experience performance issues.

Replies

  • sprunghunt
    Options
    Offline / Send Message
    sprunghunt polycounter
    orangesky said:
    I have observed that the difference between using StaticMesh and InstancedStaticMesh lies in the fact that, in the former, every time a 3D object is drawn on the screen, it generates 1 drawcall (not counting the textures associated with the model). For example, if a wall that is part of a modular kit appears 30 times in a corridor, 30 drawcalls will be generated (only if all 30 wall sections are visible at once).

    On the other hand, when using InstancedStaticMesh, a single Blueprint configured with ISM and the same wall module as in the previous case will generate only 1 drawcall, regardless of whether that module is instantiated 1 or 100 times.

    Now, the following question arises:

    Does it make sense in terms of performance to exclusively use StaticMesh in a modular kit if an excessive number of modules will never be visible on the screen simultaneously?

    Using only StaticMesh, these will not be rendered until the camera has them within its frustum. I believe that the performance difference is insignificant when choosing either method (PC, Console). For instance, if my player is inside a room, only the models they can see will be rendered, which might be 4 or 5 walls of the modular kit at a time, and the rest will be omitted until they enter the camera's field of view. In this case, there would be 4 or 5 drawcalls depending on the number of visible modules.

    I find it more useful to use the InstancedStaticMesh method when viewing a landscape from a certain height and thousands of objects can be seen on the screen at once (or perhaps in this case, it would be better to use Hierarchical Instanced Static Mesh).

    (The information I provide here is based on my understanding of how these systems work in Unreal; if I am mistaken at any point, I would appreciate your correction to ensure a correct approach).

    I have noticed that many artists do not use any system other than the basic StaticMesh and usually do not experience performance issues.
    I've used instanced static meshes in games I've shipped. I've used them in levels that were entirely inside. 

    You'd need to have a pretty low detail environment to not want to use them. Interiors for games aren't just four walls anymore. 
  • orangesky
    Options
    Offline / Send Message
    orangesky polycounter lvl 3
    I've used instanced static meshes in games I've shipped. I've used them in levels that were entirely inside. 

    You'd need to have a pretty low detail environment to not want to use them. Interiors for games aren't just four walls anymore. 
    I want to show you an example of what I mean. In this demonstration scene from Epic in UE4.10 (I had this version installed because I have an old project in it), all the models that make up the environment are StaticMeshActors, and yet I have a high refresh rate, 60FPS, and around 2019.00 draw calls. On this computer, I don't have a very powerful graphics card; I have an RTX 3050ti Laptop 4GB.



  • rexo12
    Options
    Offline / Send Message
    rexo12 interpolator

    Does it make sense in terms of performance to exclusively use StaticMesh in a modular kit if an excessive number of modules will never be visible on the screen simultaneously?
    Probably? Instancing is usually something I do after a profiling pass on the scene. They're relatively easy to drop in with the merge actor tool. Since the renderer refactor in 2019 the engine does also do a degree of dynamic batching, which will consolidate draw calls for duplicate mesh instances in more or less the same way as ISMs do. Artists are implicitly taking advantage of instancing without necessarily using the ISM actor.

    Your demo example is nearly 10 years old and would most likely be targeting hardware not unlike yours. The detail and density of environments has increased significantly since.

    Aside, Nanite more or less makes the distinction between SMs and ISMs irrelevant, you only ever pay for 1 draw per material.
  • sprunghunt
    Options
    Offline / Send Message
    sprunghunt polycounter
    orangesky said:
    I've used instanced static meshes in games I've shipped. I've used them in levels that were entirely inside. 

    You'd need to have a pretty low detail environment to not want to use them. Interiors for games aren't just four walls anymore. 
    I want to show you an example of what I mean. In this demonstration scene from Epic in UE4.10 (I had this version installed because I have an old project in it), all the models that make up the environment are StaticMeshActors, and yet I have a high refresh rate, 60FPS, and around 2019.00 draw calls. On this computer, I don't have a very powerful graphics card; I have an RTX 3050ti Laptop 4GB.



    That demonstration scene is only one room. 

    There would be more than one room visible in a complete level. And there'd probably be bigger rooms than this (and smaller ones).

    Not every mesh would need to be part of an ISM but it's something you'd use if you needed to. Especially if you found areas which had a high mesh count.

    Also many automated level creation tools use ISM meshes. For example PCG networks usually create ISM mesh groups.

  • ZacD
    Options
    Offline / Send Message
    ZacD ngon master
    Like rexo12 was saying, 4.22 added auto instancing and it can be enabled/disabled with r.MeshDrawCommands.DynamicInstancing 1/0

    That and Nanite does make any conversation around instancing from the artist perspective a lot muddier, it allows artists to get away with a lot more before draw calls start to be an issue without them even noticing. HLODs seems generally more important for fixing environment art related performance issues. 

    Properly profiling and knowing what is happening behind the scenes is a giant rabbit hole, I'd normally say it's a bad idea for artists to make assumptions and optimize too early only based off assumptions and second hand info, gotta profile to really know what's causing impact.
  • orangesky
    Options
    Offline / Send Message
    orangesky polycounter lvl 3
    sprunghunt said:
    orangesky said:
    I've used instanced static meshes in games I've shipped. I've used them in levels that were entirely inside. 

    You'd need to have a pretty low detail environment to not want to use them. Interiors for games aren't just four walls anymore. 
    I want to show you an example of what I mean. In this demonstration scene from Epic in UE4.10 (I had this version installed because I have an old project in it), all the models that make up the environment are StaticMeshActors, and yet I have a high refresh rate, 60FPS, and around 2019.00 draw calls. On this computer, I don't have a very powerful graphics card; I have an RTX 3050ti Laptop 4GB.



    That demonstration scene is only one room. 

    There would be more than one room visible in a complete level. And there'd probably be bigger rooms than this (and smaller ones).

    Not every mesh would need to be part of an ISM but it's something you'd use if you needed to. Especially if you found areas which had a high mesh count.

    Also many automated level creation tools use ISM meshes. For example PCG networks usually create ISM mesh groups.

    ZacD said:
    Like rexo12 was saying, 4.22 added auto instancing and it can be enabled/disabled with r.MeshDrawCommands.DynamicInstancing 1/0

    That and Nanite does make any conversation around instancing from the artist perspective a lot muddier, it allows artists to get away with a lot more before draw calls start to be an issue without them even noticing. HLODs kinda seem more important for fixing environment art related performance issues. 

    Properly profiling and knowing what is happening behind the scenes is a giant rabbit hole, I'd normally say it's a bad idea for artists to make assumptions and optimize too early only based off assumptions and second hand info, gotta profile to really know what's causing impact.
    As you say, there's no need to become obsessed with the optimization topic. It's good to work with common sense and keep in mind the technical capabilities of the final hardware the project is targeted for. The artist should take into account LODs, texture atlas, and conducting performance tests occasionally. If issues arise, they can be addressed as they appear.

    Technological advancements in the engine make optimization options transparent for artists, and these might go unnoticed in personal projects due to a lack of graphical load or because they are portfolio pieces. In any case, I would like to know why EPIC, before version 4.22, did not make use of ISM in their sample projects as a "tutorial" for new users. I suppose the engine had some automatic optimization system at that time.

    Apart from the mentioned methods, did the engine have any more rudimentary automatic optimization systems in the past? I've seen highly detailed pieces created by older engine versions that received little manual optimization work (excluding LODs and texture atlases).
  • sprunghunt
    Options
    Offline / Send Message
    sprunghunt polycounter
    orangesky said:
    sprunghunt said:
    orangesky said:
    I've used instanced static meshes in games I've shipped. I've used them in levels that were entirely inside. 

    You'd need to have a pretty low detail environment to not want to use them. Interiors for games aren't just four walls anymore. 
    I want to show you an example of what I mean. In this demonstration scene from Epic in UE4.10 (I had this version installed because I have an old project in it), all the models that make up the environment are StaticMeshActors, and yet I have a high refresh rate, 60FPS, and around 2019.00 draw calls. On this computer, I don't have a very powerful graphics card; I have an RTX 3050ti Laptop 4GB.



    That demonstration scene is only one room. 

    There would be more than one room visible in a complete level. And there'd probably be bigger rooms than this (and smaller ones).

    Not every mesh would need to be part of an ISM but it's something you'd use if you needed to. Especially if you found areas which had a high mesh count.

    Also many automated level creation tools use ISM meshes. For example PCG networks usually create ISM mesh groups.

    ZacD said:
    Like rexo12 was saying, 4.22 added auto instancing and it can be enabled/disabled with r.MeshDrawCommands.DynamicInstancing 1/0

    That and Nanite does make any conversation around instancing from the artist perspective a lot muddier, it allows artists to get away with a lot more before draw calls start to be an issue without them even noticing. HLODs kinda seem more important for fixing environment art related performance issues. 

    Properly profiling and knowing what is happening behind the scenes is a giant rabbit hole, I'd normally say it's a bad idea for artists to make assumptions and optimize too early only based off assumptions and second hand info, gotta profile to really know what's causing impact.
    As you say, there's no need to become obsessed with the optimization topic. It's good to work with common sense and keep in mind the technical capabilities of the final hardware the project is targeted for. The artist should take into account LODs, texture atlas, and conducting performance tests occasionally. If issues arise, they can be addressed as they appear.

    Technological advancements in the engine make optimization options transparent for artists, and these might go unnoticed in personal projects due to a lack of graphical load or because they are portfolio pieces. In any case, I would like to know why EPIC, before version 4.22, did not make use of ISM in their sample projects as a "tutorial" for new users. I suppose the engine had some automatic optimization system at that time.

    Instanced static mesh just did not exist in older versions of the engine. It wasn't properly supported by hardware before DirectX 11. Even after implementation in DirectX some hardware still didn't support it. 

    Many tutorials aren't a realistic representation of a actual game workflow. They show some of the techniques but aren't taking into account the other things that you'd need to ship a game. 

    Apart from the mentioned methods, did the engine have any more rudimentary automatic optimization systems in the past? I've seen highly detailed pieces created by older engine versions that received little manual optimization work (excluding LODs and texture atlases).
    Yes there are many older systems that have been used for optimization. Including HLOD and level streaming. Some of these things have changed or become redundant because of newer systems. For example: Nanite basically makes creating LODs redundant. 

    Were these "older pieces" a game? people don't usually optimize non-game art or worry too much about things like framerate unless it's a playable level.


  • orangesky
    Options
    Offline / Send Message
    orangesky polycounter lvl 3
    Instanced static mesh just did not exist in older versions of the engine. It wasn't properly supported by hardware before DirectX 11. Even after implementation in DirectX some hardware still didn't support it. 

    Many tutorials aren't a realistic representation of a actual game workflow. They show some of the techniques but aren't taking into account the other things that you'd need to ship a game. 

    Apart from the mentioned methods, did the engine have any more rudimentary automatic optimization systems in the past? I've seen highly detailed pieces created by older engine versions that received little manual optimization work (excluding LODs and texture atlases).
    Yes there are many older systems that have been used for optimization. Including HLOD and level streaming. Some of these things have changed or become redundant because of newer systems. For example: Nanite basically makes creating LODs redundant. 

    Were these "older pieces" a game? people don't usually optimize non-game art or worry too much about things like framerate unless it's a playable level.



    I understand that you are referring to the fact that the Instanced Static Mesh feature did not exist in versions prior to Unreal Engine 4, specifically UDK 3 and earlier. In UE4 version 4.10, it was already possible to manually instantiate one or several meshes, although this method might not have been well-known in 2015.



    I agree with you when you mention that many tutorials do not realistically represent the industry's workflow. On the other hand, I believe the workflow is dynamic, and each studio has its own approach. As long as the final result is good, differences in workflows are not an issue.

    I am interested in learning about how artists approached optimization in the early versions of UE4 while I was using Unity. I am curious about the technological evolution of the engine and enjoy exploring these topics, not just focusing on the current workflow in terms of optimization. In my free time, I like working with older engines and seeing how far they can go with current hardware.

    It surprises me that the Instanced Static Mesh option was available in older versions of Unreal Engine 4, and yet, all the examples I've seen in those versions do not make use of this option, even Epic omits it. I have mainly come across older pieces in example projects from the Unreal Asset Store.
  • poopipe
    Options
    Online / Send Message
    poopipe grand marshal polycounter
    Epic's learning materials have gotten a lot better over the last couple of years which is why you're seeing more interest/understanding in technical subjects. Ten years ago there was very little practical instruction coming from epic themselves and most of the interesting technical stuff was confined to UDN so the peasants never got to see it (UDN is pretty redundant these days unless you're interested in console specific build issues imo)

    if you're interested in this stuff for fun purposes I strongly recommend looking into older stuff - nothing really significant has changed since ue4 released, it's all iterative (if you ignore raytracing, which you should).

    The dx7-9 era was a really interesting time IMO - people had to get really inventive back then

Sign In or Register to comment.