Search Unity

Question Optimising dense forest scene

Discussion in 'General Graphics' started by andrei2002, Jun 4, 2020.

  1. andrei2002

    andrei2002

    Joined:
    May 2, 2017
    Posts:
    14
    I want to make a survival game in a forest, so like any other game like this I need an open world forest. I made the terrain and painted the textures, everything was ok until I have painted some trees to check the performance. I know this question was asked many times before(will cover some old threads below) but there was no clear answer so I want to make this thread in such a way that can help everyone with this problem. Target platform is Windows PC.
    1. Terrain: I have generated the terrain using unity terrain tools, I have one main terrain of size 1000x1000 and 4 neighbour terrains with the same size used for background mountains (terrain settings can be seen in the picture below) Camera.png
    2. Camera: Camera settings are the default ones except the Clipping Planes Far one that is set to 10.000 because I use a day and night system and I have a Plane Moon texture that orbits around the terrain and I wanted to add a cool flare effect to it. Even if they are rotating together they weren't aligned and the only solution I found to align them was to move the moon very far away. If there is any other way to do this I will be very happy to know about it. Terrain.png
    3. Trees: This is maybe the most important part of the issue everything was ok until here. This is the asset that I am using https://assetstore.unity.com/packages/3d/vegetation/trees/conifers-botd-142076. I haven't changed the settings in shaders except the GPU Instancing check-box because I found somewhere that it can help to increase performance. Unfortunately in the package there are only 4 trees and since I want to make this a large open world scene I need a more diverse enviorment so I tried to use this pack too which has very nice trees built using the tree builder from unity but these have other problems( very dark on one side of the directional light and bright on the other) so we will stick for now with the trees in the first pack. So we can see that the creator thought a bit optimising them, we can see a LOD group component added. TreePrefab.png Here is the LOD0 object. Tree LOD01.png Performance stats: When graphics are on ultra the stats are the following:
      • CPU: main 26ms
      • FPS: 37
      • Batches: 600-1.8k
      • Tris: from Hundreds of thousand to 20 Million
      • Verts: same as trees
      • SetPass calls: order of hundreds
    These performances were when the FPS Controller(Camera) was in a moderately dense forest (brush density of 40) if we can achieve ok performance in a forest this dense it would be great.
    On high settings there is some improvement the Tris and Verts are like a quarter and the lag is a bit smaller. It's not really about FPS, in the end it's not a shooter but the lag when the player is moving in the scene is just to big to be playable and I also want to add flowers, grass, rocks, and small cute details like mushrooms and pebbles.
    5. Lighting: I am using two directional lights(one for the moon and one for the sun) and they change intensity and rotation during time change. They are both set to Realtime Mode and soft shadows. In the future I will want to add a lighter to player hands(Point Light).
    In the lighting settings I use Enviorment Lighting to Color and I transition between day ambient color and night ambient color in a script. Ambient mode is also set to Realtime
    6.
    Post Processing: For now I have only 2 post processing Profiles and I blend them into a third one that I use for my Post Processing Volume, using a script and Mathf.Lerp
    7.
    What I found and tried: (if I am wrong anywhere please tell me)
    • Static batching: As the name suggests this is used for static objects. From unity docs: "In order to take advantage of static batching, you need to explicitly specify that certain GameObjects are static and do not move, rotate or scale in the game." Since I have wind this option is not suitable for my game, or I think so. And also there is this, on the same page "For example, marking trees as static in a dense forest level can have serious memory impact." https://docs.unity3d.com/Manual/DrawCallBatching.html
    • Occlusion Culling: I have seen this option and seems very interesting and there is a little more work to do on this one but if there is no other way(tweaking some soft quality settings or tricks) I am happy to learn how to that and try it out, that's why I want to this now before adding stuff later because it's easier to modify the project in this stage than later.
    • https://gamedev.stackexchange.com/q...uce-the-performance-impact-of-rendering-trees his problem was he hadn't Realtime GI enabled , as I said above Ambient Mode it's set to real time.
    • Combining Meshes: I have read that this can help too but haven't found some clear way to do it.
    If you need more details about the project dm me and I will provide you with any info that can help me get over this. Thank you in advance!
     

    Attached Files:

  2. mgear

    mgear

    Joined:
    Aug 3, 2010
    Posts:
    9,411
    can you make sun and light only be enabled one at a time?
    sounds heavy if both are always casting shadows.
     
    andrei2002 likes this.
  3. andrei2002

    andrei2002

    Joined:
    May 2, 2017
    Posts:
    14
    They are fading in time
    Code (CSharp):
    1. //sun part
    2. if (time < secondsInADay / 2)
    3.             {
    4.                 sunLight.intensity = (time - 5f / 24f * secondsInADay) / (7f / 24f * secondsInADay);
    5.                 skybox.SetFloat("_SunSizeConvergence", 1 + ((time - 5f / 24f * secondsInADay) / (7f / 24f * secondsInADay)) * 9f);
    6.                 if (time < (6.5f / 24f) * secondsInADay)
    7.                     Dawn();
    8.                 else
    9.                 {
    10.                     ambientColor = dayTimeAmbientColor;
    11.                     globalVolume.profile = dayTime;
    12.                     envState = "Day";
    13.                 }
    14.             }
    15.             else
    16.             {
    17.                 sunLight.intensity = (19f / 24f * secondsInADay - time) / (7f / 24f * secondsInADay);
    18.                 skybox.SetFloat("_SunSizeConvergence", 1 + ((19f / 24f * secondsInADay - time) / (7f / 24f * secondsInADay)) * 9f);
    19.                 if (time > (17.5f / 24f) * secondsInADay)
    20.                     Dusk();
    21.  
    22. //moon part
    23. envState = "Night";
    24.         globalVolume.profile = nightTime;
    25.         sunLight.intensity = 0;
    26.         ambientColor = nightTimeAmbientColor;
    27.         if(time>=secondsInADay/2)
    28.         {
    29.             float secondsRemaining = secondsInADay - time;
    30.             moonScript.ScaleUpdate(moonScript.scale + (secondsRemaining/(5f/24f*secondsInADay) )*0.5f*moonScript.scale );
    31.             moonLight.intensity = 0.4f * (time-19f/24f*secondsInADay)/(5f / 24f * secondsInADay);
    32.         }
    33.         else
    34.         {
    35.             moonScript.ScaleUpdate(moonScript.scale + (time / (5f / 24f * secondsInADay)) * 0.5f*moonScript.scale);
    36.             moonLight.intensity = 0.5f * (5f/24*secondsInADay-time) / (5f / 24f * secondsInADay);
    37.         }
     
  4. mgear

    mgear

    Joined:
    Aug 3, 2010
    Posts:
    9,411
    that would still double the work, since both are casting shadows (could at least disable shadows from the weaker one, if cannot completely disable)

    And check with Frame Debugger why objects are not batched more.
     
  5. andrei2002

    andrei2002

    Joined:
    May 2, 2017
    Posts:
    14
    Ok so i disabled the shadows from the moon light and here is a screenshot from frame debugger Camera.png
     
  6. mgear

    mgear

    Joined:
    Aug 3, 2010
    Posts:
    9,411
    then browse through the objects in frame debugger, it shows info like
    upload_2020-6-4_13-29-39.png
     
  7. andrei2002

    andrei2002

    Joined:
    May 2, 2017
    Posts:
    14
    What I have seen the most is "Objects have different materials" but i only have one shader for the leaves and one for the bark or this one "Rendering different meshes or submeshes with GPU instancing"
     

    Attached Files:

  8. marcb152

    marcb152

    Joined:
    Jun 20, 2019
    Posts:
    22
    Hi, I suggest you to take a look at these two links :

    The first link explains how they used world streaming.
    https://www.eastshade.com/foliage-optimization-in-unity/
    The second links uses atlases and combined meshes (I made my own script for that, I can share it if you want :)).
    This thread is interesting too : https://forum.unity.com/threads/uni...n-and-20k-trees-and-rocks-gameobjects.899219/
    I wanted to make a dense vegetation scene as well, I'm still trying to implement optimisation features for my own.
    Hope this helps.;)
     
    Last edited: Jun 6, 2020
  9. andrei2002

    andrei2002

    Joined:
    May 2, 2017
    Posts:
    14
    Hi, thanks for the video, I am curious about the combining meshes part, how does it work?
     
  10. marcb152

    marcb152

    Joined:
    Jun 20, 2019
    Posts:
    22
    Hi,
    I'm glad the video helped.
    There is the link for the mesh combiner code, you can take a look and try to understand it.
    This script can atlas and combine, the combine fonction is called CombineMeshes() on line 39.
    Here is the main script, you'll need to add it to a gameObject for it to work : https://pastebin.com/V3zdQJFv
    This is the Editor script, put this script in an Editor folder : https://pastebin.com/EbUszNLe
     
  11. andrei2002

    andrei2002

    Joined:
    May 2, 2017
    Posts:
    14
    Hi, I tried copying you script but ended up with this and I didn't found any cell data type in unity.
    Untitled.png
     
  12. marcb152

    marcb152

    Joined:
    Jun 20, 2019
    Posts:
    22
  13. andrei2002

    andrei2002

    Joined:
    May 2, 2017
    Posts:
    14
    No problem I still have to add some details to the terrain then I will try it, so what exactly does it do? Does it combine meshes of objects with the same shader/material, like GPU instancing?
     
  14. marcb152

    marcb152

    Joined:
    Jun 20, 2019
    Posts:
    22
    Hi,
    It just combine meshes, if your 3d models already share the same material, simply add all your 3d models into the items list and merge the meshes. If your 3d models don't share an atlas, add them to the item list (add only each kind of 3d model) and then atlas. The script will create a texture with all your textures.
    GPU instancing does not combine meshes, it simply renders a group of 3d models once if they share the same mesh and material.
     
    BrandyStarbrite likes this.
  15. andrei2002

    andrei2002

    Joined:
    May 2, 2017
    Posts:
    14
    Does it affect graphics quality? How exactly does it improve my performance?
     
  16. marcb152

    marcb152

    Joined:
    Jun 20, 2019
    Posts:
    22
    It doesn't affect graphics quality since the size of the textures isn't decreased. As I said before, I'm still experimenting with performance, I can't say : "it will improve your FPS by twice", I need to "play test" a bit more to be sure of what to say. But yes, it will improve your performance but I can't quantify it now.
     
  17. andrei2002

    andrei2002

    Joined:
    May 2, 2017
    Posts:
    14
    Thanks a lot I will finish adding details and I will try it.
     
  18. marcb152

    marcb152

    Joined:
    Jun 20, 2019
    Posts:
    22
    You're welcome :). Don't hesitate to ask if you have questions or problems with my scripts.
     
    BrandyStarbrite likes this.
  19. sivabalan12

    sivabalan12

    Joined:
    Jul 5, 2019
    Posts:
    11
    Hi, i need help, combining meshes decreases both batches and shadow cast, but it also decrease fps. What is the problem? (It have 5 submeshes and 5 textures 512x512p)
     
  20. warthos3399

    warthos3399

    Joined:
    May 11, 2019
    Posts:
    1,749
    I deal with this senario daily, as my games have very dense foliage, but great performance.
    • "Clipping Planes Far one that is set to 10.000", big mistake... that means camera is rendering everything in the scene at one time, not good.
    • Atlases are needed for textures for the trees.
    • Combined meshes is needed for the trees.
    • Heavy optimization is needed for import settings, and trees should have Mipmap support, as well as static batching.
    • LOD's need to be set correctly.
    • Your "day and night" system is causing alot of the performance problems as well, as your using 2 directional lights.
    • Occlusion Culling doesnt always work as intended, in fact, ive found that many times NOT using it is better.
    You need to optimize and set things up with "what the camera can see/render" theory. You really cant have "everything you want" for features, as performance takes a big hit. Also not once have you mentioned or thought of "chunk streaming" terrain, which can gain you at least a 30 FPS buffer. There are so many factors with your set up that are causing performance issues, that i cant list them all. YOU have to optimize and decide, and "shave and cut" to get what you desire.
     
    whkona likes this.
  21. stigmamax

    stigmamax

    Joined:
    Jun 30, 2014
    Posts:
    312
    I also use Conifers BOTD and to place them efficiently I use Hey Area Spawner which is a great tool.