ch1 光与表面的交互
计算机图形学(computer graphics)的主要目标之一,就是模拟光与物体(表面或介质内)交互的光学原理,将一个虚拟的数字 3D 场景,利用计算机生成一张 2D 的数字图像,供屏幕显示使用或者保存为数字文件格式。 难点:
- 对于表面上每个点,们必须在该点法线方向对应的半空间(hemisphere)上做积分运算以便求出该点的颜色值,因为每个点都可能接受来自场景中所有其他点反射的光照。
- 对于空间中传播的每一条光线(ray),我们必须遍历场景中所有物体表面上的每一个点,来计算出与该光线相交的最近的一个点的位置 (即最近点测试),从而进行光照计算。 为解决难点,可以将提出的方法理论分为两类:
- 通过寻找数学方法计算渲染积分方程,这方面有两大经典方法:即基于有限元分解的辐射度理论,以及基于蒙特卡洛积分的光线追踪技术。 有限元积分计算方法,将一个沿无限维空间的积分分解为一个有限纬度 (称为一个有限元) 的积分。如辐射度理论中通过蒙特卡洛等方法预计算出每个有限元的均值;蒙特卡洛方法是通过随机采样, 使用有限个采样点的函数贡献值,来近似计算积分方程的值。 这两种方法仍非常耗时,主要用于离线渲染。
- 根据光学现象或者其他理论拆分渲染方程,使得光照效果最终由多种效果叠加而成,包括直接光照,(软)阴影,漫反射光照,光泽反射光照,间接光照,环境遮挡,次表面散射,环境光照等等。
1.1 全局光照
早期工业中一般忽略间接光照,仅考虑光从光源出发,经过表面一次反射/折射之后到达人眼或者场景中的虚拟摄像机。这种不考虑环境其他非光源表面对着色影响的光照模型称为局部光照(local illumination)模型,反之则称为全局光照(global illumination)模型。 以下列举了一些光学现象,用来了解全局光照,以及如何理解令人信服的图形渲染目标。
阴影
直接光照通常不考虑物体间的遮挡关系,以利用GPU快速的光栅化特性,所以需要另一个单独的通道来处理阴影。可以通过GPU的光栅化特性,在运行时生成阴影贴图,或者利用GPU的模板测试生成阴影体积等。 阴影贴图是以光源中的单个点作为观察点,利用 GPU 光栅化渲染的一张图,通常它只包含深度值,所以它记录的只是物体边缘的几何信息,因此产生的阴影为硬阴影。其通常需要适当的反走样措施。 非点光源有一定面积,生成的为 软阴影,包含三个部分:完全遮挡的本影区,部分光照被遮挡的半影区,完全没有被遮挡到的光照区。
环境遮挡
反射
间接光照
除了上述镜面或光泽反射的光照,环境对于漫反射表面的影响非常重要,它 最重要的效果称为颜色渗透。间接漫反射几乎是最重要的全局光照,其计算特别昂贵,涉及渲染方程针对整个半球空间的积分,目前的主要解决方法是预处理,主要又两类方法:针对静态场景的光照贴图;针对动态物体的,在空白空间对环境光照稀疏采样。
焦散
散射
1.2 辐射度量学
略
1.3 物体的表面着色
解释光与物体的交互过程。
1.3.1 几何光学模型
几何光学(光线光学)被广泛采用与计算机图形学,并且做出简化假设:
- 物体表面绝对光滑
- 光仅可以被发射、反射、传播
- 光以无限快的速度沿直线传播 在这些假设下,光的反射由反射定律决定,折射由Snell’s Law决定。
1.3.2 光与表面的交互
- 光从光源(例如太阳或其他光源)或其他发光体中发射出来。
- 光与场景中的物体进行交互,部分被反射,部分被吸收并可能经过一定 路径传播后沿其他方向从物体表面散射出来。
- 最后,光被感应器(例如摄像机或者人的眼睛)吸收,形成图像。
光源
发出光并照亮整个场景,认为不会反射或者吸收其他光照 图形学中只用几个假设光源的光照分布只随方向而变化的模型,包括平行光、点光源、聚光灯。这些光源发出的光线会在场景中像自然光一样传播;场景中通常还有一些(间接)光不通过这种方式计算,如大面积环境光。 对于直接光源,接受到的辐射亮度L是个五维量(三维位置二维方向)太过复杂,辐射强度I通常用来表示辐射亮度分布。 表面接受的所有光照用E表示
通常用距离递减函数描述E随距离的递减关系。可以提供更多控制效果,可以提高性能。
材质
材质要从两方面理解。 计算机图形学中,物体的“形”和“色”完全分开。形由一组定点构成的网络定义。表面着色由材质决定,材质通常包含纹理。着色器以及其他着色方程所需的参数,构成一个对象附加到物体上,在渲染时传输到GPU内部对表面着色,这个过程又包括贴图、光照及其他计算。 在微观几何尺寸上,物体表面并不绝对光滑,可能有不同的反射或折射。折射的效果取决于物体的材质,材质分为两大类即金属和非金属(绝缘体)。对于非金属,可能会从另一表面离开,可能由物体内部发射回来有不固定方向性的光,称为漫散射。散射光发发射回表面的位置取决于表面性质,如果这个距离小于一个像素的尺寸(即在微观范围中) ,在着色的时候可以假设其距离为 0,这种散射称为局部次表面散射;否则称为全局次表面散射。 计算机图形学中将反射和漫反射区分开,称为光泽和漫反射光。漫反射光要对全空间积分。光泽取决于表面的粗糙程度,越粗糙、反射范围越大、表面越模糊。
感应器
传感器接收辐射亮度L,并以一定分辨率存储数字图像信息。通常成像系统,包含摄像机的点和观察矢量。然而像素点总有尺寸大小,如果只取中心点采样,会出现锯齿,这是由于采样不足的走样现象,需要用反走样技术来避免或减少。
1.4 采样和反走样
几何走样
我们按照屏幕的分辨率对于几何图形的可见性进行采样,即采样点之间的间距为一个像素,采样点的位置为每个像素的中点。 必须使用两倍于可见性函数最高频率的采样率,然后三角形的可见性总存在不连续,这种不连续导致无限大的频率。对于有限的二维或三维空间域,走样是不可避免地。这种对于几何图形的可见性函数采样导致的走样称为几何走样。可以寻求一些方法减轻这种现象,流行的方法有过采样,其本质是是使用比图像分辨率更高的采样频率对原始图像采样然后用这些采样点重建对应采样率下的函数值。相当于使用高于图像输出分辨率的频率渲染场景,然后将其缩放到输出分辨率,这个过程称为超采样。
着色走样
发生于像素着色器中,指在着色器中对一些以分析的方式得到的连续函数的采样不足导致的,而不是对纹理的采样不足。着色走样不能用MSAA解决,超采样能减少却代价高效果不明显。有效的思路是将这些参数融入光浩计算,使得原始连续函数更平缓,然后对这些光照计算结果采样。
时间走样
出现于当物体在运动时,由于渲染帧率的限制,其对运动过程的采样不足导致。一种常见的方法时运动模糊,和超采样一样依靠对时间域取更多采样点,然后进行反走样,当然这种方法成本高;另一种普遍方法是针对当前的帧渲染结果生成速率花奴才能,然后使用这些方向在后处理阶段对其邻近的像素点进行插值计算。
1.4.2 重建
1.4.3 超采样
1.5 基于物理的渲染
我们将建立光与表面复杂交互过程的数学模型,不同级别引擎会有不同级别近似。早期由于计算的限制,工业运用大都采用近似模型,这些模型能产生理想效果却不是物理正确的。现在物理渲染已经成为主流。
1.5.1 双向反射分布函数
数字图像的世界将物理世界像素化为离散图像,对于小于一个像素的微观尺寸,无法用真实的几何模型表示,对于宏观尺寸,较大区域拥有不同的粗糙度,使得相机会从不同角度看它。 从结果上来看,这种微观结构使得来自每个方向的每束光在表面的各个方向具有一个特定的分布函数。数学上,用双向反射分布函数来表示物体表面的反射,表示为反射方向上的辐射亮度增量与入射方向辐射照度增量的比率:
其中,是入射光方向,表示观察方向,为入射光方向与表面法线的夹角 如图\ref{f:intro-brdf}所示。由于在球面坐标系中,一个方向可以用一个方位角(azimuth angle)\myindex{方位角}{azimuth angle}和一个天顶角(zenith angle)\myindex{天顶角}{zenith angle}表示,因此整个BRDF函数具有4个变量。BRDF函数的单位为,其中为立体角。直观上讲,BRDF的值表示入射光方向单位立体角的能量在反射方向上反射的比率。 给定BRDF函数,可以求出该点沿观察方向的辐射亮度:
表示按RGB放分量相乘,因为辐射照度E和辐射亮度L都是RGB矢量,所有仍表示一个由RGB分量构成的矢量,这个方程又称反射方程。
1.5.2 菲涅耳公式
1.5.3 微面元理论
1.6 渲染方程
全局光照算法的目标就是计算光束在场景传播以及与物体的交互过程中的能量传递,基于物理的全局光照技术要求整个场景在光照传播过程中保持能量守恒。 使用表示光从位置向方向发射,箭头表示方向。假设表示光源或发光体在点沿方向的辐射亮度,表示物体在点向方向方向的来自反射或折射的辐射亮度,根据能量守恒。
通过BRDF定义,得到:
其中,表示沿点法线方向的半空间,如果是折射光,则是法线反方向的半空间:
渲染方程可以称为Fredholm第二类积分方程,因为其未知项辐射亮度L同时出现在两边,使得计算复杂。
1.6.1 光线路径表达式
用于度量一个全局光照算法中从光源到摄像机所能形成的路径形式,可以来指导这些算法是否应该增加或减少某些光照路径的采样密度来实现不同效果。 E 表示摄像机,L 表示光源或发光体,D 表示一次漫反射,S 表示一次光泽反射,V 表示体积内的散射,| 表示对两边的路径取或,∗ 表示零次或多次重复,+ 表示 一次或多次重复,[x] 表示路径是可选的。
ch3 着色管线
我们可以直接使用基于光栅化的经典渲染管线来对场景进行渲染着色,计算机图形学中构建了一套与上层应用无关的抽象层或基础架构——着色管线。
- 渲染:渲染通常是指将整个 3D 数字场景转换为一张 2D 图像的整个过程,它通常包含多种非常复杂多样的全局光照技术和过程;
- 着色是指计算物体表面每一个像素点的(我们所看到的)最终颜色值,即在着色器或者渲染方程中它是计算辐射亮度(radiance)的过程;
- 光照计算是计算所有光源对一个像素点的“辐射照度”(irradiance)的过程。
3.1 着色技术基础
简化渲染方程:
这里表示点处沿方向的辐射亮度,表示点处沿方向自发光的辐射亮度,表示沿方向射向点的辐射亮度,表示点处的BRDF函数。 该方程完整解通常要使用迭代的方法,这个方程不对GPU友好,不能直接在着色器中求解。实时渲染方法中通常将渲染方程分解为多个部分,并使每个部分能够以各种方式形成着色器中的一个参数,最终着色方程可以直接根据这些参数(它们通常都是某种程度上的近似值)计算出一个像素点的最终颜色。它们 可能以预处理的方式提前在预处理阶段计算出来,也可能实时地使用光栅化技 术来计算某个量,不管怎样,这些参数使得最终在着色器中我们可以使用一个 公式计算出最终的颜色值。 有了材质参数,着色方程可以写成一个只包含最基本几个变量的形式,渲染方程的各部分可以根据这些最基本的变量和材质参数计算出来,这个包含基本变量的着色方程如下:
这里的加数形式表示辐射亮度是所有光源的累积贡献,表示第个光源的辐射照度,表示入射光方向矢量,表示观察方向矢量,表示表面法线矢量,和分别表示表面的漫反射折射率和高光反射折射率,表示某个高光模型(例如Blinn-Phong模型)中的高光扩散系数(specular spread factor)或者粗糙度。 这里有两个变量是随着光源的变化而变化的:即入射光方向矢量和光源辐射照度,对于辐射照度,它一般可以通过光源参数中的辐射强度和距离递减函数求得,即:。需要注意的是,该着色公式仅考虑点光源和直线光线,它们可以很直接地计算出辐射照度的值,对于其他光源如环境贴图,在渲染中通常使用单独的渲染通道来处理,此时,利用式中的变量仍然能够满足计算辐射照度的条件(例如环境贴图需要的入射光方向)。 因此对物体表面着色就是在着色器中执行该式计算过程。不过对渲染管线需要建立不同的基础架构来改善性能问题。
3.1.1 光栅化技术
利用这个使用一些材质参数一次性计算的着色方程,场景渲染过程如下:
- 方式虚拟相机于3D场景,设置视锥体表示可视区域以映射到2D窗口。
- 场景中每个物体的顶点数据和所有环境贴图、阴影提交到OpenGL开始绘制。这些顶点构成的图元被锥体裁剪,剩下的图片被光栅化到与窗口分辨率对应的像素位置,每个像素块称为一个片元。
- 片元着色器对每个片元使用3.1.0的式子进行着色计算,遍历场景中的每个光源分别计算对该片元辐射照度的贡献,并与帧缓存上对应的像素位置上的深度值比较。
- 当所有物体被遍历完后帧缓存上的颜色缓存被显示或者读回宿主程序。 这个传统的渲染过程基本就是利用图形处理器接口提供的经典管线,有便利性:
- 结合图形接口深度测试和颜色混合的机制,传统的渲染管线可以很容易 地实现对半透明物体的绘制。
- MSAA 被集成到渲染管线,它可以对每个片元的深度进行多次采样,而使用一次着色计算以实现反锯齿。
- 每个物体可以根据其图形特征使用独立的着色器或着色器组合。 当场景结构简单时,上述方法非常简单高效,随着场景结构复杂度增加,就会变得低效。几乎所有影响性能的因素都和称为过度绘制的概念有关。
ch4 蒙特卡洛
4.1 概率论基础
4.2 蒙特卡洛积分
对积分的计算,数值分析方法常使用近似方法如划分区域求和:
这里的是每个区间的中点位置的函数值,N越大,该近似越逼近积分I的真实结果。当将这种确定性积分方法推广到d-维积分时,它要求将原始积分分为个采样空间,则无法适用。 积分的区域求和方法时一种传统的数值近似方法,它必须在每个维度上使用同样的近似结构(即对每个维度执行空间划分),因此它的采样的数量是和维度相关的;而大数定律的采样点来自于满足某个分布的一个随机数,这个随机数直接对一维或多维空间进行采样,这个采样的数量与函数的维度并无直接关系。
。。。。
。。。
ch5 路径追踪技术
全局光照算法实际上是解决光照在场景中的传输问题。离线方法中首先介绍的是基于蒙特卡洛采样方法的光线追踪技术,分别对应三种不同的采样方式:(双向)路径追踪算法、光子映射技术、基于马尔科夫链的梅特波利斯光照传输(Metropolis ligh transport, MLT)方法。
5.1 全局光照的衡量标准
首先是针对所有全局光照技术的、概念性的标准;第二种是针对蒙特卡洛方法的数学定义。从概念上从(不限于)以下角度取衡量:健壮性、渲染速度以及精确度。
5.1.1 有偏性和一致性
5.2 光线追踪及其历史
光线追踪以摄像机为起点,向屏幕的像素点发射光线,这些光线与表面进行交互传播,最终击中光源或发光体。最早的光线追踪技术称为光线投射,它从摄像机发出可视光线以找到场景中的每个像素的可视点,然后从这个可视点向光源发射阴影光线以求出该可视点的颜色。
代表光源的数量,该式计算的是直接光源。[Whitted, 1979a] 在光线投射的基础上,让光线沿反射或折射方向继续递归地传播知道遇到光源为止。该算法中,一个光线击中一个表面时随机产生3条光线,即反射光、折射光、阴影光线。这个确定性的(区别于蒙特卡洛的随机形式)光线追踪形式称为Whitted风格(也称递归)光线追踪。实现了以下光照传输:
Whitted风格的光线追踪在光线投射算法的基础上加入了间接光照,但是这些简介光照仅限于是完全的镜面反射和折射,其中的BRDF是一个狄拉克函数,即在一个给定的空间方向定义域中,该BRDF只在一个方向上是非零的。 上述限制被 [Cook et al., 1984] 的分布式光线追踪算法客服,该算法基于空间中所有方向的一个积分来近似光泽反射,以及基于使用光源面积范围内的方向的积分来计算软阴影面积效果。该算法中使用蒙特卡洛方法来近似计算这些积分值,又称随机光线追踪:
分布式光线追踪算法第一次引入蒙特卡洛方法用于计算更完整的光照传输。由于物体表面并不绝对光滑,每个出射方向的辐射亮度是由来自多个方向的入射光构成的,这涉及对空间方向的积分计算,蒙特卡洛的引入简化了积分计算。 分布式光线追踪中,结果是对空间多个方向辐射亮度的积分,即在蒙特卡洛方法中需要从空间抽取多个方向,导致了一条树形的光束树,随着光线递进,光线数量会发散得越来越多。这是其最大的缺点,使得几乎不可能计算间接漫反射。 直到 [Kajiya, 1986] 将渲染方程转换成了一个基于路径积分形式的,显式积分方程,光照传输的计算才能够被有效地使用蒙特卡洛方法进行计算,在路径积分形式的渲染方程中,整个场景的光照分布就是一条条路径的积分,不再有隐式的递归,只要我们找到足够数量的路径,就能够使用蒙特卡洛方法有效地计算光照分布。基于这种路径积分形式的全局光照技术通常称为路径追踪。
5.3 渲染方程的路径积分形式
在计算光照传输的过程中,我们需要保证能量守恒,即发射出的辐射亮度等于该店接受所有入射方向的辐射亮度和,不同分量的大小由BRDF控制。对于传统的基于半空间方向积分形式的渲染方程,我们需要知道入射光线的方向,所以这里我们把光线投影函数集成进去,表示从方向发射一条光线得到的第一个与该光线相交的点。
L(p,\omega_o)=L_e(p,\omega_o)+{\rm \int}_{\Omega}f(p,\omega_o,\omega_i)L(t(p,\omega_i),-\omega_i)|\cos\theta_i|{\rm d}\omega_i $$ 该方程为隐式方程,即需要求出所有方向到达p点的辐射亮度。分布式光线追踪形成了光线树。将无穷路径的积分转化为一条显式路径,把方向集合换转为面积形式。 ### 5.3.1 渲染方程的面积积分形式 ### 5.3.3 一个像素的颜色怎么计算 ## 5.4 基本路径追踪技术 ## 5.8 提高光线追踪算法的效率 ### 5.8.1 处理器执行模型 ### 5.8.2 加速遍历的基元结构 为了计算光线与场景中物体表面的交点,每条光线需要遍历场景中所有的基元。场景中所有基元的加速结构可以分为两大类:空间细分和物体层次结构。 空间细分是对基元所在的空间进行递归地划分,与某个空间相交的基元被存储到该部分空间区域对应的结构中。常见的有: - 八叉树:从包围场景的一个立方体开始,递归地将每个立方体细分为8个子立方体,直到满足某个终止条件。 - 二叉空间分割:递归地每次使用一个分割平面将平面细分为两个部分。分割方向通常与坐标轴对齐(对齐称为k-d树) 物体层次结构是对基元(而非空间)进行划分,这样不同节点的的空间可能重叠。常见的如: - 包围盒层次结构(BVH),递归地对基元列表进行划分,并在每一层存储子树的AABB包围空间,这些分割面通常是和坐标轴对齐的。 - 包围间隔层次结构(BIH),BIH仅存储某个轴方向上的一个间隔。 k-d树对静态场景有更快的速度,但是实践中BVH更普遍。 #### BVH的构建 #### 多分支 BVH ### 5.8.3 加速光线遍历 一个基础的光线追踪算法可以被划分为两个部分:光线/基元相交计算;顶点着色计算。 当光线在BVH树结构中进行遍历时,对于每一个叶节点,光线首先与该叶节点对应的包围盒进行相交测试,如果相交然后再对该叶节点对应的一个或多个基元进行相交测试;如果是内部节点,则直接对其包围盒进行相交测试,如果相交则再分别对其子节点进行相交测试,整个过程递归进行。这个过程既不能充分利用SIMD指令,也无法高效使用缓存系统。 #### 有序遍历 #### 连贯光线 #### 非连贯光线 ### 5.8.4 着色优化 前面针对遍历进行优化可能对着色计算的优化帮助不大:它们对数据局部性要求不同;非连贯光线的遍历,增加纹理数据访问缓存命中失败的概率。 针对着色优化的方法分为:在单个,全局的光线流上提取着色相关的连贯性;使用更小的光线流,每个光线流被分发到 CPU 的一个线程上执行,通过在局部的光线流上提取连贯性提高 CPU 上执行的性能。 #### 全局排序 # 梅特波利斯光照传输