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