一个讲皮肤渲染的paper,在gpu pro2和siggraph11的advance course会议上有提到。
先看个效果:TSD(texture space diffuse)是达到标杆效果的做法,但是效率比较低,右边是pre integrated做法,我们可以看出基本是同一级别的质量。
link:http://url.cn/VnHMEI
texture space diffuse
第一个把皮肤渲染的非常好的是《matrix》这个电影,比如smith哥,这里使用的就是在texture space做的blur来模拟scatering,效果很逼真。
顺着这个思路,随着时间的推移,开始有简单的gaussin blur/wrap lighting来模拟的(左数第三个)。
以及经典的nvidia的皮肤demo。
nv的这个可以说一直是标杆,但是就是需要做太多的blur,性能不够好。
但是这个过程一些积累成为本文的基石:
- diffusion profile:这个描述光如何在skin这样的材质中扩散的,下面这个数据是从实际皮肤中扫描出来的:
- texture space diffusion:把入射光存在texture space,然后做一些blur来模拟扩散
- FastSubsurfaceScattering:就是用在uncharted2以及后来的皮肤技术,使用jittered kernel,对rgb用不同的weight
- sssss(screen space subsurface scattering)是上面fast subsurface scattering的screenspace化
PreIntegratedSkinShading:
那么到本文,PreIntegratedSkin的优势就在于使用更高效的方法达到TextureSpaceDiffuse的效果。
这个算法主要分成3个部分:
- 处理眉骨这种大的表面弯曲的情况(surface curvature)
- 处理皮肤表面细节纹路的情况(small surface bump)
- 阴影
处理surface curvature
处理surface curvature这里使用了类似BRDF的积分,然后得出(或者近似出)一个简化的function。
这个结果目前作者还没抽象出一个简化公式,所以就存到一个look up texture,计算时候通过sample这个texture来获得预计算的结果。
上面的公式和书中的差一项,分子的2sin(x/2)应该是2r*sin(x/x),同时D(theta)变成D(theta,r),这里r是曲率的意思。
这里曲率的计算:
处理bump normal:
这里由于diffusion profile在rgb上的不同,同样的normal分布在rgb下呈现不同的结果,图出来是这样:
这里需要这样理解,实际中是同样的皮肤表面的bump,在光照下,rgb三个颜色呈现上图中rendering这一column的结果,那么实际计算中我们为了简化和提升效率,就把用于rgb计算diffuse lighting的normal map做一个filter,然后用统一的计算公式来计算,这样也能达到同样的结果。
这里pre filter normal就是使用的diffuse profile,但是可以看到计算diffuse&specular lighting需要4张normal map这个就太费了,但是我们可以看到上图中red的normal map是最糊的,specular是最清晰的,那么我们可以做一个优化就是使用specular和red的normal map,然后插值出另外2个。
shadow。。。不太感兴趣,这部分不太具备通用性,略过