次表面散射(Subsurface Scattering),简称SSS,或3S,是光射入非金属材质后在内部发生散射,

最后射出物体并进入视野中产生的现象,

即光从表面进入物体经过内部散射,然后又通过物体表面的其他顶点出射的光线传递过程。


次表面散射原理图示


真实环境中的次表面散射

要产生使人信服的皮肤和其他半透明材质的渲染效果,次表面散射(Subsurface Scattering)的

渲染效果十分重要。


有无次表面散射的渲染对比图(左图:使用次表面散射 | 右图:无次表面散射)

》中皮肤的渲染效果,很令人惊艳。当然,《神秘海域4》中

令人惊艳的,远远不止皮肤的渲染。


基于次表面散射的皮肤渲染 @《神秘海域4》

本章即描述了次表面散射的几种实时近似方法,关于皮肤的渲染,也关于近似地去模拟透明材

质的几种不同方法。

【核心内容提炼】

4.1 次表面散射的视觉特性(The Visual Effects of Subsurface Scattering)

要重现出任何视觉效果,经常的做法是考察这种效果的图像,并把可视的外观分解为其组成要

素。在观察半透明物体的相片和图像时,能注意到如下几点,即次表面散射(Subsurface Scattering)的视觉特性:

、首先,次表面散射往往使照明的整体效果变得柔和。

、一个区域的光线往往渗透到表面的周围区域,而小的表面细节变得看不清了。

、光线传入物体越深,就衰减和散射得越严重。

、对于皮肤来说,在照亮区到阴影区的衔接处,散射往往会引起微弱的倾向于红色的颜色偏移。

这是由于光线照亮表皮并进入皮肤,接着被皮下血管和组织散射和吸收,然后从阴影部分离开。

且散射在皮肤薄的部位更加明显,比如鼻孔和耳朵周围。


次表面散射原理图示

4.2 简单的散射近似(Simple Scattering Approximations)

近似散射的比较简单技巧是环绕照明(Warp Lighting)。正常情况下,当表面的法线

。而环绕光照修改漫反

射函数,使得光照环绕在物体的周围,越过那些正常时会变黑变暗的点。这减少了漫

反射光照明的对比度,从而减少了环境光和所要求的填充光的量。环绕光照是对Oren-Nayar

光照模型的一个粗糙的近似。原模型力图更精确地模拟粗糙的不光滑表面(Nayar and Oren 1995)。

下图和代码片段显示了如何将漫反射光照函数进行改造,使其包含环绕效果。

到1之间的浮点数,用于控制光照环绕物体周围距离。


环绕光照函数的图表

float diffuse = max(0, dot(L, N));

float wrap_diffuse = max(0, (dot(L, N) + wrap) / (1 + wrap));

为了在片元函数程序中的计算可以更加高效,上述函数可以直接编码到纹理中,用光线

矢量和法线的点积为索引。

时,可以显示出那种倾向于红的微小颜色漂移,这是模拟皮肤散射的

一种廉价方法。而这种偏向于红色的微小颜色漂移,也可以直接加入到此纹理中。

另外也可以在此纹理的alpha通道中加入镜面反射高光光照的功率(power)函数。

可以在示例代码Example 16-1中的FX代码展示了如何使用这种技术。对比的图示如下。


(a)没有环绕光照的球体
(b)有环绕光照明的球体
(c)有环绕光照明和颜色漂移的球体

Example 16-1 摘录纳入了环绕照明的皮肤Shader效果的代码(Excerpt from the Skin Shader

Effect Incorporating Wrap Lighting)

// 为皮肤着色生成2D查找表(Generate 2D lookup table for skin shading)

float4 GenerateSkinLUT(float2 P : POSITION) : COLOR

{

float wrap = 0.2;

float scatterWidth = 0.3;

float4 scatterColor = float4(0.15, 0.0, 0.0, 1.0);

float shininess = 40.0;

float NdotL = P.x * 2 - 1; // remap from [0, 1] to [-1, 1]

float NdotH = P.y * 2 - 1;

float NdotL_wrap = (NdotL + wrap) / (1 + wrap); // wrap lighting

float diffuse = max(NdotL_wrap, 0.0);

// 在从明到暗的转换中添加颜色色调(add color tint at transition from light to
        dark)

