11 KiB
注意:本专题也许会大面积展示人体皮肤渲染结果,这可能会引起你的不适。
0.准备工作
在专题开始之前,你需要完成二值化的光照模型以及outline
【01】从零开始的卡通渲染-描边篇 - 知乎 (zhihu.com)
【02】从零开始的卡通渲染-着色篇1 - 知乎 (zhihu.com)
可以看这位大佬的二值化渲染模型。
另外,如果对赛璐璐风格的二次元渲染仍存疑惑,我的建议是
RealToon (An Anime/Toon Shader) | VFX 着色器 | Unity Asset Store
realtoon效果
这个18刀的着色器包含了完整源码,还内置了对实时光线追踪的支持,18刀的学费不算贵喔。
光追二次元的内容放到第九篇说吧,这里就不展开了。
1.皮肤的平滑光照
显而易见,插画风格与赛璐璐风格最大的区别就在于,皮肤对于不同的光照情况有着不同的表现。
原神的插画
原神正作渲染结果
我们对皮肤颜色进行抓取
原神插画的皮肤颜色
原神渲染的皮肤颜色
可以看到,原神的插画相比原神游戏中的渲染结果,其色彩能够展示出一定的PBR特点,例如Specular高光,还有次表面散射的效果。不过,画面整体依然很二次元,因此我们是可以从赛璐璐风格着色器的基础上进行魔改得到我们期待的厚涂风格皮肤的。
因此,我们在原本赛璐璐风格的渲染基础上直接引入Specular高光和次表面散射。与PBR不同的是:
1.我们不必对其物理真实性太过较真,只要他能对我们的画面进行补正就是好文明。
2.保证所有效果可以通过参数调整权重,因为NPR保证视觉好看是第一要务。
因此,Specular可以简单用 SpecularColor∗SpecularIndensity∗dot(normal,lightDir) 实现,也可以用 SpecularColor∗SpecularIndensity∗dot(normal,viewDir) ,我个人倾向于后者。
其中, SpecularColor 是Color, SpecularIndensity 是灰度图。
实现。当然,如果物体的SpecularColor会因部位而异,那么可以和 SpecularIndensity 一起合并成一个含颜色的贴图。
次表面散射方面,可以考虑使用pre-integrated模型。
预积分的次表面散射
BSSRDF与BTDF,以及pre-integrated模型的学习: 三鳥:实时皮肤渲染综述
简单的说一下BSSRDF。
射入皮肤的光呈现漫反射的性质
当光照射到皮肤表面后,光会在皮肤下的油脂层进行多次散射,在它射出时,它体现漫反射的性质。不过,之所以他体现出漫反射的性质,是因为光射入皮肤后,多次散射会导致最终值差距较大,因此在皮肤下的油脂层中存在着各种方向混乱的散射,最终射出的光就会呈现漫反射的性质了。
BSSRDF导致的结果
这就导致光束大概照到人体表面是这个样子的。那么如何得到这个预积分图呢?除了上面文章中提到的screen space blur的办法,也可以使用基于拟合函数的方法。
【译 】Disney2015-将BRDF扩展至集成次表面散射的BSDF - 知乎 (zhihu.com)
这两种方法,都可以得到一个类似下图的渲染结果。
可爱的光圈
然后在渲染结果上以以1r采样,水平方向上以受光强度N⋅L采样,就可以得到预积分图。
如果你实在整不明白,你直接把别人的预积分结果拿去用也无所谓……反正大学时期大家应该也都抄过别人的作业吧。
在我们得到预积分图后,我们就可以考虑如何使用。
预积分贴图
常见的pre-integrated模型刚好是以 N·L 为横坐标的,这与我们的RampMap一致。此时此刻我们的赛璐璐风格RampMap应该还是一个1N大小的LUT,将这个一维LUT与pre-integrated二维LUT直接逐行相乘,得到一个新的RampMap,但是1N的RampMap拓展为了N*N,纵坐标的1/r是在球面上的,如何应用到我们的复杂网格渲染中呢?
请参考Pre-Integrated Skin Shading 的常见问题解答 - 知乎 (zhihu.com) Q&A第五节
Jeffrey Zhuang的Q&A
因此,将 ΔNormal/ΔPosition 作为纵坐标就可以了(笑)。
仅仅是换一张图,就解决了皮肤的次表面散射问题。
至此,皮肤的平滑光照问题就已经解决。
赛璐璐Only
加入了BSSRDF和Specular后的效果
(这里头发和五官的渲染已经是完结版本,所以有种降维打击的感觉)
可以看到,在加入SSS和Specular之后,我们的皮肤已经有一股插画的感觉了,并且开销并不算很高。
求求审核哥哥姐姐了,给个过吧,真的很需要展示皮肤各个角度的渲染效果……
2.皮肤的厚涂化表现
实际上到此为止的皮肤效果就已经不错了,但是不够二次元了,因为我们上述的操作都是PBR的,真实感太高有时候也不是一件好事。举个例子,在下一篇我会谈到一个叫做face normal fix的操作,这会导致脸很平面。如果你的肉体立体感太足的化,就会显得你是一个接头霸王。
实际上,在绘画过程中,画师不仅仅要考虑到皮肤的真实感,还要考虑到画面整体的协调性。
假如我们使用了基于物理的次表面散射,这会让我们的皮肤在高强度的直射光下的物理表现更为明显。但是与此同时,在反射光下的影响就会变得更弱。
注意!下述方法论非常不基于物理,这可能会引起你的不适!
为了让皮肤的质感更为可控,我们采用第二章N*N的LUT,但这张LUT我们不基于物理去生成,而是跟着感觉走
实际上,我们需要一个散射光强度与直射光相补正,而这个光就是天空光。
1.天空光是蓝色的,所以我们考虑让皮肤看上去有蓝色的散射感。
2.与此同时,在皮肤边缘,我希望有一个体现BTDF的效果,在二次元下,我希望这个颜色是粉粉的。
3.散射感在直射光射到的地方肯定会体现的不充足,在直射光射不到的地方才会比较多。
4.第二条说的BTDF肯定也得是和光照强度绑定的呀!
综上四条,我们下一步控制皮肤质感的LUT,必然有一维是 N·L ,用以表示直射强度。考虑到皮肤边缘需要BTDF,另一个维度应该是 N·V 。
这样的话我们依然需要LUT,只是这次的LUT不需要积分(毕竟也不基于物理),
直接凭感觉随便拿PS什么的画一下就好了。
这个补正方法的灵感来源于一个效果很好的Fake SSS的着色:
Shader Forge - A visual, node-based shader editor | Page 54 - Unity Forum
二次元可以使用的LUT
以天空为背景色,直射光使用肤色作为相应,然后边缘使用粉粉嫩嫩的颜色。
至于这块儿棕色,因为我们是半兰伯特模型,所以一般而言不会采样到太多。
最后一步就是厚涂化了,我们回首再对我们的厚涂做一点考察
厚涂玛修
厚涂是发源于西方油画的一种绘画技法。 画家在画布上使用很厚的颜料,利用笔刷或画刀进行涂抹,就像抹奶油一样,故名“厚涂”
在这样的绘画工艺下,导致厚涂色块十分分明。因为是用很厚的颜料,所以渐变实际上是离散的,这就和我们的赛璐璐有一点像了。
离散的同时,由于两个颜料的相互融合,边界却又十分的柔和
柔和的边界
我们直接对上面的补正LUT做处理就好了。先downsampling,再用朴素的方式放大,然后用一下小半径的均值滤波,就可以得到一张有厚涂特色的补正LUT了
把这张LUT和上面pre-integrated以相同的方式(但纵坐标轴不同)也应用进去,就完成90%的效果啦
可以看到这时候效果已经很不错了。
3.一点小方法
(1)另类高光
肩头上有高光
可以看到有些二次元厚涂作品有明显不基于物理的高光,这是因为二次元美少女每一个都滑溜溜的。
这个效果在我们使用了不基于物理的补正LUT后非常简单,在LUT的左上角点一个光点就可以了。
效果:
(2)屏幕空间补光
肩头存在补光
二次元角色的光照实际上都是以好看为第一要务的。其实许多动漫都存在“两个人面对面,但是却都向光”的情况。对于二次元美少女而言,光补的越多,就越好看(雾)
Unity URP Shader 与 HLSL 自学笔记六 等宽屏幕空间边缘光 - 知乎 (zhihu.com)
可以在这篇文章学习这个套路。因为我也是学的别人的,就不在这里班门弄斧啦。
补光后的效果,会让人感觉更有绘画感。
此外,将这个效果复制一份并以 normal·viewDir lerp一下,可以做出BDTF的效果
4.最终效果预览
最终渲染结果
为了保证气氛一致,角色受环境光的影响很大
最终的渲染效果之看看你的
感谢大家的学习!下一期会更新对角色面部的处理!
渲染群群号:817341015