GPU Gems1 - 16 次表面散射的实时近似(Real-Time Approximations to Subsurface Scattering)

这一章,浅墨这篇文章介绍的非常详细,我照扒一遍再稍加一些内容,增加记忆。https://zhuanlan.zhihu.com/p/36499291

【章节概览】

次表面散射(Subsurface Scattering),简称SSS,或3S,是光射入非金属材质后在内部发生散射,最后射出物体并进入视野中产生的现象,即光从表面进入物体经过内部散射,然后又通过物体表面的其他顶点出射的光线传递过程。原理如下图

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

                                              

真实世界中的次表面散射

                   

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

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

【核心内容提炼】

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

要重现出任何视觉效果,经常的做法是考察这种效果的图像,并把可视的外观分解为其组成要素。在观察半透明物体的相片和图像时,能注意到如下几点,即次表面散射(Subsurface Scattering)的视觉特性:

  • 首先,次表面散射往往使照明的整体效果变得柔和。
  • 一个区域的光线往往渗透到表面的周围区域,而小的表面细节变得看不清了。
  • 光线传入物体越深,就衰减和散射得越严重。
  • 对于皮肤来说,在照亮区到阴影区的衔接处,散射往往会引起微弱的倾向于红色的颜色偏移。这是由于光线照亮表皮并进入皮肤,接着被皮下血管和组织散射和吸收,然后从阴影部分离开。且散射在皮肤薄的部位更加明显,比如鼻孔和耳朵周围。

 

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

近似散射的比较简单技巧是环绕照明(Warp Lighting)。正常情况下,当表面的法线对于光源方向垂直的时候,Lambert漫反射提供的照明度是0。而环绕光照修改漫反射函数,使得光照环绕在物体的周围,越过那些正常时会变黑变暗的点。这减少了漫反射光照明的对比度,从而减少了环境光和所要求的填充光的量。环绕光照是对Oren-Nayar光照模型的一个粗糙的近似。原模型力图更精确地模拟粗糙的不光滑表面(Nayar and Oren 1995)。

下图和代码片段显示了如何将漫反射光照函数进行改造,使其包含环绕效果。其中,wrap变量为环绕值,是一个范围为0到1之间的浮点数,用于控制光照环绕物体周围距离。

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

 

为了在片元函数程序中的计算可以更加高效,上述函数可以直接编码到纹理中,用光线矢量和法线的点积为索引。

而在照明度接近0时,可以显示出那种倾向于红的微小颜色漂移,这是模拟皮肤散射的一种廉价方法。而这种偏向于红色的微小颜色漂移,也可以直接加入到此纹理中。

另外也可以在此纹理的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 lightingfloat diffuse = max(NdotL_wrap, 0.0);// 在从明到暗的转换中添加颜色色调(add color tint at transition from light todark)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)中,给定一个需要着色的点,我们可以查询这个纹理,来获得从光线进入表面的点(di)到光源间距离,通过从光线到光线离开表面的距离(do)里减去这个值,我们便可以获得光线转过物体内部距离长度的一个估计值(S)。如上图。

第一个pass渲染深度的shader代码如下:

 第二个pass计算渗透深度的shader代码如下:

 

 

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

一种模型是单次散射近似(Single Scattering Approximation),其假设光在材质中只反弹一次,沿着材质内的折射光线,可以计算有多少光子会朝向摄像机散射。当光击中一个粒子的时候,光散射方向的分布用相位函数来描述。而考虑入射点和出射点的菲涅尔效应也很重要。

另一种模型,是近似漫反射(Diffusion Approximation),其用来模拟高散射介质(如皮肤)的多次散射效果。

 

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

 

次表面散射最明显的视觉特征之一是模糊的光照效果。其实,3D美术时常在屏幕空间中效仿这个现象,通过在Photoshop中执行Gaussian模糊,然后把模糊图像少量地覆盖在原始图像上,这种“辉光”技术使光照变得柔和。

而在纹理空间中模拟漫反射[Borshukov and Lewis 2003],即纹理空间漫反射(Texture-Space Diffusion)是可能的,我们可以用顶点程序展开物体的网格,程序使用纹理坐标UV作为顶点的屏幕位置。程序简单地把[0,1]范围的纹理坐标重映射为[-1,1]的规范化的坐标。(看完shader的源代码,个人理解其实就是在顶点着色器中,将顶点用lightMatrix转换到light的渲染纹理空间后,计算漫反射光照

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

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

【核心要点总结】

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

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

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

3)基于纹理空间中的漫反射模拟(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)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/246299.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Unity HDRP渲染管线基础指南

