实时渲染的核心为:使用计算机快速绘制图片,它是计算机图形学中最具交互的领域。使用者与屏幕中的图片进行交互,交互的结果直接影响到下一帧绘制的图片。这种交互和绘制的循环以足够高的频率进行着,使得使用者沉浸在一个动态的过程中,而不会意识到这是一张张独立的图片。

图片显示的频率以FPS(frames per second)或者HZ(Hertz)为单位。如果渲染的速度为1FPS,则毫无交互可言,用户将会持续的很痛苦的等待下一张图片的到来。当达到6FPS的时候,开始慢慢有一些想去交互的感觉。视频游戏FPS的目标为30、60、72升至更高,当达到这种频率的时候,用户将会集中精神进行交互了。

电影每秒显示24帧图片,但是它会使用一个快门系统(shutter system)将每帧图片显示2-4次,用于防止出现闪烁。这样的话,刷新率也就和显示率(display rate)就独立开来,故使用HZ来表示。比如:快门系统如果将每帧图片显示3次,则刷新率为72HZ。液晶显示器(LCD)也将刷新率和显示率拆分看待。(Patrick:想了一下,这里的以防闪烁应该是以防屏幕明暗变换,而刷新率其实就是对应了vsync,那么游戏里面vsync也是60fps的。(这么骚操作...一张图片显示3次,就能把24帧的效果演成72帧的效果?但是游戏可能不行,主要是因为交互需要立即得到反馈,不过也可以试试,每绘制一张,然后下一帧就不绘制了,直接显示上一帧的RT。特别是针对timeline这种不需要交互的))

24FPS对于看视频来说,基本可以接受。但是为了降低延迟(反应时间)必须提高频率,因为15ms的延迟就足以减慢和干扰交互(参考文献[1849]),比如头戴式VR设备的要求为90FPS,以降低延迟。(Patrick:所以说,为了解决视觉上卡的问题,需要至少24fps。然后由于游戏是交互的,一般情况下,当前帧的操作,需要下一帧才会看到反馈(图片更新之类),为了解决这个延迟问题,fps需要更高。不过听unity的报告现在最新的unity的机制已经是同帧内反馈,当前帧的操作当前帧消化显示出来。需要再确认下是哪个版本unity。。)

然而,实时渲染的重点依然在渲染,而非交互。如果速度是唯一衡量标准,那么只需要根据用户输入随便在屏幕上绘制一些东西就足够了。显然这样是不行的,毕竟实时渲染主要还是用于渲染3D物件。

交互性和3D效果都是实时渲染的充分条件,另外还有第三个因素:图形硬件加速。1996年的3Dfx Voodoo 1 card开启了消费者层面的3D图形。随着市场的快速发展,现在每个电脑、平板、手机都自带图形处理器。正是由于这些硬件加速,才使得实时渲染这些精美的demo成了现实。

正是硬件的发展,才快速推动了计算机图形学交互领域的发展。在这里,我们主要关注如何提高画面质量,并提升绘制速度,同时,也会聊一下加速算法和图形API的特性和限制。我们可能无法深入覆盖到每个课题,我们的目的是告知大家关键概念和术语,解释业内最先进和最实用的算法,并指出在哪里可以获取到更多的信息。我们希望能通过这本书,给你带来理解这个行业的工具。

1.1 内容简介

