栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 游戏开发 > Cocos2d-x

Unity Shader 水多种元素的实现(反射、折射、菲涅尔、深浅、浪花/泡沫、水波、可交互)

Cocos2d-x 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Unity Shader 水多种元素的实现(反射、折射、菲涅尔、深浅、浪花/泡沫、水波、可交互)

综合效果

经过各元素叠加 和 程序的审美调参 后的综合效果
交互的水波与边缘浪花的合并需要优化一下

反射

两种方案:

  1. cubeMap
  2. 以水面对称设一个摄像机
cubeMap

实现:反射探针生成CubeMap
特性:
● 对于近处的反射会有明显的错位
● 适用于对清晰度要求不高,性能要求高的情况

设置反射摄像机

原理:在平面对称镜头摄像机的位置,建一个反射摄像机,渲染反射贴图。shader用屏幕坐标对反射贴图采样即可得到镜像

反射贴图:

//---------- 反射 ---------

float3 worldPos = float3(i.TtoW0.w, i.TtoW1.w, i.TtoW2.w);
fixed3 viewDir = normalize(UnityWorldSpaceViewDir(worldPos));

float3 tangentNormal = fixed3(0,0,1);//bump;//
//return fixed4(bump, 1);//看法线
fixed3 worldNormal = normalize(half3(dot(i.TtoW0.xyz, tangentNormal), dot(i.TtoW1.xyz, tangentNormal), dot(i.TtoW2.xyz, tangentNormal)));

	//------ cubeMap
// fixed4 texColor = tex2D(_MainTex, i.uv.xy + speed);
// fixed3 reflDir = reflect(-viewDir, worldNormal);
// fixed3 reflCol = texCUBE(_Cubemap, reflDir).rgb ;// * _Color.rgb;

	//------ 对称相机
float2 screenUV = i.scrPos.xy/i.scrPos.w - worldNormal.xz * _ReflDistortion*_Reflection_TexelSize.xy;
fixed4 texColor = tex2D(_MainTex, i.uv.xy + speed);
fixed3 reflCol = tex2D(_Reflection, screenUV).rgb  * _Color.rgb;//* texColor.rgb

return fixed4(reflCol, 1);
折射

参考《入门精要》的实现:GrabPass获得水后图像,采样噪音纹理得到offset,然后转移到tangent空间做偏移,达到随机扭曲的效果

菲涅尔效应


水的F_0 为0.02

	fixed fresnel = pow(1 - saturate(dot(viewDir, worldNormal)), 4);// 水F0 ~= 0
	fixed3 reColor = reflCol * fresnel + refrCol * (1 - fresnel);
深浅

利用深度图、视线深度来实现

浪花/泡沫
  1. 利用深度差计算一个浪花强度:相当于提取出边缘
  2. 利用浪花强度来采样坡度贴图:

可以得到

3. 再叠加浪花纹理:

得到

4. 最终浪花效果:

//---------- 浪花 ---------
	float intensityFactor = 1 - saturate(deltaDepth / _FoamStrength);    
	half3 foamGradient = 1 - tex2D(_FoamGradient, float2(intensityFactor - _Time.y*0.2, 0) + bump.xy * 0.15);

	float2 foamDistortUV = bump.xy * 0.2;
	half3 foamTex = tex2D(_Foam, i.foamUV + foamDistortUV).rgb;
	fixed4 foamColor = fixed4(foamGradient * intensityFactor * foamTex, 1);
波浪

多种方案:

  1. 随时间扰动 噪音法线贴图
  2. flowmap 参考之前的文章
  3. Gerstner参考此文
  4. FFT参考此文
可交互

参考该项目

  1. 主要分为三个Shader:生成波浪Shader、传输波浪Shader、渲染波浪Shader;
    三张纹理图:传递波浪高度贴图、生成波浪高度贴图、前一帧高度贴图
    一个摄像机脚本:记录点击位置,传给生成波浪Shader
  2. 以传递波浪高度贴图作为载体,每次渲染 先叠加 生成波浪Shader生成的波浪高度贴图 ,再叠加 利用前一帧高度贴图在 传输波浪Shader算出的衰减高度(衰减参考波的传递公式),得到最终波浪高度贴图
  3. 在渲染波浪Shader中,采样波浪高度贴图,对顶点进行偏移;对片元插值波浪颜色

渲染Shader
顶点部分:

...
float4 localPos = v.vertex;
float2 waveUv = v.texcoord.xy;
float4 waveTransmit = tex2Dlod(_WaveResult, float4(waveUv, 0, 0));
float waveHeight = DecodeFloatRGBA(waveTransmit);

localPos.y += waveHeight * _WaveScale;
float3 worldPos = mul(unity_ObjectToWorld, localPos);

o.vertex = mul(UNITY_MATRIX_VP, float4(worldPos, 1));
...

片元部分:

...
float4 waveTransmit = tex2Dlod(_WaveResult, float4(i.uv.xy, 0, 0));
float waveHeight = DecodeFloatRGBA(waveTransmit) * _WaveScale;
return lerp(finalCol, _WaveColor, waveHeight);
TODO 水下3D

3D贴图?

焦散


用焦散法线噪音贴图来模拟?

散射 辉光

项目地址 参考资料

《Unity Shader入门精要》
https://blog.csdn.net/ZanDatsu/article/details/107865706
http://blog.sina.com.cn/s/blog_89d90b7c0102vgk1.html
https://github.com/dreamfairy/interactivity-waterplane
https://blog.csdn.net/LeoHiJack/article/details/78329543
https://www.youtube.com/watch?v=zD6GV6bZenM

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/896510.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号