【译】GAMES101-现代计算机图形学入门:Lec14.5~16_BRDF、渲染方程、全局光照、路径追踪

513 阅读18分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 N 天,点击查看活动详情


大家好,我是曹骏。因为本人对计算机图形学、WebGPU等非常感兴趣,因此会陆续发布闫令琪博士的《GAMES101:现代计算机图形学入门》课程译文,希望能帮助到更多的同学理解课程,爱上图形学这一浪漫的学科。

先给出课程的链接: www.bilibili.com/video/BV1X7…
www.bilibili.com/video/BV1X7…
www.bilibili.com/video/BV1X7…

0 引入——辐射度量学概述 Radiometry — Motivation

闫老师学习方法:为什么学它(WHY)、它是什么(WHAT)、它是如何运作的(HOW),学了之后 HOW 其实是最不重要的

  • 在实现Blinn-Phong着色模型时,会设置一个数作为”光照强度“,这个数的真实物理意义我们并不清楚(其实是 Irradiance 辐照度)

  • Whitted风格光线追踪不是一个物理正确的结果,其中有很多简化;辐射度量学可以帮助我们进行物理准确的光照计算,它同样也是”路径追踪“的基础

  • 辐射度量学给出了一系列度量方法和单位描述光照 Measurement system and units for illumination

  • 辐射度量学精确的定义了光在空间中的属性:辐射通量 Radiant flux、强度 intensity、辐照度 intensity、辐射度 radiance

1 辐射度量学相关物理量

每平方米||the power emitted, reflected, transmitted or received by a surface, per unit solid angle, per projected unit area 单位面积单位立体角的功率|

1.1 Radiant energy & flux(Power)

  • Radiant energy是光源辐射的能量(在图形学里很少用这个概念) Radiant energy is the energy of electromagnetic radiation.

  • Radiant flux (power) 是单位时间内发射、反射、传输或接收的能量 Radiant flux (power) is the energy emitted, reflected, transmitted or received, per unit time.

  • Flux可以看作是单位时间内通过传感器的光子的数量 #photons  flowing through a sensor in unit time

  • 流明 lumen
    • 辐射通量相同的两个光源,如果发射的是不同波长的光波,对人眼睛所能引起的亮暗度感觉也不一样,也就是说他们有不同的发光效率,发光效率越高,人眼也会觉的越亮。因此真正影响人眼视觉明暗感受的是辐射通量于发光效率的乘积,也就是我们所说的光通量,单位是流明(lm)

1.2 Radiant Intensity

  • Radiant Intensity是点光源发出的每单位立体角的能量 The radiant (luminous) intensity is the power per unit solid angle emitted by a point light source.

  • 立体角 Solid Angles
    • 球体上一定区域面积与半径平方的比 ratio of subtended area on sphere to radius squared
    • 立体角,立体角最大是

  • 单位立体角 Differential Solid Angles
    • 球体上单位面积与半径平方的比,可以用球面坐标的的变化得到(由公式可知的划分并不是一个对球面面积均匀的划分,靠近赤道与靠近极点变化带来的立体角的变化不一样)

    • 将整个球面的单位立体角积起来,同样可以验证立体角最大是4π4\pi

  • 各向同性点光源 Isotropic Point Source

1.3 Irradiance

  • Irradiance是入射在表面点上的每单位面积的能量(光线和单位面积不垂直要投影到垂直的方向上去) The irradiance is the power per (perpendicular/projected) unit area incident on a surface point.

  • 兰伯特余弦定理(Lambert’s Cosine Law)其实体现的就是Irradiance
    • 兰伯特余弦定理也解释了为什么地球出现四季变换——太阳与地球各个位置夹角不同,Irradiance变换

  • 更正:之前我们假设假设能量集中在一个球壳上,随着球壳的增大,光的强度会有一个距离平方的衰减,这里的衰减其实也是Irradiance在衰减
    • 假设光以均匀的角度分布发射功率 比较最内部的单位球和半径为r的两个球体表面接收到的Irradiance,,即Irradiance有的衰减

1.4 Radiance

  • Radiance是为了用来描述环境中光线在空间中传播的一些属性,是每单位立体角,每单位投影面积发射、反射、发射或接收的能量 The radiance (luminance) is the power emitted, reflected, transmitted or received by a surface, per unit solid angle, per projected unit area.

1.5  Intensity & Radiance & Irradiance 的联系

1.5.1 概念总结

