I’ve been playing with instanced static mesh components lately, and my understanding is the only things you can do with their instances individually is create/delete them, and change their transforms. I have small voxel-like areas in my game and I need a way of hiding and unhiding certain instances runtime to speed up rendering, but obviously you can’t hide them individually. Constantly deleting and creating them while you play is problematic, so Is there a standard method of doing this? If I change their scale to 0,0,0 to hide the ones that need hiding, would that speed things up any? Either that or I could just relocate them offscreen I guess, or both at the same time. I’m just trying not to reinvent the wheel here lol
Spawning instance meshes is a rather fast operation. I wouldn’t discount it as a method unless you have already tried it for your setup.
Otherwise, what if you batched the instances based player view direction? So dirt blocks in front of you would be 1 set of instances, and behind would be another(divided into however many groups feel optimal). Then the instances would spawn in groups around you based on your location and rotation.
I just want to hide the ones that are buried under other blocks that won’t be shown anyway. I know how to figure out which ones need to be hidden. I just don’t know the best way to “hide” them with instanced meshes since you can’t literally set them to hidden
What you could do is not spawn them in the first place. If you know which ones need hiding you could use this information to decide if the instance should be spawned in the first place. Hope this helps.
They need to be able to disappear and reappear as you play. Like, the outside ones get destroyed so the inside blocks become unhidden. and when the outside blocks get replaced, the ones underneath get hidden again so the engine doesn’t waste time trying to draw them
Just add/remove instances. I’ve tried it and it’s pretty quick.
The problem with adding/removing instances is that depending on how you do it, removing one block could require thousands of nearby visible blocks to respawn. This is 99% seamless on my machine(with tens of thousands of instances), but there are a few areas where this could become a problem(mobile).
However, I think if you intelligently batch your instances so that only hundreds are respawned based on any given block removal, then it should be completely manageable for any PC. If you are talking about doing this on a phone though, you are going to have to run some performance tests and see how it goes.
The respawn isn’t the really the problem. It is managing the number of draw calls are happening at any one time. Whether they become visible or are spawned in, the graphics hit is roughly the same as far as I can tell, and is the most important consideration.
The question on my mind is, can unreal figure out instanced static meshs that are the same base mesh over multiple actors and reduce the amount of draw call as well?
I guess it is since it should be totally possible.
The problem I have with spawning and destroying mesh instances individually is, the engine doesn’t give you a way to access each instance as an object, just an array of instances… all you can do is edit an instance by its index in the array. So even if you try to keep track of their indexes in that array, if you destroy one instance, the array fills in the gap and all the following instances will then have a new index. So then you have to go change all your references to keep track of which instance is in which index of the array so you can access the right one. My system already does this, but it’s a whole lot of looping once you get lots of instances. I’m getting a little lag every time I delete an instance in a large array. So my solution so far is to scale the “hidden” instances all the way down to save the engine from having to draw/shade/shadow a mesh that you can’t see anyway. I’m wondering how much work it actually saves the engine when you scale the meshes down to nothing as opposed to leaving them there as is, and is there a better way of doing this.
a “hack” you could do, what I did for my dynamic pixel screen where I turn pixels on and off.
Is to set a index to scale 0,0,0 or 1,1,1 based on if it exists or not. That won’t modify the amount of instances but turns the removed one invisible.
Lol spaceman that’s what I’ve been asking about.
That is an intriguing idea… you can scale the instances on a per instance basis?
For my own stuff, I just clear and regenerate all the instances because it is almost seamless and it only needs to happen at end of turn for my game. It could make more sense to just have all the instances in the map and shrink and expand them as necessary.
The very defenition of a transform: translation rotation and scaling.
It should just end up as a final 4x4 matrix once it renders.
You can do each separatly or in any combination per instance.
Per defenition it should allways be quicker to update the transform per instnace, rather then modifying the data container where the instances are. This is due to the fact that the transforms are not stored in a fixed array, but a dynamic one, that could result in multiple copy and move actions based on the resize required to fit more elements into the array. Depending on how Epic actually implemented them. But there is allways a recomendation to work on fixed size data if modification is done often.
Just imagine a dynamic array, allocating extra space for say 16 more objects as default in theory. feed it with 2048 elements, the array would need to change it’s size 128 times. Each time could result in a state where there is not enough freespace following where it is in memory, the entire array needs to be moved to a new place where there is enough memory, this could happen as few or as many times as needed. Resulting in a recreation delete and copy of the memory space each time. Is this is done “per frame” then it’s even worse. I am not sure how the array for instances are created or managed for instances per say but this is a possible scenario. I do not know if these might result in draw calls or other side effects in the engine?
4 years later…
Say you have M instances, so the last index is M-1, and you need to “delete” an instance at index N. You could delete the last one (M-1), take its transform and set it for instance N. Then instance at index N has been “removed” and replaced by the instance at index M-1, which is now gone.
Only two references need to be changed and you do not need to update all indices for instances N to M-1.