原理:显示泡沫,让泡沫流动起来,看起来水就像流动起来。
Shader "Customer/Water01"
{
Properties
{
_Color("Color水颜色", color) = (0,0,0.8,0.5)
_WaveNormalMap("Wave Normal Map", 2D) = "bump"{}
_WaveHeight("Wave Height",Range(0,1)) = 0.1
_WaveNormalScale("Wave Scale", float) = 10.0
_WaveNormalSpeed("Wave Speed", float) = 1.0
_waveNumber("Wave Number",float) = 4
_BigWaveSpeed("Big Wave Speed",float) = 10
_BigWaveHeight("Big Wave Height",float) = 0.5
_BigWaveNumber("Big Wave Number",float) = 10
_Opacity("不透明度", range(0, 1)) = 0.5
_FoamTex("Foam Texture", 2D) = "white" {}
_FoamSpeed("FormSpeed",float) = 0.1
}
SubShader
{
Tags
{
"Queue" = "Transparent"
"RenderType" = "Transparent"
}
GrabPass{
"_GrabPassTex"
}
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#include "Lighting.cginc"
#pragma multi_compile_fog
float4 _Color;
sampler2D _WaveNormalMap;
float4 _WaveNormalMap_ST;
fixed _WaveHeight;
float _WaveNormalScale;
fixed _WaveNormalSpeed;
fixed _waveNumber;
fixed _dividHeight;
fixed _BigWaveSpeed;
fixed _BigWaveHeight;
fixed _BigWaveNumber;
// 输入参数
float4 _MainTex_ST;
uniform half _Opacity;
sampler2D _GrabPassTex;//用于渲染透明物体
uniform sampler2D_float _CameraDepthTexture;
sampler2D _FoamTex;//泡沫噪声
float _FoamSpeed;//泡沫流动速度
float4 _FoamTex_ST;//泡沫Tiling
// 输入结构
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
float3 normal:NORMAL;//法线通常都是必须的
float4 tangent : TANGENT;
float3 color:COLOR0;
};
// 输出结构
struct v2f
{
float4 uv : TEXCOORD0;
float4 vertex : SV_POSITION; // 由模型顶点信息换算而来的顶点屏幕位置
float depth : TEXCOORD2;
float3 normal:NORMAL;//法线通常都是必须的
float4 lightDir_Tangent:TEXCOORD5;
float4 screenuv:TEXCOORD1;
float3 viewDir:TEXCOORD3;
float4 vertex_Local : TEXCOORD4;
float3 color:COLOR0;
};
// 输入结构>>>顶点Shader>>>输出结构
v2f vert(appdata v)
{
//v2f o;
v2f o = (v2f)0;
UNITY_INITIALIZE_OUTPUT(v2f, o);
//获取自身深度值
COMPUTE_EYEDEPTH(o.depth);
float2 flow = float2(_Time.x * _WaveNormalSpeed, _Time.z * 1.215 * _WaveNormalSpeed);
fixed3 n = UnpackNormal(tex2Dlod(_WaveNormalMap, float4(v.uv.xy * _WaveNormalScale + flow, 0, 0))).xyz;
//float tempN = tex2Dlod(_WaveNormalMap, float4(v.uv.xy*_WaveNormalScale + flow, 0, 0)).g;这种写法也可以,当然下面的高度也要用下面这句
//v.vertex.y = v.vertex.y + tempN * _WaveHeight + height;
float height = 0;
fixed wavebevel = 5;
fixed attenuation = (1.0 - v.uv.y);
fixed b = 0.8;
fixed x = v.uv.y + b * sin(v.uv.y);
if (v.vertex.y > _dividHeight)
{
height = (cos(x * _BigWaveNumber - _Time.z * _BigWaveSpeed + v.uv.x * wavebevel) + 1) * 0.5 * _BigWaveHeight * attenuation;
height += (cos(x * _BigWaveNumber - _Time.z * _BigWaveSpeed + (1.0 - v.uv.x) * wavebevel) + 1) * 0.5 * _BigWaveHeight * attenuation;
}
v.vertex.y = v.vertex.y + n * _WaveHeight + height;
if (v.vertex.y > _dividHeight)
v.vertex.z -= height * 0.1;
o.vertex = UnityObjectToClipPos(v.vertex);
//rotation
TANGENT_SPACE_ROTATION;
o.lightDir_Tangent.xyz = mul(rotation, ObjSpaceLightDir(v.vertex));
o.normal = v.normal;//得到法线,很重要
//屏幕UV
o.screenuv = ComputeScreenPos(o.vertex);// 背景纹理采样坐标
o.viewDir = normalize(_WorldSpaceCameraPos.xyz - mul(unity_ObjectToWorld, v.vertex).xyz);
o.viewDir = mul(rotation, mul(o.viewDir, unity_ObjectToWorld));//得到视方向
//本地空間位置
o.vertex_Local = v.vertex;
o.color = v.color;
//UV
//o.uv.xy = TRANSFORM_TEX(v.uv, _FoamTex);//白沫噪声纹理采样
o.uv.zw = TRANSFORM_TEX(v.uv, _WaveNormalMap);
//UNITY_TRANSFER_FOG(o, o.vertex);
return o;
}
// 输出结构>>>像素
fixed4 frag(v2f i) : COLOR
{
//屏幕深度Z
float ScreenZ = LinearEyeDepth(SAMPLE_DEPTH_TEXTURE_PROJ(_CameraDepthTexture, UNITY_PROJ_COORD(i.screenuv)));
//float4 finalCol = _Color;
fixed mask = dot(i.normal, float3(0, -1, 0)) + 0.5;
mask = mask > 0.2 ? 0 : 1;
float2 flow = float2(_Time.x * _WaveNormalSpeed, _Time.z * 1.215 * _WaveNormalSpeed);
fixed3 tangentNormal = UnpackNormal(tex2D(_WaveNormalMap, i.uv.zw * _WaveNormalScale + flow)).xyz;
tangentNormal.xy = tangentNormal.xy * 10;
fixed3 normal = normalize(tangentNormal);//法线
//越近越白
fixed d = clamp(1.0 - (abs(i.depth - ScreenZ) * 0.5), 0, 1);
//灯光方向
fixed3 world_lightDir = normalize(-_WorldSpaceLightPos0.xyz);
fixed3 world_normal = normalize(mul(unity_ObjectToWorld, normal));//
fixed3 world_normal_self = normalize(mul((float3x3)unity_ObjectToWorld, i.normal));
fixed3 n = mask > 0 ? world_normal : world_normal_self;
fixed3 diffuse = dot(world_lightDir, n) * 0.5 + 0.5;
//计算灯光反射
fixed3 reflectDir = reflect(i.lightDir_Tangent, normal);
//高光
fixed3 specular = max(pow(max(0, dot(i.viewDir, reflectDir)), 70), 0) * (1.0 - d);
float4 finalCol = fixed4(diffuse, 0);
//Grab Tex
fixed4 grabCol;
grabCol = tex2D(_GrabPassTex, i.screenuv.xy / i.screenuv.w);
//深色
grabCol = lerp(grabCol, lerp(grabCol, _Color, _Color.a), _Opacity);
fixed2 waveUV = i.uv.xy;
finalCol = grabCol;
if (mask > 0)
finalCol.rgb += specular * 2;
return finalCol * _LightColor0;
}
ENDCG
}
}
}
网友评论