顶点着色器实现水面的起伏效果
片元着色器实现波纹效果(没有运行,所以看上去是规律的黑色斑点。。。)
各种函数实现取自Unity官网对ShaderGraph的Node的解析
Properties
{
_MainTex ("Texture", 2D) = "white" {}
_WaterSpeed("波浪起伏的速度", float) = 0.2
_WaterScale("波浪的范围", float) = 2
_RippleSpeed("波纹的速度",float) = 1
_RippleDensity("波纹的密度",float) = 1
_RippleRate("波纹的大小系数",float) = 1
_RippleColor("波纹的颜色",color) = (1,1,1,1)
_WaveColor("海水的颜色",color) = (1,1,1,1)
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
// make fog work
#pragma multi_compile_fog
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
float3 normal: NORMAL;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
float4 objPos:TEXCOORD1;
float3 Objnormal: NORMAL;
};
sampler2D _MainTex;
float4 _MainTex_ST;
float _WaterSpeed;
float _WaterScale;
float _RippleSpeed;
float _RippleDensity;
float _RippleRate;
fixed4 _RippleColor;
fixed4 _WaveColor;
//Gradient Noise的函数,用于模型顶点的波动
float2 unity_gradientNoise_dir(float2 p)
{
p = p % 289;
float x = (34 * p.x + 1) * p.x % 289 + p.y;
x = (34 * x + 1) * x % 289;
x = frac(x / 41) * 2 - 1;
return normalize(float2(x - floor(x + 0.5), abs(x) - 0.5));
}
float unity_gradientNoise(float2 p)
{
float2 ip = floor(p);
float2 fp = frac(p);
float d00 = dot(unity_gradientNoise_dir(ip), fp);
float d01 = dot(unity_gradientNoise_dir(ip + float2(0, 1)), fp - float2(0, 1));
float d10 = dot(unity_gradientNoise_dir(ip + float2(1, 0)), fp - float2(1, 0));
float d11 = dot(unity_gradientNoise_dir(ip + float2(1, 1)), fp - float2(1, 1));
fp = fp * fp * fp * (fp * (fp * 6 - 15) + 10);
return lerp(lerp(d00, d01, fp.y), lerp(d10, d11, fp.y), fp.x);
}
float Unity_GradientNoise_float(float2 UV, float Scale)
{
return unity_gradientNoise(UV * Scale) + 0.5;
}
v2f vert (appdata v)
{
v2f o;
// o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
o.objPos = v.vertex;
o.Objnormal = v.normal;
//偏移量=时间*波浪速度
float2 offsetVer = _Time.y * _WaterSpeed;
//模型的顶点坐标
float2 waveuv = o.uv * float2(1, 1) + offsetVer;
//模拟的是ShaderGraph的Gradient Noise节点的计算方式
float Gradient = Unity_GradientNoise_float(waveuv, _WaterScale);
//计算出模型空间下波浪状顶点的坐标
half3 waveVertex = o.Objnormal * Gradient + o.objPos;
o.vertex = UnityObjectToClipPos(waveVertex);
return o;
}
//Radial ShearH函数方法
float2 Unity_RadialShear_float(float2 UV, float2 Center, float Strength, float2 Offset)
{
float2 delta = UV - Center;
float delta2 = dot(delta.xy, delta.xy);
float2 delta_offset = delta2 * Strength;
return UV + float2(delta.y, -delta.x) * delta_offset + Offset;
}
//Voronoi函数
inline float2 unity_voronoi_noise_randomVector(float2 UV, float offset)
{
float2x2 m = float2x2(15.27, 47.63, 99.41, 89.98);
UV = frac(sin(mul(UV, m)) * 46839.32);
return float2(sin(UV.y * +offset) * 0.5 + 0.5, cos(UV.x * offset) * 0.5 + 0.5);
}
void Unity_Voronoi_float(float2 UV, float AngleOffset, float CellDensity,out float Out)
{
float2 g = floor(UV * CellDensity);
float2 f = frac(UV * CellDensity);
float t = 8.0;
float3 res = float3(8.0, 0.0, 0.0);
for (int y = -1; y <= 1; y++)
{
for (int x = -1; x <= 1; x++)
{
float2 lattice = float2(x, y);
float2 offset = unity_voronoi_noise_randomVector(lattice + g, AngleOffset);
float d = distance(lattice + offset, f);
if (d < res.x)
{
res = float3(d, offset.x, offset.y);
Out = res.x;
//Cells = res.y;
//return res.x;
}
}
}
//return 0;
}
fixed4 frag(v2f i) : SV_Target
{
//Radial Shear 径向剪切输出结果作为Voronoi的UV
float2 Voruv = Unity_RadialShear_float(i.uv,float2(0.5,0.5),1,0);
//Voronoi的Angle Offset=时间的Y*波纹速度
float VorAngOffset = _Time.y * _RippleSpeed;
//Voronoi函数Out出来的float值
float Vornum;
Unity_Voronoi_float(Voruv, VorAngOffset, _RippleDensity, Vornum);
//FinColor=power(Vornum,_RippleRate)*_RippleColor,输出的最终颜色
fixed4 FinColor = pow(Vornum, _RippleRate) * _RippleColor;
// fixed4 col = tex2D(_MainTex, i.uv);
return FinColor+ _WaveColor;
}
ENDCG
}
}