Created
October 26, 2011 06:10
-
-
Save nomadalex/1315586 to your computer and use it in GitHub Desktop.
Unity-水面效果的shader文件
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Shader "FX/Water" { | |
Properties { | |
_WaveScale ("Wave scale", Range (0.02,0.15)) = 0.063 | |
_ReflDistort ("Reflection distort", Range (0,1.5)) = 0.44 | |
_RefrDistort ("Refraction distort", Range (0,1.5)) = 0.40 | |
_RefrColor ("Refraction color", COLOR) = ( .34, .85, .92, 1) | |
_Fresnel ("Fresnel (A) ", 2D) = "gray" {} | |
_BumpMap ("Bumpmap (RGB) ", 2D) = "bump" {} | |
WaveSpeed ("Wave speed (map1 x,y; map2 x,y)", Vector) = (19,9,-16,-7) | |
_ReflectiveColor ("Reflective color (RGB) fresnel (A) ", 2D) = "" {} | |
_ReflectiveColorCube ("Reflective color cube (RGB) fresnel (A)", Cube) = "" { TexGen CubeReflect } | |
_HorizonColor ("Simple water horizon color", COLOR) = ( .172, .463, .435, 1) | |
_MainTex ("Fallback texture", 2D) = "" {} | |
_ReflectionTex ("Internal Reflection", 2D) = "" {} | |
_RefractionTex ("Internal Refraction", 2D) = "" {} | |
} | |
// ----------------------------------------------------------- | |
// Fragment program cards | |
Subshader { | |
Tags { "WaterMode"="Refractive" "RenderType"="Opaque" } | |
Pass { | |
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; | |
}; | |
struct v2f { | |
V2F_POS_FOG; | |
#if defined HAS_REFLECTION || defined HAS_REFRACTION | |
float3 ref; | |
#endif | |
float2 bumpuv[2]; | |
float3 viewDir; | |
}; | |
v2f vert(appdata v) | |
{ | |
v2f o; | |
PositionFog( v.vertex, o.pos, o.fog ); | |
// scroll bump waves | |
float4 temp; | |
temp.xyzw = v.vertex.xzxz * _WaveScale4 + _WaveOffset; | |
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; | |
half4 frag( v2f i ) : COLOR | |
{ | |
i.viewDir = normalize(i.viewDir); | |
// combine two scrolling bumpmaps into one | |
half3 bump1 = tex2D( _BumpMap, i.bumpuv[0] ).rgb; | |
half3 bump2 = tex2D( _BumpMap, i.bumpuv[1] ).rgb; | |
half3 bump = bump1 + bump2 - 1; | |
// fresnel factor | |
half fresnelFac = dot( i.viewDir, bump ); | |
// perturb reflection/refraction UVs by bumpmap, and lookup colors | |
#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; | |
color = lerp( refr, refl, 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 | |
return color; | |
} | |
ENDCG | |
} | |
} | |
// ----------------------------------------------------------- | |
// Radeon 9000 cards | |
Subshader { | |
Tags { "WaterMode"="Reflective" "RenderType"="Opaque" } | |
Pass { | |
CGPROGRAM | |
#pragma vertex vert | |
#include "UnityCG.cginc" | |
uniform float4 _WaveScale4; | |
uniform float4 _WaveOffset; | |
uniform float _ReflDistort; | |
struct appdata { | |
float4 vertex : POSITION; | |
float3 normal : NORMAL; | |
}; | |
struct v2f { | |
V2F_POS_FOG; | |
float2 bumpuv[2] : TEXCOORD0; | |
float3 viewDir : TEXCOORD2; | |
float4 ref : TEXCOORD3; | |
}; | |
v2f vert(appdata v) | |
{ | |
v2f o; | |
PositionFog( v.vertex, o.pos, o.fog ); | |
// scroll bump waves | |
float4 temp; | |
temp.xyzw = v.vertex.xzxz * _WaveScale4 + _WaveOffset; | |
o.bumpuv[0] = temp.xy; | |
o.bumpuv[1] = temp.wz; | |
// object space view direction | |
o.viewDir.xzy = normalize( ObjSpaceViewDir(v.vertex) ); | |
// calculate the reflection vector | |
float4x4 mat = float4x4 ( | |
.5, 0, 0,.5, | |
0,.5 * _ProjectionParams.x, 0,.5, | |
0, 0,.5,.5, | |
0, 0, 0, 1 | |
); | |
o.ref = mul (mat, o.pos); | |
return o; | |
} | |
ENDCG | |
Program "" { | |
SubProgram { | |
Keywords { "WATER_REFLECTIVE" "WATER_REFRACTIVE" } | |
SetTexture [_BumpMap] { 2D } | |
SetTexture [_BumpMap] { 2D } | |
SetTexture [_ReflectiveColor] { 2D } | |
SetTexture [_ReflectionTex] { 2D } | |
Local 0, ([_ReflDistort],0,0,0) | |
"!!ATIfs1.0 | |
StartConstants; | |
CONSTANT c0 = program.local[0]; | |
EndConstants; | |
StartPrelimPass; | |
PassTexCoord r3, t3.stq_dq; # reflection vector | |
SampleMap r0, t0.str; # bump1 | |
SampleMap r1, t1.str; # bump2 | |
PassTexCoord r2, t2.str; | |
ADD r1.half, r0.bias, r1.bias; # bump = bump1 + bump2 - 1 | |
DOT3 r2, r1.2x, r2; # fresnel: dot (bump, viewer-pos) | |
# add less offset because it's purely screenspace; big ones look bad | |
MAD r3.rg, r1, c0.r, r3; # uv += bump * strength; add less because it's not perspective | |
EndPass; | |
StartOutputPass; | |
SampleMap r3, r3.str; # reflection color | |
SampleMap r2, r2.str; # water color/fresnel | |
LERP r0.rgb, r2.a, r3, r2; # between water and reflected based on fresnel | |
MUL r0.a, r3.a, r2.a; | |
EndPass; | |
" | |
} | |
SubProgram { | |
Keywords { "WATER_SIMPLE" } | |
SetTexture [_BumpMap] { 2D } | |
SetTexture [_BumpMap] { 2D } | |
SetTexture [_ReflectiveColor] { 2D } | |
Local 0, [_HorizonColor] | |
"!!ATIfs1.0 | |
StartConstants; | |
CONSTANT c0 = program.local[0]; | |
EndConstants; | |
StartPrelimPass; | |
SampleMap r0, t0.str; | |
SampleMap r1, t1.str; | |
PassTexCoord r2, t2.str; | |
ADD r1, r0.bias, r1.bias; # bump = bump1 + bump2 - 1 | |
DOT3 r2, r1, r2; # fresnel: dot (bump, viewer-pos) | |
EndPass; | |
StartOutputPass; | |
SampleMap r2, r2.str; | |
LERP r0.rgb, r2.a, c0, r2; # fade in reflection | |
MOV r0.a, c0.a; | |
EndPass; | |
" | |
} | |
} | |
} | |
} | |
// ----------------------------------------------------------- | |
// Old cards | |
// three texture, cubemaps | |
Subshader { | |
Tags { "WaterMode"="Simple" "RenderType"="Opaque" } | |
Pass { | |
Color (0.5,0.5,0.5,0.5) | |
SetTexture [_MainTex] { | |
Matrix [_WaveMatrix] | |
combine texture * primary | |
} | |
SetTexture [_MainTex] { | |
Matrix [_WaveMatrix2] | |
combine texture * primary + previous | |
} | |
SetTexture [_ReflectiveColorCube] { | |
combine texture +- previous, primary | |
Matrix [_Reflection] | |
} | |
} | |
} | |
// dual texture, cubemaps | |
Subshader { | |
Tags { "WaterMode"="Simple" "RenderType"="Opaque" } | |
Pass { | |
Color (0.5,0.5,0.5,0.5) | |
SetTexture [_MainTex] { | |
Matrix [_WaveMatrix] | |
combine texture | |
} | |
SetTexture [_ReflectiveColorCube] { | |
combine texture +- previous, primary | |
Matrix [_Reflection] | |
} | |
} | |
} | |
// single texture | |
Subshader { | |
Tags { "WaterMode"="Simple" "RenderType"="Opaque" } | |
Pass { | |
Color (0.5,0.5,0.5,0) | |
SetTexture [_MainTex] { | |
Matrix [_WaveMatrix] | |
combine texture, primary | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment