再加亿点点细节!Cocos 基于平面着色的 3D 水面渲染方案

再加亿点点细节!Cocos 基于平面着色的 3D 水面渲染方案

但该项目基于 Cocos Creator 延迟渲染管线,对项目和装备要求较高,以是麒麟子专门准备了这个自力的水面效果分享,希望能够对人人有所辅助。

二、水面渲染流程

水面渲染手艺异常多,差异段位的产物,对水面的要求差异。

毛星云的《真实感水体渲染手艺总结》这篇文章中,通过对一些 3A 大作的水面渲染举行剖析,列出了异常多的手艺要点,有兴趣的同伙可以拜读。

水面渲染手艺从简朴到庞大来排序,可以分为以下三类:

平面着色

再加亿点点细节!Cocos 基于平面着色的 3D 水面渲染方案

极点动画

再加亿点点细节!Cocos 基于平面着色的 3D 水面渲染方案

流体模拟

再加亿点点细节!Cocos 基于平面着色的 3D 水面渲染方案

本文实现的是基于平面着色的水面效果,虽然它并非高端效果,但却是大部门 3D 项目中接纳的方案。

基于平面着色的水面渲染主要涉及以下几个部门:

反射

折射

水深效果

水岸柔边

动态天空盒

法线图与光照

岸边浪花

由于时间关系,法线图与光照与岸边浪花暂未实现。

尺度的渲染流程如下所示:

再加亿点点细节!Cocos 基于平面着色的 3D 水面渲染方案

可以看出,若是要实现所有用果,至少需要绘制场景4次。

由于这里的深度图只是和折射搭配使用,8位精度足够用了,我们可以思量借用折射图中的 Alpha 通道来存储深度信息。

优化后的流程图如下:

再加亿点点细节!Cocos 基于平面着色的 3D 水面渲染方案

三、反射贴图渲染

麒麟子在《用实时反射 Shader 增强画面颜值》中已经完整地剖析了实时反射相关原理,在此就不再敷述,有需要领会的读者可直接点击查看。

这里主要讲一讲本 DEMO 中的实现步骤。

步骤1:使用代码新建一个 RenderTexture。

步骤2:确立一个节点,添加摄像机组件,并将 clearFlags、clearColor、visibility 属性与主摄像机同步。

步骤3:设置反射摄像机的渲染优先级,确保比主摄像机先渲染。

步骤4:将新确立的 RenderTexture 赋值给此摄像机的 targetTexture 属性。

以上步骤的代码在 WaterPlane.ts 中,如下图所示:

再加亿点点细节!Cocos 基于平面着色的 3D 水面渲染方案

步骤5:在 lateUpdate 中同步主摄像机参数。

再加亿点点细节!Cocos 基于平面着色的 3D 水面渲染方案

步骤6:在 lateUpdate 中凭证实时反射原理,动态盘算摄像机关于主摄像机的镜像位置和旋转。

最终,渲染获得的 RenderTexture 如下:

再加亿点点细节!Cocos 基于平面着色的 3D 水面渲染方案

麒麟小贴士:

所有物体的材质,需要加入自界说裁剪面,裁剪掉水面以下的部门。

可以显著看到,上图中绿色物体的倒影,水面以下的部门是被裁剪掉了的。

四、折射贴图渲染

折射渲染的原理异常简朴:

渲染水平面以下的部门到 RenderTexture

在水面渲染阶段使用噪声图举行扰动,以模拟出水面折射效果

折射渲染的流程与反射渲染大致相同,只有两个细小的差异:

用于折射渲染的摄像机所有参数均与主摄像保持一致即可

折射渲染阶段,物体被裁剪掉的是水面以上的部门

下面我们来看看,本 DEMO 中关于折射的实现步骤。

步骤1:使用代码新建一个 RenderTexture。

步骤2:确立一个节点,添加摄像机组件,并将 clearFlags、clearColor、visibility 属性与主摄像机同步。

步骤3:设置反射摄像机的渲染优先级,确保比主摄像机先渲染。

步骤4:将新确立的 RenderTexture 赋值给此摄像机的 targetTexture 属性。

以上步骤的代码在 WaterPlane.ts 中,如下图所示:

