加入水岸線效果臂外,shader代碼如下
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
_BowenTex("Bowen Texture", 2D) = "white" {}
_BowenSpeed("Bowen",Range(-5,5)) = 0.1
_BowenOpacity("擾動不透明度", range(0, 1)) = 0.5
_dividHeight("分界線高度",Range(-1,1)) = -0.1
_EdgeWidth("水岸線寬度",Range(0,1)) = 0.1
_EdgeTex("水岸線形狀", 2D) = "black" {}
_EdgeSpeed("水岸線擴(kuò)展速度",Range(1,10)) = 5
}
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;
// 輸入?yún)?shù)
float4 _MainTex_ST;
uniform half _Opacity;
sampler2D _GrabPassTex;//用于渲染透明物體
uniform sampler2D_float _CameraDepthTexture;
sampler2D _BowenTex;//波紋擾動噪聲
float _BowenSpeed;//波紋擾動流動速度
float4 _BowenTex_ST;//波紋擾動Tiling
uniform half _BowenOpacity;// 波紋擾動透明度
fixed _EdgeWidth;//岸線
fixed _EdgeSpeed;//水岸下沖擊速度
sampler2D _EdgeTex;
// 輸入結(jié)構(gòu)
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
float3 normal:NORMAL;//法線通常都是必須的
float4 tangent : TANGENT;
float3 color:COLOR0;
};
// 輸出結(jié)構(gòu)
struct v2f
{
float4 uv : TEXCOORD0;
float4 vertex : SV_POSITION; // 由模型頂點(diǎn)信息換算而來的頂點(diǎn)屏幕位置
float depth : TEXCOORD2;
float3 normal:NORMAL;//法線通常都是必須的
float4 lightDir_Tangent:TEXCOORD5;
float4 screenuv:TEXCOORD1;
float3 viewDir:TEXCOORD3;
float4 vertex_Local : TEXCOORD4;
float3 color:COLOR0;
};
// 輸入結(jié)構(gòu)>>>頂點(diǎn)Shader>>>輸出結(jié)構(gòu)
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;這種寫法也可以,當(dāng)然下面的高度也要用下面這句
//v.vertex.y = v.vertex.y + tempN * _WaveHeight + height;
float height = 0;
fixed wavebevel = 5;
fixed attenuation = (1.0 - v.uv.y);
//1喇颁、波浪效果
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);// 背景紋理采樣坐標(biāo)
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, _BowenTex);//擾動波紋紋理Tilling
o.uv.zw = TRANSFORM_TEX(v.uv, _WaveNormalMap);
//UNITY_TRANSFER_FOG(o, o.vertex);
return o;
}
fixed4 texCross(sampler2D tex, float2 uv, float speed)
{
float4 col1 = tex2D(tex, uv + float2(-_Time.x*speed, -_Time.x*speed));
float4 col2 = tex2D(tex, uv + float2(_Time.x*speed*0.5, _Time.x*0.15*speed));
float4 col3 = tex2D(tex, uv + float2(_Time.x*speed*0.84, -_Time.x*0.11*speed));
float4 col4 = tex2D(tex, uv + float2(_Time.x*speed*0.105, -_Time.x*0.3515*speed));
return (col1 + col2 + col3 + col4) / 4;
}
// 輸出結(jié)構(gòu)>>>像素
fixed4 frag(v2f i) : SV_Target
{
//屏幕深度Z
float ScreenZ = LinearEyeDepth(SAMPLE_DEPTH_TEXTURE_PROJ(_CameraDepthTexture, UNITY_PROJ_COORD(i.screenuv)));
float halfWidth = _EdgeWidth * 0.5f;
float diff = saturate(abs(i.depth - ScreenZ) / halfWidth);
fixed mask = dot(i.normal, float3(0, -1, 0)) + 0.5;
mask = mask > 0.2 ? 0 : 1;
//4、Bowen Col
fixed4 boWen = texCross(_BowenTex, i.uv, _BowenSpeed)*mask;
boWen.a = 0;
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);
//越遠(yuǎn)越白
fixed d1 = clamp(abs(i.depth - ScreenZ)*0.1 + 0.1, 0, 1.0);
//燈光方向
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);
//高光,15是高光程度,這個參數(shù)也可以開放出去
fixed3 specular = max(pow(max(0, dot(i.viewDir, reflectDir)), 15), 0) * (1.0 - d);
//5姐叁、岸線
//岸線顔色
fixed4 edgeCol = mask > 0 ? lerp(_EdgeWidth, _Color, diff) : _Color;
//水岸線
fixed edge = mask > 0 ? abs(lerp(_EdgeWidth, 0, diff)) : 0;
float4 finalCol = fixed4(diffuse, 0);
//2瓦盛、透明水
//Grab Tex
fixed4 grabCol;//水的主體透明顏色值
grabCol = tex2D(_GrabPassTex, i.screenuv.xy / i.screenuv.w);
//深色
grabCol = lerp(grabCol + boWen * _BowenOpacity, lerp(grabCol, _Color, _Color.a) + boWen *0.1, _Opacity);
//水岸線最終輸出
fixed mm = (d - edge) * 2;
fixed2 edgeUV = i.uv.xy / _BowenTex_ST.xy;
fixed4 edgeColFinal = tex2D(_EdgeTex, edgeUV + float2(0.5 + sin(_Time.x), d*0.5 - _Time.x*_EdgeSpeed)).r*mm;
edgeColFinal *= tex2D(_EdgeTex, edgeUV + float2(0.5 - sin(_Time.x), d*0.5 - _Time.x*_EdgeSpeed)).r*mm;
edgeColFinal *= edgeCol.r*0.8;
finalCol = grabCol;
if (mask > 0)
finalCol.rgb += specular * 2;
return finalCol * _LightColor0 + edgeColFinal * mask;
}
ENDCG
}
}
}
水岸線關(guān)鍵代碼:
//水岸線最終輸出
fixed mm = (d - edge) * 2;
fixed2 edgeUV = i.uv.xy / _BowenTex_ST.xy;
fixed4 edgeColFinal = tex2D(_EdgeTex, edgeUV + float2(0.5 + sin(_Time.x), d0.5 - _Time.x_EdgeSpeed)).rmm;
edgeColFinal = tex2D(_EdgeTex, edgeUV + float2(0.5 - sin(_Time.x), d0.5 - _Time.x_EdgeSpeed)).r*mm;
edgeColFinal = edgeCol.r0.8;
最終效果圖:
2.gif
面板參數(shù):
image.png