Search Unity

Resolved Need small help with NdotL = dot(s.Normal, lightDir)

Discussion in 'Shaders' started by Ukounu, Jul 17, 2020.

  1. Ukounu

    Ukounu

    Joined:
    Nov 2, 2019
    Posts:
    208
    I'm trying to make a shader with adjustable self shadow.

    Code (CSharp):
    1. Shader "Custom/Test"
    2. {
    3.     Properties
    4.     {
    5.         _Color ("Main Color", Color) = (0.5,0.5,0.5,1)
    6.         _MainTex ("Base (RGB)", 2D) = "white" {}
    7.         _Shadow("Shadow", Range(0.0, 1.0)) = 0.2
    8.     }
    9.     SubShader
    10.     {
    11.         Tags { "RenderType"="Opaque" }
    12.  
    13. CGPROGRAM
    14.  
    15. #pragma surface surf Custom fullforwardshadows exclude_path:prepass
    16.  
    17.     sampler2D _MainTex;
    18.     float4 _Color;
    19.     fixed _Shadow;
    20.  
    21. struct Input
    22. {
    23.     float2 uv_MainTex;
    24. };
    25.  
    26. struct CustomSurfaceOutput {
    27.     half3 Albedo;
    28.     half3 Normal;
    29.     half3 Emission;
    30.     float Shadow;
    31.     half Alpha;
    32. };
    33.  
    34. inline half4 LightingCustom (CustomSurfaceOutput s, half3 lightDir, half atten){
    35.  
    36.     half NdotL = dot(s.Normal, lightDir) * s.Shadow;
    37.     half4 c;
    38.     c.rgb = s.Albedo * _LightColor0.rgb * atten + NdotL * s.Albedo;
    39.     c.a = 0;
    40.     return c;
    41. }
    42.  
    43. void surf (Input IN, inout CustomSurfaceOutput o) {
    44.     half4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color;
    45.     o.Albedo = c.rgb;
    46.     o.Alpha = c.a;
    47.     o.Shadow = _Shadow;
    48. }
    49.         ENDCG
    50.     }
    51.     FallBack "Diffuse"
    52. }
    Here is the effect it produces. It makes surfaces facing light brighter, while surfaces turned 180 degrees away become dark. Other surfaces are lit from brighter to darker depending on their angle (surfaces at exactly 90 degrees don't change brightness).

    Untitled-2.png

    And here is the effect I want to achieve:

    Untitled-1.png

    I want surfaces facing light to not change brightness, at 90 degrees to become partially dark, and at 180 degrees to become dark. Light distribution on surfaces should remain the same, but instead of being in "bright - no change - dark" range, it should be in "no change - partially dark - dark" range. I don't want NdotL to ever produce result brighter than original texture.

    I think I need to modify NdotL calculation in some way to achieve this effect, but I can't figure how.

    Please help.
     
  2. Invertex

    Invertex

    Joined:
    Nov 7, 2013
    Posts:
    1,547
    I believe it should just be
    half NdotL = (dot(s.Normal, lightDir) - 1) * s.Shadow;
    to pull the range down.
    dot() will return a value between -1 and 1 depending on the difference between the two input directions. It will be 1 if the angles match perfectly, 0 if they're at 90 degrees apart and -1 if 180, as examples.
     
    Ukounu likes this.
  3. Ukounu

    Ukounu

    Joined:
    Nov 2, 2019
    Posts:
    208
    Thank you.