下面为每个章节的简单介绍

  • 2.图形渲染管线:实时渲染的核心,就是这一套针对场景的描述,然后一步步将我们所看到的绘制出来。
  • 3.图形处理单元:现代GPU使用一套固定函数(fixed-function)和可编程单元(grogrammable units)实现了渲染管线中的各个阶段
  • 4.变换(Transform):变换(Transform)是一套最基本的工具,用于控制位置、方向、尺寸、物件的形状、坐标系(location)以及摄像机的镜头视角
  • 5.渲染基础:先讨论材质球和灯光,以及如何用它们来实现所需表面(不管是写实还是风格化的)外观。然后介绍了一些和外观相关的主题,比如通过AA(antialiasing)、透明度、gamma矫正来实现更高质量的图片
  • 6.纹理:实时渲染最强大的工具之一就是可以快速访问图片以及在表面显示图片。这个过程叫做纹理采样(texturing),有大量的方法用于实现它。
  • 7.阴影:在场景中添加阴影可以增加真实感和感染力(comprehension)。这里会介绍用于快速计算阴影的最常用的算法。
  • 8.灯光和颜色:在聊基于物理的渲染之前,需要先理解如何量化光照和颜色。在PBS结束之后,需要将量化后的结果,根据屏幕的属性和观察到的环境(Patrick:环境可以理解为环境光,屏幕的属性是啥,NdoL类似的东西么...),转换成数值用于显示。这两个课题在本章都会讲述。
  • 9.基于物理的渲染(PBS);我们从头开始构建一个方便理解的PBS模型。本章从基础物理现象开始说起,包含了各种渲染材质的模型(Patrick:这是啥,是准备说不同的PBS算法,还是不同材质物件的特性,金属度啥的),然后最终将材质混合在一起,过滤它们已达到AA和保留表面外观的目的(Patrick:通过PBS算法还能AA?)
  • 10.局部关照(Local Illumination):描述复杂光源的算法(Patrick:这个和第7章有什么区别,在这里区分点光源、方向光、聚光灯、面光源?)。表面着色认为光是由具有特殊形状的物理物件发射出来的。
  • 11.全局光照(Global Illumination):为了提高画面的真实感,通过算法模拟光照和场景之间的多次交互。在这里会聊一下环境光、方向光遮挡(directional occlustion(Patrick:这是什么..))以及在漫反射和高光反射渲染GI效果的方法,达到可以通过一个方案满足各种类型场景需求的效果。
  • 12.后处理:图形硬件擅长快速的图像处理。先讨论图像过滤和重计算技术(reprojection),然后聊一些常用的后效:镜头光斑(lens flares)、运动模糊(motion blur)、景深(depth of field)。
  • 13.使用多边形(Beyond Polygons):三角形并非总是构建物件的最快/最真实的办法。使用基于图像、点云、体素(voxels)或者其他的方式都各有优点。(Patrick:ES可以绘制点、线、三角形,只有DX才能绘制polygon...那么基于体素只能..另外,基于图像是什么..)
  • 14.体渲染和半透明渲染(Volumetric and Translucency Rendering):这里主要是说体渲染的理论,以及其与光源的交互。模拟的现象从大尺寸的大气散射到头发细纤维内的光散射
  • 15.非真实渲染(Non-Photorealistic Renderin):想要把一个场景绘制的真实,则只有一种渲染方法。而其他的风格,比如卡通风格或者水彩风格,在这里会介绍。除此之外,还会介绍线和文本生成技术(Patrick:线?是对应三角形的线么。文本生成是UI文本么..)
  • 16.多边形技术(Polygonal Techniques):几何数据的来源很多,且数据量庞大,经常需要做一些调整使得渲染可以加速和提高质量。这里会介绍多边形数据展示和压缩的各种方法。(Patrick:这个蛮有意思的...这里难道要说mesh的压缩优化算法...)
  • 17.曲线和曲面(Curves and Curved Surfaces):复杂表面可以在质量和渲染速度之间进行权衡,更紧凑的表示和平滑曲面的生成(Patrick:按照原话翻译,基本读不通,这是按照我理解翻译的..)
  • 18.管线优化:通过大量的优化技术可以将App更进一步提速(即便它已经使用了很有效率的算法了)。需要做的就是找到瓶颈并找到解决方案。这里还会讨论下多线程。
  • 19.加速算法:功能完成后,就要进行优化。这里会讨论剔除和LOD渲染等方面的优化方案。
  • 20.有效渲染:大量的光照会影响性能,在确定一个物件是否可见之前就对其进行完全着色也是一种浪费。所以我们需要找各种办法解决这之类渲染中的低效率。
  • 21.虚拟现实和增强现实:在这里领域,想要快速一致的渲染真实图片,需要有挑战性的特殊技术。
  • 22.交叉测试(Intersection Test Methods):交叉测试对于渲染、用户交互和碰撞检测非常重要。这里提供了常用的最有效的几何交叉试验算法。(Patrick:按照原话翻译,基本读不通,等看了原文后再来改改吧..)
  • 23.图形硬件:这里介绍基本的架构类型、帧缓存(framebuffer)、颜色、深度。对GPU的一个案例进行研究
  • 24.未来:随便聊聊
  • 碰撞检测:鉴于篇幅的原因,碰撞检测一章被放到了网站realtimerendering.com上供免费下载,并附录上了线性代数和三角函数算法

