快速次表面散射的原理与实现

快速次表面散射

上图是灯光从玉石材质的雕像的背后射出,然后照射到玉石表面上所形成的透光效果
左边是没有实现次表面散射的玉石效果
右边是带有次表面散射的通透感表现,同时还加上了Bloom泛光,从而实现了画面冲击力更强的场景
如果想要精确模拟次表面散射效果,需要使用光线追踪技术,这在手机平台上的性能开销是比较大的
所以今天的关键词除了次表面散射以外,还有快速,我们要在手机平台上快速地实现次表面散射效果
版权声明
本文为“优梦创客”原创文章,您可以自由转载,但必须加入完整的版权声明
更多学习资源请加QQ:1517069595或WX:alice17173获取(企业级性能优化/热更新/Shader特效/服务器/商业项目实战/每周直播/一对一指导)
点赞、关注、分享可免费获得配套学习资源
详细内容可参考文末完整视频
次表面散射的应用

左上角的图片是人体的真实皮肤表面,平时用比较亮的光源在皮肤的背面照射皮肤时,皮肤不会完全遮挡住光线,光线会把皮肤特别是皮肤的边缘照亮
右上角的图片是玉石材质的龙,它也有透射的效果,另外,玉石的透光性也是可以通过次表面散射模拟出来的
最下方的图片是《功夫熊猫》场景里的画面,最前面的角色的耳朵是比较通透的,这种通透感也可以通过次表面散射进行模拟
开启和关闭次表面散射的对比

课程主题

一、次表面散射的原理
二、次表面散射效果实现
三、使用内置管线或者URP管线实现的次表面散射和在PBR中实现的次表面散射有什么区别
次表面散射原理

当有一束光线射入物体的表面时,由于物体的表面可能是凹凸不平的,所以会产生四种类型的光线功能
BRDF:光线照射到物体表面时会沿着物体表面相反的方向反射出去
BSSRDF:灯光射入物体表面,在物体表面内不停地反弹,最终又射出物体表面,但它和灯光直接射出物体表面是不一样的,因为它射出的方向是随机的
BTDF:光线穿透物体的表面,形成了透彻感
次表面散射是由BRDF加上BTDF构成的,也就是说既有透射的部分,又有光线的规则反射和不规则反射部分
SSS

次表面散射是由背光加扰动加扩散这三个步骤构成的,接下来就来看一看背光如何实现、扰动如何实现、扩散如何实现以及实现背光以后会有什么变化、实现了扰动会有什么变化、实现扩散又会产生什么样的变化
背光的实现

要实现背面光照,可以使用背离灯光的方向向量,也就是将灯光方向L加一个负号
因为只有物体表面的法线方向和灯光的夹角小于90度时才是受光面,灯光方向与法线方向的夹角超过90度就没有任何光照
注意点:
将灯光方向反过来再和物体表面法线方向做点乘得到的其实不是背光,只是让光照的效果相反而已
背光在计算点乘时,不是和向量N做点乘,而是和另外一个向量:与视线向量V做点乘
这就是背光的基本原理,在编写Shader代码时只要用视线向量与灯光方向的反方向向量做简单的点乘就可以了,具体什么是点乘,可以参考我们的《Unity小白的TA之路》
表面扰动的实现

上面是背光最基本的实现,但仅仅只是这样实现的背光还是有点假的,所以还有一个步骤,就是对背光进行表面扰动

上图是不带表面扰动的

上图是带有表面扰动的
当物体的表面不带有任何扰动时,它的背光会更亮,但这个背光并不能反映出物体表面方向不同,这是因为没有考虑到法线扰动,所以只能得到简单的背光
那怎样把法线朝向带来的变化考虑进去呢?方法是利用下面的公式
$V * -(L + δN)= V * -H$
向量H是光照方向L与物体法线方向N的中间向量,它可以通过L + N得到,将它作为经过表面扰动后的向量来计算次表面散射可以使次表面散射效果更加真实
背光扩散的实现

要实现背光扩散需要用到下面的公式
$saturate(V * -(L + δN))^p *s$
扩散的实现并不难,就像在计算高光时调整高光的集中度或者扩散度一样,只需要对点乘的结果进行saturate,saturate就是把点乘的结果限制在0到1
然后将0到1之间的数只乘以P次方,P越大算出来的高光效果就越集中
整体背光强度由于P次方的存在会越乘越小,要将它的整体提亮就需要再乘以一个S,这个S是超过一的数值
代码实现

效果增强:局部厚度
这是经过刚刚一系列步骤后所实现出的效果

因为兔子本身是玉石材质,玉石有的地方薄,有的地方厚,如果不考虑厚度就会有过曝(过度曝光)的效果(如上图所示),只有计算厚度以后才能达到比较合理的背光效果
要计算厚度需要用到厚度图
那么怎么看厚度图呢?

比较厚的部分在图中是比较黑的;比较薄的部分在图里是比较亮的
有了厚度图以后渲染出的效果是什么样的呢?
使用厚度图渲染出的雕像(如下)

没有使用厚度图渲染出的雕像(如下)

厚度图的实现

实现代码
商业项目进阶1:URP环境下多光源的处理

游戏中通常不止有一个方向光,比如上面左图的方向光是从右上角射过来,它的周围也有一些环境光
场景里也不仅仅只有方向光,比如右图中的小兔子腿位置就放了一个点光源,这时由于我们的小兔子是透光的,所以能看见透光效果
在现代也不应该仅仅只支持一盏点光源,还要支持多盏点光源,上图右边的小兔子身体接近头部的位置能看到有微微泛红的光线,这是因为我在那里增加了一盏红色的光源
要开发在商业项目里可用的Shader就必须考虑到:
不仅仅要实现基本的光照效果,还需要实现多盏光照的叠加
商业项目进阶2:PBR与非PBR效果对比

实现PBR和不实现PBR在效果上究竟有什么样的区别呢?
上面的每张图都可以分成左边和右边,左边的是没有实现PBR,右边是已经实现了PBR
如果不采用PBR,那么不管环境如何变化,小兔子得到的光照都是完全相同的,不受任何间接光影响
实现了PBR后物品会受到环境光的影响
所以采用PBR可以使物体的效果更加真实,但PBR的实现是一项系统工程,它需要你去熟悉Unity的渲染框架、清楚PBR的技术原理、了解Unity是如何实现PBR效果的
商业项目进阶3:深入思考

如何实现多光源环境下的SSS?
如何实现正面光照的通透?
如何在PBR中实现SSS?
如何在SG中实现SSS?
如何在ASE中实现SSS?
二次元卡渲的PBR实现
写在最后
更多学习资源请加QQ:1517069595或WX:alice17173获取(企业级性能优化/热更新/Shader特效/服务器/商业项目实战/每周直播/一对一指导)
点赞、关注、分享可免费获得配套学习资源
详细内容可参考下方完整视频
