I put a shadowCollector pass in my shader,but why does it cant recieves shadow,why?

I put a shadowCollector pass in my shader,but why does it cant recieves shadow,why?
what happens,

I’d need to see your code to be sure.

Shader "Tut/Shadow/Collector_0" {
Properties {
    _MainTex ("Base (RGB)", 2D) = "white" {}
}

SubShader {
	//pass to render object
	pass{
		CGPROGRAM
		#pragma vertex vert
		#pragma fragment frag
		#include "UnityCG.cginc"

		struct vertOut {
			float4 oPos:SV_POSITION;
		};
		vertOut vert(appdata_base v)
		{
			vertOut o;
			float4 pos=mul(UNITY_MATRIX_MVP,v.vertex);
			o.oPos=pos;
			return o;
		}
		float4 frag(vertOut i):COLOR
		{
			float4 c;
			c=float4(0,1,0,1);
			return c;
		}
		ENDCG
	}

    // Pass to render object as a shadow collector
    Pass {
       Name "ShadowCollector"
       Tags { "LightMode" = "ShadowCollector" }

       Fog {Mode Off}
       ZWrite On ZTest Less

		CGPROGRAM
		// Upgrade NOTE: excluded shader from Xbox360; has structs without semantics (struct appdata members vertex)
		#pragma exclude_renderers xbox360
		#pragma vertex vert
		#pragma fragment frag
		#pragma fragmentoption ARB_precision_hint_fastest
		
		#define SHADOW_COLLECTOR_PASS
		#include "UnityCG.cginc"
		
		struct appdata {
		    float4 vertex;
		};
		
		struct v2f {
		    V2F_SHADOW_COLLECTOR;
		};
		
		v2f vert (appdata v)
		{
		    v2f o;
		    TRANSFER_SHADOW_COLLECTOR(o)
		    return o;
		}
		
		half4 frag (v2f i) : COLOR
		{
		    SHADOW_COLLECTOR_FRAGMENT(i)
		}
		ENDCG
    }//endpass
	}
}

//here is the screen shot in the game view,the green one

You haven’t put anything in your shader to give it shadows.

Look into the macros about lighting.

http://forum.unity3d.com/threads/145856-Simplest-possible-fragment-shader-that-has-shadows

I cant find answers there,there is only a shader cast shadow by Fallback “Diffuse”

From the built-in shaders, linked here

http://forum.unity3d.com/threads/2085-Builtin-Unity-shaders-source

you can find that you need 2 passes to get shadows fully working. One for casting one for recieving.

The code for that is here:

	// Pass to render object as a shadow caster
	Pass {
		Name "ShadowCaster"
		Tags { "LightMode" = "ShadowCaster" }
		
		Fog {Mode Off}
		ZWrite On ZTest LEqual Cull Off
		Offset 1, 1

		CGPROGRAM
		#pragma vertex vert
		#pragma fragment frag
		#pragma multi_compile_shadowcaster
		#pragma fragmentoption ARB_precision_hint_fastest
		#include "UnityCG.cginc"

		struct v2f { 
			V2F_SHADOW_CASTER;
		};

		v2f vert( appdata_base v )
		{
			v2f o;
			TRANSFER_SHADOW_CASTER(o)
			return o;
		}

		float4 frag( v2f i ) : COLOR
		{
			SHADOW_CASTER_FRAGMENT(i)
		}
		ENDCG

	}
	
	// Pass to render object as a shadow collector
	Pass {
		Name "ShadowCollector"
		Tags { "LightMode" = "ShadowCollector" }
		
		Fog {Mode Off}
		ZWrite On ZTest LEqual

		CGPROGRAM
		#pragma vertex vert
		#pragma fragment frag
		#pragma fragmentoption ARB_precision_hint_fastest
		#pragma multi_compile_shadowcollector

		#define SHADOW_COLLECTOR_PASS
		#include "UnityCG.cginc"

		struct appdata {
			float4 vertex : POSITION;
		};

		struct v2f {
			V2F_SHADOW_COLLECTOR;
		};

		v2f vert (appdata v)
		{
			v2f o;
			TRANSFER_SHADOW_COLLECTOR(o)
			return o;
		}

		fixed4 frag (v2f i) : COLOR
		{
			SHADOW_COLLECTOR_FRAGMENT(i)
		}
		ENDCG

	}

But you will still not get shadows appearing on your shader without adding in the attenuation/shadow value to your shader, the code for which is in the linked thread I posted earlier.

Adding it to your code gets you this:

