How do shadows work?

Well, basically, I’ve got this awesome Frankenstein of a shader for my water (looks great) but I want it to receive shadows. Unfortunately, I have no idea to do that, and the shadow samplers need a coordinate that I’m not exactly sure to come up with…oh and I keep hitting the instruction limit whenever I try something.

So here’s the file as is. It’s mostly copied code from here and there, with a few enhancements from when I was stuck in SM 1.4. I would much appreciate it if someone could point me in the right direction - say tell me how these shadows actually work. I can understand the projection part, but how all these shaders magically sample these maps is totally beyond me.

Random Image for Reference because Images can Make Things Easier to Figure Out Sometimes (Especially when the Shader params are Described with a showing of the Textures being Used with Them).

Shader "Water/Basic Scrolling" {
	Properties {
		_Color ("Main Color", Color) = (1,1,1,0.5)
        _SpecColor ("Specular Color", Color) = (0.5, 0.5, 0.5, 1)
		_RefrColor ("Refraction Tint", Color) = (1,1,1,1)
        _Shininess ("Shininess", Range (0.03, 1)) = 0.078125
		_MainTex ("Base (RGB)", 2D) = "white" {}
		_BumpMap ("Bump (RGB) Illumin (A)", 2D) = "bump" {}
		_BumpMap2 ("Bump (RGB) Illumin (A)", 2D) = "bump" {}
		_Fresnel ("Fresnel (A) ", 2D) = "gray" {}
		_ReflectiveColor ("Reflective color (RGB) fresnel (A) ", 2D) = "" {}
			/*_Fresnel ("Fresnel (A) ", 2D) = "gray" {}
			_ReflectiveColor ("Reflective color (RGB) fresnel (A) ", 2D) = "" {}
	_ReflectiveColorCube ("Reflective color cube (RGB) fresnel (A)", Cube) = "" { TexGen CubeReflect }*/
		_ReflectionTex ("Internal Reflection", 2D) = "" {}
		_RefractionTex ("Internal Refraction", 2D) = "" {}
	}
	
Category {
    //Blend AppSrcAdd AppDstAdd
	//Blend SrcAlpha OneMinusSrcAlpha     // Alpha blending
    //Fog { Color [_AddFog] }
    //Tags { "RenderType"="Opaque" }
	//Tags { "RenderType"="Transparent" }
	Tags { "Queue" = "Transparent" }
	Cull Off

	SubShader {
		Tags { "WaterMode"="Refractive" }
		Pass {
			Name "Water"
			Tags { "LightMode" = "Always"}
			//Blend SrcAlpha OneMinusSrcAlpha     // Alpha blending
			//Blend AppSrcAdd AppDstAdd
			//Blend One One
			//Blend Off
			
			CGPROGRAM
				#pragma vertex vert
				#pragma fragment frag
				#pragma fragmentoption ARB_precision_hint_fastest 
				#pragma fragmentoption ARB_fog_exp2
				#pragma multi_compile WATER_REFRACTIVE WATER_REFLECTIVE WATER_SIMPLE

				#if defined WATER_REFLECTIVE || defined WATER_REFRACTIVE
				#define HAS_REFLECTION 1
				#endif
				#if defined WATER_REFRACTIVE
				#define HAS_REFRACTION 1
				#endif


				#include "UnityCG.cginc"

				//uniform float4 _WaveScale4;
				//uniform float4 _WaveOffset;

				#ifdef HAS_REFLECTION
				//uniform float _ReflDistort;
				#endif
				#ifdef HAS_REFRACTION
				//uniform float _RefrDistort;
				#endif

				struct appdata {
					float4 vertex : POSITION;
					float3 normal : NORMAL;
					float2 texcoord : TEXCOORD0;
				};

				struct v2f {
					V2F_POS_FOG;
					#if defined HAS_REFLECTION || defined HAS_REFRACTION
					float3 ref;
					#endif
					float2 bumpuv[2];
					float3 viewDir;
				};
				
				uniform float4 _BumpMap_ST, _BumpMap2_ST;

				v2f vert(appdata v)
				{
					v2f o;
					PositionFog( v.vertex, o.pos, o.fog );
					
					// scroll bump waves
					float4 temp;
					temp.xy = TRANSFORM_TEX(v.texcoord, _BumpMap)+_Time[0];
					temp.zw = TRANSFORM_TEX(v.texcoord, _BumpMap2)-_Time[0];
					temp.z += _Time[0]*0.2;
					
					o.bumpuv[0] = temp.xy;
					o.bumpuv[1] = temp.wz;
					
					// object space view direction (will normalize per pixel)
					o.viewDir.xzy = ObjSpaceViewDir(v.vertex);
					
					#if defined HAS_REFLECTION || defined HAS_REFRACTION
					// calculate the reflection vector
					float3x4 mat = float3x4 (
						0.5, 0, 0, 0.5,
						0, 0.5 * _ProjectionParams.x, 0, 0.5,
						0, 0, 0, 1
					);	
					o.ref = mul (mat, o.pos);
					#endif
					
					return o;
				}

				#if defined WATER_REFLECTIVE || defined WATER_REFRACTIVE
				sampler2D _ReflectionTex;
				#endif
				#if defined WATER_REFLECTIVE || defined WATER_SIMPLE
				sampler2D _ReflectiveColor;
				#endif
				#if defined WATER_REFRACTIVE
				sampler2D _Fresnel;
				sampler2D _RefractionTex;
				uniform float4 _RefrColor;
				#endif
				#if defined WATER_SIMPLE
				uniform float4 _HorizonColor;
				#endif
				sampler2D _BumpMap;
				sampler2D _BumpMap2;

				half4 frag( v2f i ) : COLOR
				{
					i.viewDir = normalize(i.viewDir);
					
					// combine two scrolling bumpmaps into one
					half3 bump1 = tex2D( _BumpMap, i.bumpuv[0] ).rgb;
					i.bumpuv[1] += bump1.rg*0.1;
					half3 bump2 = tex2D( _BumpMap2, i.bumpuv[1] ).rgb;
					half3 bump = bump1 + bump2 - 1;
					
					half3 norm = half3( 0,(bump.x + bump.y)*0.1 + 1,0 );
					
					// fresnel factor
					half fresnelFac = dot( i.viewDir,norm );
					
					// perturb reflection/refraction UVs by bumpmap, and lookup colors
					float4 _ReflDistort, _RefrDistort;
					_ReflDistort.xyzw = 0.2;
					_RefrDistort.xyzw = 0.4;
					
					#ifdef HAS_REFLECTION
					float3 uv1 = i.ref; uv1.xy += bump * _ReflDistort;
					half4 refl = tex2Dproj( _ReflectionTex, uv1 );
					#endif
					#ifdef HAS_REFRACTION
					float3 uv2 = i.ref; uv2.xy -= bump * _RefrDistort;
					half4 refr = tex2Dproj( _RefractionTex, uv2 ) * _RefrColor;
					#endif
					
					// final color is between refracted and reflected based on fresnel	
					half4 color;
					
					#ifdef WATER_REFRACTIVE
					half fresnel = tex2D( _Fresnel, float2(fresnelFac,fresnelFac) ).a;
					fresnel += 0.2;
					fresnel = fresnel*fresnel;
					//half fresnel = fresnelFac;
					color = lerp( refr, refl, saturate(fresnel) );
					//color = lerp( refr, refl, 1 );
					//color.rgb = fresnel;
					#endif
					
					#ifdef WATER_REFLECTIVE
					half4 water = tex2D( _ReflectiveColor, float2(fresnelFac,fresnelFac) );
					color.rgb = lerp( water.rgb, refl.rgb, water.a );
					color.a = refl.a * water.a;
					#endif
					
					#ifdef WATER_SIMPLE
					half4 water = tex2D( _ReflectiveColor, float2(fresnelFac,fresnelFac) );
					color.rgb = lerp( water.rgb, _HorizonColor.rgb, water.a );
					color.a = _HorizonColor.a;
					#endif
					
					// Make water more opaque
					//color.a += 0.8;
					
					return color;
				}
			ENDCG

		}//end pass
	//}
	//SubShader {
		// Ambient pass
        /*Pass {
            Name "BASE"
            Tags {"LightMode" = "PixelOrNone"}
            //Blend AppSrcAdd AppDstAdd
            Color [_PPLAmbient]
            SetTexture [_MainTex] {constantColor [_Color] Combine texture * primary DOUBLE, texture * constant}
        }
		
		
		// Vertex lights
        Pass {
            Name "BASE"
            Tags {"LightMode" = "Vertex"}
            Lighting On
            Material {
                Diffuse [_Color]
                Emission [_PPLAmbient]
            }
			CGPROGRAM
				#pragma fragment frag
				#pragma fragmentoption ARB_fog_exp2
				#pragma fragmentoption ARB_precision_hint_fastest

				#include "UnityCG.cginc"

				uniform sampler2D _MainTex;

				half4 frag (v2f_vertex_lit i) : COLOR
				{
					return VertexLight( i, _MainTex );
				}
			ENDCG
		}*/
	// Pixel lights
        Pass {
            //Name "PPL"   
            Tags { "LightMode" = "Pixel"}
			//Tags { "Queue" = "Opaque" }
			//Blend SrcAlpha OneMinusSrcAlpha     // Alpha blending
			Blend SrcAlpha One
			//Blend SrcAlpha SrcColor
			//Blend One One
			//AlphaTest Greater 0.5

			//ZWrite Off
			//Blend One One
			CGPROGRAM
				#pragma vertex vert
				#pragma fragment frag
				#pragma multi_compile_builtin
				#pragma fragmentoption ARB_fog_exp2
				#pragma fragmentoption ARB_precision_hint_fastest
				#include "UnityCG.cginc"
				#include "AutoLight.cginc"

				struct v2f {
					V2F_POS_FOG;
					LIGHTING_COORDS
					float3    uvK; // xy = UV, z = specular K
					float4    uv2; // bumpmap UV, specmap UV
					//float4    uv3; // bumpmap UV, specmap UV
					float3    viewDirT;
					float3    lightDirT;
				};

				uniform float4 _MainTex_ST, _BumpMap_ST, _BumpMap2_ST, _SpecMap_ST;
				uniform float _Shininess;

				v2f vert (appdata_tan v)
				{   
					v2f o;
					PositionFog( v.vertex, o.pos, o.fog );
					o.uvK.xy = TRANSFORM_TEX(v.texcoord, _MainTex)+_Time[0];
					o.uvK.z = _Shininess * 128;
					o.uv2.xy = TRANSFORM_TEX(v.texcoord, _BumpMap)+_Time[0];
					//o.uv2.zw = TRANSFORM_TEX(v.texcoord, _SpecMap);
					o.uv2.zw = TRANSFORM_TEX(v.texcoord, _BumpMap2)-_Time[0];
					o.uv2.z += _Time[0]*0.2;
					TANGENT_SPACE_ROTATION;
					o.lightDirT = mul( rotation, ObjSpaceLightDir( v.vertex ) );   
					o.viewDirT = mul( rotation, ObjSpaceViewDir( v.vertex ) );   

					TRANSFER_VERTEX_TO_FRAGMENT(o);   
					return o;
				}

				uniform sampler2D _BumpMap;
				uniform sampler2D _BumpMap2;
				uniform sampler2D _MainTex;
				//uniform sampler2D _SpecMap;
				uniform float4 _LightColor0;
				uniform float4 _SpecColor;

				// Calculates Blinn-Phong (specular) lighting model
				inline half4 SpecularColorLight( half3 lightDir, half3 viewDir, half3 normal, half4 color, half4 specColor, float specK, half atten )
				{
					#ifndef USING_DIRECTIONAL_LIGHT
					lightDir = normalize(lightDir);
					#endif
					viewDir = normalize(viewDir);
					half3 h = normalize( lightDir + viewDir );
				   
					half diffuse = dot( normal, lightDir );
				   
					float nh = saturate( dot( h, normal ) );
					float spec = pow( nh, specK ) * color.a;
				   
					half4 c;
					c.rgb = (color.rgb * _ModelLightColor0.rgb * diffuse + _LightColor0.rgb * specColor.rgb * spec) * (atten * 2);
					//c.a = _LightColor0.a * specColor.a * spec * atten; // specular passes by default put highlights to overbright
					c.a = (_LightColor0.a * specColor.a * spec * atten * 4) + 0.2;
					return c;
				}


				half4 frag (v2f i) : COLOR
				{       
					
					//half4 speccol = tex2D( _SpecMap, i.uv2.zw );
					half4 speccol = _SpecColor;
					float3 normal = tex2D(_BumpMap, i.uv2.xy).xyz * 2.0 - 1.0;
					i.uv2.zw += normal.rg * 0.1;
					float3 normal2 = tex2D(_BumpMap2, i.uv2.zw).xyz * 2.0 - 1.0;
					//float3 normal2 = tex2D(_BumpMap2, normal.rg).xyz * 2.0 - 1.0;
					//normal.rgb = (normal.rgb + normal2.rgb)*0.5;
					normal = (normal + normal2)*0.5;
					
					i.uvK.xy += normal.rg * 0.1;
					half4 texcol = tex2D( _MainTex, i.uvK.xy );
					
					half4 c = SpecularColorLight( i.lightDirT, i.viewDirT, normal, texcol, speccol, i.uvK.z, LIGHT_ATTENUATION(i) );
					//c.a = normal.r + normal.b;
					//c.a = ( c.r + 0.2 )*2;
					//c.a = 0.2;
					return c;
				}
			ENDCG  
		} // end pass*/
	}
}
FallBack "Diffuse"

}

Unfortunately, shaders with tag “Transparent” can’t receive shadows.

yyyyyyyyyyyyeeeeeeeeeaahhhhhhhhhh THAT WORKED AWESOME - setting the water to Opaque made the shadows work without a hitch.

Thank you, things are looking better! I’ll be sure to remember that in the future.

New Question
I’m curious to how, when using rendering with replaced shaders, how I can allow certain render tags to just default back to the original shader. For example, say something has the tag RenderType Warp, I want to render that object using the shader with that tag.

Edit: I mean, without using UsePass, though I’m going to try that now to see if that works alright. Humn.