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.
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"
}