物理量图示符号国际单位制单位符号注释
Radiant energy辐射能焦耳the energy of electromagnetic光源辐射出的能量
Radiant flux(Power)辐射通量瓦特the energy emitted, reflected, transmitted or received, per unit time单位时间的能量,也可理解为单位时间内通过这个平面的光子数量
Radiant intensity辐射强度瓦特每立体角the power per unit solid angle emitted by a point light source单位立体角的辐射通量
Irradiance辐照度瓦特每平方米the power per (perpendicular/projected) unit area incident on a surface point单位时间内,每个单位面积上接受到的辐射通量(光线和单位面积不垂直要投影到垂直的方向上去)
Radiance辐射率瓦特每立体角每平方米the power emitted, reflected, transmitted or received by a surface, per unit solid angle, per projected unit area单位面积单位立体角的功率

1.5.2 Incident Radiance & Exiting Radiance

  • Incident radiance是到达平面每立体角的irradiance,即所有方向上的radiance积起来就是irradiance,radiance是irradiance在某个单位立体角的分量

  • Exiting radiance是单位面积辐射出的intensity,即整个面上的radiance积起来就是intensity,radiance是intensity在某个单位面积上的分量

1.5.3 Irradiance & Radiance

  • Radiance是Irradiance在某个方向上的分量,如下图,整个半球范围内单位面积接收到的各个方向的radiance积分起来即为接收到的irradiance

2 双向反射分布函数 BRDF(Bidirectional Reflectance Distribution Function)

  • 反射的过程可以理解为:一道光打在一个表面上,这个表面吸收了这道光的能量,随后又将一部分能量向不同方向辐射出去
  • 考虑一个微小面积表示从某一方向射入radiance,被表面吸收后得到的irradiance;随后得到的irradiance一部分辐射出去,表示从某一方向辐射出的radiance

  • BRDF就是一个定义了对于某一方向上单位面积接收的irradiance,如何分配到各个方向上的radiance的函数,即(任何一个出射方向的radiance)/(单位面积接收到的irradiance)

  • BRDF描述了物体和光线之间的相互作用。如果是镜面反射,那么只有反射方向上会有能量,其他所有方向上都没有能量;如果是漫反射,这个进来的能量会被均等的分布到各个方向上,即BRDF定义了材质

3 反射方程渲染方程 The Reflection EquationThe Rendering Equation

3.1 反射方程 The Reflection Equation

  • BRDF描述了某一方向上射入的irradiance最后如何反射到某一个方向上,而在实际反射的过程中某一个点可以接受来自四面八方的irradiance,所以要将每一个方向上(半球范围内)的irradiance积分起来,得到所有可能的入射光在这一点对观测方向的贡献之和

3.2 渲染方程(绘制方程) The Rendering Equation

  • 反射方程本身是一个递归的定义方式,反射点接受的irradiance并不只来自光源,还会来自其他表面反射而来的光线(因为光线不止弹射一次),这里我们先不深入考虑这一点,通过添加一个自发光(Emission)做一个通用化

  • 渲染方程(默认所有方向都是朝外的) The Rendering Equation

4 深入理解渲染方程 Understanding the rendering equation

4.1 渲染方程 The Rendering Equation

  • 如果有一个点光源,则反射光=自发光+入射光BRDF入射光与法线夹角的余弦

  • 如果有多个点光源,则多个点光源的影响结果需要累加起来

  • 如果有面光源,我们可以将面光源理解为点光源的集合,所以可以改写为积分形式

  • 如果还有其他物体反射的光,我们可以把其他物体的反射面当作光源,可以改写成一个递归的过程

The Rendering Equation (Kajiya 1986) 论文配图

4.2 全局光照 Global illumination

  • 渲染方程(是标准的第二类Fredholm积分方程)

  • 通过将位置和角度变量概括成,对渲染方程进行简化

  • 写成算子的形式,进一步简化

  • 利用算子的运算性质(求逆和泰勒展开)求解方程,解出L

  • 渲染方程被拆解成以光的弹射次数为区分的很多项。用渲染方程来理解光栅化,光栅化能做的只有自发光与直接光照;全局光照是经过了多次反射后的结果,即把表示间接光照的项也加起来

  • 光线经过多次弹射后结果会越来越亮,逐渐收敛(第四次弹射时上方灯亮了,是因为这里玻璃时双层的,光线需要两次弹射进入两次弹射射出才能到达相机)

