Update: From further testing, I have found that a mesh with the WrapLambert shader can still cast shadows, but it will not receive them. However, even if I add a shadow collector to the bottom of the shader class, it still does not receive shadows. I tried adding this to the bottom (after the shadow caster): Code (CSharp): Pass { Name "ShadowCollector" Tags { "LightMode" = "ShadowCollector" } Fog {Mode Off} ZWrite On ZTest LEqual CGPROGRAM #pragma vertex vert #pragma fragment frag #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 } Original Post: My goal is to have the effects of WrapLambert where light bleeds over edges, as well as geometry still casting and receiving shadows. If I use the Lambert surface shader, shadows cast appropriately, but light does not wrap around edges. If I use WrapLambert, light wraps around edges like it should -- but it doesn't cast/receive shadows! I have tried placing the Lambert shader code after the WrapLambert shader (and vice-versa) in the same file, but one just overwrites the other - they don't layer or combine in any way. How can I combine the effects of these two shaders? WrapLambert shader: Code (CSharp): Shader "Custom/BlockShader" { Properties { _MainTex ("Texture For Diffuse Material Color", 2D) = "white" {} _Color ("Overall Diffuse Color Filter", Color) = (1,1,1,1) } SubShader { //This has wrap, but not shadows CGPROGRAM #pragma surface surf WrapLambert half4 LightingWrapLambert (SurfaceOutput s, half3 lightDir, half atten) { half NdotL = dot (s.Normal, lightDir); half diff = NdotL * 0.7 + 0.3; half4 c; c.rgb = s.Albedo * _LightColor0.rgb * (diff * atten * 2); c.a = s.Alpha; return c; } struct Input { float2 uv_MainTex; }; sampler2D _MainTex; fixed4 _Color; void surf (Input IN, inout SurfaceOutput o) { fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color; o.Albedo = c.rgb; o.Alpha = c.a; } ENDCG 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 #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 } } } Lambert Shader: Code (CSharp): Shader "Custom/BlockShader" { Properties { _MainTex ("Texture For Diffuse Material Color", 2D) = "white" {} _Color ("Overall Diffuse Color Filter", Color) = (1,1,1,1) } SubShader { //this allows for shadows, but doesn't allow wrap CGPROGRAM #pragma surface surf Lambert finalcolor:mycolor sampler2D _MainTex; fixed4 _Color; struct Input { float2 uv_MainTex; }; void mycolor (Input IN, SurfaceOutput o, inout fixed4 color) { color.a = 1; } void surf (Input IN, inout SurfaceOutput o) { fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color; o.Albedo = c.rgb; o.Alpha = c.a; } ENDCG 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 #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 } } }
If you're fine with Surface Shaders, just create a new one inside Unity (which will give you a clone of the built-in Diffuse shader to start off with) and then copy the WrapLambert lighting function into it as per http://docs.unity3d.com/Manual/SL-SurfaceShaderLighting.html --- there's no reason such a Surface Shader would behave differently than any others with respect to casting and receiving shadows, and speaking from experience, as a matter of fact it won't.
Add in a fallback shader, that should let it receive and cast shadows. Diffuse should work, or simply VertexLit. Or you could add in the shadow caster/receiver passes yourself to your shader (but generally it's just easier to use the ones defined in the fallback).