Origin
zhuanlan.zhihu.com
Tags
风格化
渲染
经验分享
项目
收藏夹
创建时间
收藏类型
Cubox 深度链接
更新时间
原链接
描述
写这篇文章快一年过去了,放两张在这期间里,用 URP 中最后做的仿原神的 demo 图。之前没考虑到 tonemapping 和叠加高度雾的效果。色彩参考原神和间谍过家家 ED(约尔在天台 24h 的天空变化)。
notion image
notion image
分享一下学习过程中的碎碎念,最终效果视频指路:
程序化天空盒,实际上就是写个 shader,把这个球从内部展现出来。其实也没什么可说的,搞明白贴图如何正确去映射到球面上就行了。
  1. 日月绘制
  1. 天空颜色
  1. 星星、银河绘制
  1. 大气散射
日月绘制
可参考下面这篇:
太阳绘制根据方向光的方向计算距离就行,
但是月亮就不能只画区域了吧,我想将月亮贴图搞上去,但天空球这个 uv 不太好直接用,强行用 uv.xz 贴上去那么只在中心点的效果比较好,稍微动一下 offset 就发现没法看:
notion image
天空球的 uv 是按照一个在原点的球体映射的,在球体的面上,上下顶点的地方切面平行于 xz 平面,采样完看图像不会被明显拉伸,在靠近边缘的地方采样则不能很好对应。既然在原点映射比较好,那么就把月亮固定在原点,但我们要根据光线方向旋转它,那在方向光的空间搞就好了,把天空球的 uv 转换到方向光的空间,转换矩阵我用脚本从 transform 去拿:
到这日月就可以了
notion image
天空颜色
比较简单,搞几个颜色 lerp 就行
notion image
星星、银河
星星贴图搞上去,这张图是我从资源商店搞的,但我现在还不知道怎么去生成或是它有什么专门的名字,如果有知道的请告诉我一下。(更新:泊松噪声采样点图,可以用脚本搞一下)
notion image
notion image
随便搞张 noise 控制范围及闪烁,亮度不要拉太高,密度也不要拉太大,不然会有纹理抖动。
notion image
starColor 用了 galaxy.r,一个银河 mask 里面的星星亮一点,周围暗一点。
银河系绘制首先我们要去…. 看原神的延时摄影!!(bushi)
不难看出有一个银河系的范围,加两次采样 noise,那就很简单了,自己 PS 画一下范围得了(其实为了方便调用程序生成 SDF 改的):
notion image
r 通道是整体,g 通道划定中间的一个范围,r-g 就能做出中间那一块缺的效果。
notion image
然后我们就可以看到美丽的星空拉
notion image
大气散射(一些改动只是个人理解,请斟酌斟酌)
先跟着大哥做一遍大气散射,然后再讨论后面的:
只要跟着这个大哥做一遍,就不难发现,Rayleigh 是解释你看到的太阳光的颜色,天为什么是蓝色的,夕阳为什么是红色的,Mie 就解释了日出日落 halo。
既然做卡通渲染,那就只保留 Mie 好了,我只想做个日出日落,但是要做天空盒还要按照大哥说的用 raymarching 计算 D(CP) + D(PA) 那太浪费了,对于基于物理的渲染有预计算的方法节省时间,视频
notion image
不过既然是做卡通渲染,就不需要物理正确性了,自然有很多做法。
SkyScattering 部分代码:
这里面我直接把 D(CP) 砍掉了,一是因为它计算太耗时了,二是因为对我最终的效果影响不大。
notion image
不过为什么会这样?我自己的理解是 mie 散射的相位函数其实是更倾向于直接沿着原方向进行散射,而 rayleigh 倾向于朝着不同方向,并且对不同波长影响也差别巨大。那么当我不计算 D(CP) 时,对 mie 的影响是比较小的,对于 rayleigh 散射影响较大,散射出的不同颜色也会变得相同。
notion image
notion image
用后处理基于物理大气散射看一下?
notion image
最后,在天空盒里计算,脚本控制下颜色
notion image
插一嘴:
拿到后处理效果能更好一些,我们用了 raymarching,自然能想到体积雾体积光什么的对吧,其实之前计算 density 就是计算的大气雾,最后再乘以 mie 相位函数才有了最终效果,那么在计算的时候加上高度雾,就能做到地面雾效和 mie 散射结合的结果。如果仔细研究下 PC 上原神的日落日出可以发现地面雾效和散射的结合很好,如果飞得高一些会发现 mie 散射会有变化,大气散射和高度雾应该是结合在一起去做的。手机上的原神就少了地面雾的散射变化只有 mie,可能是为了节约性能?
用后处理 raymarching 做下高度雾和大气散射:
notion image
这个好像没啥好说的吧,原神是在崩三经典云的基础上加了 SDF 做出消散的效果。
资源准备:
参考文章,请:
在最后这个兄弟实现的基础上,生成图片后再改成多张 SDF 混合 lerp,(忘了哪篇文章了说的好像有问题,就这个混合地方被误导了挺久)
例如 4 张进行 lerp:
最终结果就是这张图:
notion image
notion image
先 PS 画好几个阶段的效果,这块就是美术的东西了,不会美术,画得不好!!!!,最后全扔给 Visual Studio 生成 SDF 后混合去。混合后的图片应该塞到原图的 alpha 通道里去,不过我调不好效果就没搞。这几张图可以私我 b 站发给你。
到这里资源准备还没完,我要做的是一个天空盒,可是这个云怎么放上去啊,采样采上去也不是不行,但是我总不能一个一个云去采样把,那消耗太大了。那在 unity 里面一个面片一个面片摆上去?这么多面片对应的云形状不是一样的吧?而且消散的程度不能是一样的吧?那岂不是每片云我都得整个 Material 去控制,太麻烦了。还有一个问题,怎么让 rim 边缘光正确对应到太阳周围?
这么多问题,把所有的云整成一个多面片的模型就得了,调整 uv0 让每个面片的云对应图片中的不同片云,再整个 uv1 将云片平铺,将 uv1 对应到世界坐标 x 轴旋转角、y 轴旋转角,消散信息放到顶点色。
Maya 搞一下:
notion image
notion image
notion image
代码准备:
云贴图应该做成的几个通道:r 暗部 1、g 暗部 2、b 高光、aSDF。
云的亮部 = 1 - 暗部之和
边缘光部分要结合 SDF,图没做好用了一堆 lerp、smooth,美术苦手:
notion image
ProceduralSkybox,凑活看,比较乱:
本文由简悦 SimpRead 转码