当前位置:网站首页>Water rendering example
Water rendering example
2022-07-28 06:41:00 【Mr.QSheng】
Water rendering
This time I share about the rendering of water , It is by far the most satisfactory result of self-made , The specific process is similar to many on the Internet
Running effect

Effect analysis
1. Wave effect , You can see the water from high to low , The effect of the reef being covered and exposed .
2. Secondly, the effect of horizontal flow
3. The middle part of the water is dark , The depth effect of light surrounding color
1. Wave effect
The realization of wave effect is mainly through sin Curve combination time coefficient , Then modify the vertex position along the normal to achieve , But we also join here z The influence of depth , Make it farther away , The effect of water surface fluctuation is also obvious
The code is as follows ( Example ):
v2f o;
float3 local_vert = v.vertex;
float3 offset_vert = (_WaveAmplitude * sin(_WaveAmount * local_vert.z + _Time.y)) * v.normal;
v.vertex.xyz += offset_vert;
o.vertex = UnityObjectToClipPos(v.vertex);
2. Secondly, the effect of horizontal flow
The effect of water flow is to stagger the sampled normal texture , Then mix it into new normals
loat2 panner22 = ( 1.0 * _Time.y * float2( -0.03,0 ) + uv0_WaterNormal);
float2 panner19 = ( 1.0 * _Time.y * float2( 0.04,0.04 ) + uv0_WaterNormal);
float3 normal_1 = UnpackNormal(tex2D(_WaterNormal, panner22));
float3 normal_2 = UnpackNormal(tex2D(_WaterNormal, panner19));
float3 blend_normal = normal_1 + normal_2;
blend_normal.xy *= _NormalScale;
blend_normal = normalize(blend_normal);
The middle part of the water is dark , The depth effect of light surrounding color
Sampling depth map , Make a deep comparison
float depth = LinearEyeDepth(SAMPLE_DEPTH_TEXTURE_PROJ(_CameraDepthTexture, UNITY_PROJ_COORD(i.srceen_pos)));
float diff = saturate(pow(abs(depth - i.srceen_pos.z) + _WaterDepth, _WaterFalloff));
float4 lerpResult13 = lerp(_DeepColor, _ShalowColor, diff);
sampling _GrabTexture texture , Blend edge effects
float2 grab_uv = (i.srceen_pos.xy / i.srceen_pos.w);
float4 grab = tex2D(_GrabTexture, (float3(grab_uv, 0) + blend_normal * _Distortion).xy);
float4 lerpResult93 = lerp(lerpResult117, grab, diff);
Basic lighting
float3 albedo = lerpResult93.rgb;
float3 ambient = UNITY_LIGHTMODEL_AMBIENT.rgb * albedo;
float3 diffuse = _LightColor0.rgb * albedo * saturate(dot(world_normal, world_light_dir));
float3 half_spec = normalize(world_view_dir + world_light_dir);
float3 specular = _LightColor0.rgb * albedo * pow(saturate(dot(world_normal, half_spec)), _Specular) * _WaterSmoothness ;
Complete code
Properties
{
_WaterNormal("WaterNormal", 2D) = "bump" {
}
_NormalScale("Normal Scale", Float) = 0
_DeepColor("DeepColor", Color) = (0, 0, 0, 0)
_ShalowColor("ShalowColor", Color) = (1, 1 ,1, 1)
_WaterDepth("Water Depth", Float) = 0
_WaterFalloff("Water Falloff", Float) = 0
_Distortion("Distortion", Float) = 0.5
_Foam("Foam", 2D) = "white" {
}
_FoamDepth("FoamDepth", Float) = 0
_FoamFalloff("Foam Falloff", Float) = 0
_WaveAmplitude("WaveAmpitude", Float) = 0.1
_WaveAmount("WaveAmount", Float) = 8
_Specular("Specular", Float) = 2
_WaterSmoothness("WaterSmoothness", Float) = 1
}
SubShader
{
Tags {
"RenderType"="Opaque" "Queue"="Transparent" "LightdMode"="ForwardBase"}
LOD 100
GrabPass{
}
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#include "Lighting.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
float3 normal :NORMAL;
float4 tangle : TANGENT;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
float4 srceen_pos :TEXCOORD1 ;
float4 Ttow0 :TEXCOORD2;
float4 Ttow1:TEXCOORD3 ;
float4 Ttow2:TEXCOORD4 ;
};
sampler2D _WaterNormal;
float4 _WaterNormal_ST;
float _NormalScale;
float4 _DeepColor;
float4 _ShalowColor;
float _WaterDepth;
float _WaterFalloff;
float _Distortion;
sampler2D _Foam;
float4 _Foam_ST;
float _FoamDepth;
float _FoamFalloff;
float _WaveAmplitude;
float _WaveAmount;
sampler2D _CameraDepthTexture;
float _Specular;
float _WaterSmoothness;
sampler2D _GrabTexture;
v2f vert (appdata v)
{
v2f o;
float3 local_vert = v.vertex;
float3 offset_vert = (_WaveAmplitude * sin(_WaveAmount * local_vert.z + _Time.y)) * v.normal;
v.vertex.xyz += offset_vert;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
o.srceen_pos = ComputeScreenPos(o.vertex);
COMPUTE_EYEDEPTH(o.srceen_pos.z);
float3 world_pos = mul(unity_ObjectToWorld, v.vertex);
float3 world_normal = UnityObjectToWorldNormal(v.normal);
float3 world_tangel = UnityObjectToWorldDir(v.tangle);
float3 world_borind = cross(world_normal, world_tangel) * v.tangle.w;
o.Ttow0 = float4(world_tangel.x, world_borind.x, world_normal.x, world_pos.x);
o.Ttow1 = float4(world_tangel.y, world_borind.y, world_normal.y, world_pos.y);
o.Ttow2 = float4(world_tangel.z, world_borind.z, world_normal.z, world_pos.z);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
float2 uv0_WaterNormal = i.uv * _WaterNormal_ST.xy + _WaterNormal_ST.zw;
float2 panner22 = ( 1.0 * _Time.y * float2( -0.03,0 ) + uv0_WaterNormal);
float2 panner19 = ( 1.0 * _Time.y * float2( 0.04,0.04 ) + uv0_WaterNormal);
float3 normal_1 = UnpackNormal(tex2D(_WaterNormal, panner22));
float3 normal_2 = UnpackNormal(tex2D(_WaterNormal, panner19));
float3 blend_normal = normal_1 + normal_2;
blend_normal.xy *= _NormalScale;
blend_normal = normalize(blend_normal);
float3 world_pos = float3(i.Ttow0.w, i.Ttow1.w, i.Ttow2.w);
float3 world_view_dir = normalize(UnityWorldSpaceViewDir(world_pos));
float3 world_light_dir = normalize(UnityWorldSpaceLightDir(world_pos));
float3 world_normal = float3(dot(i.Ttow0.xyz, blend_normal), dot(i.Ttow1.xyz, blend_normal),
dot(i.Ttow2.xyz, blend_normal));
float depth = LinearEyeDepth(SAMPLE_DEPTH_TEXTURE_PROJ(_CameraDepthTexture, UNITY_PROJ_COORD(i.srceen_pos)));
float diff = saturate(pow(abs(depth - i.srceen_pos.z) + _WaterDepth, _WaterFalloff));
float4 lerpResult13 = lerp(_DeepColor, _ShalowColor, diff);
float2 uv_foam = _Foam_ST.xy * ((_Time.x * float2(0.1, 0.1)) + i.uv);
float3 foam = tex2D(_Foam, uv_foam);
float foam_diff = saturate(pow((abs(depth - i.srceen_pos.z) + _FoamDepth), _FoamFalloff) * foam.r);
float4 lerpResult117 = lerp( lerpResult13 , float4(1,1,1,0) , foam_diff);
float2 grab_uv = (i.srceen_pos.xy / i.srceen_pos.w);
float4 grab = tex2D(_GrabTexture, (float3(grab_uv, 0) + blend_normal * _Distortion).xy);
float4 lerpResult93 = lerp(lerpResult117, grab, diff);
float3 albedo = lerpResult93.rgb;
float3 ambient = UNITY_LIGHTMODEL_AMBIENT.rgb * albedo;
float3 diffuse = _LightColor0.rgb * albedo * saturate(dot(world_normal, world_light_dir));
float3 half_spec = normalize(world_view_dir + world_light_dir);
float3 specular = _LightColor0.rgb * albedo * pow(saturate(dot(world_normal, half_spec)), _Specular) * _WaterSmoothness ;
return fixed4(ambient + diffuse + specular, 1);
//return fixed4(grab, 1);
}
ENDCG
}
}
summary
That's what we're sharing , Other effects will be updated continuously in the future .
边栏推荐
猜你喜欢
随机推荐
Mysql-8.0.17-winx64 (additional Navicat) manual configuration version installation
OJ 1284 counting problem
What is hash? (development of Quantitative Trading Robot System)
OJ 1020 最小的回文数
OJ 1253 点菜问题
OJ 1131 美丽数
图形管线基础(一)
OJ 1089 Spring Festival travel
Getting started with hugging face
[pta---- output full arrangement]
Leetcode 刷题日记 剑指 Offer II 048. 序列化与反序列化二叉树
江中ACM新生10月26日习题题解
Leetcode 刷题日记 剑指 Offer II 055. 二叉搜索树迭代器
[C note] data type and storage
NFT data storage blind box + mode system development
Treasure plan TPC system development DAPP construction
What's a good gift for your girlfriend on Chinese Valentine's day? Boys who can't give gifts, look!
OJ 1451 digital games
代码整洁之道(二)
OJ 1045 反转然后相加


![[PTA----树的遍历]](/img/d8/260317b30d624f8e518f8758706ab9.png)
![[untitled]](/img/de/746832bfb3bb79b090215b135b8917.jpg)





