Search Unity

Question Custom third-party terrain shader isn't producing accurate baked albedo - meta pass broken

Discussion in 'Shaders' started by Zergling103, Jun 6, 2022.

  1. Zergling103

    Zergling103

    Joined:
    Aug 16, 2011
    Posts:
    392
    Problem

    I downloaded a custom terrain shader from the asset store. It looks great in the normal rendered view.
    But when I try to bake lightmaps on this terrain, the albedo used for lightmap baking is completely wrong - the terrain appears gre
    en in most areas, but the albedo is an off-white. After baking, light probes are way too bright.

    Project Details

    Our project uses the built-in render pipeline. Our Unity version is 2021.3.4f1.

    Things I've Tried to Fix it
    • Adding a Meta pass to the shader used by the terrain. I added a custom meta pass - just to verify that it was working, I told it to output pure red as the albedo color. After telling it to rebake, the albedo remained an off-white. Unity appears to outright ignore custom meta passes, despite copying it from the documentation.
    • Changing the name of the main color texture
      _ColorTex
      to _MainTex.
      The terrain doesn't derive most of its color from the textures used in the splatmap. Instead, it uses a texture that encompasses the entire terrain that is then modulated with the splatmap textures. The splatmap textures themselves are fairly bright, so that when modulated, they look correct. I assumed that one of the fallback shaders or dependency shaders assumed that the albedo was derived from a texture called _MainTex. This had no effect.
    • Removed references to other shaders so that it'd use a custom Meta pass instead. As noted before, I used a custom meta pass. I figured Unity was ignoring it and using a shader in the dependencies instead for the meta pass. Removing these references simply caused the baked albedo to turn completely black (0,0,0), despite having a meta pass provided in the shader.
    • Changed the material to Standard, using the texture originally referenced by
      _ColorTex
      as the albedo map, baking, then switching the material back.
      If you don't use "Auto Generate" in the lighting settings, you can sneakily switch shaders to one that has well-behaved baked albedo, bake, then switch back. However, all non-terrain shaders - even ones provided by Unity like Standard - simply have black (0,0,0) albedo when used on terrain. Unity just outright ignores their meta passes!
    • Changed the material to the default Standard terrain shader provided by unity. However, the default terrain shader provides no option to modulate the terrain's albedo with an all-emcompassing albedo texture like
      _ColorTex
      .
      This caused the albedo to appear cream color because the textures used by the splatmap do not have their overall color baked into them, and instead depend on
      _ColorTex
      .
    • Changed the material to the default Standard terrain shader provided by unity, but then swapped the splatmap textures to ones that best approximated their appearance with the custom terrain shader, rebake the GI, then switch the shaders and textures back. This "works", but very very poorly. It allows me to have a very crude approximation of the correct albedo, but is far from ideal. It is also a pain in the ass to do this.
    This has been very painful to deal with and it still isn't anywhere where it should be.

    What do I need to do to make Unity cooperate here?

    If I were to suggest a change: If you provide a meta pass in your shader, Unity just uses it, no excuses - especially when you use a non-terrain shader in a terrain material. If terrain shaders need special handling for their meta passes (understandable since terrains can have multiple albedo textures via splatmapping), then clear documentation should be provided on how to provide terrain compatible meta passes (of which there is none).

    Anyway, thanks for the help. :)
     
    Last edited: Jun 7, 2022
  2. LazloBonin

    LazloBonin

    Joined:
    Mar 6, 2015
    Posts:
    813
    Hi! Did you ever figure this out?
     
  3. Invertex

    Invertex

    Joined:
    Nov 7, 2013
    Posts:
    1,550
    The meta pass should just work.
    If it's a surface shader though, I believe a certain #pragma is needed. And for the new render pipelines the meta pass might have some different syntax.
     
  4. LazloBonin

    LazloBonin

    Joined:
    Mar 6, 2015
    Posts:
    813
    It sure should, except it doesn't, and that's the point of the thread.

    I'm using a simple barebones vert/frag shader with a meta pass in BIRP and I can't get a any solid albedo to render on the terrain. With the same meta pass, I'm able to get it working on normal renderers.
     
  5. Zergling103

    Zergling103

    Joined:
    Aug 16, 2011
    Posts:
    392
    I figure the best way to figure out what is going on here is to clone the standard terrain shaders provided by Unity, and then modify their meta passes - say, make it output red. If you see red after baking, success!

    Then, if you can't figure out why THAT cloned shader works and your original shader doesn't, you can modify the clone bit-by-bit to match your original shader.

    It seems to be the case that Unity's GI is sensitive to the contents of a terrain shader and thus its dependencies in other shaders/cgincludes. Otherwise, I wouldn't be able to force the terrain shaders to have black baked albedo by commenting out those dependency references.
     
    Beauque likes this.
  6. LazloBonin

    LazloBonin

    Joined:
    Mar 6, 2015
    Posts:
    813
    Have you tried that?
    I'm just digging in now and the shaders are now surface and cross-referenced, it's a mess to sort through them.
     
  7. Zergling103

    Zergling103

    Joined:
    Aug 16, 2011
    Posts:
    392
    No, that is a fairly non-trivial undertaking and I have been busy with higher priority work.