Improving the foliage tool performance

I haven’t used the foliage tool because for some reason the instances that are far and not visible continue to waste resources and slow down the game.
This, on a 10x10 Km map, is a problem.

In the configuration of the foliage tool there is a range of visibility, and the instances are hidden beyond that range, but it seems that the engine continues to process them.

The method I used is very simple, it hides clusters that are far, achieving an improvement of 30% on average, especially on large maps.

Here is an example, before:

and after:

As you can see in the stats, the draw task is the great beneficiary

This is the function I used to hide the far instances:



//To hide clusters beyond 60000 units, example:     hidefoliage true 60000
//To unhide all clusters:     hidefoliage false 0

exec function HideFoliage(bool B, int R)
{
    local InstancedFoliageActor F;
    local int i, n;
    local vector PL;
    local InstancedStaticMeshComponent IC;
    local int contCompo, contSMdata;

    PL = getalocalplayercontroller().pawn.location;

    foreach AllActors(class'InstancedFoliageActor',F)
    {
        for(i=0; i < F.InstancedStaticMeshComponents.Length; i++)
        {
            IC = F.InstancedStaticMeshComponents*;
            contCompo++; //for final resume
            for(n=0; n < IC.PerInstanceSMData.length; n++)
            {
                contSMdata++;
                if ( vsize(PL - MatrixGetOrigin(IC.PerInstanceSMData[n].Transform)) > R)
                {
                    IC.sethidden(B);
                    break; // as the complete cluster is hide, we don't need to check the remain instances of that cluster
                }
            }
        }
    }
    `log("FOLIAGE: "@contcompo@"clusters  "@contSMdata@"instances");
} 


This only hides/show the cluster based on distance. To implement in the game there are some ways.

You can divide the map in sectors, then when the player enter in a sector, execute the function to hide and show the clusters. This produce a little hitch. It’s like a “streaming”.

But the best way is to distribute along several ticks, checking a limited number of clusters in each tick. So if the player has moved 1000 units, per example, then start a check in each tick, a few instances each time, with a multiplier based on the player velocity.

I have done a quick test to check clusters in each click, and 100 checks per tick waste about 0.1 ms. But you can save 2 or 3 ms in the draw task.

I’m not sure about using the foliage tool instead the dynamic foliage script (spawn instances around the player). Each one has their advantages/disadvantages. Foliage tool can place instances where you want. Dynamic is random. Foliage tool is more stable for the framerate and better for the garbage collector.
A good option is to use foliage tool for the trees, and the dynamic for the grass, as the number of instances is too large.

But the problem with the Foliage Tool is that there are no rigid body collision, so when a Pawn enters in ragdoll mode, it crosses trees, walls, rocks and anything that is using foliage tool. Some idea about fix this?