当前位置:网站首页>水渲染示例
水渲染示例
2022-07-28 05:27:00 【Mr.QSheng】
水渲染
本次分享的是关于水体的渲染,是目前为止自己做的效果最满意的 ,具体流程跟网上很多都相似
运行效果

效果分析
1.波浪效果,能看到水面时高时低,礁石被覆盖和露出的效果。
2.其次水平面流动的效果
3.水面中间部分颜色深,周围颜色浅的深度效果
1.波浪效果
波浪效果的实现主要通过sin曲线结合时间系数,然后沿着法线修改顶点位置实现,不过我们这里还加入z深度的影响,使其越远,水面起伏效果也明显
代码如下(示例):
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.其次水平面流动的效果
水面流动效果就是错开采样法线纹理,再混合成新的法线
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);
水面中间部分颜色深,周围颜色浅的深度效果
采样深度图,做深度对比
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);
采样_GrabTexture 纹理,混合边缘效果
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 ;
完整代码
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
}
}
总结
以上就是本次分享内容,后续会持续更新其他效果。
边栏推荐
- 自定义组件--插槽
- QT painting event - set background picture
- 小程序创建组件
- Solve the problem that the memory occupation is higher than that of the application process
- Get the current directory in QT
- OJ 1242 大一上之初出茅庐
- 【学习笔记】驱动
- 【二叉树基础知识】
- OpenGL development environment configuration [vs2017] + frequently asked questions
- Treasure plan TPC system development DAPP construction
猜你喜欢

【C语言】字符串库函数介绍及模拟

如何模拟实现strcpy库函数

Hugging face's problem record I

刷题记录----二叉树的层序遍历

What are the open earphones? Four types of air conduction earphones with excellent sound quality are recommended

2022-05-24 use of spiel

What is hash? (development of Quantitative Trading Robot System)

Problems of font modification and line spacing in word automatic directory

【C笔记】数据类型及存储

气传导蓝牙耳机什么牌子好、气传导耳机最好的品牌推荐
随机推荐
Perl introductory learning (XI) file operation
OJ 1451 数字游戏
[PTA----输出全排列]
[哈希表基础知识]
2022-05-24 use of spiel
[队列,栈的简单应用----包装机]
Icc2 (III) clock tree synthesis
OJ 1242 大一上之初出茅庐
刷题记录----哈希表
SSAO By Computer Shader(二)
error: redefinition of ‘xxx‘
MFC uses the console to print program information
Execjs call
新的selenium
Development of Quantitative Trading Robot System
[c语言]简易通讯录的实现
Listener
微信小程序自定义编译模式
2022-07-19 Damon database connection instance, execution script, system command
【学习笔记】编码能力