HDRP和LWRP简介 Unity2018中引入了可编程渲染管线&#xff08;Scriptable Render Pipeline&#xff0c;简称SRP&#xff09;&#xff0c;是一种在Unity中通过C#脚本配置和执行渲染的方式。至2018.1版本&#xff0c;Unity中除了默认渲染管线&#xff0c;还提供了轻量级渲染管线…

SSDO AO 图像空间的动态全局光照

本文仅记述SSDO学习笔记&#xff01; 概述 SSDO Screen-space Direction Occlusion 是对AO的扩充&#xff0c;在AO的基础上&#xff0c;假设没有遮蔽的方向有直接入射光&#xff0c;有遮蔽的方向&#xff0c;可能有间接光的反射。 SSAO理论分析 AO&#xff1a;在计算点的周围…

GPU Gems1 - 17 环境遮挡

环境光遮蔽&#xff08;Ambient Occlusion&#xff09;“AO”为Amblent Occlusion的缩写&#xff0c;中文译为环境光遮蔽。在DirectX 10.1 API推出后&#xff0c;Amblent Occlusion升级为SSAO&#xff08;Screen-Space Ambient Occlusion:屏幕空间环境光遮蔽&#xff09;&#…

GPU Gems1 - 18 空间BRDF(Spatial BRDFs)

这章主要介绍了空间双向反射分布函数&#xff08;SBRDF&#xff09;&#xff0c;接着文章讨论了压缩SBRDF表达式&#xff0c;以及由离散光或环境贴图所照明的SBRDF的渲染方法。关于BRDF请参考大佬浅墨的这篇文章https://blog.csdn.net/poem_qianmo/article/details/75943714 S…

浅谈表面反射——波动光学篇

Radiometric Definitions 首先让我们来回忆一下辐射度量学中关于irradiance和radiance的定义&#xff1a; 我们在这里定义光源(source)在x-z平面&#xff0c;因此入射光就可以只用θi\theta_{i}θi​来描述。dAs\mathrm{d}A_{s}dAs​是表面积。定义dΦi\mathrm{d}\Phi_{i}dΦ…

GPU Gems1 - 19 基于图像的光照(Image-Based Lighting)

这篇文章打破了当时立方体贴图环境&#xff08;Cube-Map Environment&#xff09;用法的桎梏&#xff0c;深入研究了更多可能的逼真光照效果。文章主要研究了基于图像的光照&#xff08;Image-Based Lighting&#xff0c;IBL&#xff09;&#xff0c;包括局部化的立方体映射&am…

Polygonal-Light Shading with LTC

概述 如果我们有一个上半球的余弦分布函数(Do)(D_{o})(Do​)&#xff0c;并对这个余弦分布函数进行一个矩阵(M)(M)(M)变换&#xff0c;变换为一个新的分布函数(D)(D)(D)。 DMDoD M D_{o}DMDo​ 这就是基本思想&#xff1a;用一个余弦分布函数来拟合出不同的分布函数&#xff…

GPU Gems1 - 20 纹理爆炸(Texture Bombing)

【章节概览】 这章介绍了纹理爆炸&#xff08;Texture Bombing&#xff09;和相关的细胞技术&#xff0c;它们能在Shader中增加视觉的丰富性&#xff0c;图像的多样性&#xff0c;并减少大块纹理图案的重复性。 【核心要点】 纹理爆炸&#xff08;Texture bombing&#xff0…

Catlike Coding网站文章解析 -- 1.Procedural Grid

原文英文版链接https://catlikecoding.com/unity/tutorials/procedural-grid/&#xff0c;里面有每一部分的untiy工程链接&#xff0c;文章内容也更详实。 本章内容&#xff1a; 创建一系列点使用协程实现他们的摆放位置定义一个由三角形组成的平面自动生成法线添加纹理坐标和…

GPU Gems1 - 21 实时辉光(Real-Time Glow)

这章浅墨的文章讲的很细了&#xff0c;这里基本照扒一遍加深印象&#xff0c;原文链接&#xff1a;https://zhuanlan.zhihu.com/p/36499291 【章节概览】 这章讲到2D光照效果中的辉光&#xff08;Glow&#xff09;和光晕&#xff08;Halo&#xff09;&#xff0c;展示了如何通…

