Unity动态雪地(沙地)
技术综合 3163 1
实名

通过了实名认证的内容创造者

发布于 2021-4-4 16:30:17

您需要 登录 才可以下载或查看,没有账号?注册

x
Unity动态雪地(沙地)
文/刘鲲

image.png

  动态雪地这个命题半年前就第一次做了,当初用了纯平的地面来降低难度入手,代码也比较累赘和散乱,算是第一次实践Compute Shader的尝试。到发文的这个进度,中间绕了一些弯路,功能也逐渐完善,也考虑到了RT的利用率,生成和释放,更结构性的脚本构成,注释,也是我个人C#代码练习的一次很好的经验。建议成长中的TA,做完调研,思考后从0到1的做完,中间遇到核心代码实在解决不到再去看代码,这样能收获很多,这篇文章也不会分享代码和资源,仅交流思路。
Compute Shader应该是技术美术成长过程里面比较重要的一环,特别是对于美术向的非程序员出身的技美,它可以利用GPU的并行效率来做大规模的简单计算,比如光线追踪,流体模拟,各种美术Trick效果的实现等。

1.核心原理
利用两个深度相机从下朝天空方向分别只渲染层过滤的对象,一个是踩踏物,比如图中的人,一个是地表基础的地面,这样通过比较两张深度图,再和美术的基础高度图三者一起计算,就能画出仅脚踩出的归一化深度图。可以理解为一个动态的笔刷。

v2-ffe654872dea4d2be9b6c62397638b0b_720w.jpg
地表深度

人物深度

俯视图正交

为什么要多一个渲染地表的深度相机而不是仅渲染踩踏物,是因为除非地面模型是纯平的,否则就需要这个相机记录捕捉区域的地表深度。
计算出的这个笔刷图和美术定义的基础高度图混合出最后用于置换效果的高度图,利用Shader的曲面细分功能,将沙地雪地绘制出凹凸不平的效果。

2.资源构成

  Debug可视化用的着色器一个,仅为了方便观察(可选),如图中黑色的方片

主要的沙地着色器一个,在满足美术需求的基础上附加功能性的计算,我这里使用了AEG第三方着色器连连看,它的快捷键和UE4一致,交互性能也比Shader Graph要好,最主要它自带跨平台的曲面细分功能,不论Built-in,URP,HDRP

C#脚本一个,主要负责深度相机的相关初始化和更新,RT动态贴图的初始化和更新,着色器的传参
Compute Shader一个,负责计算,为了实现动态效果,可以是仅在上面练练看来做,脚本工作会多一些因为涉及到跨帧,还可以是用OnRenderImage来配合着色器实现,这里并不是唯一选择

3.实现思路和踩坑

半年前,为了更简单的入手,我选择了纯平且对齐世界轴向的正方块地表,也使用了一个固定不动的捕捉区域且刚好对齐整个方块,这样最大的问题就是RT贴图的面积浪费,因为为了记录整个区域的信息,RT贴图的分辨率大面积都是没有更新的垃圾信息,也导致了踩踏部分的精度不够,这是问题之一,不过是个好的开始。
第二个问题和第一个问题相关,就是因为不熟练,就把所有计算都放到了Compute Shader这边,连连看那边仅接收最终的结果,连到高度置换那里。

下面是我个人认为实现过程中比较难的点:

一:本地UV(Tangent UV)几乎可以忽略参与不到核心计算,所有计算都是在本地坐标系或者世界坐标系下完成的,中间涉及了归一化的值和物理尺度的转换。
这里的计算哪怕山坡是斜面,它在二维平面上依然是有投影的,所以三维空间最终就是一个二维空间的UV计算,就和采样贴图对上了,不用去想三维空间或者Tangent空间下怎么知道表面发生了什么,因为我们的依赖也只能是正交深度相机,没有Tangent世界的信息收集工具,老弟你还想做毛发一样的射线检测吗:)

二:动态的捕捉空间,为了最大化利用RT贴图的分辨率,如果有个跟随主角的动态捕捉区域,那么区域就不用设置那么大了,那么精度就会提高,这里也是在第一步的基础上的,第一步的UV来源于本地空间或者世界空间,人移动,UV就发生了变化,那么这一帧的UV去采样上一帧的贴图结果,就不会原地不动,UV采样出的贴图就有了偏移。
如果把捕捉空间内的景象想象成一个万花筒,你在里面看到的图像,比如上一帧在图像正中间有个脚印,那个脚印就会在这一帧的UV采样过后挪了挪位置,再用Max计算比较本帧脚印和上帧脚印相互更大的部分,脚印就实现了叠加,这个是动态捕捉范围的采样原理核心。
这里面还关联了一个问题,如果沙地雪地需要恢复成美术高度贴图的样子,那么捕捉区域不能是非常小的,否则读秒结束,出圈了的凹陷,就会死亡,哦,不对,就会停留在出圈时候的模样。

三:上面说到了沙地雪地恢复成美术高度贴图的样子,这里的思路是比如10秒复原,美术用的贴图在某个点,比如贴图值是0.7(贴图是归一化的非物理尺度),那么0.7除以10就得到了每秒要恢复的值,那么就是0.07,但是这个值是需要乘以DeltaTime的,就是归一化的每帧用时,这样帧率低的时候,权重就猛,每一帧补齐的高度就猛,帧率高的时候,权重就低,每一帧就会少恢复点高度。这样才能实现现实世界的10秒恢复。
四:卷积核的应用,图像卷积核处理是我们熟悉的锐化,模糊,描边之类图像处理效果的基础。我们有个脚印,那么没有图像处理就只有一个脚印,但是经过卷积核处理,我们可以拓宽它的范围,或者区分处它的边缘区域,这块知识大家就上网搜索了。我自己实现的过程中,使用Sobel 卷积核Outline描边并不能很好的拓宽我想要的边缘区域,作为反向凸起的遮罩(因为脚印边的沙或者雪应该是反向变得更高的),最后使用的是Robert Crosse算法。
有了边缘遮罩可以干更多的事情,比如区分对待斜面区域使用Triplenar Mapping来贴图。
五:关于曲面细分,之前看UE4官方的视频,堡垒之夜里面那个河流的曲面细分是需要部分细分高,不重要部分细分低,这个在AEG练练看里面的那个算法是做不到的会产生断缝,没有仔细研究过相关实现,待大家自己发掘了,不然这个面的细分代价还是有点大。

4.更高吧兄弟

3A大作里面的效果都是非常综合的应用,更好的动态雪地沙地效果还需要配合比如粒子系统发射雪沫,沙粒,还例如战神里面的那种速度场影响这些粒子。更好的基础环境氛围打造,比如雪地雾气,沙地有流沙,希望作为技美的你站在更内行的角度去剖析需求和手段,我想这也是我们存在的意义所在。

END

评分

参与人数 1活跃度 +20 展开 理由
元素小行家... + 20 【给力】阅贴无数,楼主最强!

查看全部评分

本帖被以下画板推荐:

天若有情天亦老, 人间正道是沧桑。
使用道具 <
落雪成白  发表于 2021-4-8 04:11:59  
2#
个人觉得还行
回复 收起回复
使用道具
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表