Real-Time Rendering 4rd Chapter 14 Reading Note | RTR4第14章笔记-体积与半透明渲染
Real-Time Rendering出第四版了,新增了不少内容,这里做一些笔记,一章一章来。
 
有一些介质,比如水 雾等,分子比较稀疏,和光作用时效果不同于普通BRDF,会有散射(scattering)。另一些较致密的物质也有散射。其实普通的diffuse颜色也会有散射,只不过作用尺度很小,比如小于一像素。所有物质都会散射

14.1 散射理论

14.1.1 介质材质

    吸收(Absorption),光子成为物体内能
    向外散射(Out Scattering),光子没有按路径继续向前,而是被扩散向周边,取决于相函数
    发光:物体内能太高会发光
    向内散射(In Scattering):环境光被散射进入光线路径
 
 
    定义了灭绝度(extinction),是吸收和向外散射之和。
 
所以颜色定义成散射与灭绝之比
散射少吸收多:黑烟 红酒
散射多吸收少:云 空气 牛奶
 
因此相机接收到的光线理论上可以表示成下面这个公式:
相机接收到的光 = 物体表面颜色 * 介质透射系数 + (透射系数 * 散射)在光线路径上的积分
第一项是吸收和向外散射,降低物体颜色;第二项是向内散射,增加物体颜色
 
 

14.1.2 透射(Transmittance)

 
这个是灭绝系数的一个深度积分。它作用于三点:1. 上面公式第一项,不透明物体表面颜色会被遮蔽 2. 上面公式第二项,向内散射,造成遮蔽灯光的效果 3. 每一个散射事件到光源的路径,造成体积自阴影。

14.1.3 散射事件

 
积分向内散射的强度,p是相函数,取决于v和l;v是灯光的可见性;c是光强
 
v是灯光的可见性,可能被体积自己遮蔽,前者是shadowmap也就是不同物体的阴影,后者是体积的自阴影,也就是位置到灯光的投射度,也就是灭绝系数的积分
对于一个散射系数(0.5,1,2),吸收系数(0,0,0);
 
当介质很薄,透射高灭绝低,第一项不怎么起作用,主要是第二项起作用,积分完蓝色部分比较高,所以最终颜色是蓝色的,比如白天的天空
当戒指很厚,透视低灭绝高,第一项导致红色透射更多,第二项作用不那么大(指数比线性快),总和是红色比较高,所以最终颜色偏红,比如太阳在地平线上时
 

14.1.4 相函数

 
就是一个散射的分布,
取决于波长和粒子大小,分三种:
sp << 1,粒子比波长小很多,Rayleigh
sp ~ 1,粒子波长差不多,Mie
sp >> 1 粒子大很多,几何体散射
 
Rayleight在两级大一点,描述空气中阳光散射
 
Mie在一级更大
云比较像这个

14.2 专用体积渲染

14.2.1 大规模雾气

基本就是雾气颜色blend,可以有线性深度或者指数深度,后者更像物理。这都是比较传统的做法了。
比较高级是用深度图做全屏后处理了。高度雾是近地面一个片,计算光线在这个片中传播距离,参考
Wenzel, Carsten, Real-Time Atmospheric Effects in Games Revisited,” Game Developers Conference, Mar. 2007
 
雾的颜色可以有各种处理,比如采样cubemap,用相方程算,混合高度与深度雾等
 
对于非全局的雾,而是有形状的雾,采样一个前后深度计算Tr好了
 
在水下差不多灭绝系数(1.2, 0.31, 0.46),所以在水下时也可用雾的逻辑处理

14.2.2 简单体积光

最简单模拟雾气时放半透明片了,splatting approach,模拟光柱light shaft等,不过就是太占用带宽了
另一个简单的方式是沿路径在恒定介质均匀相方程中做积分,还有一些优化效果不过ALU计算太多
 
另一种是做后处理bloom,有个做lightshaft的方法是先在太阳上渲染一个大白圆片,然后被前面物体遮住,然后做径向模糊,再叠回去
Rohleder, Pawel, and Maciej Jamrozik, Sunlight with Volumetric Light Rays, in Wolfgang Engel, ed., ShaderX6, Charles River Media, pp. 325-330, 2008.
 

14.3 通用体积渲染

14.3.1 体积数据可视化

对于几何体,可以转成三角面polygon
对透明物体,可转成多个slice一层一层
另外还可以每个体素储存颜色透明度,映射成密度。
还有一种切slice的方式是不要面向相机,而是面向h = ( v + l ) / 2,从后向前,后一层还可以是前一层的输入,这样有体积阴影,多散射等
 

14.3.2 介质渲染

最简单单光源的是从相机开始raymarching,不在影子里的部分积分起来;也可以用灯光空间深度图创建一个mesh,从正面算起到背面结束。不过对非均匀介质,体积阴影就不行了
 
