Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice

2019.2: Overriding shaders of Terrain-Grass

Discussion in 'Shaders' started by Selupsis, Aug 9, 2019.

  1. ijidau

    ijidau

    Joined:
    Nov 5, 2015
    Posts:
    2
    @VitaSkr as @zackblack has mentioned, the ability to override or replace terrain shaders of all types is sorely needed. This is an engine failure if not addressed. Please pass on to the team how important this is.
     
  2. Alexsandro-Natsume

    Alexsandro-Natsume

    Joined:
    Apr 20, 2015
    Posts:
    24
    almost one year with this problem and nothing ... modifying UniversalRenderPipelineEditorResources worked for a while but the new URP update made impossible to modify it ...

    the source UniversalRenderPipelineAsset.cs is loading it directly from the GUID
    public static readonly string packagePath = "Packages/com.unity.render-pipelines.universal";
    public static readonly string editorResourcesGUID = "a3d8d823eedde654bb4c11a1cfaf1abb";
     
  3. PancakeTAS

    PancakeTAS

    Joined:
    Jul 2, 2020
    Posts:
    6
    You can copy the package urp from the Library/PackageCache to Packages and then copy the Shader into the Shaders folder.

    Everytime i replace the shader the grass disappears... Can someone send me his billboard shader to see if that works?
     
  4. lyrapuff

    lyrapuff

    Joined:
    Oct 23, 2019
    Posts:
    7
    Okay, I've found a working way to do it, it's a terrible workaround, but it works.
    Find the original grass shader
    Open it's .meta file
    Copy the guid
    Open custom shader's .meta file
    Paste the guid
    Now unity will use your shader.
     
  5. PancakeTAS

    PancakeTAS

    Joined:
    Jul 2, 2020
    Posts:
    6
    That doesn't work for me, the grass still completely disappears..
    I just want billboarded grass please why is this not included.
     
  6. lyrapuff

    lyrapuff

    Joined:
    Oct 23, 2019
    Posts:
    7
    There's another workaround I found. Just write your shader code right into default shader's file.
     
  7. PancakeTAS

    PancakeTAS

    Joined:
    Jul 2, 2020
    Posts:
    6
    Well... That doesn't work either, the grass shows up but only because the shader is getting overwritten back on start of Unity
     
  8. Alexsandro-Natsume

    Alexsandro-Natsume

    Joined:
    Apr 20, 2015
    Posts:
    24
    just give up , unity is too busy trying to become unreal engine to give a S**** about terrain shaders .
     
  9. lyrapuff

    lyrapuff

    Joined:
    Oct 23, 2019
    Posts:
    7
    Anyone from Unity?... please
     
  10. adamgryu

    adamgryu

    Joined:
    Mar 1, 2014
    Posts:
    186
    Is there still no way to change the grass shaders in the built-in pipeline?
     
  11. rekindledphoenix

    rekindledphoenix

    Joined:
    Dec 6, 2017
    Posts:
    3
    Bump for anyone at @Unity to reply. What's the Unity-expected work-around for known issues with grass shaders in HDRP for 2019.4.11+?

    I added an override to a new HDRPPipelineEditorResource file under Shaders > Terrain Detail Grass > [Custom ShaderGraph] but it won't honor the `_Cutoff` value and completely ignores the `alpha` used within the `_MainTex`; even though they are defined within the new shader.
     
    Last edited: Dec 1, 2020
  12. Bordeaux_Fox

    Bordeaux_Fox

    Joined:
    Nov 14, 2018
    Posts:
    589
    Interesting, how does this work?
    I assigned an own HDRenderPipelineEditorRessources asset and have overridden the Detail shaders. But it does not have any affect. My Detail meshes render completely white. I tried with HDRP 10.2.0. The HDRenderPipelineEditorRessource seems to be completely useless and a cosmetic thing. Not sure how it works internally, but I assume they just ignore any overrides. If not so, please point me on the right directions.

    And if you look closely, you see when overriding the detail shaders and than save your session, the detail meshes will turn black for a brief moment until they reverted. So looks to me like they really block any attempt to override it.
     
    Last edited: Dec 7, 2020
  13. wechat_os_Qy09oQj46wCoXNKXVCJThpiEg

    wechat_os_Qy09oQj46wCoXNKXVCJThpiEg

    Joined:
    Jan 11, 2021
    Posts:
    3
    bump
     
  14. Bordeaux_Fox

    Bordeaux_Fox

    Joined:
    Nov 14, 2018
    Posts:
    589
    You can still not override it with the EditorRessourceAsset. I tried with HDRP and 2020.1.
     
  15. TerraUnity

    TerraUnity

    Joined:
    Aug 3, 2012
    Posts:
    1,249
    IMO, best bet right now is to use GPU Instancing for grass and other dense vegetation rendering.
     
  16. Alexsandro-Natsume

    Alexsandro-Natsume

    Joined:
    Apr 20, 2015
    Posts:
    24
    i just gave up
     
  17. wechat_os_Qy09oQj46wCoXNKXVCJThpiEg

    wechat_os_Qy09oQj46wCoXNKXVCJThpiEg

    Joined:
    Jan 11, 2021
    Posts:
    3
    i modified the manifest.json,use my own git.
    problem solved.
     
  18. lyrapuff

    lyrapuff

    Joined:
    Oct 23, 2019
    Posts:
    7
    That's just so frustrating and mentally painful, even, in some sense that Unity forces you to involve such horrible workarounds to make games, I really hope that it's CEO will change his mind. He may be good at making money and attracting investors, but for me as a small, ambitious gamedev it just feels like a betrayal.
     
  19. Nefron

    Nefron

    Joined:
    Jun 21, 2013
    Posts:
    6
    Bump! All I want is a little custom terrain grass shader.
     
  20. AvrgJoe

    AvrgJoe

    Joined:
    Oct 9, 2017
    Posts:
    2
    If people are still having this issue, I managed to get it working (using an overrided) with a custom shader by adding it to the always include shaders, and then setting the parameters using Shader.SetGlobal...

    Im using 2020.1.0f1 as well :D
    Hope that helps!
     
  21. morepixels

    morepixels

    Joined:
    May 21, 2014
    Posts:
    18
    Can you please explain how to do it in more detail? Which shader are you copying?
     
  22. AvrgJoe

    AvrgJoe

    Joined:
    Oct 9, 2017
    Posts:
    2
  23. Edwige

    Edwige

    Joined:
    Nov 25, 2010
    Posts:
    35
    Hi @bgolus and @Tristan-Moore! I'm on URP and I'm still stuck with the same issue. Can't find a resource file where I could put my custom details shaders... Help would be greatly appreciated :)
     
  24. Edwige

    Edwige

    Joined:
    Nov 25, 2010
    Posts:
    35
    So I finally found a solution (with help ^^) for URP + 2019.4.13
    It is way faster than changing the whole detailprototypes of a terrain

    1/ Outside of Unity, go to the URP package of your project to get URP resource : C:\xx\Library\PackageCache\com.unity.render-pipelines.universal@7.3.1\Runtime\Data (replace C:\xx with your project location)
    then copy “UniversalRenderPipelineEditorResources.asset” in your Asset folder (it has to keep the same name!!!)

    2/ Still outside of Unity, go get the URP grass shader and its includes, and bring a copy of it to your asset folder:
    C:\xx\Library\PackageCache\com.unity.render-pipelines.universal@7.3.1\Shaders\Terrain
    WavingGrass.shader
    WavingGrassInput.hlsl

    3/ In the shader, change its name to tell it apart (I just removed the Hidden/ at the beginning)
    Then change the target of the includes of WavingGrassInput.hlsl (twice in the file) so it points toward your WavingGrassInput.hlsl

    4/ In the scriptable object UniversalRenderPipelineEditorResources, put the new shader in the appropriate field (see screenshot below)
    screenResources.png

    5/ In WavingGrassInput.hlsl, after CBUFFER_START(UnityPerMaterial), add:
    Code (hlsl):
    1. float4 _MyCustomGrassColor;
    and at the end of the TerrainWaveGrass, change to :
    Code (hlsl):
    1. color = _MyCustomGrassColor;
    2. color.a = saturate(2 * (_WaveAndDistance.w - dot(offset, offset)) * _CameraPosition.w);
    3. return half4(2 * waveColor * color.rgb, color.a);
    (any operation would work, you can add or multiply your color if you prefer)

    6/ Create a C# script and put it in the scene with :
    Code (Csharp):
    1.  Shader.SetGlobalColor("_MyCustomGrassColor", targetColorHealthy);
    I still don't understand why the variables of the terrain detail prototypes are not accessible easily in script, or whether it is undocumented and so hard to do to change the resources, but for me it did the trick, at least partially! Hope it helps someone as well :)
     
    Last edited: Feb 22, 2021
  25. florianalexandru05

    florianalexandru05

    Joined:
    Mar 31, 2014
    Posts:
    1,803
    I tried what you said in Unity 2020 but whatever I do I can't edit the shade. :confused: It worked so well for standard RP thou... I guess it only works for 2019. It's time to write some sort of grass shader for SRP. :(
     
  26. Edwige

    Edwige

    Joined:
    Nov 25, 2010
    Posts:
    35
    So if you copy the shader in your asset folder, you cannot edit it? What version of 2020 do you have? I can try it as well.
     
  27. florianalexandru05

    florianalexandru05

    Joined:
    Mar 31, 2014
    Posts:
    1,803
    Unity 2020.1.3f1. I have a completely redone shader, it works in standard but not in URP. I'll try editing the shader with a simple edit, maybe my shader just doesn't work. I can send you the shader over if you want.
     
  28. Alexsandro-Natsume

    Alexsandro-Natsume

    Joined:
    Apr 20, 2015
    Posts:
    24
    you cant use this with the new URP , its not a Unity Version problem , its the URP source thats is loading the shader directly from the GUID

    from the UniversalRenderPipelineAsset.cs code
    public static readonly string packagePath = "Packages/com.unity.render-pipelines.universal";
    public static readonly string editorResourcesGUID = "a3d8d823eedde654bb4c11a1cfaf1abb";

    so i just gave up lol
     
    florianalexandru05 likes this.
  29. michael-y

    michael-y

    Joined:
    Apr 9, 2013
    Posts:
    18
    Here's a solution which being tested on 2019.4.19f1 , macOS Catalina

    The magic is the package cache folder :
    /Users/{UserName}/Library/Unity/cache/packages/packages.unity.com/com.unity.render-pipelines.universal@7.5.3/Runtime/Data/

    . You mades changes to the package cache folder , for example,

    Editing UniversalRenderPipelineAsset.cs :

    public static readonly string editorResourcesGUID = "d49f4ce0d1cb44223acf23bcf4e9fc8e"; //"a3d8d823eedde654bb4c11a1cfaf1abb";


    Then restart unity, now you get your shader overwrites. Same happens for windows version
     
  30. adamgryu

    adamgryu

    Joined:
    Mar 1, 2014
    Posts:
    186
    I haven't been able to get any of the above techniques to work for me yet. (Editing code in the URP Package itself isn't stable and keeps resetting anyway.)

    What is the recommended way to replace the terrain detail shader in Unity 2020.2 with URP 10.2.2? It would be really nice to simply have a material slot on the terrain inspector for this.
     
    Last edited: Mar 11, 2021
  31. florianalexandru05

    florianalexandru05

    Joined:
    Mar 31, 2014
    Posts:
    1,803
    Code something yourself like The vegetation engine or give up, I give up! lol
     
    Alexsandro-Natsume likes this.
  32. StaggartCreations

    StaggartCreations

    Joined:
    Feb 18, 2015
    Posts:
    2,254
    This is honestly pretty ridiculous at this point. I think the idea on Unity's side is to wait on the new "environment system", which may provide the means for grass rendering, outside of the black box terrain system. Though the last word on this was back in August and reiterated "it's coming". But specifying the terrain grass shader seems like such low hanging fruit! It would work, with limitations, but we're stubbornly being locked out. Instead we'd be forced to upgrade to 2021.3 or 2022 when an alternative lands, and it would be in preview for 2-3 years :rolleyes:

    Vegetation is really one of Unity's weakest points. The fact that Unity's own tech demos use a workaround (BotD), or implement a custom terrain/grass system (Adam environment) highlights this.

    If it's important to anyone, I'd recommend to pick up Nature Renderer, you'll be able to use any kind of grass prefab and its custom shader. Technically speaking, it does exactly what Unity should have done a long time ago. I can't quite fathom the reason, but any terrain feature seems to literally take years before they're released. Asset store developers nocks these things out in 2-6 weeks.
     
    noio, sirleto and hippocoder like this.
  33. adamgryu

    adamgryu

    Joined:
    Mar 1, 2014
    Posts:
    186
    Yes, it really does feel like a low hanging fruit. Perhaps there's some technical reason why it's difficult, but it really doesn't feel that way.

    I could roll out my own solution, or I could try using the "Tree" tool to place grass prefabs. It just feels so close to being useful, it's such a shame we can't use the default terrain grass tool. I feel like there are so many cases where the default grass shader isn't suitable for a project, I really wish we could change it!
     
  34. adamgryu

    adamgryu

    Joined:
    Mar 1, 2014
    Posts:
    186
    I figured out how to replace the terrain detail shader in the URP, without editing the package code directly! Of course, it's still a bit of a hack, but this worked for me:

    1. Extend the URP asset and override the detail billboard shader:
    Code (CSharp):
    1. [CreateAssetMenu]
    2. public class CustomURP : UniversalRenderPipelineAsset {
    3.  
    4.     public Shader myShader;
    5.  
    6.     public override Shader terrainDetailGrassBillboardShader => myShader;
    7. }
    8.  
    2. Create the custom URP scriptable object, assign the
    myShader
    field to your desired shader.
    3. Hook up the custom URP asset into the Graphics window and the Quality Settings window.
    4. Restart Unity.

    I only just got this working, so hopefully there are no weird side effects!

    You might also want to create an editor script for the new URP asset and copy over your existing quality settings to the new pipeline assets. (I did this by opening up the existing pipeline asset YAML and changing the script ID to the new one.)
     
    Last edited: May 17, 2021
  35. Ferdi7

    Ferdi7

    Joined:
    Mar 12, 2013
    Posts:
    9
    This whole situation is ridiculous. Allowing us to simply change the grass shader is such a basic option that should be there but isn't.

    I tried your solution @adamgryu but somehow it seems to default back to the standard shader anyways. The shader I used is a copy of the standard Unity WavingGrassBillboard.shader. Changing the values however does nothing, even deleting the whole code doesn't even give an error, it just keeps shoving that ugly standard Unity waving grass in my face. I have billboard checked in the paint details grass texture, I even added another override for the terrainDetailGrassShader, tested it with billboard unchecked, but it also shows the default shader. This was on versions 2020.2 btw.

    What do you mean by this? And is the YAML step needed? If so then that's probably why it isn't working on my side.
     
    Vincent454 likes this.
  36. adamgryu

    adamgryu

    Joined:
    Mar 1, 2014
    Posts:
    186
    @Ferdi7 Hmm, are you certain that your custom pipeline is being used? If you change some other setting on your custom pipeline asset (like shadow settings or something) are those changes reflected?

    And by editor, I mean that your custom pipeline asset will have the default inspector editor, which isn't ideal. And the YAML step is optional.
     
  37. Arkounay

    Arkounay

    Joined:
    Mar 16, 2018
    Posts:
    1
    Thanks @adamgryu this seems to be working. The key was to restart unity to see the changes =)

    I've also tested if it works when the game is built, both on desktop and mobile and it did

    For those like me who aren't well-versed in unity, the YAML is actually the .asset file.
    When you extend the UniversalRenderPipelineAsset, it will look bad in unity inspector that's why it was suggested to just copy the existing yaml file into the newly created CustomURP file. I wonder if there is a way to have a normal appearance for it ?
    I'm glad this works. Tried so many things and nothing worked at all until now, I was seriously considering having to rewrite a grass system on my own, that would have been horrible =) I wish this field was just public in the default pipeline asset
     
    adamgryu likes this.
  38. Ferdi7

    Ferdi7

    Joined:
    Mar 12, 2013
    Posts:
    9
    Late reply, because I am in the middle of moving houses. Just want to confirm that I found out what went wrong. In step 3 of @adamgryu's solution it says:
    I hadn't changed the quality settings, only the graphics settings, which is why the custom pipeline asset wasn't being used. So the "and/or" should be just "and", at least in my case.
    Thanks @adamgryu!
     
    adamgryu likes this.
  39. adamgryu

    adamgryu

    Joined:
    Mar 1, 2014
    Posts:
    186
    Just to save people some time, here's an editor script that makes the new CustomURP asset use the default URP inspector.

    CustomURP.cs
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.Rendering.Universal;
    5.  
    6. [CreateAssetMenu(menuName = "Rendering/Universal Render Pipeline/Custom URP (Pipeline Asset)")]
    7. public class CustomURP : UniversalRenderPipelineAsset {
    8.  
    9.     public Shader detailGrassBillboardShader;
    10.  
    11.     public override Shader terrainDetailGrassBillboardShader => detailGrassBillboardShader;
    12. }
    13.  
    CustomURPEditor.cs
    Code (CSharp):
    1. using UnityEditor;
    2. using UnityEditor.Rendering.Universal;
    3.  
    4. [CustomEditor(typeof(CustomURP), true)]
    5. public class CustomURPEditor : Editor {
    6.     private Editor originalEditor;
    7.  
    8.     public override void OnInspectorGUI() {
    9.  
    10.         EditorGUILayout.LabelField("Custom URP Properties", EditorStyles.boldLabel);
    11.         EditorGUILayout.PropertyField(serializedObject.FindProperty(nameof(CustomURP.detailGrassBillboardShader)));
    12.         EditorGUILayout.Space();
    13.  
    14.         if (originalEditor == null) {
    15.             originalEditor = Editor.CreateEditor(target, typeof(UniversalRenderPipelineAssetEditor));
    16.         }
    17.         originalEditor.OnInspectorGUI();
    18.         serializedObject.ApplyModifiedProperties();
    19.     }
    20. }
     
    Last edited: Jun 21, 2021
  40. pimpekdev

    pimpekdev

    Joined:
    Feb 18, 2020
    Posts:
    4
    Your solution does not work, when i assign shader, it magically disappear when i close inspector tab. I am using UWP@10.5.0 and unity 2020.3.11f1
     
  41. adamgryu

    adamgryu

    Joined:
    Mar 1, 2014
    Posts:
    186
    Ah, maybe I forgot to put in a
    serializedObject.ApplyModifiedProperties();
    at the end.
    I'll test it later to see if that's the problem.

    EDIT: That was the problem. Hope that helps!
     
    Last edited: Jun 21, 2021
  42. CogumeloSoft

    CogumeloSoft

    Joined:
    Dec 28, 2012
    Posts:
    88
    This hole situation is absurd. I'm just stocked with this ugly grass shader or need to purchase a third party solution.
     
    Vincent454 likes this.
  43. Ferdi7

    Ferdi7

    Joined:
    Mar 12, 2013
    Posts:
    9
    lilacsky824 likes this.
  44. Claytonious

    Claytonious

    Joined:
    Feb 16, 2009
    Posts:
    902
    Thanks, @adamgryu - both for the approach and for the script to make the inspector sane - so helpful! Works in 2021.1.15f1.
     
    adamgryu likes this.
  45. Zante

    Zante

    Joined:
    Mar 29, 2008
    Posts:
    429
    Simple question, how can I modify the terrain grass shader to support fade/soft alpha with the built-in renderer?

    Is this not possible anymore?
     
    sirleto likes this.
  46. MMeyers23

    MMeyers23

    Joined:
    Dec 29, 2019
    Posts:
    101
    ^^ I second this question. Also, after implementing @adamgryu method of replacing shader, how can we then edit the material? Is this possible, or do we need to set the shaders default values to the desired settings and never edit?
     
    sirleto likes this.
  47. Ferdi7

    Ferdi7

    Joined:
    Mar 12, 2013
    Posts:
    9
    If anyone finds these solutions too hacky/complex, I suggest using Nature Renderer's free trial. It has a feature to replace the grass shader with a custom shader (Shader Graphs included). You can use the trial indefinitely until you find another solution or you can simply buy it before releasing.
     
  48. reedreedchen

    reedreedchen

    Joined:
    Feb 12, 2017
    Posts:
    11
    Edit: thanks I just restarted unity, and it overrides fine.

    Is there a way to change grass shader for built-in pipeline? any update? thanks
     
  49. florianalexandru05

    florianalexandru05

    Joined:
    Mar 31, 2014
    Posts:
    1,803
    There is a very easy way to override this shader in Built-in. See ref link: https://forum.unity.com/threads/2019-2-overriding-shaders-of-terrain-grass.725294/
    Also if you want I can share my edited grass shader. All you need to do is have a shader named "WavingDoublePass" with the shader path "Hidden/TerrainEngine/Details/WavingDoublePass" in your project folder.
     
  50. florianalexandru05

    florianalexandru05

    Joined:
    Mar 31, 2014
    Posts:
    1,803
    Here it is, It's still not very good, there are issues and the code is messy. I made it in amplify shader then hardcoded a few things in because that was the only way. If anyone wants to help improve this shader feel free to do so.
     

    Attached Files: