Hi ,
I am working on an AR project these days and I was using this shader provided by Unity to cast shadows in my scene.
Today I wanted to add a second directional light (which should also cast shadows) so I followed the comments written in the shader. I added a new pass with Light Mode set to ForwardAdd and changed the pragma to multi_compile_fwdadd. It didn’t seem to do the trick and I couldn’t find a solution anywhere to cast the shadow of my second light. Am I missing something obvious when following the comments?
Here the shader :
Shader "Custom/Matte Shadow" {
Properties
{
_Fade ("Wave scale", Range (0,1)) = 0.5 // sliders
_FadeMarkerDist ("Wave scale", Range (0,1)) = 0.5 // sliders
}
SubShader {
Pass {
// 1.) This will be the base forward rendering pass in which ambient, vertex, and
// main directional light will be applied. Additional lights will need additional passes
// using the "ForwardAdd" lightmode.
// see: http://docs.unity3d.com/Manual/SL-PassTags.html
Tags { "LightMode" = "ForwardBase" "RenderType"="Opaque" "Queue"="Geometry+1" "ForceNoShadowCasting"="True" }
LOD 150
Blend Zero SrcColor
ZWrite On
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
// 2.) This matches the "forward base" of the LightMode tag to ensure the shader compiles
// properly for the forward bass pass. As with the LightMode tag, for any additional lights
// this would be changed from _fwdbase to _fwdadd.
#pragma multi_compile_fwdbase
// 3.) Reference the Unity library that includes all the lighting shadow macros
#include "AutoLight.cginc"
float _Fade;
float _FadeMarkerDist;
struct v2f
{
float4 pos : SV_POSITION;
float3 worldPos : TEXCOORD2;
float3 objWorldPos : TEXCOORD3;
// 4.) The LIGHTING_COORDS macro (defined in AutoLight.cginc) defines the parameters needed to sample
// the shadow map. The (0,1) specifies which unused TEXCOORD semantics to hold the sampled values -
// As I'm not using any texcoords in this shader, I can use TEXCOORD0 and TEXCOORD1 for the shadow
// sampling. If I was already using TEXCOORD for UV coordinates, say, I could specify
// LIGHTING_COORDS(1,2) instead to use TEXCOORD1 and TEXCOORD2.
LIGHTING_COORDS(0,1)
};
v2f vert(appdata_base v) {
v2f o;
o.pos = UnityObjectToClipPos (v.vertex);
o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
o.objWorldPos = mul(unity_ObjectToWorld,float4(0,0,0,1));
// 5.) The TRANSFER_VERTEX_TO_FRAGMENT macro populates the chosen LIGHTING_COORDS in the v2f structure
// with appropriate values to sample from the shadow/lighting map
TRANSFER_VERTEX_TO_FRAGMENT(o);
return o;
}
fixed4 frag(v2f i) : COLOR {
// 6.) The LIGHT_ATTENUATION samples the shadowmap (using the coordinates calculated by TRANSFER_VERTEX_TO_FRAGMENT
// and stored in the structure defined by LIGHTING_COORDS), and returns the value as a float.
float attenuation = LIGHT_ATTENUATION(i);
float dist = distance(i.worldPos, i.objWorldPos);
return min(1,fixed4(1.0,1.0,1.0,1.0) * attenuation + (dist * (_Fade/_FadeMarkerDist)));
}
ENDCG
}
Pass {
Tags { "LightMode" = "ForwardAdd" "RenderType"="Opaque" "Queue"="Geometry+1" "ForceNoShadowCasting"="True" }
LOD 150
Blend Zero One
ZWrite On
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#pragma multi_compile_fwdadd
#include "AutoLight.cginc"
float _Fade;
float _FadeMarkerDist;
struct v2f
{
float4 pos : SV_POSITION;
float3 worldPos : TEXCOORD2;
float3 objWorldPos : TEXCOORD3;
LIGHTING_COORDS(0,1)
};
v2f vert(appdata_base v) {
v2f o;
o.pos = UnityObjectToClipPos (v.vertex);
o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
o.objWorldPos = mul(unity_ObjectToWorld,float4(0,0,0,1));
TRANSFER_VERTEX_TO_FRAGMENT(o);
return o;
}
fixed4 frag(v2f i) : COLOR {
float attenuation = LIGHT_ATTENUATION(i);
float dist = distance(i.worldPos, i.objWorldPos);
return min(1,fixed4(1.0,1.0,1.0,1.0) * attenuation + (dist * (_Fade/_FadeMarkerDist)));
}
ENDCG
}
}
Fallback "VertexLit"
}
Thanks