5 简单的概率论回顾 Probability Review

  • 离散型随机变量
    • 随机变量与分布 Random Variables and PDF

    • 概率 Probabilities

    • 期望 Expected Value of a Random Variable

  • 连续型随机变量
    • 概率密度函数 Probability Density Function

    • 随机变量的函数和该函数的期望 Function of a Random Variable and Expected value

6 蒙特卡洛积分 Monte Carlo Integration

6.1 为什么学习蒙特 Why

  • 蒙特卡洛积分可以用来计算复杂定积分的值 we want to solve an integral, but it can be too difficult
    to solve analytically

6.2 什么是蒙特卡洛积分 What

  • 举一个例子,如果在定义域内随意取一点,得到对应的的值,则我们可以用一个高为,宽为的一个长方形面积来估计曲线下围出的面积,如果多次在间采样,随后把长方形面积平均起来,就能得到一个相对准确的结果
  • 蒙特卡洛积分是一种通过随机采样然后平均函数值来估计整个函数积分的方法 estimate the integral of a function by averaging random samples of the function’s value

6.3 如何进行蒙特卡洛积分 How

  • 定义一个函数,使用蒙特卡洛积分用一定概率密度去采样,估计其在定义域内的积分

  • 一种特殊情况是概率密度函数PDF为常数C,即在函数定义域内均匀采样,这样得到的蒙特卡洛积分的形式很符合直觉:即一开始说的多个长方形的面积(长,高)的和平均(除以)结果


  • 对于不同采样频率,更为通用的形式即为

  • 蒙特卡洛积分采样的样本越大(N越大),越准确

7 路径追踪 Path Tracing

7.1 Whitted风格光线追踪的问题 Motivation: Whitted-Style Ray Tracing

Whitted风格光线追踪会在光线打到光滑表面会进行镜面反射,打到漫反射表面会停止

  • Whitted风格光线追踪无法做出Glossy的材质(不是完全的镜面反射)

  • Whitted风格光线追踪不考虑漫反射的效果,但实际上光线也会在漫反射表面弹射,如右图中有Color Bleeding效果,而左图没有

此处为康奈尔大学做出的The Cornell Box模型,被广泛的用于测试全局光渲染效果

  • Whitted风格光线追踪是错的,渲染方程是正确的,但是渲染方程的求解涉及到了半球上的积分和递归运算

7.2 求解渲染渲染方程