再加亿点点细节!Cocos 基于平面着色的 3D 水面渲染方案

麒麟小贴士: 注重红色线框部门,本 DEMO 中折射贴图的 Alpha 通道用于符号深度信息,以是需要确保 Alpha 通道的值为 255。

步骤5:在 lateUpdate 中同步主摄像机参数、位置、旋转等信息。

最终,渲染获得的 RenderTexture 如下:

再加亿点点细节!Cocos 基于平面着色的 3D 水面渲染方案

五、水面渲染

水面渲染主要行使了投影纹理手艺,将极点的投影坐标转化为 UV,对折射和反射贴图举行采样。

由于使用了折射贴图,我们的水面材质不需要开启 Alpha 夹杂。

折射渲染

步骤1:凭证投影坐标盘算出屏幕 UV。如下所示:

vec2 screenUV = v_screenPos.xy / v_screenPos.w * 0.5 + 0.5;

步骤2:采样折射贴图,可以获得如下渲染效果:

再加亿点点细节!Cocos 基于平面着色的 3D 水面渲染方案

左边为正常渲染效果,右边为符号了折射内容的效果

步骤3:使用噪声图对折射举行扰动,可获得如下效果:

再加亿点点细节!Cocos 基于平面着色的 3D 水面渲染方案

反射渲染

步骤1:与折射渲染一样,凭证投影坐标盘算出屏幕 UV。

步骤2:采样反射贴图,可以获得如下渲染效果:

再加亿点点细节!Cocos 基于平面着色的 3D 水面渲染方案

步骤3:使用噪声图对反射举行扰动,可获得如下效果:

再加亿点点细节!Cocos 基于平面着色的 3D 水面渲染方案

菲涅尔夹杂

菲涅尔的盘算公式从玉兔的边缘光教程最先,到实时反射等场所,已经泛起过许多次了。下面是焦点代码:

再加亿点点细节!Cocos 基于平面着色的 3D 水面渲染方案

折射可以视为水体本色,行使菲涅尔因子与反射内容夹杂,即可实现一个带折射和反射的水体效果。

伪代码如下:

finalColor = mix(refractionColor,reflectionColor,fresnel)

最终可以获得如下显示效果:

再加亿点点细节!Cocos 基于平面着色的 3D 水面渲染方案

完整代码代码请查看项目中的 effect-water.effect 文件。

六、水深效果

从上面的动画中可以看出,虽然折射和反射效果都有了。但画风有些新鲜,完全没有水面的感受。

这是水面没有深浅效果导致的。

我们来看看,若何获取深度信息,并凭证深度信息实现水深效果。

获取深度信息

再加亿点点细节!Cocos 基于平面着色的 3D 水面渲染方案

从上图中,我们可以清晰地看到,靠近岸边的海水的颜色比远处海水的颜色透明得多。

发生这种征象的主要缘故原由,就是基于视线偏向的水体厚度差异。

什么叫基于视线偏向的水体厚度,请看下图:

再加亿点点细节!Cocos 基于平面着色的 3D 水面渲染方案

我们通常说的水体深度,是指在忽略视线因素的情形,水面到水底的高度差。

在不追究细节的情形下,我们可以简朴地使用高度差来作为水的深度。

一种可能的伪代码如下:

depth = clamp((g_waterLevel – v_position.y) * depthScale,0.0,1.0);

其中 depthScale 是我们的深度缩放因子,可以用来调治比例尺问题,以及水体能见度线性衰减速率。

而基于视线偏向的水体厚度,是指视线偏向与水平面和水底交点的距离差。即图中 点 P1 到 点 P2 的距离。

下面我们来推导一下,使用基于视线偏向水体的厚度来作为深度因子的公式。

许多同伙第一反映是解直线方程,但用空间向量的特征来求解会更容易。

为利便对照明晰,再贴一次上面的图:

再加亿点点细节!Cocos 基于平面着色的 3D 水面渲染方案

设考察偏向为 viewDir,厚度为 depth 则有:

P1 + viewDir * depth = P2

分拆为分量运算可得:

P1.x + viewDir.x * depth = P2.x

P1.y + viewDir.y * depth = P2.y