float scatter = smoothstep(0.0, scatterWidth, NdotL_wrap) *

smoothstep(scatterWidth * 2.0, scatterWidth,

NdotL_wrap);

float specular = pow(NdotH, shininess);

if (NdotL_wrap <= 0) specular = 0;

float4 C;

C.rgb = diffuse + scatter * scatterColor;

C.a = specular;

return C;

}

// 使用查找表着色皮肤(Shade skin using lookup table)

half3 ShadeSkin(sampler2D skinLUT,
        
        half3 N,
        
        half3 L,
        
        half3 H,
        
        half3 diffuseColor,
        
        half3 specularColor) : COLOR

{
        
        half2 s;
        
        s.x = dot(N, L);
        
        s.y = dot(N, H);
        
        half4 light = tex2D(skinLUT, s * 0.5 + 0.5);
        
        return diffuseColor * light.rgb + specularColor * light.a;

}

4.3 使用深度贴图模拟吸收(Simulating Absorption Using Depth Maps)

吸收(Absorption)是模拟半透明材质的最重要特性之一。光线在物质中传播得越远,

它被散射和吸收得就越厉害。

为了模拟这种效果,我们需要测量光在物质中传播的距离。

而估算这个距离可以使用深度贴图(Depth Maps)技术[Hery 2002],此技术非常类似

于阴影贴图(Shadow Mapping),

而且可用于实时渲染。


使用深度贴图计算光在物体中的传播的距离

深度贴图(Depth Maps)技术的思路是:

在第一个通道(first pass)中,我们从光源的视点处渲染场景,存储从光源到某个纹理的距离。

然后使用标准的投射纹理贴图(standard projective texture mapping),将该图像投射回场景。

在渲染通道(rendering pass)中,给定一个需要着色的点,我们可以查询这个纹理,来获得

从光线进入表面的点(d_i)到光源间距离,通过从光线到光线离开表面的距离(d_o)里减去

这个值,我们便可以获得光线转过物体内部距离长度的一个估计值(S)。如上图。

原文中详细分析了此方法的实现过程,也附带了完整的Shader源码,具体细节可以查看原文,

这里因为篇幅原因就不展开了。


使用深度贴图去近似散射,物体上薄的部位传输更多的光

也有一些更高端的模型试图更精确地模拟介质内散射的累积效应。

一种模型是单次散射近似(Single Scattering Approximation),其假设光在材质中只

反弹一次,

沿着材质内的折射光线,可以计算有多少光子会朝向摄像机散射。当光击中一个粒子

的时候,

光散射方向的分布用相位函数来描述。而考虑入射点和出射点的菲涅尔效应也很重要。

另一种模型,是近似漫反射(Diffusion Approximation),其用来模拟高散射介质(如皮

肤)的多次散射效果。

4.4 纹理空间的漫反射(Texture-Space Diffusion)

次表面散射最明显的视觉特征之一是模糊的光照效果。其实,3D美术时常在屏幕空间中

效仿这个现象,通过在Photoshop中执行Gaussian模糊,然后把模糊图像少量地覆盖在

原始图像上,这种"辉光"技术使光照变得柔和。

而在纹理空间中模拟漫反射[Borshukov and Lewis 2003],即纹理空间漫反射(Texture-S

pace Diffusion)是可能的,我们可以用顶点程序展开物体的网格,程序使用纹理坐标UV

作为顶点的屏幕位置。程序简单地把[0,1]范围的纹理坐标重映射为[-1,1]的规范化的坐标。

另外,为了模拟吸收和散射与波长的相关的事实,可以对每个彩色通道分为地改变滤波权重。


(a)原始模型
(b)应用了纹理空间漫反射照明的模型,光照变得柔和


基于纹理空间漫反射照明的效果

同样,原文中详细分析了此方法的实现过程,也附带了完整的Shader源码,具体细节

可以查看原文,这里因为篇幅原因就不展开了。

