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. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Custom surface shader only receives indirect lighting... why?

Discussion in 'Shaders' started by invicticide, Sep 25, 2018.

  1. invicticide

    invicticide

    Joined:
    Nov 15, 2009
    Posts:
    109
    If I create a custom surface shader and change the RenderType and the Queue to "Transparent" and add a "#pragma alpha:fade", I can fade an object in and out like I would expect, but the object seems to only receive baked lighting, and completely ignores realtime lighting.

    If I leave the custom surface shader set to Opaque then it picks up the realtime lighting just fine.

    Is there some other setting or pragma I need to do to make a custom surface shader with transparency pick up realtime lighting?

    I really only care about the lighting here, NOT realtime shadows. The problem is my object is much darker than the surrounding (opaque) objects because it's only showing up with baked indirect lighting and completely ignoring the realtime direct lighting that's illuminating everything else.
     
  2. invicticide

    invicticide

    Joined:
    Nov 15, 2009
    Posts:
    109
    After much digging around, I found a resolution to this.

    I had to implement a custom lighting/GI model and manually apply the direct lighting. That involves a few steps. First, declare the new model:

    Code (CSharp):
    1. #pragma surface surf StandardDefaultGI fullforwardshadows alpha:fade
    2.  
    3. #include "UnityPBSLighting.cginc"
    The "StandardDefaultGI" bit is our new model declaration, and the #include brings in some necessary functionality we'll use in the model implementation, which is like this:

    Code (CSharp):
    1. inline half4 LightingStandardDefaultGI(SurfaceOutputStandard s, half3 viewDir, UnityGI gi)
    2. {
    3.   return LightingStandard(s, viewDir, gi);
    4. }
    5.  
    6. inline void LightingStandardDefaultGI_GI(SurfaceOutputStandard s, UnityGIInput data, inout UnityGI gi)
    7. {
    8.   LightingStandard_GI(s, data, gi);
    9.   gi.light.color = data.light.color; // This is where the magic happens!
    10. }
    It's not clear to me *why* I had to manually add the direct lighting like this, but this seems to have resolved the issue.