Unity water shader with depth and distortion
Thu Mar 10 2022 17:49:35 GMT+0000 (Coordinated Universal Time)
Saved by @BryanJ22
Shader "Water/SimpleWater"
{
Properties
{
[Header(Appearance)] [Space]
_MainTex ("Water Texture", 2D) = "white" {}
[Space]
_Color("Tint", Color) = (1,1,1,1)
_Emission("Emissive Color", Color) = (0.1886792,0.1486294,0.1486294,1)
_Opacity("Opacity", Range(0,1)) = .85
[Header(Wave Distortion)] [Space]
_NoiseTex("Noise Texture", 2D) = "white" {}
[Space]
_NoiseSize("Noise Fineness", Range(0.01, 1)) = 0.126
_Frequency("Frequency", Range(2, 0.2)) = 0.5
_Intensity("Intensity", Range(0.0002, .0035)) = 0.002
_Containment("Containment", Range(0.22, 2.5)) = 0.73
[Header(Movement)][Space]
_HorizontalSpeed("Horizontal Speed", Range(0, 20)) = 12
_VerticalSpeed("Vertical Speed", Range(0, 20)) = 2
[Space]
//Create a dropdown of Enum values and their numeric equivalents
[Enum(Left,0,Right,2)] _HorizontalDirection("Horizontal Direction", Float) = 0
[Enum(Down,0,Up,2)] _VerticalDirection("Vertical Direction", Float) = 0
[Header(Wave Behavior)][Space]
_WaveFrequency("Frequency", Range(0, 1.6)) = 0.4
_WaveSpeed("Speed", Range(0,10)) = 5
_WaveHeight("Height", Range(0,1)) = .16
[Header(Underwater Fog)][Space]
_WaterFogDensity("Fog Density", Range(0.3,4)) = 1.3
[Header(Underwater Distortion)][Space]
_RefractionStrength("Distrortion Strength", Range(0,1)) = 0.5
}
SubShader
{
Tags {"Queue" = "Transparent" "RenderType"="Transparent" }
LOD 200
//Use Grabpass to get background color
//Reduce GrabPass to single draw call giving grabbed texture explicit name, which is set in WaterMaths.cginc
GrabPass{"_WaterBackground"}
CGPROGRAM
//include our cginc file
#include "WaterMaths.cginc"
//Physically based Standard lighting model, and enable shadows on all light types
//use ResetAlpha function of finalcolor type to reset alpha value
#pragma surface surf StandardSpecular alpha fullforwardshadows vertex:CreateWaves finalcolor:ResetAlpha
//Use shader model 3.0 target, to get nicer looking lighting
#pragma target 3.0
fixed4 _Color, _Emission;
sampler2D _MainTex, _NoiseTex;
half _HorizontalSpeed, _VerticalSpeed;
half _Opacity;
float _HorizontalDirection;
float _VerticalDirection;
half _NoiseSize, _Frequency, _Intensity, _Containment;
half _WaveFrequency, _WaveSpeed, _WaveHeight;
//time var set in our buoyancy c# script so floating objects and waves are in sync
float _time;
struct Input
{
float2 uv_MainTex;
//for grabbing screen uv
half4 screenPos;
};
void CreateWaves(inout appdata_full v)
{
//if in editor mode, set _time var to built in _Time variable since it can't be set in script
if (!_time)
_time = _Time.y;
//Create Waves math
//multiply time var with wave speed var to get speed
half speed = _time * _WaveSpeed;
half4 wpos = mul(unity_ObjectToWorld, v.vertex);
float waveValueA = sin(speed + wpos.x * _WaveFrequency) * _WaveHeight;
wpos.y += waveValueA;
v.vertex = mul(unity_WorldToObject, wpos);
v.normal.x += waveValueA * .03f;
//
}
void surf (Input IN, inout SurfaceOutputStandardSpecular o)
{
//offset the _HorizontalDirection/_VerticalDirection variables to give -1 or 1,
//since Enum values can not be negative and we need negative values to change texture scroll direction
int Xfloat = _HorizontalDirection - 1;
int Zfloat = _VerticalDirection - 1;
//
//Scrolling texture
fixed2 ScrolledUV = IN.uv_MainTex;
fixed MoveX = _HorizontalSpeed * Xfloat * _Time;
fixed MoveZ = _VerticalSpeed * Zfloat * _Time;
ScrolledUV += fixed2(MoveX, MoveZ);
//
//Grab updated water text that has been moved using ScrolledUV
//and grab noise texture but use the water texture UV's
fixed4 waterTex = tex2D(_MainTex, ScrolledUV);
fixed4 noise = tex2D(_NoiseTex, ScrolledUV * _NoiseSize);
half waterDistortion =
DistortWater
(
half(_Time[1]) + (noise.xy) * _Containment,
half(-_Intensity),
half(_Intensity),
half(_Frequency));
fixed4 finalColor = tex2D(_MainTex, (ScrolledUV * .18) + waterDistortion * 5) * _Color;
// Albedo comes from a texture tinted by color
o.Albedo = finalColor.rgb;
o.Alpha = _Opacity;
o.Emission = _Emission * ColorBelowWater(IN.screenPos, o.Albedo);
}
void ResetAlpha(Input IN, SurfaceOutputStandardSpecular o, inout fixed4 color)
{
color.a = 1;
}
ENDCG
}
}
Water shader for Unity that includes depth based alpha, moving vertices to create waves and image distortion.



Comments