Search Unity

Question How to get current shadowcaster light direction?

Discussion in 'General Graphics' started by ununion, May 11, 2021.

  1. ununion

    ununion

    Joined:
    Dec 2, 2018
    Posts:
    275
    in old version of unity I can get current shadow caster light via _WorldSpaceLightPos0 whatever sunlight/point light/spot light.
    but in urp version,the "_WorldSpaceLightPos0" return sunlight pos whenever, ,so How can i get spot light pos?
     
  2. ununion

    ununion

    Joined:
    Dec 2, 2018
    Posts:
    275
    btw,i m work in the shadowcaster pass only.
    so I thought the _WorldSpaceLightPos0 only return sunlight info in this pass in urp/
     
  3. ununion

    ununion

    Joined:
    Dec 2, 2018
    Posts:
    275
    @bgolus
    Hey bro,sorry for bothering you.hope you can help me thanks
     
  4. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,348
    The URP works completely differently than the built in render paths;
    _WorldSpaceLightPos0
    isn't used at all. However if you're working in the shadow caster pass, then the light direction is the current world space view direction, which you can get using
    UNITY_MATRIX_I_V._m02_m12_m22
    . For directional lights
    _WorldSpaceLightPos0
    is actually a vector facing the opposite direction as the light is pointing, due to how the dot product math for lighting works. You may need to slap a
    -
    in front of that above matrix to get the same behavior, but I think it'll work out properly without as forward in view space is actually -z.
     
    ununion likes this.
  5. ununion

    ununion

    Joined:
    Dec 2, 2018
    Posts:
    275
    hey bgolus,thanks for replying me!
    this is another thread that i posted about this problem,it has few pictures.https://forum.unity.com/threads/problem-with-billboard-shadow-caster.1108367/

    i just tried using UNITY_MATRIX_I_V._m02_m12_m22 instead of _WorldSpaceLightPos0 or _LightDirection but it show as same as before, that directional light shadow is what i want,but spot light still like normal.

    it look like spot light do not use shadowcaster pass?
     
  6. ununion

    ununion

    Joined:
    Dec 2, 2018
    Posts:
    275
    Code (CSharp):
    1. Shader "Custom/B2" {
    2.     Properties {
    3.         _MainTex ("Base (RGB) Trans (A)", 2D) = "white" {}
    4.         _BumpMap ("Normalmap", 2D) = "bump" {}
    5.         _Cutoff ("Alpha cutoff", Range(0,1)) = 0.5
    6.     }
    7.    
    8.     SubShader {
    9.         Pass{
    10.             Tags
    11.             {
    12.                 "Queue"="AlphaTest"
    13.  
    14.             }
    15.             LOD 100
    16.             cull off
    17.  
    18.             HLSLPROGRAM
    19.             #pragma vertex vert
    20.             #pragma fragment frag
    21.             #include"Packages\com.unity.render-pipelines.universal\ShaderLibrary\Lighting.hlsl"
    22.  
    23.             struct appdata
    24.             {
    25.                 float4 vertex:POSITION;
    26.                 float2 texcoord:TEXCOORD0;
    27.             };
    28.            
    29.             sampler2D _MainTex;
    30.             sampler2D _BumpMap;
    31.            
    32.             struct v2f {
    33.                 float4 vertex:SV_POSITION;
    34.                 float2 texcoord:TEXCOORD0;
    35.             };
    36.            
    37.             v2f vert(appdata v){
    38.                 v2f o;
    39.                 Light l=GetMainLight();
    40.                 //GetAdditionalLight(0,mul(unity_ObjectToWorld,v.vertex));
    41.  
    42.                 float3 forward= mul(unity_WorldToObject,l.direction).xyz;
    43.                
    44.                 forward.y=0;
    45.                 forward=normalize(forward);
    46.                 float3 up=float3(0,1,0);
    47.                 float3 right=normalize(cross(forward,up));
    48.                 up=normalize(cross(right,forward));
    49.  
    50.                
    51.                 float3 vertex= v.vertex.x*right+v.vertex.y*up+v.vertex.z*forward;
    52.                
    53.                 o.vertex=TransformObjectToHClip(v.vertex);
    54.                 o.texcoord=v.texcoord;
    55.                 return o;
    56.                
    57.             }
    58.             float4 frag(v2f i):SV_Target
    59.             {
    60.                 float4 c=tex2D(_MainTex,i.texcoord);
    61.                 clip(c.a-0.8);
    62.                 Light l=GetMainLight();
    63.                 float4 color=mul(unity_WorldToObject,l.direction);
    64.  
    65.                 return color;
    66.                 return c;
    67.             }
    68.            
    69.             ENDHLSL
    70.         }
    71.         Pass{
    72.             Tags
    73.             {
    74.                 "LightMode" = "ShadowCaster"
    75.             }
    76.             LOD 100
    77.             cull off
    78.  
    79.             HLSLPROGRAM
    80.             #pragma vertex vert
    81.             #pragma fragment frag
    82.             #pragma multi_compile _SPOT _DIRECTIONAL
    83.  
    84.             #include"Packages\com.unity.render-pipelines.universal\ShaderLibrary\Lighting.hlsl"
    85.            
    86.  
    87.             float3 _LightDirection;
    88.             float3 _LightPosWS;
    89.             uint _ShadowLightIndex;
    90.  
    91.             struct appdata
    92.             {
    93.                 float4 vertex:POSITION;
    94.                 float2 texcoord:TEXCOORD0;
    95.             };
    96.            
    97.             sampler2D _MainTex;
    98.             sampler2D _BumpMap;
    99.            
    100.             struct v2f {
    101.                 float4 vertex:SV_POSITION;
    102.                 float2 texcoord:TEXCOORD0;
    103.             };
    104.            
    105.             v2f vert(appdata v){            
    106.                 v2f o;
    107.                 float3 forward= mul(unity_WorldToObject,UNITY_MATRIX_I_V._m02_m12_m22).xyz;
    108.                 forward.y=0;
    109.                 forward=normalize(forward);
    110.                 float3 up=float3(0,1,0);
    111.                 float3 right=normalize(cross(forward,up));
    112.                 up=normalize(cross(right,forward));
    113.  
    114.                
    115.                 float3 vertex= v.vertex.x*right+v.vertex.y*up+v.vertex.z*forward;
    116.  
    117.                 o.vertex=TransformObjectToHClip(vertex);
    118.                 o.texcoord=v.texcoord;
    119.                 return o;
    120.                
    121.             }
    122.             float4 frag(v2f i):SV_Target
    123.             {              
    124.                 float4 c=tex2D(_MainTex,i.texcoord);
    125.                 clip(c.a-0.8);
    126.                 return float4(1,1,1,1);
    127.             }          
    128.             ENDHLSL
    129.         }        
    130.     }
    131. }
    here is my code
     
  7. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,348
    Using the above will work for directional, and kind of work "well enough" for spot lights, but not really for point lights because there's no "forward" direction for point lights. The direction for point lights, and technically spot lights, requires you know the direction from your object's pivot to the light's position. Also it should be noted the URP cannot differentiate between a spot light and a point light shadow, so they will have to use the same behavior.

    Looking at the URP's shadow caster shader code, they have code to calculate the light direction for per vertex shadow biasing.
    https://github.com/Unity-Technologi...s.universal/Shaders/ShadowCasterPass.hlsl#L27
    Code (csharp):
    1. #if _CASTING_PUNCTUAL_LIGHT_SHADOW
    2.     float3 lightDirectionWS = normalize(_LightPosition - positionWS);
    3. #else
    4.     float3 lightDirectionWS = _LightDirection;
    5. #endif
    So you should probably do something like that, but using your pivot position rather than the vertex position. You can simplify that a bit for you code by transforming the
    _LightPosition
    into object space either as a position for spot / point or rotation for directional (w of 1.0 or 0.0) depending on
    _CASTING_PUNCTUAL_LIGHT_SHADOW
    .
     
    ununion likes this.
  8. ununion

    ununion

    Joined:
    Dec 2, 2018
    Posts:
    275
    thanks bgolus very much!finally i m using UNITY_MATRIX_I_V._m02_m12_m22 and have well work for directional light and well enough for spot light!