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.
  2. Dismiss Notice

Terrain shader surface shader

Discussion in 'Shaders' started by khlorghaal, Jan 20, 2019.

  1. khlorghaal

    khlorghaal

    Joined:
    Nov 15, 2018
    Posts:
    9
    mirror of https://answers.unity.com/questions/1592635/terrain-surfaceshader-or-terrain-shader-supporting.html

    I'm having trouble figuring out how to get a surface shader with access to the splatmaps and supporting multiple lights. Does anyone know of relevant documentation or examples?

    The only examples I've seen so far require:
    -My current situation of not using a surface shader, manually copypasting from the terraincommon include, and only supporting 1 light
    -Manually making a whole separate pass for ForwardAdd, which due to the length of my shader is quite prohibitive, since afaik it would require copypasting my light and noise functions, doubling the length of the shader, and making it horrible to maintain.

    I would like a way to either:
    -Access multiple pixel-light uniforms within a single pass. Since the cost of my lighting functions is minor compared to the noise calculations I'm doing.
    -Access terrain splatmap values from a surface shader, since that takes care of all the hassle of multiple lights/passes.

    Heres the source if it helps, my failed attempt at getting a surfaceshader, but this is more of a general issue. https://gist.github.com/khlorghaal/e4d3aaa1d07232d3f67f2e938edd4ec7
     
    Last edited: Jan 21, 2019
  2. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    5,445
    You can pack up the light uniforms yourself and set them on your shader, or access the splat weights as _Control0, _Control1, etc..

    Or you could just write a MicroSplat module to add your functionality to it's system and skip the rest.
     
  3. khlorghaal

    khlorghaal

    Joined:
    Nov 15, 2018
    Posts:
    9
    Whats the code I would use to access these from a surface shader? Are they builtin vertex inputs?
    Or more importantly where did you learn about their existence? I've not found a good complete reference for all the shader builtins in a single location.
     
    Last edited: Jan 22, 2019
  4. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    5,445
    Unity doesn’t document shaders really. You can download the built in shader source. They aren’t stored in the vertices, but are rather textures passed in (one for every 4 textures used on the terrain)
     
  5. khlorghaal

    khlorghaal

    Joined:
    Nov 15, 2018
    Posts:
    9
    Trudging through the builtins -... theres 0-3 comments per file, everything has dependencies. Since the dependencies are by tag and not directory/filename, their locations aren't apparent. With all the different fallbacks and passes, I have no idea what is actually the modern standard shaders vs what is legacy.
    I've tried copypasting the builtins into a custom shader to see what's what, and theres lots of z-fighting and things that in general don't make sense. Some of them don't even compile?!?

    All the standard nightmares of development.
    My assessment is that despite their existence, from a view of being practical to implement with the same ease as other features, unity in a sense doesn't support custom terrain shaders.
     
    Last edited: Jan 24, 2019
  6. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    5,445
    The standard shader is a giant mess; macros that expect explicitly named variables to exist in scope but aren’t passed into the macro, etc. it’s basically a giant pile of Macro Foo that’s way harder to parse than it needs to be.

    This is why surface shaders are nice; they abstract lighting and pass semantics from you, but still let you write very complex shaders they wouldn’t be practical in a graph. MicroSplat is entirely done in a surface shader, and it’s the most advanced terrain shader system currently on the store. But this abstraction has been removed in SRP, with the only way to write shaders which are compatible across pipelines being to write them in their shader graph. Any code based shader must inherit the full complexity of the pipeline, as well as managing all changes to that pipeline over time. To me this is a massive loss to Unity, and combined with their near refusal to document their shader system, make it impractical for many uses it excelled in previously.
     
  7. jbooth

    jbooth

    Joined:
    Jan 6, 2014
    Posts:
    5,445
    And if you want to write custom terrain shaders in a surface shader, I suggest looking at MicroSplats output; it writes a shader with very few macros or dependencies. It’s also a modular system which is easy to extend with custom features.
     
  8. khlorghaal

    khlorghaal

    Joined:
    Nov 15, 2018
    Posts:
    9
    Finally found some good information, https://forum.unity.com/threads/shaderlab-dependency-property.215130/#post-1444388

     
  9. khlorghaal

    khlorghaal

    Joined:
    Nov 15, 2018
    Posts:
    9
    Okay I've decided that the best thing to do is use tag lightmode = forwardbase for my existing shader, and UsePass with a builtin additive shader. The trouble is, I'm getting silent errors. So purple geometry with 0 error output.
    I'm driving blindfolded on ice here. This error occurs on some shaders and not on others, yet I have no idea what is causing it. I'm certain they are the right shader names, as it does give an error if the shader doesn't exist. I'm guessing this is because external shaders somewhy aren't parsed for errors.
     
  10. khlorghaal

    khlorghaal

    Joined:
    Nov 15, 2018
    Posts:
    9
    ARGH the header I was hacking onto has been changed in an update. Now I have potentially hours of refactoring.
    A surface shader would completely have avoided this.