再附几张基于次表面散射的皮肤渲染效果图,结束这一节。


基于次表面散射的皮肤渲染


基于次表面散射的皮肤渲染 @Unreal Engine 4


基于次表面散射的皮肤渲染 @《神秘海域4》


基于次表面散射的皮肤渲染 @《神秘海域4》

【核心要点总结】

文中提出的次表面散射的实时近似方法,总结起来有三个要点:


基于环绕照明(Warp Lighting)的简单散射近似,Oren-Nayar光照模型。


使用深度贴图来模拟半透明材质的最重要特性之一——吸收(Absorption)。

)基于纹理空间中的漫反射模拟(Texture-Space Diffusion),来模拟次表面散

射最明显的视觉特征之一——模糊的光照效果。

【本章配套源代码汇总表】

Example 16-1 摘录纳入了环绕照明的皮肤Shader效果的代码

(Excerpt from the Skin Shader Effect Incorporating Wrap Lighting)

Example 16-2 深度Pass的顶点Shader代码

(The Vertex Program for the Depth Pass)

Example 16-3 深度Pass的片元Shader代码

(The Fragment Program for the Depth Pass)

Example 16-4 使用深度贴图来计算穿透深度的片元Shader代码

(The Fragment Program Function for Calculating Penetration Depth Using Depth Map)

Example 16-5 用于展开模型和执行漫反射光照的顶点Shader代码

(A Vertex Program to Unwrap a Model and Perform Diffuse Lighting)

Example 16-6 用于漫反射模糊的顶点Shader代码

(The Vertex Program for Diffusion Blur)

Example 16-7 用于漫反射模糊的片元Shader代码

(The Fragment Program for Diffusion Blur)

【关键词提炼】

皮肤渲染(Skin Rendering)

次表面散射(Subsurface Scattering)

纹理空间漫反射(Texture-Space Diffusion)

环绕照明(Warp Lighting)

深度映射(Depth Maps)

 
 

来自 <https://github.com/QianMo/Game-Programmer-Study-Notes/blob/master/Content/%E3%80%8AGPU%20Gems%201%E3%80%8B%E5%85%A8%E4%B9%A6%E6%8F%90%E7%82%BC%E6%80%BB%E7%BB%93/README.md#%E4%B8%80%E3%80%81-%E7%94%A8%E7%89%A9%E7%90%86%E6%A8%A1%E5%9E%8B%E8%BF%9B%E8%A1%8C%E9%AB%98%E6%95%88%E7%9A%84%E6%B0%B4%E6%A8%A1%E6%8B%9F%EF%BC%88effective-water-simulation-from-physical-models%EF%BC%89>

 
 

(转)GEM -次表面散射的实时近似的更多相关文章

  1. Unity3d shader之次表面散射(Subsurface Scattering)

    次表面散射是一种非常常用的效果,可以用在很多材质上如皮肤,牛奶,奶油奶酪,番茄酱,土豆等等  初衷是想做一个牛奶shader的,但后来就干脆研究了sss这是在vray上的次表面散射效果 这是本文在un ...

  2. Unity3d 屏幕空间人体皮肤知觉渲染&次表面散射Screen-Space Perceptual Rendering & Subsurface Scattering of Human Skin

    之前的人皮渲染相关 前篇1:unity3d Human skin real time rendering 真实模拟人皮实时渲染 前篇2:unity3d Human skin real time ren ...

  3. 次表面散射(SubSurface Scattering) Shader 【转】

    原文 http://www.azure.com.cn/article.asp?id=231 用深度值近似模拟物体的厚度,厚度越小处透光越多. varying vec4 position;varying ...

  4. Unity5 Screen-Space Subsurface Scattering屏幕空间次表面散射SSSSS

    用unity5自带的standard shader        ------------by wolf96 

  5. 极化SAR图像基础知识(1)

    从今天开始学习极化SAR图像,记录于此. 极化散射矩阵S是用来表示单个像素散射特性的一种简便办法,它包含了目标的全部极化信息.

  6. 实时&离线皮肤渲染技术(Real-time&Offline Skin Rendering)

    目录 现实皮肤模型 BSSRDF 渲染模型 [2001] Diffusion Profile(扩散剖面)[2001] 偶极子 [2002] 高斯和 [2007] Burley Normalized D ...

  7. 大气散射 GPU Gems2 Chapter 16. Accurate Atmospheric Scattering

    效果图 这次先上效果图*4 散射概念 光线击中空气中的微小颗粒后的偏折导致了光线的散射.我们看到的阳光应该是由视线上的散射在视线方向上的集合.如果由地面的反射,还要加上经过散射计算的地面反射. Ray ...

  8. 【翻译】西川善司「实验做出的游戏图形」「GUILTY GEAR Xrd -SIGN-」中实现的「纯卡通动画的实时3D图形」的秘密,前篇(2)

    Lighting和Shading(2)镜面反射的控制和模拟次级表面散射技术 http://www.4gamer.net/games/216/G021678/20140703095/index_2.ht ...

  9. 剖析Unreal Engine超真实人类的渲染技术Part 3 - 毛发渲染及其它

    目录 四.毛发渲染 4.1 毛发的构造及渲染技术 4.1.1 毛发的构造 4.1.2 Marschner毛发渲染模型 4.1.3 毛发的间接光照 4.2 毛发的底层实现 4.3 毛发的材质解析 4.3 ...