另一种是splatting,raymarching采颜色和遮蔽信息
 
Valient考虑点光源和体积光,把受灯光影响的体积放进一个buffer来做raymarching,还会做一些随机采样避免banding
 
异质介质可以存成体素信息,用1/8比例映射进裁剪空间作为密度,再模糊upsample,不过这和其它透明元素的渲染顺序还是不好解决,比如非凸半透明面。
 
要不然全体素储存了,散射亮度直接从世界空间映射到裁剪空间,通过裁剪空间中体素在世界坐标中的位置,从后向前更新裁剪空间中的体素信息
 
坏处是性能差的平台不太好用,但splatting方法带宽更多,而且不通用。UE里就实现了体积Lightmap。体素化了一个灭绝体extinction volume,作为统一数据来投影。

14.4 天空渲染

14.4.1 天空视角

需要两部分,一部分是大气的Rayleigh散射,另一部分是太阳周边粒子的散射。
ONeil的方式是vertex上做raymarching模拟散射,pixel上计算相方程。
另外是用数学模型和参考图,前者比如Preetham的,不过不能模拟艺术效果
还有一种是用预计算查表储存透射和散射,参数包括:视角高度,视角与子午线夹角,太阳方位角,太阳与子午线夹角等。于是就可以做一个四维LUT模拟。还可以省略掉一个参数做三维LUT,EA Frosbite就是这么干的,主要对美术也比较友好。
Hillaire, Sebastien, “Physically Based Sky, Atmosphere and Cloud Rendering in Frostbite,” SIGGRAPH Physically Based Shading in Theory and Practice course, July 2016.

14.4.2 云

灭绝系数在 低层浮云0.04~0.06 积雨云 0.05-0.12,颜色在1
 
传统的方式是一张图,Guerrette给了一种云移动的方法
Guerrette, Keith, \Moving The Heavens,” Game Developers Conference, Mar. 2014.
作为粒子
Yusov给了一种体粒子的方法,用四维LUT代替
Yusov, Egor, “High-Performance Rendering of Realistic Cumulus Clouds Using Pre-computed Lighting,” in Proceedings of the Eurographics / ACM SIGGRAPH Symposium on High Performance Graphics, Eurographics Association, pp. 127-136, Aug. 2014.
 
