Search Unity

Question Changing received shadow color

Discussion in 'Shader Graph' started by alanmthomas, Oct 21, 2019.

  1. alanmthomas

    alanmthomas

    Joined:
    Sep 7, 2015
    Posts:
    197
    I'm working on a shader and have reached a stumbling point. I'd like to be able to set the color of the shadow that an object receives. Is this possible? Any pointers?
     
  2. larsbertram1

    larsbertram1

    Joined:
    Oct 7, 2008
    Posts:
    6,902
    hdrp or lwrp/urp? latter would be easy by writing a custom lighting function which splits attenuation into distance atten and shadow atten. then you take the shadow atten and lerp/multipy the lit result with your shadow color.
     
  3. alanmthomas

    alanmthomas

    Joined:
    Sep 7, 2015
    Posts:
    197
    I'm using Lwrp/urp. I have no idea how to write that function but I'll look into it. For now, I'm setting the ambient light color in the scene, but that isn't really the effect I'm going for.
     
  4. alanmthomas

    alanmthomas

    Joined:
    Sep 7, 2015
    Posts:
    197
    I was able to get all of this working. Thanks for the help. I was basically trying to create a shader that would meet the following requirements:
    • Toon shading
    • Casts and receives shadows with shadow colors being variable
    • based color variable based on camera distance
    • shadows and shading variable based on camera distance
    I was able to get everything working. My last step is to add in rim lighting, also having intensity based on camera distance.
     
  5. whoisj

    whoisj

    Joined:
    Jan 4, 2018
    Posts:
    26
    I'll add an answer here because this thread comes up in search queries, but there's no usable answer here.

    As best I know, there really isn't a way to change the color of "cast shadows" because the color is generally "received". This means the shader coloring a model has to do the work to multiply a color value instead of just 0 (aka black).

    The Custom Lighting in Shader Graph blog has a nice step-by-step solution on how to control the lighting / shadowing of a model using a Shader Graph generated shader. Once the example from the blog is working, the next step is fairly easy.

    Instead of sending the dot product of the world-space normal and the direction of the light into saturate, to calculate NdotL, send the dot product result into a remap{[-1,1]=>[0,1]}, and then use the output value as the input into a gradient sampler. The gradient to be sampled should be the color of you shadow to white.
     
    Olmi likes this.
  6. larsbertram1

    larsbertram1

    Joined:
    Oct 7, 2008
    Posts:
    6,902
    oh, yes. depends on what "shadows" means for you. i only thought about real time shadows :)

    here i collect light color, intensity and distance attenuation separately from NdotL and shadow attenuation and finally take both to colorize the final pixel and blend between 2 texture sets.

    toon.PNG

    more info about custom lighting and lwrp: https://medium.com/@larsbertram1/lwrp-and-custom-lighting-in-shader-graph-6a7c48008a1d

    the entire toon shader is part of my Lux LWRP Essential package, currently at sales :)
    https://assetstore.unity.com/packages/vfx/shaders/lux-lwrp-essentials-150355
     
  7. whoisj

    whoisj

    Joined:
    Jan 4, 2018
    Posts:
    26
    Great write up. To address the issue at the end you cover about being forced to use emission instead of albedo, I create a custom Shader Graph Master Node and submitted it to Unity. They're in the middle of a Shader Graph re-write so they kindly rejected my submission, but you can still feel free to use it.

    https://github.com/Unity-Technologies/ScriptableRenderPipeline/pull/4912

    To try it...
    1. Start Unity 2019.3b (beta 8 or later should work)
    2. Copy the files from the pull-request into the PackageCache folder of your target project
    3. Give Unity desktop focus (click on its Window) and it'll compile
    4. Now create a new Shader Graph and you'll the option for `Surface Graph`
    Best of luck!