1.2 符号和定义

首先,先聊一下书中出现的数学符号。如果想要更全面的了解本节以及本书中出现的术语,可以参考realtimerendering.com提供的线性代数附录。

1.2.1 数学符号

表1.1 总结了我们所使用的大多数数学符号。这里将详细介绍其中的一部分。

T01

但万事皆有例外,比如渲染公式中就明确的定义了其中一些符号的含义:L(光照radiance)、E(辐射度irradiance)、σs(散射系数scattering coefficient)

其中,角度和标量是真实数字。向量和点由粗体小写字母标识,表示方式如下所示。在CG领域,默认均为列向量。但是有些地方使用(Vx,Vy,Vz),而非正确格式:(Vx,Vy,Vz)T,也仅仅只是为了阅读方便。

T01

即使是使用相同的表达式,比如四分量的vector,坐标是由v = (Vx Vy Vz Vw)T表示,向量是由v = (Vx Vy Vz 0)T表示,点是由v = (Vx Vy Vz 1)T表示。然而有时,我们会使用三分量的vector表示向量/点,但是一定要尽量避免数据类型级别的误解。当进行矩阵运算的时候,向量和点使用相同的表达式非常重要。更多详情,请参照第四章:变换(Transform)。有些算法,比较喜欢使用数字索引,替代x、y、z,比如v = (V0 V1 V2)T。以上这些规则,一样适用于二分量vector,只需要简单的忽略三分量vector的最后一个成员即可。

针对矩阵运算,需要更详细的解释。常见的矩阵尺寸为2*2,3*3,4*4。我们以3*3为例进行讲解,然后可以很容易的扩展到其他类型的矩阵。矩阵中的一个标量元素为Mij,0<=(i, j) <= 2,其中i表示行,j表示列,如下所示

T01

下图为使用vector的形式展示矩阵,M,j为第j列向量,Mi,为第i行向量(由于该向量是列向量,所以要加上转置符号T)。和向量、点类似,索引可以使用x、y、z、w。

T01

平面是通过数学公式π: n * x + d = 0表示,其中n为平面法线,表示平面的朝向;d为标量,是平面上的一个点。如果是对应曲面等,法线n为表面上某一点的法线,而针对平面,所有的点的法线都相同。平面π将整个空间分成了两半,正的一半为:n * x + d > 0;负的一半为:n * x + d < 0。其它的点都在平面上。

一个三角形,可以通过三个点定义:V0、V1、V2,然后通过ΔV0V1V2表示。

T01