Pass{
		CGPROGRAM
		#pragma vertex vert
		#pragma fragment frag
		
		#pragma multi_compile_fwdbase // NEEDED FOR SHADOWS.
		
		#include "UnityCG.cginc"

		struct vertOut {
		    float4 oPos:SV_POSITION;
		    LIGHTING_COORDS(0,1) // NEEDED FOR SHADOWS.
		};
		
		vertOut vert(appdata_base v)
		{
		    vertOut o;
		    float4 pos=mul(UNITY_MATRIX_MVP,v.vertex);
		    o.oPos=pos;
		    TRANSFER_VERTEX_TO_FRAGMENT(o); // NEEDED FOR SHADOWS.
		    return o;
		}
		
		float4 frag(vertOut i):COLOR
		{
			fixed atten = LIGHT_ATTENUATION(i);// NEEDED FOR SHADOWS.
			float4 c;
			c = float4(0,1,0,1) * atten;
			return c;
		}
		ENDCG
	    }

You’ll need to add an extra pass for Forward Add, but I’ll leave that up to you.

Thanks farfarer,the object applys this shader cast a pretty shadow,but it seems ’ LIGHT_ATTENUATION(i)’ just returns a constant value in the pass fwdadd,in the pass fwdbase,it seems just return 1.0:(
here is the two screen shots,the sphere with texture
1095335--41148--$fwdadd.png1095335--41149--$fwdbase.png

Add here is the two pass render object

	//pass to render object
	pass{
		CGPROGRAM
		#pragma vertex vert
		#pragma fragment frag
		#pragma multi_compile_fwdbase
		#include "UnityCG.cginc"
		#include "AutoLight.cginc"
		
		sampler2D _MainTex;
		
		struct vertOut {
			float4 pos:SV_POSITION;
			float4 uv;
			LIGHTING_COORDS(0,1)
		};
		vertOut vert(appdata_base v)
		{
			vertOut o;
			o.pos=mul(UNITY_MATRIX_MVP,v.vertex);
			o.uv=v.texcoord;
			TRANSFER_VERTEX_TO_FRAGMENT(o);
			return o;
		}
		float4 frag(vertOut i):COLOR
		{
			
			fixed atten=LIGHT_ATTENUATION(i);
			float4 c;
			c=tex2D(_MainTex,i.uv.xy);
			c=c*atten;
			return c;
		}
		ENDCG
		}//endpass
		
		pass{
		CGPROGRAM
		#pragma vertex vert
		#pragma fragment frag
		#pragma multi_compile_fwdadd
		#include "UnityCG.cginc"
		#include "AutoLight.cginc"
		
		sampler2D _MainTex;
		
		struct vertOut {
			float4 pos:SV_POSITION;
			float4 uv;
			LIGHTING_COORDS(0,1)
		};
		vertOut vert(appdata_base v)
		{
			vertOut o;
			o.pos=mul(UNITY_MATRIX_MVP,v.vertex);
			o.uv=v.texcoord;
			TRANSFER_VERTEX_TO_FRAGMENT(o);
			return o;
		}
		float4 frag(vertOut i):COLOR
		{
			
			fixed atten=LIGHT_ATTENUATION(i);
			float4 c;
			c=tex2D(_MainTex,i.uv.xy);
			c=c*atten;
			return c;
		}
		ENDCG
	}

In your vertOut struct, you’ll need to set the numbers in LIGHTING_COORDS(#,#) to be the next two available texcoords, taking into account any you’ve added.

So for your code, you’d have:

struct vertOut {
float4 pos : SV_POSITION;
float4 uv : TEXCOORD0;
LIGHTING_COORDS(1,2)
};

or if you had two UVs, you’d have:

struct vertOut {
float4 pos : SV_POSITION;
float4 uv : TEXCOORD0;
float4 uv2 : TEXCOORD1;
LIGHTING_COORDS(2,3)
};

or if you had two UVs and light direction, you’d have:

struct vertOut {
float4 pos : SV_POSITION;
float4 uv : TEXCOORD0;
float4 uv2 : TEXCOORD1;
float3 lightDir : TEXCOORD2;
LIGHTING_COORDS(3,4)
};

1 Like

I did have tried the texcoord numbers,it result the same thing

pass{
		CGPROGRAM
		#pragma vertex vert
		#pragma fragment frag
		#pragma multi_compile_fwdbase
		#include "UnityCG.cginc"
		#include "AutoLight.cginc"
		
		sampler2D _MainTex;
		
		struct vertOut {
			float4 pos:SV_POSITION;
			float4 uv:TEXCOORD0;
			LIGHTING_COORDS(1,2)
		};
		vertOut vert(appdata_base v)
		{
			vertOut o;
			o.pos=mul(UNITY_MATRIX_MVP,v.vertex);
			o.uv=v.texcoord;
			TRANSFER_VERTEX_TO_FRAGMENT(o);
			return o;
		}
		float4 frag(vertOut i):COLOR
		{
			
			fixed atten=LIGHT_ATTENUATION(i);
			float4 c;
			c=tex2D(_MainTex,i.uv.xy);
			c=c*atten;
			return c;
		}
		ENDCG
		}//endpass
		
		pass{
		CGPROGRAM
		#pragma vertex vert
		#pragma fragment frag
		#pragma multi_compile_fwdadd
		#include "UnityCG.cginc"
		#include "AutoLight.cginc"
		
		sampler2D _MainTex;
		
		struct vertOut {
			float4 pos:SV_POSITION;
			float4 uv:TEXCOORD0;
			LIGHTING_COORDS(1,2)
		};
		vertOut vert(appdata_base v)
		{
			vertOut o;
			o.pos=mul(UNITY_MATRIX_MVP,v.vertex);
			o.uv=v.texcoord;
			TRANSFER_VERTEX_TO_FRAGMENT(o);
			return o;
		}
		float4 frag(vertOut i):COLOR
		{
			
			fixed atten=LIGHT_ATTENUATION(i);
			float4 c;
			c=tex2D(_MainTex,i.uv.xy);
			c=c*atten;
			return c;
		}
		ENDCG
	}

It does seem to work in Unity v4_3, but you need to add the tags to the Pass / Passes:
Tags { “LightMode” = “ForwardBase” }
etc.

For one important directional light in Forward rendering:

Shader “Custom/ShadowsInFwdRenderingVertFrag” {
Properties {
_MainTex (“Base (RGB)”, 2D) = “white” {}//Needed by the Diffuse Fallback
}
SubShader {
Tags { “RenderType”=“Opaque” }
//LOD 200

Pass{
Tags { “LightMode” = “ForwardBase” }
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_fwdbase
#include “UnityCG.cginc”
#include “AutoLight.cginc”

struct vertOut {
float4 pos : SV_POSITION;
LIGHTING_COORDS(0,1) // NEEDED FOR SHADOWS.
};

vertOut vert(appdata_base v)
{
vertOut o;
o.pos= mul(UNITY_MATRIX_MVP, v.vertex);
TRANSFER_VERTEX_TO_FRAGMENT(o); // NEEDED FOR SHADOWS.
return o;
}

float4 frag(vertOut i):COLOR
{
fixed atten = LIGHT_ATTENUATION(i);// NEEDED FOR SHADOWS.
float4 c;
c = float4(0,1,0,1) * atten;
return c;
}
ENDCG
}//Pass

// Pass to render object as a shadow caster
Pass {
Name “ShadowCaster”
Tags { “LightMode” = “ShadowCaster” }

Fog {Mode Off}
ZWrite On ZTest LEqual Cull Off
Offset 1, 1

CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_shadowcaster
#pragma fragmentoption ARB_precision_hint_fastest
#include “UnityCG.cginc”
#include “AutoLight.cginc”

struct v2f {
V2F_SHADOW_CASTER;
};

v2f vert( appdata_base v )
{
v2f o;
TRANSFER_SHADOW_CASTER(o)
return o;
}

float4 frag( v2f i ) : COLOR
{
SHADOW_CASTER_FRAGMENT(i)
}
ENDCG
} //Pass

// Pass to render object as a shadow collector
Pass {
Name “ShadowCollector”
Tags { “LightMode” = “ShadowCollector” }

Fog {Mode Off}
ZWrite On ZTest LEqual

CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma fragmentoption ARB_precision_hint_fastest
#pragma multi_compile_shadowcollector

#define SHADOW_COLLECTOR_PASS
#include “UnityCG.cginc”

struct appdata {
float4 vertex : POSITION;
};

struct v2f {
V2F_SHADOW_COLLECTOR;
};

v2f vert (appdata v)
{
v2f o;
TRANSFER_SHADOW_COLLECTOR(o)
return o;
}

fixed4 frag (v2f i) : COLOR
{
SHADOW_COLLECTOR_FRAGMENT(i)
}
ENDCG
}//Pass

} //SubShader
FallBack “Diffuse” //note: required for passes: ForwardBase, ShadowCaster, ShadowCollector
}

2 Likes