另外可能会有渲染层级不对的问题,可以用rasterizer order view解决,RT记录层级
作为介质
Bouthor提供了用mesh和hypertexture表示的方法
Bouthors, Antoine, Fabrice Neyret, Nelson Max, Eric Bruneton, and Cyril Crassin, \Interactive Multiple Anisotropic Scattering in Clouds,” in Proceedings of the 2008 Symposium on Interactive 3D Graphics and Games, ACM, pp. 173{182, 2008. Cited
 
也可以做raymarching,Horizon里那种,用Perlin+Worley两层噪声模拟
Schneider, Andrew, and Nathan Vos, \Nubis: Authoring Realtime Volumetric Cloudscapes with the Decima Engine,” SIGGRAPH Advances in Real-Time Rendering in Games course, Aug. 2017.
 
云的透射可以做raymarching,也可以每帧更新一个投射曲线(???)
Elcott, Sharif, Kay Chang, Masayoshi Miyamoto, and Napaporn Metaaphanon, \Rendering Techniques of Final Fantasy XV,” in ACM SIGGRAPH 2016 Talks, ACM, article no. 48, July 2016.
 
全像素更新云太慢了,可以4×4里更新一个像素,用前一帧填充
 
云的相方程很复杂,可以预处理成贴图,
环境光的散射可以用cubemap或者一个颜色渐变
多散射模拟
云与大气交互
 
用一张深度图作为云层的深度和透射,太阳的大气散射会根据它降低。

14.5 半透明表面

14.5.1 覆盖率和透射

一般透明物体使用blend混合,但半透明是
Tr是透射率,RGB的,需要用现代API的two output混合,要不然没法做带颜色的透明
更通用一点是这样,(对unity意味着要grab了)
透射率是指数按深度计算的.
对薄膜来说要这个深度是考虑法线和视角的夹角的结果
 
对水面来说,会有全反射的问题,在水下的时候

14.5.2 折射

按折射率计算,不多说了
 
一种折射的简单处理方法是用cubemap,按折射方向采样
还有一种屏幕空间的,按法线偏移uv采样背景

14.5.3 投影和Caustic

光线折射反射后有聚焦造成的
 
模拟一般用uv贴图滚动就行了
水下light shaft可以用模拟光线方向的线来blur

14.6 次表面散射

光线会进入表面散射再出来,BRDF不管用了。大部分模拟的单次散射。

14.6.1 扭曲光线Wrap Lighting

wrap lighting, colorshift

14.6.2 法线模糊

只对diffuse的反射的法线做模糊,specular的不变
Jensen, Henrik Wann, Stephen R. Marschner, Marc Levoy, and Pat Hanrahan, ”A Practical Model for Subsurface Light Transport,” in SIGGRAPH ’01 Proceedings of the 28th Annual Conference on Computer Graphics and Interactive Techniques, ACM, pp. 511-518, Aug. 2001.

14.6.3 颜色预积分

两个坐标轴是NdL和曲率,参数是透射和散射率
Penner, E., “Pre-Integrated Skin Shading,” SIGGRAPH Advances in Real-Time Rendering in Games course, Aug. 2011.

14.6.4 材质空间扩散

将表面的辐照度强度存到一张RT,做多层模糊,模糊时对R通道的filter更宽,放回去参与贴图计算
Borshukov, George, and J. P. Lewis, “Fast Subsurface Scattering,” SIGGRAPH Digital Face Cloning course, Aug. 2005.

14.6.5 屏幕空间扩散

屏幕空间计算光照强度,带stencil,线性深度空间做模糊,模糊在切线空间做
Jimenez, Jorge, “Next Generation Character Rendering,” Game Developers Conference, Mar. 2013

14.6.6 深度图技术

用光线空间的深度图查找可以快速获得物体表面到光线的scatter距离,不过采样多次太费了。采样一次就好了,还有问题就是可能深度图被别的东西遮挡,就用了deep shadowmap
还有一种translucent shadow mapping,储存光线空间的强度法线之类,模拟多次散射
 
树叶也有散射效果,不过因为就一层,用法线就行,下面公式代表背光的计算
类似,Bouchard还有一种计算SSS的方法,用反向法线计算AO,获得一个局部厚度图,用这个来计算表面光照
Barr_e-Brisebois, Colin, and Marc Bouchard, “Approximating Translucency for a Fast, Cheap and Convincing Subsurface Scattering Look,” Game Developers Conference, Feb.-Mar. 2011.
 

14.7 头发和毛发

头发是角质层,有三个主要部分 cuticle, cortex medulla
 
可能透光,BRDF不行了,需要全球面积分 BSDF。另外还有吸收光,多次散射等现象
 

14.7.1 几何和透明

一般用四边面片代替就行
可以用alphablend渲染,不过可能会有顺序问题,比如可以预先排序indexbuffer,但要交织就不行了。也可以用alphatest,但会有锯齿问题,可以msaa不过带宽比较大。也可以各种order independent transparency。TressFX就储存最近的片元一次混合。另一个alphatest问题是远距离mipmap
 

14.7.2 头发

KajiyaKay有一个BRDF,但还有散射的问题。
比如R是对颜色的反射,TT是透射进头发再透射出来,TRT是投射进头发反射再透射回来。 可以考虑这些主要的散射路径
 
d’Eon, Eugene, Guillaume Fran_cois, Martin Hill, Joe Letteri, and Jean-Mary Aubry, “An Energy-Conserving Hair Reectance Model,” Computer Graphics Forum, vol. 30, no. 4, pp. 1467-8659, 2011.
Karis, Brian, “Physically Based Hair Shading in Unreal,” SIGGRAPH Physically Based Shading in Theory and Practice course, July 2016. Cited
 
多散射复杂一点比如Zinke的模型
 
环境光的影响也比较复杂,一般用SH和假法线
Yuksel, Cem, and Sara Tariq, SIGGRAPH Advanced Techniques in Real-Time Hair Rendering and Simulation course, July 2010.

14.7.3 毛发

更短更规则。有一种体贴图的方法,每次往外移动一点。GS可以直接建模。也可以用四边形面片

14.8 统一的方法

目前体积渲染已经基本上可以承受了,那么将来呢?是不是可以统一不透明物体和体积材质的表达?都是由散射和相方程决定的。
 
SGGX?
Dupuy, Jonathan, Eric Heitz, and Eugene d’Eon, \Additional Progress Towards the Unification of Microfacet and Microake Theories,” in Proceedings of the Eurographics Symposium on Rendering: Experimental Ideas & Implementations, Eurographics Association, pp. 55{63,
2016.

扩展阅读

天空和云有Hillaire的讲义
Hillaire, S_ebastien, \Physically Based Sky, Atmosphere and Cloud Rendering in Frostbite,” SIGGRAPH Physically Based Shading in Theory and Practice course, July 2016.
 
头发和毛发可以看Yuksel和Tariq的
Yuksel, Cem, and Sara Tariq, SIGGRAPH Advanced Techniques in Real-Time Hair Rendering
and Simulation course, July 2010.
 
 
 
 
欢迎关注微信公众号:码工图形

发表评论

邮箱地址不会被公开。 必填项已用*标注