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?
btw,i m work in the shadowcaster pass only.
so I thought the _WorldSpaceLightPos0 only return sunlight info in this pass in urp/
@bgolus
Hey bro,sorry for bothering you.hope you can help me thanks
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.
hey bgolus,thanks for replying me!
this is another thread that i posted about this problem,it has few pictures. https://discussions.unity.com/t/840527
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?
Shader "Custom/B2" {
Properties {
_MainTex ("Base (RGB) Trans (A)", 2D) = "white" {}
_BumpMap ("Normalmap", 2D) = "bump" {}
_Cutoff ("Alpha cutoff", Range(0,1)) = 0.5
}
SubShader {
Pass{
Tags
{
"Queue"="AlphaTest"
}
LOD 100
cull off
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
#include"Packages\com.unity.render-pipelines.universal\ShaderLibrary\Lighting.hlsl"
struct appdata
{
float4 vertex:POSITION;
float2 texcoord:TEXCOORD0;
};
sampler2D _MainTex;
sampler2D _BumpMap;
struct v2f {
float4 vertex:SV_POSITION;
float2 texcoord:TEXCOORD0;
};
v2f vert(appdata v){
v2f o;
Light l=GetMainLight();
//GetAdditionalLight(0,mul(unity_ObjectToWorld,v.vertex));
float3 forward= mul(unity_WorldToObject,l.direction).xyz;
forward.y=0;
forward=normalize(forward);
float3 up=float3(0,1,0);
float3 right=normalize(cross(forward,up));
up=normalize(cross(right,forward));
float3 vertex= v.vertex.x*right+v.vertex.y*up+v.vertex.z*forward;
o.vertex=TransformObjectToHClip(v.vertex);
o.texcoord=v.texcoord;
return o;
}
float4 frag(v2f i):SV_Target
{
float4 c=tex2D(_MainTex,i.texcoord);
clip(c.a-0.8);
Light l=GetMainLight();
float4 color=mul(unity_WorldToObject,l.direction);
return color;
return c;
}
ENDHLSL
}
Pass{
Tags
{
"LightMode" = "ShadowCaster"
}
LOD 100
cull off
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile _SPOT _DIRECTIONAL
#include"Packages\com.unity.render-pipelines.universal\ShaderLibrary\Lighting.hlsl"
float3 _LightDirection;
float3 _LightPosWS;
uint _ShadowLightIndex;
struct appdata
{
float4 vertex:POSITION;
float2 texcoord:TEXCOORD0;
};
sampler2D _MainTex;
sampler2D _BumpMap;
struct v2f {
float4 vertex:SV_POSITION;
float2 texcoord:TEXCOORD0;
};
v2f vert(appdata v){
v2f o;
float3 forward= mul(unity_WorldToObject,UNITY_MATRIX_I_V._m02_m12_m22).xyz;
forward.y=0;
forward=normalize(forward);
float3 up=float3(0,1,0);
float3 right=normalize(cross(forward,up));
up=normalize(cross(right,forward));
float3 vertex= v.vertex.x*right+v.vertex.y*up+v.vertex.z*forward;
o.vertex=TransformObjectToHClip(vertex);
o.texcoord=v.texcoord;
return o;
}
float4 frag(v2f i):SV_Target
{
float4 c=tex2D(_MainTex,i.texcoord);
clip(c.a-0.8);
return float4(1,1,1,1);
}
ENDHLSL
}
}
}
here is my code
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.
#if _CASTING_PUNCTUAL_LIGHT_SHADOW
float3 lightDirectionWS = normalize(_LightPosition - positionWS);
#else
float3 lightDirectionWS = _LightDirection;
#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
.
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!