7.2.1 使用蒙特卡洛积分求解渲染方程

  • 假设有一个有面光源、着色点、其他物体挡住光的的场景,首先我们先考虑直接光照 Suppose we want to render one pixel (point) in the following scene for direct illumination only

  • 在不考虑自发光的情况下,我们可以忽略渲染方程中的自发光项(仍然默认向量方向朝外) Abuse the concept of Reflection Equation a little bit (again, we assume all directions are pointing outwards)

  • 我们要计算点到相机的Radiance,由于这里渲染方程的形式是积分的形式,我们可以使用蒙特卡洛积分进行求解,最简单的我们可以假设在半球面均匀的采样,则PDF值(球面积分,半球面积分,PDF在所有立体角上积分起来是,所以PDF是

  • 使用蒙特卡洛积分求解渲染方程(这里符号分数线上面是点,下面表示的是pdf)

shade(p,wo)                                       //着色点p,沿wo方向到达观测点
	Randomly choose N directions wi~pdf           //以某一pdf采样N个方向的光线
	Lo=0.0                                        //初始化
	For each wi                                   //对于任何一个被选中的方向都从p点向这个方向打出一条光线
		Trace a ray r(p,wi)
		If ray r hit the light                    //如果打出的光线打到了光源,则利用渲染方程着色
			Lo += (1 / N) * L_i * f_r cosine / pdf(wi)
	Return Lo                                     //返回着色结果
  • 如果考虑间接光照,即从点连线没有直接打到光源,而是先打到了点,点可以将光反射到点,这里可以递归地想这个过程相当于在点地位置观测点得到的反射来的radiance

shade(p,wo)                                          //着色点p,沿wo方向到达观测点
	Randomly choose N directions wi~pdf              //以某一pdf采样N个方向的光线
	Lo=0.0                                           //初始化
	For each wi                                      //对于任何一个被选中的方向都从p点向这个方向打出一条光线
		Trace a ray r(p,wi)
		If ray r hit the light                       //如果打出的光线打到了光源,则利用渲染方程着色
			Lo += (1 / N) * L_i * f_r cosine / pdf(wi)
		Else If ray r git an object at q             //如果打出的光线打到了q点,计算p点看q点的着色再作为光源着色p点
			Lo += (1 / N) * shade(q, -wi) * f_r * cosine / pdf(wi)
	Return Lo                                        //返回着色结果
  • 到这一步仍未完全解决问题

7.2.2 问题一:光线数量问题——令N=1

  • 如果按照以上算法,则光线多次弹射时数量会爆炸 Explosion of #rays as #bounces go up:

  • 解决方法:只有当时光线数量不会爆炸(是path tracing,是Distributed Ray Tracing,现在很少提了)

shade(p,wo)                                   //着色点p,沿wo方向到达观测点
	Randomly choose ONE directions wi~pdf(w)  //*这里只采样一个方向,同时也不用for循环了*
	Trace a ray r(p,wi)
	If ray r hit the light                    //如果打出的光线打到了光源,则利用渲染方程着色
		Return L_i * f_r cosine / pdf(wi)
	Else If ray r git an object at q          //如果打出的光线打到了q点,计算p点看q点的着色再作为光源着色p点
		Return shade(q, -wi) * f_r * cosine / pdf(wi)
  • 误差很大,这里只需要同一个像素多取几个路径,然后再平均他们的radiance就可以了(这里其实也是一个蒙特卡洛积分过程) But this will be noisy! No problem, just trace more paths through each pixel and average their radiance!

ray_generation(camPos,pixel)                                  //向哪一个像素打出很多光线
	Uniformly choose N sample positions within the pixel      //再像素内均匀的取N个不同的位置
	pixel_radiance 0.0
	For each sample in the pixel
		Shoot a ray r(camPos, cam_to_sample)                  //任意一个采样都从视点到样本的位置连一条光线
		If ray r hit the scene at p                           
			pixel_radiance += 1 / N * shade(p, sample_to_cam) //连的光线打在了物体上,则着色
	Return pixel radiance

7.2.3 问题二:递归没有终止条件——俄罗斯轮盘赌 Russian Roulette (RR)

  • 真实世界中光线确实不会停止,限制光的弹射次数会造成能量损失,而没有终止条件的无限的递归无法计算 Dilemma: the light does not stop bouncing indeed! Cutting #bounces == cutting energy!
  • 为了解决上述问题,引入俄罗斯轮盘赌的概念(决定一定的概率停止光线往下追踪)

  • 首先,我们虽然会在中间停掉追踪,但我们期望最终得到的积分结果还是
    我们假设以一定概率往外打一条光线,着色结果是,同时有的概率不会打出光线,着色结果是
    所以最后可以得到期望

shade(p,wo)                                        //着色点p,沿wo方向到达观测点

   Manually specify a probability P_RR
   Randomly select ksi in a uniform dist. in [0, 1]
   If (ksi > P_RR)return 0.0;                      //[0,1]取一个数ksi,ksi大于规定概率则不能生存

   Randomly choose ONE directions wi~pdf(w)        //这里只采样一个方向,同时也不用for循环了
   Trace a ray r(p,wi)
   If ray r hit the light                          //如果打出的光线打到了光源,则利用渲染方程着色
   	Return L_i * f_r cosine / pdf(wi) / P_RR
   Else If ray r git an object at q                //如果打出的光线打到了q点,计算p点看q点的着色再作为光源着色p点
   	Return shade(q, -wi) * f_r * cosine / pdf(wi) / P_RR

7.3 对光线采样 Sampling the Light

  • 我们已经得到了一个正确的Path Tracing的方法,但是效率并不高 Now we already have a correct version of path tracing! But it’s not really efficient.

  • 光源较小的时候,如果使用之前的方法对着色点半球范围内的光线均匀采样,则很多光线就会被浪费掉,能打到光源的很少 there will be 1 ray hitting the light. So a lot of rays are “wasted” if we uniformly sample the hemisphere at the shading point.

  • 蒙特卡洛积分允许我们用任何方式采样,所以我们可以只对光源采样,这样光线就不会浪费
    假设我们在光源上采样,则
    但是渲染方程的积分是定义在立体角上的,而蒙特卡洛积分要求积分和采样在一个域上,现在是在光源的面积采样,在着色点半球积分,并不在一个域上

  • 要转换成一个域上我们要把渲染方程写成在光源上的积分,即需要找到的关系
    是在光源上的一个小的表面,是这个小的表面对应到单位球上的立体角是多少
    可以得到垂直于连线方向的投影面积,再除以两点距离的平方即可得到(立体角定义)

  • 找到之间的关系后,我们就可以对渲染方程进行改写,此时是在光源进行采样,光源进行积分,就可以利用蒙克卡罗积分进行计算

  • 现在我们可以对光源进行采样,相比之前在着色点上向各个方向采样完全看运气 Previously, we assume the light is “accidentally” shot by uniform hemisphere sampling
    此时我们在着色时应该考虑两部分 Now we consider the radiance coming from two parts:
    来自光源的贡献直接采样光源,不用俄罗斯轮盘赌 light source (direct, no need to have RR)
    来自其他表面的间接光照,需要用俄罗斯轮盘赌 other reflectors (indirect, RR)

shade(p, wo)
	# Contribution from the light source.
	L_dir = 0.0
	Uniformly sample the light at x' (pdf light = 1 / A)
	L_dir = L_i * f_r * cosθ * cosθ / |x' - p|^2 / pdf_light
	
	# Contribution from other reflectors.
	L_indir = 0.0
	Test Russian Roulette with probability P_RR
	Uniformly sample the hemisphere toward wi (pdf_hemi 1 / 2pi)
	Trace a ray r(p, wi)
	If ray r hit a non-emitting object at q
		L_indir = shade(q, -wi) * f_r * cos θ / pdf_hemi / P_RR
		
	Return L_dir + L_indir
  • 一个小问题,我们还需要考虑光源与物体之间是否有遮挡,在光源和物体间连线,判定中间有没有物体遮挡 One final thing: how do we know if the sample on the light is not blocked or not?

# Contribution from the light source.
L_dir = 0.0
Uniformly sample the light at x' (pdf light = 1 / A)

Shoot a ray from p to x'
If the ray is not blocked in the middle

	L_dir = ...

PPT中路径追踪伪代码迭代过程

8 其他 Some Side Notes

  • 路径追踪真的很难 Path tracing (PT) is indeed difficult
    • 把它当作本科CS里最具挑战性的任务 Consider it the most challenging in undergrad CS
    • 为什么:涉及了物理、概率论、计算、代码能力 Why: physics, probability, calculus, coding
    • 通过学习路径追踪你会对之前的知识理解更深 Learning PT will help you understand deeper in these
  • 路径追踪还算”入门吗“ Is it still “Introductory”?
    • 要进阶一点点,但是是”现代的“ Not really, but it’s “modern" :)
    • 学路径追踪你会收获很大,因为路径追踪是几乎100%正确的算法(左:照片,右:渲染)And so learning it will be rewarding also because ...

  • 早期的光线追踪概念和现在的光线追踪概念 Ray tracing: Previous vs. Modern Concepts
    • 早期的光线追踪说的就是Whitted风格光线追踪 Ray tracing == Whitted-style ray tracing
    • 现在的光线追踪是所有光线传播方法的大集合(闫老师个人理解) The general solution of light transport, including
      • 单向/双向路径追踪 (Unidirectional & bidirectional) path tracing
      • 光子映射 Photon mapping
      • Metropolis light transport
      • VCM / UPBP...
  • 我们没有涉及/不会涉及的内容 Things we haven’t covered / won’t cover
    • 怎样让方向均匀分布在半球上,怎样采样一个函数 Uniformly sampling the hemisphere, And in general, how to sample any function?

    • 蒙特卡洛积分可以用任意的pdf,选择什么样的pdf是最好的(重要性采样理论) Monte Carlo integration allows arbitrary pdfs, What's the best choice? (importance sampling)

    • 随机数有质量的好坏(低差异序列) Do random numbers matter?-Yes! (low discrepancy sequences)

    • 采样光源和采样半球两者可以结合起来 I can sample the hemisphere and the light -Can I combine them? Yes! (multiple imp. sampling)

    • 为什么一个像素所有路径的radiance平均起来就是这个像素的radiance?The radiance of a pixel is the average of radiance on all paths passing through it, Why? (pixel reconstruction filter)

    • radiance和像素的颜色不是线性对应的,需要经过伽马矫正 Is the radiance of a pixel the color of a pixel? No. (gamma correction, curves, color space)

最后再问一遍,路径追踪还算”入门“吗? Asking again, is path tracing still “Introductory”?
是的,敬畏科学,我的朋友 This time, yes. Fear the science, my friends.