Search Unity

Shadow too dark in custom deferred shader

Discussion in 'Shaders' started by kulesz, Jan 25, 2018.

  1. kulesz

    kulesz

    Joined:
    Jul 1, 2012
    Posts:
    140
    Hi Folks,

    I've got a problem with a grass shader I wrote (for deferred rendering).
    Shadows that fall on the grass quad seem to tint it too dark - as you can see in the screenshot below.
    Grass is much darker than shadows that fall on it.
    I've tried to mess with the quad normal directions (pointing up, perpendicular to quad etc.), but the effect is the same.
    Here's the fragment shader code:

    Code (CSharp):
    1. void fragGrass(Vert2Frag IN, out half4 outDiffuse : SV_Target0, out half4 outSpecular : SV_Target1, out half4 outNormal : SV_Target2, out half4 outEmission : SV_Target3)
    2. {
    3.     float4 color = tex2D(_GrassTex, IN.uv);
    4.     clip(color.a - _AlphaCutoff);
    5.     color.a = 0;
    6.  
    7.     outDiffuse = color;
    8.     outSpecular = float4(0, 0, 0, 0.05);
    9.     outNormal = float4(UnityObjectToWorldNormal(IN.norm) * 0.5 + 0.5, 1);
    10.  
    11.     outEmission = 0.015 * color;
    12. }


    Did anyone could give me some help?
    Thanks :)
     
  2. Invertex

    Invertex

    Joined:
    Nov 7, 2013
    Posts:
    1,550
    Because the stuff being rendered with surface shaders is being affected by ambient light, but your grass shader isn't since it's not a surface shader and thus doesn't have the ambient calculation built in.

    https://docs.unity3d.com/Manual/SL-UnityShaderVariables.html

    Use the built-in ambient light variables from this page to adjust it.
     
  3. kulesz

    kulesz

    Joined:
    Jul 1, 2012
    Posts:
    140
    Should _LightColor just do it?
    Seems that adding it to color makes everything almost white.
     
  4. Invertex

    Invertex

    Joined:
    Nov 7, 2013
    Posts:
    1,550
    No, I said ambient not the light :p You can use the ambient texture values listed on that page to do it in a very hacky way, or, you can do what it properly by utilizing the ShaderSH9 function it mentions on that page, which you have to look into the UnityCG.cginc file that's in your Unity install folder to see how it's defined, there's a few different functions in there that can be used, but the main one is that one.

    Code (CSharp):
    1. float3 ambientColor = ShadeSH9(IN.norm);
    Really though, I think you should just make this a Surface shader instead so that you can make use of the many different variants and features Unity will generate for your code, because there are different ambient sampling methods depending on the model/material setup, and Unity handles all those conditions for you.
     
  5. kulesz

    kulesz

    Joined:
    Jul 1, 2012
    Posts:
    140
    But this is used with custom tesselation and geometry shader, so surface shader is not supported.
    I'll check the ShadeSH9 one, thank you :)
     
  6. kulesz

    kulesz

    Joined:
    Jul 1, 2012
    Posts:
    140
    Seems that it does not work.
    Doing:
    Code (CSharp):
    1.    
    2. float3 ambientColor = ShadeSH9(half4(UnityObjectToWorldNormal(IN.norm), 1));
    3. finalColor.rgb += ambientColor;
    4.  
    Makes grass much brighter (too much), but the ones covered by shadow are still dark.