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.

Question Do you know how to access all 8 terrain layers from a shader graph?!

Discussion in 'General Graphics' started by Marou1, Mar 17, 2023.

  1. Marou1

    Marou1

    Joined:
    Dec 13, 2021
    Posts:
    130
    Hi,

    I am using a graph shader for the terrain. The texture _Control has in its channels the 4 painting masks of the 4 first layers.
    In TerrainLit_Splatmap.hlsl, there is this:
    #ifdef _TERRAIN_8_LAYERS
    DECLARE_TERRAIN_LAYER_TEXS(4);
    DECLARE_TERRAIN_LAYER_TEXS(5);
    DECLARE_TERRAIN_LAYER_TEXS(6);
    DECLARE_TERRAIN_LAYER_TEXS(7);
    TEXTURE2D(_Control1);
    #endif

    It seems that for the 4 last layers, it is _Control1 texture that is used. However, all the channels of this texture are white (where they should be black) and painting the terrain does not affect them. I see there is a condition on _TERRAIN_8_LAYERS, but I am not a programmer and have no idea what to do with it.

    Do you have any lead on this?

    Thanks!
     
  2. Marou1

    Marou1

    Joined:
    Dec 13, 2021
    Posts:
    130
    I really looked everywhere and couldn't find an answer.
    I mean, there must be someone who already made a shader graph for the terrain with 8 layers! :)
    I mean it seems really common!
     
  3. Marou1

    Marou1

    Joined:
    Dec 13, 2021
    Posts:
    130
    Up. Maybe a Unity Dev knows the answer?
     
  4. c0d3_m0nk3y

    c0d3_m0nk3y

    Joined:
    Oct 21, 2021
    Posts:
    384
    Don't know but defines like this can be set as shader keywords in the material (inspector debug view -> valid keywords). However, it is possible, that just setting the material keyword won't be enough. Just because the shader expects a texture it doesn't mean that the client will also pass it.
    You could also try setting it as a scripting symbol in the project settings.
     
  5. Marou1

    Marou1

    Joined:
    Dec 13, 2021
    Posts:
    130
    Haha you are Code Monkey, I didn't pay attention to your name when your answered in the other thread. I love your Youtube tutorials, they are lifesavers :)

    Ok, thanks. I'll check that. For the scripting part, I use Visual Scripting, so c# scripting is tedious for me, but I don't have a choice, so I'll check that too.
    I'm still surprized though, unity terrain shader is pretty limited, so I thought it was common to make terrain shader graphs... It seems not... And there is no documentation from Unity...
     
  6. c0d3_m0nk3y

    c0d3_m0nk3y

    Joined:
    Oct 21, 2021
    Posts:
    384
    Sorry, that's another guy.
     
  7. c0d3_m0nk3y

    c0d3_m0nk3y

    Joined:
    Oct 21, 2021
    Posts:
    384
    Actually, this only works if there is a corresponding #pragma shader_feature or #pragma multi_compile. Forgot to mention that.
     
  8. Marou1

    Marou1

    Joined:
    Dec 13, 2021
    Posts:
    130
    Really?! That's a funny coincidence :p
    So I checked the material based on unity shader that support 8 layers ad it it is not there:
    upload_2023-3-21_14-5-35.png

    I checked the saved properties, it is weird. For example, could find _TerrainHolesTexture that defines the terrain opacity, but I couldn't find _Control. Also all the textures have 5 versions:
    upload_2023-3-21_14-10-15.png

    Not 4 not 8...
    This is really frustrating, there is no documentation on this. And I have to do some 'reverse engineering', and it seems even programmers (which I am not) cannot figure it out?!
     
  9. Marou1

    Marou1

    Joined:
    Dec 13, 2021
    Posts:
    130
    I know someone out there knows the secret of 8 the layers!
    Where are you?!!!
     
  10. Marou1

    Marou1

    Joined:
    Dec 13, 2021
    Posts:
    130
  11. latachaudhary

    latachaudhary

    Joined:
    Mar 2, 2023
    Posts:
    5
    The terrain Layer holds textures and other properties that the Terrain’s Material uses to render the Terrain surfaces. Because Terrain Layers are Assets, you can easily reuse them on multiple Terrain tiles.
     
  12. JasonBooth

    JasonBooth

    Joined:
    Jan 27, 2014
    Posts:
    591
    Unity's shader doesn't draw 8 layers in a single pass, instead it draws the terrain multiple times to the screen, blending the results with the last pass- and is limited to 8 textures in HDRP because you can't blend PBR materials correctly with this technique.

    You can write a shader to do it all in one pass though, and unity even has a pragma you can set to stop it from rendering multiple passes of the terrain.
     
  13. Marou1

    Marou1

    Joined:
    Dec 13, 2021
    Posts:
    130
    Thanks for the answer but I don't understand how this helps me. I am not asking to use single or multiple passes, nor using more that 8 layers (if that's what you meant by textures, because you can use much more than 8 textures on the terrain).

    I already have a shader graph for the terrain, it is working but I am only able to control the 4 first layers using _Control texture.
    I see there is another texture called _Control1 to control the 4 last layers, but it is not working.
    There is some kind of condition in TerrainLit_Splatmap.hlsl:
    #ifdef _TERRAIN_8_LAYERS
    DECLARE_TERRAIN_LAYER_TEXS(4);
    DECLARE_TERRAIN_LAYER_TEXS(5);
    DECLARE_TERRAIN_LAYER_TEXS(6);
    DECLARE_TERRAIN_LAYER_TEXS(7);
    TEXTURE2D(_Control1);
    #endif
    My question is how to make it work.
    upload_2023-3-31_8-16-36.png
     
    Last edited: Mar 31, 2023
  14. JasonBooth

    JasonBooth

    Joined:
    Jan 27, 2014
    Posts:
    591
    Get out of a shader graph where you can actually see the code your writing? _Control1 is just passed to the material by the terrain when it has more than 4 textures, nothing special about it. The macro your referencing is just declaring diffuse/normal/mask textures for each terrain layer, and the define keyword is specific to their shader - either way _Control1 will be passed if there's more than 4 layers on the terrain.
     
  15. Marou1

    Marou1

    Joined:
    Dec 13, 2021
    Posts:
    130
    Because all developers are programmers and everybody writes code?
    The terrain has 8 layers:
    upload_2023-3-31_18-1-47.png

    The channels of the texture _Control are black by default. When painting the terrain, they change.
    The channels of the texture _Control1 are white. Painting on the terrain does not affect them. It means that _Control1 is not passed even though the terrain has 8 layers.
    It is very easy to test and you can see it is not working.
    If the next suggestion is to learn how to code, this is not part of my roadmap and the title of this thread clearly specifies "access from a shader graph".
     
  16. JasonBooth

    JasonBooth

    Joined:
    Jan 27, 2014
    Posts:
    591
    Works for me, and everyone else who uses my shaders, so not sure what your doing wrong. And if your going to get pissed at me for trying to help you, go debug it yourself.
     
  17. Marou1

    Marou1

    Joined:
    Dec 13, 2021
    Posts:
    130
    I'm not getting pissed at you, I'm just saying that suggesting to write a shader is not helping when I need to use a shader graph.
    Good for you. This is still not helping me but thanks for posting it anyway, it keeps the thread visible :p
     
  18. Marou1

    Marou1

    Joined:
    Dec 13, 2021
    Posts:
    130
    Up!
    We are almost at 500 viewers and none of us knows how to use a shader graph with unity terrain!
    Are Unity Devs among us? o_O
    :D
     
  19. Marou1

    Marou1

    Joined:
    Dec 13, 2021
    Posts:
    130
    Up...
     
  20. Marou1

    Marou1

    Joined:
    Dec 13, 2021
    Posts:
    130
    Still no one... :/
     
  21. burningmime

    burningmime

    Joined:
    Jan 25, 2014
    Posts:
    827
    Bumping this topic isn't going to get you anywhere. Jason Booth knows more about the terrain system than anyone outside Unity... and probably almost anyone inside Unity considering it's not being actively developed. If he can't help you, your next best bet is to buy a support contract with Unity themselves.

    But I think your final answer is going to be "you can't access it directly from shader graph". You could code parts of it and use a custom function node.
     
  22. Marou1

    Marou1

    Joined:
    Dec 13, 2021
    Posts:
    130
    Thanks for the answer. I was thinking if _Control can be accessed from a shader graph, _Control1 should too.
    If not, there must be a reason. I was hoping that someone would be able to confirm that this reason exists actually and explain what it is. And that would be a definitive "Not possible". However, for now I see that we don't know why actually _Control works and not _Control1.