Catlike Coding网站文章解析 -- 2.Procedural Grid

本章内容 创建一个闭合的cube mesh给cube添加带弧度平滑的边缘定义法线使用sub-meshes&#xff08;子mesh&#xff09;创建一个常规shader合并碰撞体1.合成一个cube 上一章https://mp.csdn.net/postedit/89474068我们已经实现了一个平面mesh。一个cube由6个平面组成&#xff…

GPU Gems1 - 23 景深技术综述

本章主要介绍如何使用GPU创建实时的景深&#xff08;Depth of Field&#xff09;效果。参考浅墨总结文章的链接https://zhuanlan.zhihu.com/p/36499291 聚焦在枪上&#xff0c;背景模糊【核心要点】 物体在距离镜头的一个范围之内能够清晰成像&#xff08;经过聚焦&#xff09…

GPU Gems1 - 22 颜色控制(Color Controls)

这章将在游戏中图像处理的讨论&#xff0c;扩展到技术和艺术上控制颜色的方法和应用&#xff0c;包括将图像从一些的色彩空间中移入移出&#xff0c;以及快速地给任何2D或3D场景加上精美的色调。 色彩校正&#xff08;Color Correction&#xff09;是几乎所有印刷和胶片成像应…

GPU Gems1 - 25 用纹理贴图进行快速过滤宽度的计算

这章介绍在片元shader中计算导数近似值的技术。这个技术把特别的值载入纹理mipmap的每个级别&#xff0c;以特殊的方式使用纹理映射硬件&#xff0c;计算出导数的结果&#xff0c;给出在屏幕上的像素间某个量的变化率。 Cg标准程序库提供ddx和ddy函数&#xff0c;计算任意关于…

GPU Gems1 - 24 高质量的过滤

在一些应用中&#xff0c;高质量的过滤是至关重要的&#xff0c;可以用像素shader代码执行任何过滤。GPU着色程序不用于CPU的主要之处在于&#xff1a;一般来说&#xff0c;CPU数学操作比纹理访问更快&#xff0c;而在GPU中恰恰相反。图像过滤的目的很简单&#xff1a;对于给你…

GPU Gems1 - 26 OpenEXR图像文件格式与HDR(The OpenEXR Image File Format and HDR)

【章节概览】 这章中&#xff0c;大名鼎鼎的工业光魔公司的Florian Kainz、Rod Bogart和DrweHess介绍了OpenEXR标准&#xff0c;这是一种当时新的高动态范围图像&#xff08;HDRI&#xff09;格式&#xff0c;在计算机成像的顶级电影中正在快速推广。对于基于图像照明的开发者…

ID Tech 5 中Megatexture针对地形的D3D9 基本实现原理

看GPU Gems2中的 使用基于GPU几何体裁剪图的地形渲染&#xff08;Terrain Rendering Using GPU-Based Geometry Clipmaps&#xff09;一文&#xff0c;对Clipmap技术不是理解很好&#xff0c;所以上网搜索一番&#xff0c;发现了这篇文章&#xff0c;实在是太棒的文章&#xff…

[知乎] 开放世界游戏中的大地图背后有哪些实现技术?

今天看到的一篇关于大世界的技术文章&#xff0c;写的太好了&#xff0c;膜拜大佬。各位如果有时间一定要看看 原文&#xff1a;http://gulu-dev.com/post/2014-11-16-open-world#toc_10 一、程序技术篇&#xff1a;算法和架构&#xff08;Programming Algorithms & Arch…

GPU Gems2 - 2 使用基于GPU几何体裁剪图的地形渲染(Terrain Rendering Using GPU-Based Geometry Clipmaps)

【章节概览】 本章描述了一种通过顶点纹理实现的&#xff0c;基于GPU的几何体裁剪图&#xff08;Geometry Clipmaps&#xff09;技术。通过把地形几何体当做一组图像来处理&#xff0c;可以在GPU上执行几乎所有的计算&#xff0c;因此可以减少CPU的负载。且该技术较为容易实现…

球谐光照

一.原理 球谐光照实际上是一种对光照的简化&#xff0c;对于空间上的一点&#xff0c;受到的光照在各个方向上是不同的&#xff0c;也即各向异性&#xff0c;所以空间上一点如果要完全还原光照情况&#xff0c;那就需要记录周围球面上所有方向的光照。注意这里考虑的周围环境往…