Subsurface Scattering初探之预积分(Pre-Integrated Subsurface Scattering)的实现及效果

Subsurface Scattering初探之预积分(Pre-Integrated Subsurface Scattering)的实现及效果

我们知道,类似皮肤,蜡和牛奶等物质在渲染中需要考虑Subsurface Scattering(以下简称sss),我这几天对这个问题有点感兴趣,突然来了劲,想试试看效果如何,那种期待的心情就像买了一个想要的东西坐等快递到来一样 …扯远了,以下是正文:
PS:sss有很多种实现方法,例如贴图空间的sss,屏幕空间的sss,还有预积分的sss。我想先研究一下预积分的sss,没有什么原因,只是因为觉得预积分的那张LUT图很有意思,另外,也有很多游戏是基于预积分做的sss,例如

1.理论基础

这一块已经有很多资料可以搜索,所以我就不展开了,只推荐一下这篇文章,作者介绍了sss的基础知识,讲述了目前主流的几种sss实现方法,具有一定的参考价值。

2.生成LUT

这一块其实可以网上找一些别人生成的LUT,但是显然就不好做调整了,只能找资源。最好的方法当然是我们自己生成LUT。生成LUT这件事说起来也是一个坑,看了很多资料,竟然都是错误的,除非实践一遍,把坑趟一遍,否则还真的难以定夺究竟哪个是真,哪个是假。
2.1GPU Gems简化方法
GPU Gems1的Chapter 16. Real-Time Approximations to Subsurface Scattering一篇有讲到一个近似方法,可以用来生成LUT,但是只能生成一长条的LUT,没有纵向的随厚度变换的信息,因此我又做了一些改进,做了一些trick,最终效果如下:
左侧是参考,右侧是我修改后生成的
左侧是参考,右侧是我修改后生成的

2.2 来自Penner pre-integrated skin rendering 的改动版
前面提到的简化版sss可以说是丐中丐版,做一些简单的效果可能还可以,比如蜡烛什么的,要做人的皮肤,就不太够了,需要进一步的研究。
这部分公式我参考了两个来源,其中第一个为Penner pre-integrated skin rendering (siggraph 2011 advances in real-time rendering course),根据PPT里的公式实现后发现效果很诡异,于是又找了一些资料,其中知乎幽玄的公式推导是不错的参考,我经过最终实践,验证了以下公式是正确的:
公式
这里,R(x)为↓
r项
这里,G(x)为↓
G
这个公式在Shader里实现也不难,主要是积分,积分的话在离散情况下就是求和,所以需要执行一个循环来求和就可以了。
可以看到,最终实现已经和参考几乎一致。
实现
我最后还把这个生成LUT的功能做成了一个小插件,可以点一下生成一个LUT。参数可调。
直接把LUT的结果映射到直接光漫反射效果不太好,可以看到皮肤上很强的颗粒感,解决方法是specular的rgb通道取不同模糊程度的法线信息,这里我对红通道的法线进行了模糊,也就是取较高的mip级别,对绿蓝通道的法线还是取0级mip,以获取细节高光。直接光漫反射的高光也取了较高的mip层级,以去除颗粒感。
对比

最终效果如下,可以看到,在耳朵背光的地方,sss效果显著。测试环境为unity 2019.4.1f1中的built-in 管线。
对比
整体效果对比
对比

展望:
1.想把LUT生成的工具做得更加实用,可以生成大理石和蜡等等的LUT。
2.后续把其他的sss实现方式也看一下,可以对比对比效果。
3.本次是在Built-in中实现的,管线太古早了,下次换到URP中实现。HDRP已经有一套sss的解决方案了,所以应该有需求可以用那套方案,毕竟是异教徒留下来的资产,其实还不错。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值