上图描述了一些运算符的意义。点积、叉积、行列式、长度运算符都可以从网站realtimerendering.com的线性代数附录中获取详细的解释。转置运算符可以将列向量转成行向量,反之亦然。第4个运算符,是在Graphics GemsIV中出现的,是一个作用于两分量vector的一元运算符,作用是获取当前vector v = (Vx Vy)T的垂直向量,即:v⊥ = (-Vy Vx)T。我们可以通过Ιa Ι来表示标量a的绝对值,或者通过 ΙA Ι表示矩阵A的行列式,当然,我们也可以通过ΙA Ι=Ι a b c Ι=det(a, b, c)来表示矩阵,其中a、b、c为矩阵的列向量。第8、9个运算符,是clamp运算符,在shader中经常会被使用,第8个运算符的目的是将负值clamp到0,第9个运算符,是将数值clamp到0到1。第10个运算符,阶乘,定义:(n! = n(n - 1)(n - 2) *** 3 * 2 * 1),注意0!=1。第11个运算符,二项式因子,定义如下:

T01

之后,我们将x = 0, y = 0, z = 0这三种平面称为坐标平面或者轴对齐平面。而轴ex = (1 0 0)T , ey = (0 1 0)T , ez = (0 0 1)T为主轴或者主方向,分别为x轴、y轴、z轴。这组轴通常被称为标准基。除非有特别说明,我们都将使用正交基(由相互垂直的单位向量组成)。

[a; b]用于表示a和b中间的值,包含a和b。(a; b)用于表示a和b中间的值,不包含a和b。[a;b)表示A和B之间的所有数字,包括A但不包括B。

文中还经常使用到atan2(y,x)。它是arctan(x)的扩展,主要区别是:-π/2 < arctan(x) < π/2 , 0 <= atan2(y; x) < 2π(Patrick:0-2pi是几个意思。。0-pi就足以了吧)。arctan的常用方式为arctan(y/x),但是当x=0的时候,就会出现“division by zero”的错误。(Patrick:遇到过一次有意思的事情,pps的dof代码中有一段做了除0保护,也就是使用了max(x,1e-5),但是对应的变量使用的是half的,ios上half的精度只到0.001,所以1e-5后,还是0,相当于没做除0保护。)但是如果使用atan2(y,x)就不会这样。

T01

log(n)指的是自然对数,loge(n),而非以10位底的对数,log10(n)

CG行业,默认3D坐标系为右手坐标系。

颜色将由三分量vector表示,比如(r,g,b),每个分量的范围为[0, 1]

1.2.2 几何定义

几乎所有的图形学硬件所使用的基本渲染图元(也被称为渲染图元)都是点、线、三角形。(我们所知道的唯一例外就是像素平面(参考文献[502]),可以绘制球体,nvdia的nv1芯片可以绘制椭圆球)

在本书中,我们将几何实体的集合看成是一个模型或者一个物件。而场景则是包含所要渲染的环境中所有模型的集合,场景还包括了材质、光照和视角信息。

一辆车、一栋建筑甚至一条线都可以被称为是一个物件。实际上,一个物件通常是由一组绘制图元组成,甚至有可能由更高类型的几何组成,比如贝塞尔曲线(Bézier curve)、曲面或者细分曲面。另外一个物件可以由其他的多个物件组成。比如汽车就是由4个门物件、4个轮子物件组成等。

1.2.3 着色

根据公认的计算机图形学用法,本书中提到的"shading"、"shader"以及相关的文字都对应着两种有区别,但是又有联系的概念:计算机生成的可视化外观(比如:"shading model"、"shading equation"、"toon shading"),或者是渲染系统中的一个可编程组件(比如:"vertex shader"、"shading language")。不管是哪一种,通过上下文都应该可以很容易看出来。

更多资源

其他我们能给到你的最重要的资源就是这本书的网站:http://www.realtimerendering.com。其中包含了最新信息以及本书中每章内容关联的网址链接。实时渲染领域在时刻变化着,本书中我们试图将重点放在基本概念和不太可能过时的技术概念。而网站中我们可以展现当今软件发展相关的信息,并且我们有能力使其保持最新。


虽然并非全部原创,但还是希望转载请注明出处:电子设备中的画家|王烁 于 2019 年 1 月 19 日发表,原文链接(http://geekfaner.com/shineengine/Translation1_RealTime_Rendering_4th_Edition1.html)