随机推荐

  1. HDU 2102 A计划(两层地图加时间限制加传送门的bfs)

    传送门: http://acm.hdu.edu.cn/showproblem.php?pid=2102 A计划 Time Limit: 3000/1000 MS (Java/Others)    Me ...

  2. 点击HTML页面问号出现提示框

    本demo的功能:点击页面按钮在其边缘出现提示信息,点击页面任何一处则消失. 如下图: 1.所需插件: jquery插件: layer插件: 2.HTML内容: ==注意==: class=" ...

  3. 具有代码执行潜力的Vimeo SSRF

    最近我在Vimeo上发现了一个半响应的SSRF代码执行的可能性.这篇博客文章解释了我是如何找到并利用它的. 背景 Vimeo为其API提供了一个名为API Playground的API控制台,使用此W ...

  4. mac 无法写入设备的最后一个块 格式化

    硬盘,U盘,装在硬盘盒通过USB连接到电脑.但是无法格式化硬盘 失败的页面显示: 正在卸载磁盘 无法写入设备的最后一个块 操作失败 建议您这样做: 1.切换进Windows系统,或者找一台安装有Win ...

  5. ubuntu14.04安装qt-4.8.4

    题记:因为工作中用到qt的qmake工具生成x项目的Makefile文件,因为原有工程用的是4.8.4版本的,因此在此基础之上安装此版本. 用安装包工具进行安装qt不能直接安装到4.8.4版本的,因此 ...

  6. PHP运行原理之Opcodes

    在我之前的博客<Laravel5框架性能优化技巧>中提到开启OPcache可以提升php性能.那么为什么开启OPcache就可以提升php运行性能呢?这里就要提到php的运行原理了--Op ...

  7. Spark运行模式_Spark自带Cluster Manager的Standalone Client模式(集群)

    终于说到了体现分布式计算价值的地方了! 和单机运行的模式不同,这里必须在执行应用程序前,先启动Spark的Master和Worker守护进程.不用启动Hadoop服务,除非你用到了HDFS的内容. 启 ...

  8. Python 爬虫 (三)

    #对第一章的百度翻译封装的函数进行更新 1 from urllib import request, parse from urllib.error import HTTPError, URLError ...

  9. WinSCP与Putty远程连接linux

    1.  有时putty连接不上,可能是linux机器上的telnet服务未开,把蓝线上的√去掉. 2. ctrl + p 打开putty窗口: 3. putty如果显示乱码,右键 putty窗口,选择 ...

  10. 如何把C盘里的文件默认位置更改到D盘指定目录?

    如何把C盘里的文件默认位置更改到D盘指定目录? 1.打开运行,输入 %HOMEPATH% 2.以”桌面”文件转移到D盘目录为例(其他文档类比进行操作) 3.鼠标右键”桌面”----选择属性-----定 ...