P1.z + viewDir.z * depth = P2.z

可推导出:

depth = (P2.y – P1.y) / viewDir.y

由此可得如下盘算公式:

vec3 viewDir = normalize(v_position.xyz – cc_cameraPos.xyz);

float depth = (v_position.y – g_waterLevel) / viewDir.y

depth = clamp(depth * depthScale,0.0,1.0);

比起直接使用水体深度来说,多了一次求 viewDir 单元向量的运算,以及一次除以 viewDir.y 运算。

在非极端情形下,多出的这一点纯逻辑运算在 GPU 上是可以忽略不计的,可以放心使用。

将上述公式添加到渲染工具的 Shader 中,并在折射渲染阶段启用,将效果存入 Alpha 通道即可。

项目中的 Shader 代码如下图所示:

再加亿点点细节!Cocos 基于平面着色的 3D 水面渲染方案

最终获得的深度信息如下:

再加亿点点细节!Cocos 基于平面着色的 3D 水面渲染方案

深度夹杂

有了上面的深度信息,我们只需要在盘算出折射颜色后,再用深度信息与水底颜色夹杂即可。Shader 代码如下图所示:

再加亿点点细节!Cocos 基于平面着色的 3D 水面渲染方案

由于水体的可见度是非线性的,以是对 diffDepth 使用了 pow 函数,这个 power 参数默认是 2.0。

最终可以获得如下效果:

再加亿点点细节!Cocos 基于平面着色的 3D 水面渲染方案

六、水岸柔边

再加亿点点细节!Cocos 基于平面着色的 3D 水面渲染方案

当我们把摄像机拉近,考察水面与物体交接处的时刻,可以显著看到一条清晰的界线。

这条界线在反射越强的时刻越显著,使我们的水面效果大打折扣。

幸亏我们已经有了深度信息,可以凭证深度来判断出那里靠近岸边,并修改菲涅尔因子,使反射越靠近岸边的时刻越弱即可。

焦点代码如下:

再加亿点点细节!Cocos 基于平面着色的 3D 水面渲染方案

最终可以实现在全反射的情形下,水面与岸边依然平滑过渡。效果如下图所示:

再加亿点点细节!Cocos 基于平面着色的 3D 水面渲染方案

再来一张远视角的图:

再加亿点点细节!Cocos 基于平面着色的 3D 水面渲染方案

七、动态天空盒

再加亿点点细节!Cocos 基于平面着色的 3D 水面渲染方案

为了增强气氛感,DEMO 中使用了动态天空盒。

这是一个稀奇简朴的高效的动态天空盒方案,仅使用了一个双层纹理夹杂的半球模子,调治两张纹理的水平偏向流动速率即可。

再加亿点点细节!Cocos 基于平面着色的 3D 水面渲染方案

再加亿点点细节!Cocos 基于平面着色的 3D 水面渲染方案

八、关于DEMO

所有用果参数均可调治,如下图所示:

再加亿点点细节!Cocos 基于平面着色的 3D 水面渲染方案




泉源:COCOS


原文:https://mp.weixin.qq.com/s/yLEt3yHBj9lBNWm_xANvJw

3月28日—4月3日共有23款游戏开测|GameRes

GameRes游资网统计了2022年3月28日—2022年4月3日的最新手游开测信息,共有23款游戏开测。

温馨提示:

1.本站大部分内容均收集于网络!若内容若侵犯到您的权益,请联系站长处理!

2.如果您喜欢我们,可开通终身会员,享受全站资源免费下载!

3.本站所有内容只做学习和交流使用。 版权归原作者所有。

给TA打赏
共{{data.count}}人
人已打赏
!
也想出现在这里? 联系我们
创意广告区块 - WordPress区块
4 条回复 A文章作者 M管理员
表情包
  • AC��01
  • AC��02
  • AC��03
  1. lingbings

    打卡

  2. lengyue689

    这对你来说,也许是最糟糕的结果了。

  3. 1145141919

    你喜欢的人已经心有所属不是正常的吗,因为你喜欢他,所以你的眼中就只有她。人啊,总是盲目地去爱。

  4. 苏兔

    繁华只是散场的开始。

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索