Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.

[Released] Advanced Terrain Grass

Discussion in 'Assets and Asset Store' started by larsbertram1, Sep 11, 2017.

  1. abbasjafari

    abbasjafari

    Joined:
    Mar 7, 2020
    Posts:
    6
    You were right, the scene view shows Unity grasses. I get same result when I disable Grass manager
     
  2. cmo

    cmo

    Joined:
    Aug 10, 2012
    Posts:
    12
    Has anyone gotten this package to work with URP 14? I see earlier in the thread the author said it should probably work with URP 13 even though it was only updated for 12. I installed, updated with the URP packages (installing 12.1 last) but there's a cascade of warnings, several pink materials and nothing displaying in the URP demo scene. Besides URP 14 I'm using regular forward rendering so that shouldn't be an issue.

    I did read the documentation but I don't know if it's reliable -- one of the first lines in the URP section says: "check Universal Render Pipeline at the top of the Grass Manger inspector" --> this is not visible anywhere in Grass Manager so I suppose it was deprecated?

    Anyway, just wondering if it's worth time to try to tinker with or if it's a hopeless cause for URP 14.
     
  3. larsbertram1

    larsbertram1

    Joined:
    Oct 7, 2008
    Posts:
    6,773
    which warnings?
     
  4. larsbertram1

    larsbertram1

    Joined:
    Oct 7, 2008
    Posts:
    6,773
    i just get a single error using URP 14.
    to fix it open "ATG URP Translucent Lighting.hlsl", go to line 78 and change it like so:
    Code (CSharp):
    1. uint meshRenderingLayers = GetMeshRenderingLayer();
    it will not turn the shaders into URP 14 shaders - but at least you will see some grass :)
     
  5. Yany

    Yany

    Joined:
    May 24, 2013
    Posts:
    85
    Just a quick question: as I understood, this asset "grows" grass only on terrain. Though do you have or can you create an asset that puts grass on custom mesh surfaces. I'd like to use it on tile-based landscapes which I generate using a WFC tool. Thanks.
     
    alisinan likes this.
  6. andreiagmu

    andreiagmu

    Joined:
    Feb 20, 2014
    Posts:
    148
    Does ATG support split-screen camera setups? (e.g.: local multiplayer)

    EDIT: I purchased ATG, and I'm really impressed with the quality of its grass! :)
    The results are much more beautiful and natural than Unity's built-in grass shader.
    And it's well optimized for all its improved quality!

    I'm using ATG 1.36.1, URP 12.1.10, Unity 2021.3.22f1.

    From my tests, it seems ATG doesn't support split-screen cameras out of the box, because the grass culling takes only the first camera into consideration. So, my second camera may end up looking at an area where the grass isn't rendered because of the culling (e.g.: in the opposite direction of the first camera's view).

    Is there any way to make it work with split-screen?
    Preferably, with the grass culling (and Compute setting) being based on all of the currently active split-screen cameras.
     
    Last edited: Apr 7, 2023
  7. larsbertram1

    larsbertram1

    Joined:
    Oct 7, 2008
    Posts:
    6,773
    atg does not support split screen out of the box. you will have do adjust the grass manager script: mainly you have to make it accept 2 different cameras, compute then might already work out of the box. memory consumption will not be optimal and basically twice the amount of what you actually need but compute should work right away if fed with 2 different matrices.
    so basically you call DrawGrass() 2 times.
     
    andreiagmu likes this.
  8. andreiagmu

    andreiagmu

    Joined:
    Feb 20, 2014
    Posts:
    148
    Thank you very much for the answer! :)
    Yes, I'm aware split-screen will make the grass processing heavier. I'm willing to have that compromise for split-screen play.

    I already tried doing what you suggested, in a quick and dirty test:
    I added a camera list to the GrassManager script, and I essentially call "foreach (camera in camList) DrawGrass(camera)"
    But the resulting behavior isn't correct.

    I'm testing with two cameras.
    The grass gets rendered by both cameras, but Compute only takes into consideration the last camera from the list (the rendered grass follows the second camera's movement).
    With Compute disabled, it's pretty much the same behavior.

    In other words, both cameras as rendering the grass for the last camera (the last DrawGrass() execution).
    It seems the DrawGrass() processing for the last camera completely overrides DrawGrass() for the first one, instead of both being done at the same time.

    @larsbertram1 I'll send you my test project in a PM, if you want to take a look.
     
  9. larsbertram1

    larsbertram1

    Joined:
    Oct 7, 2008
    Posts:
    6,773
    well, if it still runs in LateUpdate() it will be executed just before any camera renders. so the result from the 2nd cam will stomp on the result from the first one.
    i think you will have to use OnPreCull() or OnPreRender() to make it being executed just before the rendering of each camera starts: this way you shooud get 2 different culling results.
    so create a small script and add this to your cams. this uses OnPreCull() or OnPreRender() to call the grass manager's DrawGrass() function.
    using OnPreCull() or OnPreRender() some global shader variables might no be initialized properly but this should only affect the wind and should be easy to fix once the culling works.

    if your cameras are at rather different locations looking into totally different directions the way the grass manager handles cells will not work. you could try to disable visibility for the culling spheres and use a rather huge cache distance.
    a more rubust solution would only leave the shared stuff in the grass manager (terrain height array, grass density arrays and maybe a shared draw buffer) and move the cell related stuff to individual scripts so you have 2 cell caches: 1 for each cam.
     
    andreiagmu likes this.
  10. andreiagmu

    andreiagmu

    Joined:
    Feb 20, 2014
    Posts:
    148
    Great! I think this answers all the questions I had regarding my custom ATG implementation for split-screen.
    Thank you very much for the detailed answer and implementation ideas!
     
  11. andreiagmu

    andreiagmu

    Joined:
    Feb 20, 2014
    Posts:
    148
    @larsbertram1 I tried implementing (the best I could) the potential solutions you described above.
    In summary, the results for split-screen were sub-optimal and buggy (just like you mentioned they'd probably be).

    To clarify, I'm using in my tests:
    - Unity 2021.3.22f1
    - ATG 1.36.1
    - URP 12.1.10

    I also made a few tests in a Built-in RP project:
    OnPreRender() throws an error.
    OnPreCull() kinda works (it seems to display two different culling results, one for each camera), but the cell culling during split-screen is (naturally) quite buggy.

    URP doesn't have the OnPreRender() camera event.
    I tried using the RenderPipelineManager.beginCameraRendering delegate (and a few other of its delegates) but that didn't work. It didn't behave the same as OnPreRender() - its result was essentially the same behavior from my earlier tests, with only one culling result being displayed for both cameras.

    Based on some research I did, for the "ATG on split-screen" to work with URP, I'd possibly need to implement this in a custom URP pass/renderer feature.
    But that seemed much overkill to me.

    I also considered implementing the "more robust solution" you described, but trying to move the cell-related stuff to another script proved to be much harder than I expected (at least to the best of my skill).
    So, I didn't manage to make that work too.

    ---
    In the end, I think I'll just fall back to the default Unity grass renderer during split-screen play (this is also good for performance, I guess), and keep using ATG for single-player mode only.

    Is there a way to toggle between ATG/default Unity grass during runtime?
    Simply disabling/enabling the GrassManager component isn't working for me:

    - I start the game with the GrassManager component enabled. ATG grass is rendered.
    - If I disable GrassManager, all ATG grass disappears, but the default Unity grass isn't rendered.
    - If I re-enable GrassManager, the ATG grass is rendered again.
     
  12. larsbertram1

    larsbertram1

    Joined:
    Oct 7, 2008
    Posts:
    6,773
    ah, i wasn't aware of URP.
    and i think using a custom pass is not the way to go here: the grass may need several passes: depth, geometry, motion vectors, shadows...
    from a quick search public static event Action<Camera> beginCameraRendering should do the job. i did not look into it, but the per camera thing is important here.

    not out of the box. but it should be easy to implement.
    add a public bool _doRender
    in the LateUpdate check _doRender: if true then just let atg do its work, if not: skip DoRender() and reset the detail distance on the terrain.
     
    andreiagmu likes this.
  13. andreiagmu

    andreiagmu

    Joined:
    Feb 20, 2014
    Posts:
    148
    Yeah, about beginCameraRendering, that's the URP event I tried to use earlier (via RenderPipelineManager.beginCameraRendering delegate - it was being executed per camera), but it didn't work correctly.
    In my tests, it didn't result in the same behavior as OnPreCull() in Built-in RP.

    Anyway, from my tests, I realized the performance loss was quite bad during split-screen while using ATG (when calling DrawGrass() for each camera, using either beginCameraRendering or OnPreCull()), and it would be too much work for me to try to optimize it.
    I think in my case, it's easier to just fall back to Unity's grass shader for split-screen.

    I didn't notice the terrain's Detail Distance was being set to 0 when ATG is enabled. :p
    Resetting Detail Distance was the piece I missed, to fall back to the default Unity grass. :)

    Thanks again for the advice and support!
     
    Last edited: Apr 12, 2023
  14. andreiagmu

    andreiagmu

    Joined:
    Feb 20, 2014
    Posts:
    148
    After more tests, I realized I was using beginCameraRendering in the wrong way.
    I was calling DrawGrass() for each camera more times than I should. :oops:

    Now, I managed to achieve in URP the same behavior as OnPreCull(), using the RenderPipelineManager.beginCameraRendering delegate the proper way.
    And the performance drop during split-screen is much more acceptable. :D

    Now, I just have to find a way to fix the split-screen culling.
    When I move one of my cameras, very frequently, some cells from the other camera end up disappearing.
    I'll try these workarounds again.
     
  15. andreiagmu

    andreiagmu

    Joined:
    Feb 20, 2014
    Posts:
    148
    Here's a video showcasing my current results with ATG and split-screen.
    Sorry about the video's choppiness! (that's my GPU encoder's fault)



    The only changes I made to ATG's code are in the GrassManager.cs script:
    - I set DrawGrass() to public
    - In LateUpdate(), I only call the original DrawGrass() when I'm not playing the game (this is needed for the grass to be correctly rendered in edit mode)

    Here's the code I'm using to make both cameras draw grass, via URP's beginCameraRendering event.
    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.Rendering;
    3.  
    4. namespace AdvancedTerrainGrass
    5. {
    6.     public class AtgDrawGrassSplitScreen : MonoBehaviour
    7.     {
    8.         private GrassManager _grassManager;
    9.  
    10.         private void Start()
    11.         {
    12.             _grassManager = FindObjectOfType<GrassManager>();
    13.  
    14.             RenderPipelineManager.beginCameraRendering -= OnBeginCameraRendering;
    15.             RenderPipelineManager.beginCameraRendering += OnBeginCameraRendering;
    16.         }
    17.  
    18.         private void OnBeginCameraRendering(ScriptableRenderContext context, Camera camera)
    19.         {
    20.             if (!_grassManager.enabled)
    21.                 return;
    22.  
    23.             _grassManager.Cam = camera;
    24.             _grassManager.DrawGrass();
    25.         }
    26.  
    27.         private void OnDestroy()
    28.         {
    29.             RenderPipelineManager.beginCameraRendering -= OnBeginCameraRendering;
    30.         }
    31.     }
    32. }
    33.  
    I also created a simple script to swap the currently active fly cam, when I press the "Number 4" key.

    In the video, I tested ATG's rendering two times: with Compute enabled, then with Compute disabled.
    I'm aware the video is very choppy, but still, I think you can have a good idea of the culling results.

    It kinda seems like the second camera is still being prioritized over the first camera (it's more noticeable in the second test, where Compute is disabled).
    And even if the two cameras are now drawing separate grass, I guess they're still sharing the same cells.
    I believe this is the final issue to fix regarding ATG and split-screen.

    I guess this would fix the culling issue. But I'm having difficulty implementing this myself.

    @larsbertram1 I'll share the current version of my test project in a PM, in case you're interested in taking a look at this. :)
     

    Attached Files:

    Last edited: Apr 12, 2023
  16. larsbertram1

    larsbertram1

    Joined:
    Oct 7, 2008
    Posts:
    6,773
    yeah, it looks as if the stomps on the cells created according to the first camera. cells will be released if they are outside the cache distance. so it would need a double check and double ok, lets drop it from both invocations...

    otherwise cam1 queues a cell to be generated and cam2 might drop it before it has finished. or some other strange race conditions :)

    if you are happy with using the built in grass rendering during split screen: fine. just use the atg grass shader with the terrain grass rendering as well.
     
    andreiagmu likes this.
  17. andreiagmu

    andreiagmu

    Joined:
    Feb 20, 2014
    Posts:
    148
    I just discovered an optimization to my ATG split-screen logic. :D

    If I set CameraSelection to "Main Camera Only" instead of "All Cameras", this really boosts the performance during split-screen.
    I had to set this by code though, because for some reason, changing the "Cameras" enum from the GrassManager component isn't changing the internal CameraSelection variable, like it isn't being serialized correctly.

    I guess with "All Cameras", the grass was being rendered twice for each camera. Both cam1 and cam2 grass were rendered to both cameras.
    Using "Main Camera Only", each split-screen camera only renders its own grass. Before calling DrawGrass() for each camera, I set the Cam variable to the correct camera.

    I also added a Camera list "mainCameras" to my AtgDrawGrassSplitScreen.cs script, to avoid unneeded DrawGrass() calls in OnBeginCameraRendering(), from secondary cameras (e.g.: Scene Preview Camera).

    Code (CSharp):
    1. // AtgDrawGrassSplitScreen.cs
    2.  
    3. private void Start()
    4. {
    5.     _grassManager = FindObjectOfType<GrassManager>();
    6.     _grassManager.CameraSelection = GrassCameras.MainCameraOnly;
    7.  
    8.     RenderPipelineManager.beginCameraRendering -= OnBeginCameraRendering;
    9.     RenderPipelineManager.beginCameraRendering += OnBeginCameraRendering;
    10. }
    11.  
    12. private void OnBeginCameraRendering(ScriptableRenderContext context, Camera camera)
    13. {
    14.     if (!mainCameras.Contains(camera) || !_grassManager.enabled)
    15.         return;
    16.  
    17.     _grassManager.Cam = camera;
    18.     _grassManager.DrawGrass();
    19. }
    I'm still investigating the "shared cells" issue.
     
  18. andreiagmu

    andreiagmu

    Joined:
    Feb 20, 2014
    Posts:
    148
    One more test video of ATG and split-screen. :)

    The grass culling is almost working like I want. The main grass seems to be correctly instantiated while I move through the scene with both cameras.
    Sadly, there are many unwanted grass instances on the ground and in the air (weeds getting high :rolleyes:).

    Even so, the performance is really great, even with two cameras rendering all their grass (including the extra ones) while using some rather heavy rendering stuff (real-time shadows, SSAO).

     
  19. andreiagmu

    andreiagmu

    Joined:
    Feb 20, 2014
    Posts:
    148
    I did it!
    I managed to make ATG work with split-screen :D



    To achieve this result, first, I tried duplicating certain variables and code blocks from GrassManager.cs.
    So each camera would work on its own copy of these variables.

    numResults, resultIndices, isVisibleBoundingSpheres, numOfVisibleCells, CellsOrCellContentsToInit

    As a simple hardcoded test, I duplicated these variables and the code blocks that use them, so my second camera would have its data processed in numResults1, resultIndices1, isVisibleBoundingSpheres1, etc.
    This didn't solve my split-screen issues, but may have helped with the following step.

    Then, I tried duplicating the cullingGroup variable, so each camera would have its own culling group (cullingGroup for cam1, cullingGroup1 for cam2), instead of using a single culling group and alternating cullingGroup.targetCamera every frame (as I was doing before).

    After I did this, the grass was finally culled/rendered correctly in both cameras!
    Now, I just need to clean up the logic, and check if I still need any of the other variables that I had duplicated for my second camera.
     
    Last edited: Apr 14, 2023
  20. andreiagmu

    andreiagmu

    Joined:
    Feb 20, 2014
    Posts:
    148
    Yeah, creating the second CullingGroup for my second camera (and sharing again all those variables/arrays I tried to separate) did the trick for me!

    From the CullingGroup docs:
    https://docs.unity3d.com/Manual/CullingGroupAPI.html

     
  21. larsbertram1

    larsbertram1

    Joined:
    Oct 7, 2008
    Posts:
    6,773
    cool. looks like you are becoming more of an expert than me.
    great!
     
    andreiagmu likes this.
  22. andreiagmu

    andreiagmu

    Joined:
    Feb 20, 2014
    Posts:
    148
    Thank you very much for your tips and advice!
    They helped me to direct my implementation ideas. :)
     
  23. andreiagmu

    andreiagmu

    Joined:
    Feb 20, 2014
    Posts:
    148
    I want to report another potential performance optimization for projects using ATG :)

    In my previous video (ATG split-screen test 3), I got between 30~40 FPS at 720p.
    This is essentially the same FPS I get from testing vanilla (single-camera) ATG on a clean URP project.

    That's partly the fault of my old GPU. :D
    And also me purposefully using some heavy graphics stuff like SSAO and real-time shadows, default URP HighFidelity settings, etc.
    And in GrassManager, I also had a Cache Distance of 1000000, a leftover from previous tests, that was also making things heavier. :oops:

    I tried optimizing my URP settings, but that didn't make much difference. Except for lowering Render Scale, which brings a massive boost to FPS. But I wanted to keep this test on 1x scale.

    Then, I checked the project's Quality settings, and changing the Anisotropic Textures setting to anything that isn't Forced On really boosted the FPS!
    Anisotropic Textures at Forced On seems to be quite a heavy setting, and Unity sets it as the default. o_O

    After changing that setting (I set it to Per Texture), I got between 50~60 FPS at 720p with ATG grass rendering, depending on how many grass instances and grass shadows are being rendered.
    All while keeping those same "heavy" graphics processing stuff and my two split-screen cameras! :p
     

    Attached Files:

  24. Anima_Game

    Anima_Game

    Joined:
    Jan 29, 2021
    Posts:
    1
    Hello,
    Can I use It on unity 2022/2023? Is there a possibly for this implementation in the future?

    I have this error "shader error "undeclared identifier 'GetMeshRenderingLightLayer'"
     
    Last edited: Apr 24, 2023
  25. andreiagmu

    andreiagmu

    Joined:
    Feb 20, 2014
    Posts:
    148
    I haven't finished my ATG split-screen implementation yet. I'll resume it soon!

    Last week, I worked on a short demo of my NekoSuki! game project, using Advanced Terrain Grass along with other assets (mainly Platformer Project, for the gameplay). :)

    Game link: (PC, Android)
    https://andymiira.itch.io/nekosuki-frontiers

    Trailer video


    I used ATG's "Full Demo URP" map on this demo, to test its performance on builds (especially mobile), and with a very fast player character. I also did some fun tests with the grass displacement feature. :p

    The results are awesome, ATG contributed positively to the game's mood and visuals!
    I'm really glad I purchased ATG (and Lux URP Essentials), it's what I always wanted from Unity grass. :D

    For the next demo, I'll create an original map. I wanna try rendering other grass/vegetation assets with ATG!
     
  26. creat327

    creat327

    Joined:
    Mar 19, 2009
    Posts:
    1,688
    it looks nice, what grass did you use for this? is the video from the android version?
     
  27. Solidcomer

    Solidcomer

    Joined:
    Sep 12, 2017
    Posts:
    93
    I have a quick question, when using the Unity built-in terrain editor to paint the grass, the density of the grass is either very high or low, not even at all although I adjusted the Density and changes the brush. I know this is not an issue with ATG, but can you share some tips for that? Or, I'm wondering in order to achieve the similar distribution of grass as in the demo scene, shall I use a 3rd party terrain tool with a biome feature that could paint grass with some rules? Have you used any tools like that to create the demo? If so, which tool works with ATG in the easiest way?
     
  28. creat327

    creat327

    Joined:
    Mar 19, 2009
    Posts:
    1,688
    I have a question, what's the advantage of using Vegetation Studio with this asset? I see the demo video uses it. I thought that this asset was a replacement for Vegetation Studio. What is it doing that his one doesn't?
     
  29. Solidcomer

    Solidcomer

    Joined:
    Sep 12, 2017
    Posts:
    93
    Two screenshots, it's not properly configurated yet.
     

    Attached Files:

  30. abbasjafari

    abbasjafari

    Joined:
    Mar 7, 2020
    Posts:
    6
    Any idea why both ATG and Unity details are visible at same time? As you can see, the ferns have to version. A static and an ATG version.
    Screenshot 2023-05-07 195401.png