KAIST-CS580-计算机图形学笔记-全-

KAIST CS580 计算机图形学笔记(全)

001:OpenGL图形管线基础

在本节课中,我们将学习计算机图形学中一个核心概念:OpenGL图形管线。我们将回顾如何将三维场景中的几何信息,通过一系列步骤处理,最终渲染成二维图像。本节课将重点介绍管线中的几何处理部分,包括模型变换、相机投影和光栅化。

上一节我们介绍了课程的整体结构,本节中我们来看看图形渲染的基础框架。

图形管线概述

在计算机图形学中,渲染管线可以被视为模拟电影拍摄的过程。这个过程包含几个基本组成部分:

  • 三维物体:我们需要用数学方法表示场景中的三维物体,包括其几何形状外观属性
  • 动画:我们需要表示物体在三维空间中的运动和变化,这涉及到三维空间中的变换
  • 相机:我们需要一个模型来模拟相机,以将三维场景捕捉到二维图像上。
  • 光照:我们需要模拟光线在场景中的传播,以计算最终到达相机镜头的光线,从而生成图像。

在入门课程中,我们讨论了上述所有方面的基础知识。在本进阶课程中,我们将更深入地关注外观、光照和相机模型,以实现更精确、更逼真的图像模拟。

将三维场景转换为二维图像,主要有两种渲染框架:

  • 基于光栅化的框架:这是OpenGL等许多图形应用的基础。其核心思想是将三维物体投影到二维平面上,然后在图像空间进行处理。这是本节课将简要回顾的内容。
  • 基于光线追踪的框架:这种方法不直接将三维物体投影到二维平面,而是从二维图像平面向三维空间发射光线,逆向追踪光线的路径,直到光源。本课程后续将重点讨论这种框架。

OpenGL图形管线流程

以下是OpenGL图形管线处理几何信息的主要步骤流程图:

管线从原始的几何数据开始,经过一系列处理阶段,最终输出图像。其中,顶点处理器片段处理器是可编程的(通常使用着色器语言编写),而光栅化器等则是硬件固定的功能单元。本节课我们将重点关注顶点处理器光栅化器的工作原理。

1. 原始几何表示

最常用的三维几何表示方法是三角形网格。它由以下部分构成:

  • 顶点:三维空间中的点。
  • :由三个顶点连接形成的三角形。
  • 附加信息:每个顶点可以附带额外信息,如表面法线、颜色、纹理坐标等。

三角形网格是一种用紧凑方式表示三维表面的简单形式。

2. 顶点处理器

顶点处理器负责对每个顶点进行一系列坐标变换。它包含几个关键步骤:

模型视图变换

此步骤的目的是将物体从其自身的局部坐标系放置到场景的世界坐标系中,并进一步转换到相机坐标系。这通常通过一个4x4仿射变换矩阵来完成。

在三维图形中,存在多种类型的变换:

  • 刚体变换:仅包含平移和旋转。
  • 欧几里得变换:包含平移、旋转和反射。
  • 相似变换:在欧几里得变换基础上增加均匀缩放。
  • 仿射变换:包含平移、旋转、反射、非均匀缩放和剪切。
  • 投影变换:包含所有上述变换以及投影。

在OpenGL管线中,我们使用齐次坐标4x4矩阵来统一表示这些变换。一个4x4仿射变换矩阵可以写为:

M = [ R   t ]
    [ 0   1 ]

其中 R 是一个3x3矩阵,代表线性变换(旋转、缩放、剪切),t 是一个3x1向量,代表平移。

三维旋转可以用多种方式表示,例如欧拉角(绕X、Y、Z轴顺序旋转)或四元数。一个绕X、Y、Z轴分别旋转角度 α, β, γ 的变换可以表示为矩阵连乘:R = R_z(γ) * R_y(β) * R_x(α)

模型视图变换的结果是将所有顶点坐标转换到相机坐标系

相机投影

接下来,我们需要将相机坐标系中的三维点投影到二维图像平面。我们首先考虑简单的针孔相机模型

假设我们沿负Z轴方向观察场景,针孔位于原点,图像平面位于 Z = -1 处。对于一个三维点 P(x, y, z),其投影点 P' 的坐标为 (-x/z, -y/z, -1)。为了避免图像倒置,我们直接投影到 Z = -1 平面。

这种投影映射可以巧妙地利用齐次坐标的性质,用一个4x4矩阵表示。齐次坐标 (x, y, z, 1)(kx, ky, kz, k) (k ≠ 0)表示同一个三维点。因此,将点 (x, y, z, 1) 映射到 (x, y, z, -z),再除以最后一个分量 -z,就得到了正确的投影坐标 (-x/z, -y/z, -1)。对应的投影矩阵为:

P = [ 1 0 0  0 ]
    [ 0 1 0  0 ]
    [ 0 0 1  0 ]
    [ 0 0 -1 0 ]

在实际图形管线中,我们通常使用透视投影,它将一个视锥体(由左、右、下、上、近、远平面定义)映射到一个标准设备坐标的立方体内(其坐标范围从-1到1)。这个变换同样由一个4x4矩阵实现。保留Z轴信息对于后续的深度测试至关重要。

视口变换

经过投影和齐次除法后,我们得到标准化设备坐标,其X、Y、Z分量都在[-1, 1]范围内。最后一步是视口变换,将这些坐标映射到实际的屏幕像素坐标。例如,将X从[-1, 1]映射到[0, 屏幕宽度W],将Y从[-1, 1]映射到[0, 屏幕高度H]。这是一个二维的非均匀缩放变换。

至此,顶点处理器的任务完成,它输出了每个顶点在屏幕空间的位置及其他需要插值的属性。

3. 光栅化与深度测试

顶点处理器之后是光栅化器。它的任务是确定一个图元(如三角形)覆盖了哪些屏幕像素(称为片段),并为每个片段插值计算顶点的各种属性(如颜色、纹理坐标、深度等)。

以下是插值计算的关键点:

重心坐标插值

对于三角形内的任意一点P,其属性可以通过三个顶点的属性线性插值得到。在二维屏幕空间中,可以使用重心坐标 (α, β, γ) 作为权重,其中 α + β + γ = 1,且均非负。点P的属性 V_p 可计算为:
V_p = α * V_a + β * V_b + γ * V_c
其中 V_a, V_b, V_c 是三个顶点的属性。重心坐标可以通过计算子三角形面积与总面积之比得到。

透视校正插值

这里存在一个关键问题:在三维空间中线性插值属性,然后投影到二维屏幕,与先将顶点投影到二维屏幕,然后在屏幕空间线性插值属性,这两种方法得到的结果并不相同。直接使用屏幕空间计算的重心坐标进行插值会导致错误,尤其是在纹理映射时产生扭曲。

为了解决这个问题,必须进行透视校正插值。原理是:虽然投影变换本身不是仿射变换,但我们可以利用齐次坐标 w 分量进行校正。

正确的插值方法如下:

  1. 在顶点着色器中,对于需要插值的任意属性 V 和齐次坐标的 w 分量,我们输出两个值:V/w1/w
  2. 光栅化器在屏幕空间对这两个值分别进行线性插值(使用屏幕空间的重心坐标)。
  3. 在片段着色器中,通过以下计算得到透视校正后的属性值:
    V_corrected = interpolated(V/w) / interpolated(1/w)

这样就能保证插值结果与在三维空间进行线性插值后再投影的结果一致。

深度测试与裁剪

在光栅化过程中,还会进行深度测试。每个片段都有其插值得到的Z值(深度)。当多个图元覆盖同一个像素时,深度测试会比较它们的Z值,只保留离相机最近(Z值最小)的片段,从而正确处理遮挡关系。

此外,为了提升效率,管线还会进行裁剪,剔除完全在视锥体之外的图元,并对与视锥体相交的图元进行裁剪。

4. 片段处理器

光栅化之后是片段处理器(片段着色器)。在这里,我们可以利用插值得到的属性(如纹理坐标、法线等)进行进一步计算,例如从纹理中取样颜色、计算光照效果等。这部分内容将在后续课程中详细展开。

总结

本节课我们一起学习了OpenGL图形管线的基础知识。我们回顾了从三维几何表示开始,经过模型视图变换相机投影变换视口变换的顶点处理流程。接着,我们探讨了光栅化阶段如何确定像素覆盖并进行属性插值,重点讲解了透视校正插值的必要性和方法,以及深度测试的作用。这些步骤共同构成了将三维场景渲染为二维图像的核心流程。下一节课,我们将深入探讨另一种表示三维旋转的工具——四元数。

002:3D旋转与四元数

在本节课中,我们将学习3D旋转的表示方法,特别是四元数。我们将回顾刚体变换的应用,探讨欧拉角及其局限性,并深入理解四元数如何以一种更优雅和高效的方式表示和组合3D旋转。

刚体变换的应用

上一节我们介绍了变换的基本概念,本节中我们来看看一种特殊的变换——刚体变换。刚体变换是旋转和平移的组合,在计算机图形学、机器人学和计算机视觉中有广泛应用。

以下是刚体变换的一些常见应用场景:

  • 虚拟场景构建:在3D场景中放置和排列物体时,通常需要对其进行平移和旋转。
  • 角色动画:通过控制角色骨架中各个关节的旋转,可以驱动角色模型运动。
  • 机器人学:控制机器人关节的旋转和平移,使其末端执行器能与真实物体交互。
  • 计算机视觉(运动恢复结构):从多视角图像中估计每个相机的位姿(旋转和平移)。
  • 神经渲染:运动恢复结构是神经渲染中获取多视角图像相机位姿的基础技术。

旋转的矩阵表示与挑战

任何仿射变换都可以用一个4x4齐次坐标矩阵表示。平移、缩放和错切都可以通过修改矩阵中特定位置的元素来实现。

然而,表示一个任意的3D旋转(例如绕空间任意轴旋转特定角度)则不那么直观。问题在于:我们如何设置矩阵中的所有数值,才能精确表示我们想要的旋转?

欧拉角

表示任意3D旋转所需的最少参数是三个。最直观的方法之一是使用欧拉角,即绕X、Y、Z轴旋转的三个角度 (α, β, γ)。通过按特定顺序(如先Z、再Y、后X)连续应用这三个旋转,可以表示任何3D旋转。

欧拉角在航空领域对应俯仰、偏航和横滚角,在硬件上也有体现,例如相机云台稳定器就是一种三轴万向节结构。

但欧拉角存在两个主要问题:

  1. 旋转顺序不可交换R_x * R_y * R_z 的结果通常不等于 R_z * R_y * R_x
  2. 万向节死锁:当中间轴的旋转角为90度时,会失去一个旋转自由度,导致第一轴和第三轴的旋转效果相同,从而总共失去两个自由度。这使得在该姿态附近进行旋转插值变得困难。

此外,组合多个欧拉角旋转的计算并不直观。例如,绕Y轴旋转90度后再绕X轴旋转90度,结果等价于绕对角线轴旋转120度,而非简单的角度相加。

从2D旋转到四元数

为了解决旋转组合的问题,我们引入四元数。首先,让我们回顾2D旋转的优雅表示。

在2D复平面上,单位复数可以表示一个2D旋转。根据欧拉公式,一个旋转角度 θ 可以表示为:
e^(iθ) = cosθ + i sinθ
其中 i 是虚数单位。两个单位复数相乘,其结果对应于两个旋转的叠加。

19世纪的数学家哈密顿思考:能否找到一个3D空间,其中的“单位”点能对应3D旋转,并且其“乘法”对应旋转的组合?他发现答案不在3D空间,而在4D空间。由此他发现了四元数。

四元数基础

一个四元数 q 定义如下:
q = a + bi + cj + dk
其中 a 是实部,b, c, d 是虚部,i, j, k 是满足以下关系的虚数单位:
i² = j² = k² = ijk = -1
ij = k, jk = i, ki = j
ji = -k, kj = -i, ik = -j
关键点在于,四元数的乘法不满足交换律

以下是四元数的一些基本运算和术语:

  • 范数||q|| = sqrt(a² + b² + c² + d²)
  • 共轭q* = a - bi - cj - dk
  • :对于单位四元数(||q||=1),其逆等于其共轭:q⁻¹ = q*
  • 共轭运算:对于四元数 pq,定义共轭运算为 q p q⁻¹。这个运算是一个线性变换,可以写成一个4x4矩阵与四维向量 p 的乘法。

四元数与3D旋转

最重要的结论是:单位四元数(||q||=1)可以表示一个3D旋转

具体来说,如果一个单位四元数 q 表示为:
q = cos(θ/2) + (u_x i + u_y j + u_z k) sin(θ/2)
那么它对应于绕单位轴向量 u = (u_x, u_y, u_z) 旋转角度 θ 的变换。

通过共轭运算 q v q⁻¹(这里将纯虚四元数 v = xi + yj + zk 视为3D向量 (x, y, z)),可以将该旋转作用于向量 v。这个运算对应的线性变换矩阵的左上3x3部分,就是一个标准的3D旋转矩阵。

单位四元数位于4D空间中的单位超球面(3-球面)上。这个映射是满射(每个3D旋转都有对应的四元数)但不是单射q-q 表示同一个3D旋转。因此,这是从3-球面到3D旋转群的一个二对一映射。

四元数的优势

四元数表示3D旋转的主要优势在于旋转的组合与插值

  • 组合旋转:如果旋转 R_q 对应四元数 q,旋转 R_p 对应四元数 p,那么组合旋转 R_q ∘ R_p 就对应四元数乘法 q * p。这比矩阵乘法或欧拉角组合更简洁高效。
  • 球面线性插值:要在两个旋转 q0q1 之间平滑插值,可以使用四元数的球面线性插值公式。这在角色动画、相机路径平滑等方面至关重要。插值公式的核心思想是在4D单位超球面上沿大圆弧行走。
    slerp(q0, q1; t) = (q0 * sin((1-t)Ω) + q1 * sin(tΩ)) / sin(Ω)
    其中 Ωq0q1 之间的夹角。
  • 其他有用性质
    • 四元数的共轭(逆)表示旋转的逆。
    • 两个旋转 q0q1 之间的相对旋转是 q0⁻¹ * q1
    • 四元数的平方根 q^(1/2) 表示旋转角度的一半。

不同旋转表示的转换

在实际应用中,我们经常需要在不同表示之间转换:

  • 轴-角 → 四元数q = [cos(θ/2), u sin(θ/2)]
  • 四元数 → 旋转矩阵:通过共轭运算的线性变换矩阵提取3x3部分。
  • 四元数 → 轴-角θ = 2 * arccos(a), u = (b, c, d) / sin(θ/2) (其中 q = a + bi + cj + dk
  • 欧拉角 ↔ 旋转矩阵 ↔ 四元数:均有标准转换公式。

在神经网络中的应用

当需要训练神经网络来预测3D旋转时(如姿态估计),选择哪种旋转表示是一个重要问题。轴-角、旋转矩阵、欧拉角、四元数各有优劣(连续性、参数数量、是否存在奇点等)。研究表明,四元数(需注意处理 q-q 的歧义)或6D表示(旋转矩阵前两列)通常是较好的选择。

总结

本节课中我们一起学习了3D旋转的多种表示方法。我们首先回顾了刚体变换及其广泛应用,然后指出了使用矩阵直接表示旋转的困难。接着,我们探讨了直观的欧拉角表示及其固有的万向节死锁和组合复杂性问题。

为了解决这些问题,我们深入学习了四元数。我们从2D旋转的复数表示出发,理解了哈密顿如何将其推广到4D空间以表示3D旋转。我们学习了四元数的基本定义、运算规则,以及它如何通过共轭运算与3D旋转建立联系。

四元数的核心优势在于它能以简洁的形式组合旋转,并能实现平滑的球面线性插值,这对于计算机图形学中的动画至关重要。最后,我们了解了不同旋转表示之间的转换,并简要探讨了在神经网络中表示旋转的考量。

掌握四元数为我们后续学习光线追踪、动画系统以及更高级的图形学主题奠定了坚实的数学基础。

003:光线追踪

概述

在本节课中,我们将要学习光线投射与光线追踪的基本概念。我们将探讨它们与光栅化渲染管线的区别,理解光线与三维物体求交的基本原理,并初步了解用于加速计算的包围盒层次结构。

上一节我们介绍了基于光栅化的渲染管线,本节中我们来看看另一种截然不同的渲染方法。

光栅化与光线追踪的区别

光栅化渲染管线首先将所有三维三角形投影到二维平面上,然后处理每个三角形,确定其覆盖了哪些像素(片段),并通过插值计算颜色和深度信息来更新像素。

相比之下,光线追踪和光线投射则从像素出发。对于图像平面上的每个像素,我们从相机中心发射一条光线,并检测这条光线与场景中三维物体的第一个交点。然后,我们从该交点获取颜色或材质信息来更新像素。

以下是两者的核心流程对比:

  • 光栅化:物体优先。处理每个物体,将其投影,然后更新被覆盖像素的信息。
  • 光线追踪:像素优先。处理每个像素,发射光线,找到与物体的交点,然后更新像素信息。

光线投射的基本思想

光线投射是一个相对古老的概念,其核心是模拟光学过程,但为了提高效率,我们通常进行“反向追踪”。

真正模拟光线传播应从光源出发,向场景发射光线,并追踪它们经过反射、折射后最终到达成像平面的路径。但这种方法效率极低,因为只有极少量的光线能最终到达成像平面。

因此,在实际的光线投射中,我们采取反向策略:从相机(眼睛)出发,通过成像平面上的每个像素向场景发射光线。我们检查这条光线与场景中物体的第一个交点。

仅仅找到交点还不够。为了确定该点的颜色,我们不仅需要考虑物体表面的固有属性,还需要考虑光照。因此,我们从该交点向光源再发射一条阴影光线。如果这条阴影光线未被遮挡,直达光源,则该点被照亮;如果被遮挡,则该点处于阴影中。

代码描述核心过程

for each pixel in image:
    ray = generate_ray_from_camera_through_pixel()
    intersection_point, surface = find_closest_intersection(ray, scene)
    if intersection_point exists:
        shadow_ray = ray_from_point_to_light(intersection_point, light_source)
        if not is_occluded(shadow_ray, scene):
            color = calculate_color(intersection_point, surface, light_source)
            set_pixel_color(pixel, color)
        else:
            set_pixel_color(pixel, BLACK) # 阴影

从光线投射到光线追踪

光线投射只关心第一条光线(从相机出发)与物体的第一个交点。而光线追踪则更进一步,它递归地追踪光线的完整路径。

在第一个交点处,根据物体表面的材质属性(如镜面反射、折射),光线可能会产生新的方向。例如,对于镜面,我们会根据入射角和法线计算反射方向,并发射一条新的次级光线继续追踪。对于透明物体,我们还会计算折射光线。

这个过程可以递归进行多次,每次在交点处都可能产生新的反射或折射光线。最终,像素的颜色由沿着这条光线路径上所有交点处计算的颜色累积(通常以某种方式加权组合)而成。

公式描述反射方向
若入射光线方向为 I,表面法线为 N(单位向量),则反射光线方向 R 可通过以下公式计算:
R = I - 2 * (I · N) * N

因此,光线追踪能够更精确地模拟光与物体的复杂交互,如多次反射、折射、焦散等效果,从而生成非常逼真的图像。当然,其计算量也远大于光线投射和光栅化。

光线与物体求交

实现光线追踪系统的第一步是计算光线与场景中物体的交点。这不仅用于从相机发射的主光线,也用于阴影光线和次级光线。

一条光线可以用参数方程表示:P(t) = O + t * D。其中,O 是光线起点(如相机位置),D 是方向向量,t 是大于等于0的参数。

以下是几种常见求交情况:

光线与平面求交

假设平面由一个点 P0 和法向量 N 定义。平面上任意点 P 满足方程:(P - P0) · N = 0
将光线方程代入平面方程:
(O + tD - P0) · N = 0
求解 t:
t = ( (P0 - O) · N ) / (D · N )
如果 t >= 0,则交点存在,位置为 O + tD。若分母 D · N = 0,则光线与平面平行,无交点。

光线与三角形求交

三维物体常由三角形网格表示。求交分为两步:

  1. 计算光线与三角形所在平面的交点。
  2. 判断该交点是否位于三角形内部。

第二步通常使用重心坐标来判断。三角形由三个顶点 P1P2P3 定义。三角形内的任意点 P 可以用重心坐标 (u, v, w) 表示,其中 u + v + w = 1,且 u, v, w >= 0。点 P 可表示为:
P = u * P1 + v * P2 + w * P3
由于 w = 1 - u - v,我们实际上只需要两个参数 (u, v)

将光线方程 P(t) = O + tD 代入,得到:
O + tD = u * P1 + v * P2 + (1 - u - v) * P3
这是一个关于 tuv 的线性方程组。求解后,若 t >= 0u >= 0v >= 0u + v <= 1,则光线与三角形相交。

光线与球体求交

球体由球心 C 和半径 r 定义。球面上点 P 满足:||P - C||^2 = r^2
将光线方程代入:
||O + tD - C||^2 = r^2
展开后得到一个关于 t 的二次方程:
at^2 + bt + c = 0
其中:
a = D · D
b = 2 * D · (O - C)
c = (O - C) · (O - C) - r^2
求解二次方程。若有正实根,取最小的正根作为交点对应的 t

光线与隐式表面求交

有些物体通过隐式函数 f(P) = 0 定义(例如,f(P) = ||P - C||^2 - r^2 就是球体的隐式表示)。对于这类表面,一种简单的求交方法是光线步进:从起点开始,沿光线方向一步步前进,每次评估 f(P),直到其值接近零或符号改变。
更高效的方法是球体追踪:当评估点 Pf(P) 值为正(在物体外)时,其值通常代表到物体表面的最近距离。我们可以安全地沿光线前进至少这个距离,然后重复此过程,直到 f(P) 接近零。

加速求交计算:包围盒层次结构

在复杂场景中,可能有数百万个三角形和数百万像素,对每一对“光线-物体”都进行求交计算是不可行的。加速计算的核心思想是使用包围盒

基本思路是用一个简单的体积(如轴对齐包围盒)包裹住复杂的物体或一组物体。首先计算光线与包围盒是否相交,如果不相交,则可以跳过盒内所有物体的求交计算;如果相交,再进一步检查盒内的物体。

单个大的包围盒效率不高,因为一旦光线击中它,仍需检查盒内所有物体。为每个物体单独设包围盒则数量太多。理想的解决方案是包围盒层次结构

其思想类似于二叉搜索树。我们将所有图元(如三角形)用一个顶层包围盒包裹。然后,选择一种策略(如沿某个轴按图元中心排序),将图元集合分成两个子集,并为每个子集创建包围盒。递归地对每个子集进行同样的划分,最终形成一棵树(BVH树)。

当需要计算一条光线与场景的交点时,我们从根节点开始:

  1. 检查光线与当前节点包围盒是否相交。
  2. 若不相交,跳过该节点及其所有子节点。
  3. 若相交,则递归检查其子节点。
  4. 到达叶节点时,才与节点内的图元进行精确求交。

这大大减少了需要进行的精确求交测试的次数。关键问题是如何划分图元集合以构建高效的BVH树。一个常见的目标是使划分后两个子包围盒的总体积最小化,同时保持树的平衡。

总结

本节课中我们一起学习了光线追踪的核心思想。我们了解了光线投射与光线追踪的区别,知道了光线追踪通过从相机反向追踪光线路径来模拟复杂的光照效果。我们详细探讨了光线与几种基本几何体(平面、三角形、球体)的求交计算方法,这是光线追踪的基石。最后,我们介绍了使用轴对齐包围盒和包围盒层次结构来大幅加速求交过程的基本原理,这是处理复杂场景的关键技术。在接下来的课程中,我们将深入探讨如何计算交点处的颜色,即光照与材质模型。

004:辐射度量学与光度学

在本节课中,我们将学习计算机图形学中用于描述和计算光照的核心物理概念:辐射度量学和光度学。理解这些术语和单位对于后续学习光照模型和渲染方程至关重要。

概述

上一节我们介绍了光线追踪的基本思想,它与光栅化不同,是从相机向场景发射光线并计算与物体的交点。为了高效计算这些交点,我们讨论了使用层次包围盒等加速结构。本节中,我们将深入探讨如何精确地描述和计算光线与物体交互时的光照能量,这是实现逼真渲染的基础。

辐射度量学基本量

辐射度量学是用于描述电磁辐射(包括可见光)功率的物理学分支。在计算机图形学中,我们主要关注以下四个基本量。

辐射通量

辐射通量,也称为功率,表示单位时间内通过某个区域或从光源发出的总能量。其单位是瓦特。

公式Φ = dQ / dt,其中 Q 是能量,t 是时间。

辐射强度

辐射强度描述了光源在特定方向上的发光强弱。它定义为在单位立体角内发出的辐射通量。其单位是瓦特每球面度。

公式I = dΦ / dω,其中 ω 是立体角。

立体角

立体角是二维角度在三维球面上的扩展。它衡量了一个锥体所覆盖的球面区域大小。单位立体角所对应的球面面积等于球半径的平方。

公式:对于一个球面区域面积 A 和球半径 r,其对应的立体角 ω = A / r²。整个球面的立体角为 球面度。

辐照度

辐照度衡量的是单位表面积所接收到的入射辐射通量。它表示光线照射到表面某一点的“密度”。其单位是瓦特每平方米。

公式E = dΦ / dA,其中 A 是面积。

兰伯特定律

当光线以倾斜角度照射表面时,表面接收到的辐照度会减小。具体来说,辐照度与光线方向和表面法线夹角的余弦值成正比。这就是兰伯特定律,也是季节变化的原因之一(阳光直射与斜射)。

公式E ∝ cosθ

辐射率

辐射率是计算机图形学中最重要的量。它描述了在单位立体角、单位投影面积上的辐射通量。它同时包含了方向性和空间分布信息,是描述光线在空间中传播的基本量。其单位是瓦特每球面度每平方米。

公式L = d²Φ / (dω · dA · cosθ)

这里 cosθ 项源于投影面积的计算,确保了无论观察方向如何,辐射率在真空中沿光线传播路径保持不变。

光度学基本量

光度学与辐射度量学类似,但度量的不是物理功率,而是人眼感知到的“亮度”。每个辐射度量学的量都有一个对应的光度学量。

以下是辐射度量学与光度学量的对应关系及单位:

辐射度量学量 单位 光度学量 单位
辐射通量 瓦特 光通量 流明
辐射强度 瓦特/球面度 发光强度 坎德拉
辐照度 瓦特/平方米 照度 勒克斯
辐射率 瓦特/(球面度·平方米) 亮度 尼特

注意:对于特定光源,其辐射度量学功率和光度学亮度之间的转换比例取决于光源的发光效率。

从辐射率计算辐照度

在渲染中,我们经常需要将来自各个方向的入射辐射率积分,得到表面上某点的总辐照度。

考虑表面上一点,来自半球空间所有方向的入射光。该点的辐照度 E 可以通过对上半球所有立体角方向的入射辐射率 L_i(ω) 进行积分得到:

公式E = ∫_Ω L_i(ω) cosθ dω

其中 θ 是入射方向与表面法线的夹角,cosθ 项源于兰伯特定律。

一个简单例子:如果来自所有方向的入射辐射率是恒定值 L,那么辐照度 E = L * π

总结

本节课我们一起学习了辐射度量学和光度学的基本概念。我们明确了辐射通量、辐射强度、辐照度和辐射率这四个核心物理量的定义、单位和相互关系,特别是辐射率作为核心量的重要性。我们还了解了对应的光度学量,以及如何从入射辐射率积分得到辐照度。掌握这些术语和概念是理解后续光照模型、材质属性和渲染方程的基础。下一节,我们将开始探讨物体的材质属性,学习它们如何与光线相互作用,从而决定最终的表面颜色。

005:蒙特卡洛积分 1

概述 📖

在本节课中,我们将要学习蒙特卡洛积分方法。这是一种通过随机采样来近似计算复杂积分的数值方法,在计算机图形学中,尤其是在渲染方程的计算中至关重要。我们将从基础概念开始,逐步理解其原理、性质以及如何评估其效率。


从辐射度量学到渲染方程 🔄

上一节我们介绍了辐射度量学中的基本概念,如通量、辐射强度和辐射率。本节中我们来看看如何将这些概念整合到渲染方程中。

渲染的核心是计算场景中每个点的辐射率。当光线到达一个表面点时,它会根据该点的材质属性被反射到各个出射方向。这个反射过程由双向反射分布函数描述。

BRDF 是一个函数,它描述了从某个入射方向 ω_i 来的微分辐射亮度,有多少比例被反射到某个出射方向 ω_o。其数学形式为:

f_r(p, ω_i → ω_o) = dL_o(p, ω_o) / dE(p, ω_i)

其中 dL_o 是出射方向的微分辐射亮度,dE 是入射方向的微分辐照度。

基于此,我们可以写出在点 p 处、沿出射方向 ω_o 的辐射亮度 L_o 的渲染方程:

L_o(p, ω_o) = L_e(p, ω_o) + ∫_{Ω} f_r(p, ω_i → ω_o) L_i(p, ω_i) cosθ_i dω_i

这里:

  • L_e 是表面自身发出的辐射亮度。
  • 积分项表示从所有入射方向 ω_i 收集并反射到 ω_o 的光线总和。
  • cosθ_i 是入射光线与表面法线夹角的余弦值。

这个积分通常没有解析解,因此我们需要数值方法来近似计算它。这就是蒙特卡洛积分发挥作用的地方。


蒙特卡洛积分基础 🎲

蒙特卡洛积分是一种通过随机采样来估计积分值的统计方法。其核心思想非常简单。

假设我们要计算一维函数 f(x) 在区间 [a, b] 上的积分 I

I = ∫_{a}^{b} f(x) dx

以下是蒙特卡洛积分的基本步骤:

  1. 在区间 [a, b] 上按照某种概率密度函数 p(x) 随机抽取 N 个独立同分布的样本 X_i
  2. 计算每个样本处的函数值 f(X_i)
  3. 用这些样本构造一个估计量 F_N 来近似积分 I
    F_N = (1/N) * Σ_{i=1}^{N} (f(X_i) / p(X_i))
    

估计量的性质

这个估计量 F_N 具有一些重要性质:

  • 无偏性:估计量的期望值等于真实的积分值,即 E[F_N] = I。这意味着平均来看,我们的估计是准确的。
  • 收敛性:估计量的方差 V[F_N] 与采样数量 N 成反比,即 V[F_N] ∝ 1/N。这意味着随着采样数增加,估计误差会以 1/√N 的速度减小。

扩展到高维

蒙特卡洛方法的一个巨大优势是它可以轻松扩展到高维积分。无论积分维度多高,其基本形式保持不变,只需在高维定义域内采样即可。这避免了传统数值积分方法中因维度灾难导致的计算量爆炸式增长。


一个简单示例:估算面积 📐

让我们通过一个具体例子来理解蒙特卡洛积分。假设我们想计算二维空间中一个不规则区域 Ω 的面积。

我们可以这样做:

  1. 找到区域 Ω 的轴对齐包围盒,其面积为 A_box
  2. 定义一个指示函数 f(x, y),当点 (x, y)Ω 内时值为1,否则为0。
  3. 区域 Ω 的面积 A 就等于该指示函数在包围盒上的积分:A = ∫_{box} f(x, y) dx dy
  4. 应用蒙特卡洛积分。在包围盒内均匀采样 N 个点 (X_i, Y_i)(此时概率密度 p(x, y) = 1/A_box)。
  5. 面积估计量为:
    A_est = (A_box / N) * Σ_{i=1}^{N} f(X_i, Y_i)
    
    这等价于:A_est = A_box * (落在区域内的样本数 / 总样本数)

这个例子直观地展示了如何将几何问题转化为积分问题,并用随机采样来解决。


估计量的效率与方差 ⚡

我们不仅关心估计量是否正确(无偏),还关心它需要多少计算资源才能达到可接受的精度。这引出了对估计量“效率”的考量。

效率综合了估计量的方差和生成每个样本所需的计算时间。即使一个估计量方差更低,但如果它计算每个样本的速度慢很多,其整体效率可能反而不如一个方差稍高但计算更快的估计量。

形式化地说,考虑两个估计量 F1F2。假设 F2 的方差是 F1 的一半,但计算每个样本的时间是 F1 的三倍。在相同的总计算时间内,F1 能采集的样本数是 F2 的三倍。由于方差与 1/N 成正比,F1 在相同时间内的有效方差可能比 F2 更低,因此 F1 的效率更高。

因此,在设计蒙特卡洛积分方案时,我们需要在方差采样成本之间进行权衡。


无偏与有偏估计 ⚖️

之前我们讨论的是无偏估计量。但有时,使用有偏估计量可能更有利。

有偏估计量是指其期望值不等于真实积分值的估计量,即 E[F_N] ≠ I。一个经典的例子是对方差本身的估计。用样本方差 S^2 = (1/N) Σ (X_i - μ)^2 来估计总体方差 σ^2 是一个有偏估计,其期望为 E[S^2] = (N-1)/N * σ^2。无偏的估计量应为 (1/(N-1)) Σ (X_i - μ)^2

有偏估计量并非没有用处。虽然它在期望上不准确,但随着样本数 N 增大,偏差通常会减小(称为渐近无偏)。关键在于,某些有偏估计量可能以引入微小偏差为代价,换来方差的大幅降低,从而更快地收敛到真实值附近,提高了计算效率。在实时渲染等对性能要求极高的场合,有偏但高效的估计量往往是更实用的选择。


提高效率:分层采样 🎯

如何改进基础蒙特卡洛积分的效率?分层采样是一种有效且保证不降低性能的技术。

其思想是将整个积分域划分为多个互不重叠的子区域(层)。然后,在每个子区域内独立地进行采样,而不是在整个域内完全随机采样。

以下是分层采样的优势:

  • 方差永不增加:与在整个域内简单随机采样相比,分层采样永远不会增加估计量的方差。
  • 通常降低方差:通过确保采样点能更均匀地覆盖整个积分域,避免了样本过度聚集在某些区域,从而通常能显著降低方差。
  • 实现简单:在许多情况下,划分区域和分配样本都非常直观。

在渲染中,分层采样被广泛应用。例如,在像素内采样抗锯齿时,将每个像素划分为更小的网格并在每个网格单元内采样,比在像素内完全随机采样能获得更平滑、噪声更少的图像。


总结 🏁

本节课中我们一起学习了蒙特卡洛积分的基础知识。

  1. 动机:渲染方程涉及复杂的高维积分,需要数值近似。蒙特卡洛积分提供了解决方案。
  2. 核心方法:通过随机采样构造估计量来近似积分。其估计量具有无偏性和以 1/√N 速度收敛的特性。
  3. 关键概念:我们讨论了估计量的无偏性有偏性,以及衡量其性能的方差效率。效率需要综合考虑方差和计算成本。
  4. 优化技术分层采样是一种通过划分积分域来系统性地降低方差、提高效率的重要技术。

蒙特卡洛积分是物理渲染的基石。在接下来的课程中,我们将深入探讨如何将这些方法具体应用到光线追踪流程中,以高效地求解渲染方程。

006:蒙特卡洛积分 2 与直接光照 1 🎲💡

在本节课中,我们将要学习蒙特卡洛积分方法的进一步应用,特别是如何通过重要性采样等技术来提高积分估计的效率。我们还将探讨如何将这些方法应用于计算机图形学中的直接光照计算。


概述

上一节我们介绍了蒙特卡洛方法的基本思想,它是一种通过随机采样来近似计算积分值的数值方法。本节中,我们来看看如何通过选择更优的概率密度函数(PDF)来减少估计器的方差,从而提高计算效率,即重要性采样。我们还将学习如何在不同的几何域(如圆盘、球体)上进行均匀采样,并最终将这些技术应用于渲染方程,实现直接光照的计算。


重要性采样

蒙特卡洛估计器的核心公式如下:

[
F_N = \frac{1}{N} \sum_{i=1}^{N} \frac{f(X_i)}{p(X_i)}
]

其中,( f(X) ) 是被积函数,( p(X) ) 是采样所用的概率密度函数。估计器的好坏很大程度上取决于我们如何选择 ( p(X) )。

核心思想

如果我们可以选择一个概率密度函数 ( p(x) ),使其形状与被积函数 ( f(x) ) 相似,那么估计值的方差就会显著降低。最理想的情况是令 ( p(x) ) 正比于 ( f(x) ),即:

[
p(x) = \frac{f(x)}{\int f(x) dx}
]

此时,估计器中的每一项 ( f(X_i)/p(X_i) ) 都等于常数(积分值本身),方差为零。然而,这通常不现实,因为我们的目标正是计算这个未知的积分值。因此,重要性采样的目标是:在无法精确知道 ( f(x) ) 的情况下,根据对其形状的粗略了解,设计一个近似其形状的 PDF,以降低方差

一个简单例子

假设被积函数 ( f(x) ) 在定义域内呈一个尖峰形状。如果使用均匀分布 PDF 进行采样,许多样本会落在函数值很小的区域,贡献很低,导致方差较大。

以下是几种不同的 PDF 选择及其对应的方差比较(数值仅为示例):

  • 均匀分布 PDF:方差约为 0.0365。
  • 一个近似 ( f(x) ) 形状的 PDF:方差降低至约 0.0054(减少了约 6.7倍)。

这表明,选择一个好的 PDF 能极大地加速收敛。


基于 PDF 的采样方法

为了进行重要性采样,我们必须能够根据任意给定的 PDF 生成随机样本。一个通用方法是逆变换采样

逆变换采样

  1. 计算累积分布函数(CDF):对于给定的 PDF ( p(x) ),计算其 CDF ( P(x) = \int_{-\infty}^{x} p(t) dt )。
  2. 生成均匀随机数:生成一个在 [0, 1] 区间上均匀分布的随机数 ( \xi )。
  3. 求逆:计算 ( X = P^{-1}(\xi) ),则 ( X ) 即为服从 PDF ( p(x) ) 分布的样本。

示例:采样 ( p(x) = 3x^2 )

假设我们要在 [0,1] 区间内根据 PDF ( p(x) = 3x^2 ) 进行采样。

  1. 计算 CDF:( P(x) = \int_{0}^{x} 3t^2 dt = x^3 )。
  2. 求逆 CDF:( P^{-1}(u) = u^{1/3} )。
  3. 采样:生成均匀随机数 ( \xi \sim U[0,1] ),则样本 ( x = \xi^{1/3} )。

在特定几何域上的均匀采样

在图形学中,我们经常需要在圆盘、球面等区域进行均匀采样(例如,采样入射光线方向)。直接对参数进行均匀采样通常无法得到在面积或立体角上均匀的分布。

在单位圆盘内均匀采样 ❌→✅

错误方法:均匀采样半径 ( r \in [0,1] ) 和角度 ( \theta \in [0, 2\pi) ),然后转换到笛卡尔坐标 ( (x, y) = (r\cos\theta, r\sin\theta) )。这会导致样本点向圆心聚集,因为外圈环状区域的面积更大,但每个环被选中的概率却相同。

正确方法:我们需要 PDF 与微分面积元 ( dA = r dr d\theta ) 成正比。因此,关于 ( r ) 的 PDF 应设为 ( p(r) = 2r )(线性),而 ( \theta ) 保持均匀分布。

  1. ( r ) 的 CDF:( P(r) = r^2 )。
  2. 逆采样:( r = \sqrt{\xi_1} ),( \theta = 2\pi \xi_2 )。
  3. 坐标转换:( (x, y) = (\sqrt{\xi_1} \cos(2\pi \xi_2), \sqrt{\xi_1} \sin(2\pi \xi_2)) )。

在单位球面上均匀采样 🌐

目标是均匀采样球面上的点,等价于均匀采样三维空间中的方向。使用球坐标 ( (\theta, \phi) ),其中 ( \theta ) 是天顶角,( \phi ) 是方位角。微分面积元为 ( dA = \sin\theta d\theta d\phi )。
为了使采样均匀,PDF 应与 ( \sin\theta ) 成正比。可以推导出:

  • ( p(\theta) = \frac{\sin\theta}{2} )
  • ( p(\phi) = \frac{1}{2\pi} ) (均匀)

通过逆变换采样,可以得到采样公式:

  • ( \theta = \cos^{-1}(1 - 2\xi_1) ) 或等价地 ( \theta = \cos^{-1}(2\xi_1 - 1) )
  • ( \phi = 2\pi \xi_2 )

进而转换为笛卡尔坐标:
[
\begin{aligned}
z &= 1 - 2\xi_1 \
x &= \cos(2\pi \xi_2) \cdot \sqrt{1 - z^2} \
y &= \sin(2\pi \xi_2) \cdot \sqrt{1 - z^2}
\end{aligned}
]

这种采样方法在光线追踪中对于采样半球方向至关重要。


应用于渲染方程与直接光照

现在,我们将蒙特卡洛积分应用于渲染方程。渲染方程描述了场景中一点的光线出射辐射率:

[
L_o(p, \omega_o) = L_e(p, \omega_o) + \int_{\Omega} f_r(p, \omega_i, \omega_o) L_i(p, \omega_i) \cos\theta_i d\omega_i
]

其中,积分项计算了来自所有入射方向 ( \omega_i ) 的贡献。

简单的蒙特卡洛估计

最直接的方法是在半球 ( \Omega ) 上均匀采样立体角。设 PDF 为常数 ( p(\omega_i) = 1 / (2\pi) )(半球立体角为 ( 2\pi )),则蒙特卡洛估计为:

[
L_o(p, \omega_o) \approx \frac{2\pi}{N} \sum_{j=1}^{N} f_r(p, \omega_j, \omega_o) L_i(p, \omega_j) \cos\theta_j
]

问题:如果光源在场景中只占很小一块立体角(例如一个小窗户),那么绝大多数随机采样的方向都不会击中光源,这些样本对最终积分的贡献为零,造成方差极大,收敛缓慢。

更高效的方法:对光源采样 💡

与其在半球上随机采样方向,不如直接在光源表面上采样点。这本质上是一种重要性采样,因为我们把样本集中在真正可能发出光线的区域。

将立体角微分 ( d\omega_i ) 转换为光源表面的面积微分 ( dA )(通过几何关系 ( d\omega = \frac{\cos\theta_{light}}{||x' - x||^2} dA )),渲染方程的积分可以重写为对光源面积 ( A ) 的积分:

[
L_o(p, \omega_o) = \int_{A} f_r(p, \omega_i, \omega_o) L_i(p, \omega_i) \frac{\cos\theta_i \cos\theta_{light}}{||x' - x||^2} V(x, x') dA
]

其中 ( V(x, x') ) 是两点间的可见性函数(遮挡测试)。

现在,如果我们在光源表面均匀采样,即 PDF ( p(x') = 1 / A_{light} ),则蒙特卡洛估计器变为:

[
L_o(p, \omega_o) \approx \frac{A_{light}}{N} \sum_{j=1}^{N} f_r(p, \omega_j, \omega_o) L_i(p, \omega_j) \frac{\cos\theta_i \cos\theta_{light}}{||x' - x||^2} V(x, x'_j)
]

这种方法确保每个样本都直接来自于光源表面,从而显著提高了采样效率,降低了噪声。


总结

本节课中我们一起学习了:

  1. 重要性采样的核心原理:通过设计与被积函数形状相似的 PDF 来降低蒙特卡洛估计器的方差。
  2. 逆变换采样方法:一种根据任意 PDF 生成样本的通用技术。
  3. 在圆盘和球面上的均匀采样:需要注意参数均匀并不等于面积均匀,并学习了正确的采样公式。
  4. 将蒙特卡洛积分应用于渲染方程:分析了在半球上均匀采样方向的问题,并引入了更高效的对光源直接采样的方法来计算直接光照。

这些技术是构建现代光线追踪器的基础。下一节,我们将探讨如何将这些思想扩展到全局光照,处理光线在场景中的多次弹射。


007:直接光照 2 与全局光照

在本节课中,我们将深入学习蒙特卡洛积分在直接光照计算中的应用,并探讨如何将其扩展到更复杂的全局光照场景。我们将重点讨论多重重要性采样技术,并介绍全局光照的基本概念和光传输方程。

直接光照回顾与多重重要性采样

上一节我们介绍了重要性采样的基本思想,即根据与被积函数形状相似的概率密度函数来采样,以获得更快的收敛速度。其核心是使用逆变换采样技术:通过计算概率密度函数的累积分布函数及其逆函数,将均匀分布的样本映射到目标分布。

在渲染方程中,我们计算的是积分。实践中,我们有两种主要采样策略:

  • 立体角采样:在半球面上随机采样方向。
  • 光源面积采样:在光源表面上随机采样点。

以下是两种策略的对比:

  • 立体角采样可能产生大量未击中光源的光线,导致方差较高、收敛慢。
  • 光源面积采样能确保每次采样都击中光源,通常收敛更快。

然而,渲染方程的被积函数可以看作是双向反射分布函数入射光亮度函数的乘积。这两个函数通常相对简单,但它们的乘积可能很复杂。这就引出了一个问题:我们应该基于BRDF采样,还是基于光源采样?

考虑两种典型场景:

  1. 镜面反射表面 + 大面积光源:此时,基于BRDF采样更有效,因为只有特定方向的光线对出射亮度贡献最大。
  2. 漫反射表面 + 小面积光源:此时,基于光源采样更有效,因为随机方向的光线很难击中微小的光源。

显然,最佳策略取决于场景的具体配置。那么,是否存在一种统一的采样策略,能适应各种情况呢?

答案是多重重要性采样。其核心思想是结合多种不同的采样分布。我们定义一个新的估计器:

公式
F_mis = (1/N1) * Σ [ (f(X_i) * w_1(X_i)) / p_1(X_i) ] + (1/N2) * Σ [ (f(Y_j) * w_2(Y_j)) / p_2(Y_j) ]

其中,权重函数 w_k(x) 需要满足对于任意样本 x,有 Σ w_k(x) = 1,且当 p_k(x) = 0w_k(x) = 0。可以证明,该估计器也是无偏的。

一个常用且简单的权重函数选择是平衡启发式

公式
w_k(x) = (N_k * p_k(x)) / Σ (N_i * p_i(x))

当所有采样数 N_i 相同时,权重简化为 w_k(x) = p_k(x) / Σ p_i(x),即根据各PDF在该样本点处的相对概率来分配权重。这相当于用所有PDF的加权平均定义了一个新的混合PDF。平衡启发式虽然不是理论最优,但其方差与可能的最优估计器方差之差存在一个上界,且随着采样数增加,这个差距会趋近于零,因此在实际中非常有效。

通过结合BRDF采样和光源采样,多重重要性采样能够生成质量更高的图像,既能准确捕捉高光细节,又能有效计算来自光源的直接照明。

全局光照简介

直接光照只考虑从相机出发,击中物体表面后直接射向光源的那条路径。而全局光照则模拟光线在场景中经过多次反射、折射后最终进入相机的复杂过程,这能产生更真实的光照效果,如颜色渗透和柔和的间接照明。

光传输方程是描述全局光照的数学框架。它本质上是渲染方程的递归形式,表达了场景中能量的平衡。在假设没有参与介质(即真空)的情况下,某点 p 沿方向 ω 的入射光亮度,等于从 p 点沿 方向发出的射线首次击中点 p' 的出射光亮度。这建立了光线在场景中弹射的递归关系。

公式(三点形式的光传输方程):
L(p' -> p) = L_e(p' -> p) + ∫_A f(p'' -> p' -> p) * L(p'' -> p') * G(p'' <-> p') * dA(p'')

其中:

  • L(p' -> p) 是从点 p' 到点 p 的辐射亮度。
  • L_e 是自发光项。
  • f 是BRDF。
  • G 是几何项,包含可见性测试和距离衰减因子。

为了求解这个复杂的积分方程,我们将其展开为无限求和的形式,其中每一项代表一条特定长度的光路(例如,长度为1是自发光,长度为2是直接光照,长度为3及以上是间接光照)。路径追踪算法就是通过蒙特卡洛方法随机采样这些光路来求解该方程。

路径追踪的基本步骤是:

  1. 从相机像素发射一条射线,找到与场景的第一个交点 p1
  2. p1 处,随机选择下一个方向继续追踪射线,得到交点 p2
  3. 重复此过程,直到射线击中光源或达到最大弹射次数。
  4. 沿着这条路径,将各点的BRDF、几何衰减和光源发光度相乘,得到该路径对像素亮度的贡献。
  5. 对每个像素重复上述过程多次,并将结果平均,最终得到渲染图像。

本节课我们一起学习了多重重要性采样的原理及其在改善直接光照计算中的作用,并初步了解了全局光照的概念和光传输方程的基本形式。路径追踪作为求解全局光照的经典算法,其核心思想正是基于这些数学原理。要深入理解实现细节,强烈推荐阅读《Physically Based Rendering: From Theory to Implementation》一书。

008:路径追踪与反射模型

在本节课中,我们将学习全局光照的核心算法——路径追踪,并深入探讨用于描述光线与表面交互的反射模型。我们将从回顾路径追踪的基本思想开始,然后介绍如何高效地处理长路径,最后详细讲解几种关键的反射模型及其物理特性。


全局光照与路径追踪回顾

上一节我们介绍了如何通过蒙特卡洛积分来估计渲染方程。本节中,我们来看看如何将这一思想扩展到全局光照,即计算直接光照和间接光照。

路径追踪的核心思想是:通过随机采样场景中的光线路径,并累加这些路径对像素亮度的贡献,来近似求解复杂的渲染方程。我们之前看到的渲染方程可以重写为光传输方程

\[L_o(p, \omega_o) = L_e(p, \omega_o) + \int_{S^2} f_r(p, \omega_o, \omega_i) L_i(p, \omega_i) |\cos \theta_i| d\omega_i \]

为了计算全局光照,我们需要考虑所有可能的光线路径。一条长度为 k 的路径 P_k 可以表示为一系列表面点的序列:P_k = x0, x1, ..., xk,其中 x0 是相机,xk 是光源。最终到达像素的辐射亮度是所有可能路径贡献的期望值:

\[I = \sum_{k=1}^{\infty} \int_{P_k} \text{贡献}(P_k) dP_k \]

其中,每条路径的贡献是路径上各点BRDF、几何项和光源发射率的乘积。由于这是一个无限维积分,我们使用蒙特卡洛方法进行估计。对于每个像素,我们随机生成 N 条路径,计算其贡献并取平均:

\[\hat{I} = \frac{1}{N} \sum_{i=1}^{N} \frac{\text{贡献}(P_i)}{pdf(P_i)} \]

这里 pdf(P_i) 是生成该路径的概率密度函数。

随着路径长度(即光线反弹次数)的增加,我们能够捕捉到更真实的间接光照效果,例如颜色溢出和柔和的阴影。然而,更长的路径也意味着更高的计算成本。


俄罗斯轮盘赌:高效路径终止

上一节我们提到,长路径计算成本高但贡献度低。本节中,我们来看看如何通过一种称为“俄罗斯轮盘赌”的技术,在保持估计无偏性的同时提前终止长路径。

直接限制路径的最大长度(例如,只计算长度≤3的路径)会引入偏差,因为完全忽略了更长路径的贡献。俄罗斯轮盘赌提供了一种无偏的提前终止方法。

其基本思想如下:我们设定一个继续概率 q (0 < q < 1) 和一个缩放常数 C。对于一条待评估的长路径(例如长度≥4),我们首先生成一个在 [0, 1] 区间均匀分布的随机数 ξ

  • 如果 ξ < q,我们继续计算这条路径的贡献,但将其结果除以 q 进行缩放。
  • 如果 ξ ≥ q,我们则终止这条路径的计算,并返回一个常数值 C(通常设为0)。

新的估计量 F’ 定义为:

\[F' = \begin{cases} \frac{F}{q}, & \text{if } \xi < q \\ C, & \text{otherwise} \end{cases} \]

可以证明,这个新估计量的期望值与原估计量 F 的期望值相同:E[F'] = E[F]。这意味着,虽然我们以概率 (1-q) 丢弃了耗时的计算,但通过缩放剩余样本的贡献,我们仍然得到了一个无偏估计。

在实际应用中,通常设置 C=0。这意味着我们以概率 q 继续追踪路径,并以概率 1-q 提前终止(贡献为0)。这种方法显著减少了计算量,但代价是会增加估计的方差(噪声)。需要根据场景和计算资源权衡选择 q 值。


反射模型与BRDF属性

路径追踪需要知道光线在表面如何反射,这由双向反射分布函数 描述。在深入具体模型前,我们先了解一个物理正确的BRDF应满足的基本属性。

BRDF f_r(p, ω_o, ω_i) 定义了从入射方向 ω_i 到出射方向 ω_o 的辐射亮度比例。它需要满足以下关键属性:

  1. 非负性f_r(p, ω_o, ω_i) ≥ 0。反射的光量不能为负。
  2. 互易性(亥姆霍兹互易律)f_r(p, ω_o, ω_i) = f_r(p, ω_i, ω_o)。交换入射和出射方向,函数值不变。
  3. 能量守恒:对于任何入射方向 ω_i,反射到所有出射方向的总能量不能超过入射能量。即:

    \[\forall \omega_i, \int_{H^2} f_r(p, \omega_o, \omega_i) |\cos \theta_o| d\omega_o \leq 1 \]

    当积分结果小于1时,表示部分光能被表面吸收。

此外,根据材质特性,BRDF还可能是各向同性或各向异性的:

  • 各向同性BRDF:当表面绕法线旋转时,反射分布不变。它只依赖于入射和出射方向的天顶角以及它们的方位角之差,因此是一个三参数函数:f_r(θ_i, θ_o, |φ_i - φ_o|)。大多数常见材质(如哑光漆、纸张)是各向同性的。
  • 各向异性BRDF:反射分布随表面旋转而变化。这需要四个参数完整描述:f_r(θ_i, φ_i, θ_o, φ_o)。例如,拉丝金属、头发、某些织物表现出各向异性。

经典局部光照模型

在全局光照成为主流之前,图形学长期使用基于经验组合的局部光照模型。本节中,我们回顾这些经典模型,它们可以看作是对特定BRDF的近似。

一个典型的局部光照模型(如Phong模型)将出射辐射度表示为几项之和:

L_o = L_ambient + L_diffuse + L_specular

以下是各项对应的理想化BRDF描述:

1. 理想镜面反射
光线严格按照反射定律出射。其BRDF包含狄拉克δ函数:

\[f_r(p, \omega_o, \omega_i) = \frac{\rho_s}{|\cos \theta_i|} \delta(\omega_o - R(\omega_i, n)) \]

其中 R(ω_i, n)ω_i 关于法线 n 的反射方向,ρ_s 是反射率。在路径追踪中,这意味着一旦击中表面,下一个方向是确定性的,而非随机采样。这可能导致需要非常长的路径才能命中光源。

2. 理想漫反射(朗伯反射)
光线均匀地散射到所有方向。其BRDF是一个常数:

\[f_r(p, \omega_o, \omega_i) = \frac{\rho_d}{\pi} \]

其中 ρ_d 是漫反射率(0 ≤ ρ_d ≤ 1)。将其代入渲染方程,可得到熟悉的 L_o = ρ_d * E,其中 E 是入射辐照度。常数 1/π 的引入是为了满足能量守恒定律。

3. 光泽反射(Phong模型)
这是一种对非理想镜面反射的经验近似。它认为高光强度与反射方向 R 和观察方向 V 之间夹角的余弦值的某次幂成正比:

\[L_specular = k_s (R \cdot V)^{\alpha} \]

其中 k_s 是高光系数,α 是光泽度(反光度),控制高光区域的集中程度。这并非基于物理的BRDF,但计算简单,曾广泛应用。

这些经典模型在光栅化渲染管线(如OpenGL固定管线)中组合使用,模拟了基本的光照效果,但无法处理复杂的全局光照现象。


折射与透射模型

现实世界中,光线不仅会被反射,还会穿透物体,即发生折射。本节中,我们来看看如何将透射现象纳入路径追踪框架。

描述透射的函数称为双向透射分布函数 。将BRDF和BTDF结合,可统称为双向散射分布函数

折射方向计算
折射方向由斯涅尔定律决定:

\[\eta_i \sin \theta_i = \eta_t \sin \theta_t \]

其中 η_iη_t 分别是入射侧和透射侧介质的折射率,θ_iθ_t 是入射角和折射角。当光线从光疏介质进入光密介质(η_t > η_i)时,折射角小于入射角,光线弯向法线;反之则远离法线。

全内反射
当光线从光密介质射向光疏介质,且入射角大于临界角 θ_c = arcsin(η_t / η_i) 时,会发生全内反射,没有透射光。这是水下看到“光学视窗”现象的原因。

菲涅尔方程
在界面处,入射光能量会部分反射、部分透射。反射的比例 R_F菲涅尔方程给出,它取决于入射角、偏振光和两侧介质的折射率。对于非偏振光,常用以下近似:

\[R_F = \frac{1}{2} \left( \frac{\eta_t \cos \theta_i - \eta_i \cos \theta_t}{\eta_t \cos \theta_i + \eta_i \cos \theta_t} \right)^2 + \frac{1}{2} \left( \frac{\eta_i \cos \theta_i - \eta_t \cos \theta_t}{\eta_i \cos \theta_i + \eta_t \cos \theta_t} \right)^2 \]

透射比例 T_F = 1 - R_F。菲涅尔效应意味着,即使在同一种材质上,掠射角(grazing angle)下的反射率也远高于正入射时。

在路径追踪中处理反射与折射
在具有透射能力的表面(如玻璃)交点处,路径会分叉:一条路径反射,一条路径折射。简单追踪所有路径会导致计算量指数增长(2^k)。更高效的方法是使用俄罗斯轮盘赌的思想进行随机选择:

  1. 计算当前入射角下的菲涅尔反射率 R_F
  2. 生成一个随机数 ξ ~ Uniform(0,1)
  3. 如果 ξ < R_F,则选择反射方向作为下一个路径顶点。
  4. 否则,选择折射方向作为下一个路径顶点。
    这样,每次相交只追踪一条路径,仍然能得到无偏估计,同时避免了计算爆炸。

薄板近似
对于像玻璃窗这样的薄板,光线会在两个界面间发生多次内反射。所有透射光的总和是一个几何级数。可以推导出一个等效的“总”反射率 R'_F 和透射率 T'_F

\[R'_F = R_F + \frac{T_F^2 R_F}{1 - R_F^2}, \quad T'_F = 1 - R'_F \]

其中 R_FT_F 是单界面的菲涅尔系数。使用这个等效系数进行采样,可以更准确地渲染薄透射物体。


总结与展望

本节课中我们一起学习了路径追踪算法的核心思想以及关键的反射与透射模型。

我们首先回顾了如何通过蒙特卡洛积分和路径采样来解决全局光照问题。接着,介绍了俄罗斯轮盘赌这一重要技术,它允许我们无偏地终止对贡献度低的长路径的追踪,从而提升计算效率。

然后,我们系统探讨了BRDF的物理属性(非负性、互易性、能量守恒)和分类(各向同性/各向异性),并回顾了理想漫反射理想镜面反射Phong光泽模型这些经典局部光照模型背后的BRDF形式。

最后,我们将模型扩展到透射现象,学习了斯涅尔定律计算折射方向,菲涅尔方程决定反射/透射能量比例,以及如何在路径追踪中通过随机采样高效地同时处理反射和折射路径。

这些反射和透射模型是构建逼真渲染器的基石。在接下来的课程中,我们将探讨更复杂的材质现象,如微表面模型(用于模拟金属、粗糙表面)和次表面散射(用于模拟皮肤、蜡、大理石等材质中光在内部传播的效果),并进一步介绍参与介质(如雾、烟、水)中的渲染技术。这些高级主题也与近年兴起的神经渲染技术密切相关。

009:反射模型与颜色

在本节课中,我们将完成对反射模型的讨论,重点介绍微表面模型,并探讨渲染流程中的另一个关键组成部分:相机测量与颜色。

上一节我们介绍了菲涅尔方程和薄板模型,本节中我们来看看如何通过微表面模型来更精细地描述材料的表面特性。

微表面模型

微表面模型的基本假设是,宏观表面由无数微小的、理想光滑的镜面小平面(微表面)构成。这些微小表面的朝向分布决定了材料整体的反射和透射特性。

以下是微表面模型的核心概念:

  • 微表面分布函数 D:该函数描述了表面法线方向为 ω_m 的微表面所占的相对面积比例。对于一个完全光滑的表面,其分布函数是一个狄拉克δ函数:D(ω_m) = δ(ω_m - n),其中 n 是宏观表面法线。
  • 归一化约束:所有微表面在宏观表面法线方向上的投影面积之和必须等于宏观表面的面积。这给出了分布函数 D 必须满足的积分约束条件。

遮蔽与阴影函数

由于微表面之间存在相互遮挡,我们需要引入遮蔽函数 G1 来描述从某个观察方向 ω 可见的微表面比例。

史密斯近似是一个常用的方法,它假设微表面的高度和法线在统计上是独立的。基于此,我们可以从分布函数 D 推导出遮蔽函数 G1

以下是需要考虑的遮挡效应:

  • 遮蔽:从出射方向看,一些微表面被其他微表面挡住。
  • 阴影:从入射方向看,一些微表面处于其他微表面的阴影中。
  • 联合遮蔽阴影项 G:通常假设遮蔽和阴影是独立事件,因此联合项可近似为 G(ω_i, ω_o) = G1(ω_i) * G1(ω_o)

Cook-Torrance BRDF 模型

基于微表面模型,我们可以推导出 Cook-Torrance BRDF。其核心思想是:只有那些法线方向 m 恰好等于入射方向 ω_i 和出射方向 ω_o 的半角向量 h 的微表面,才会将光从 ω_i 反射到 ω_o

最终的 Cook-Torrance BRDF 公式如下:
f_r(ω_i, ω_o) = (D(h) * G(ω_i, ω_o) * F(ω_i, h)) / (4 * (n·ω_i) * (n·ω_o))
其中:

  • D(h) 是微表面分布函数。
  • G(ω_i, ω_o) 是联合遮蔽阴影项。
  • F(ω_i, h) 是菲涅尔项,表示反射比例。
  • n 是宏观表面法线。

这意味着,只要定义了微表面分布函数 D,就可以计算出相应的 GF,进而得到完整的 BRDF。

双向散射表面反射分布函数

对于某些材料(如皮肤、蜡、大理石),光会进入表面下方,经过多次散射后从另一点射出。这种现象称为次表面散射,需要用双向散射表面反射分布函数(BSSRDF)来描述。

BSSRDF 不仅依赖于入射和出射方向,还依赖于表面上的入射点和出射点位置。它比 BRDF 更复杂,但能产生非常逼真的效果,尤其在渲染皮肤等材质时至关重要。

颜色与光谱渲染

在光线追踪系统中,我们最终需要为每个像素计算颜色。然而,所有辐射度量(如辐射率)本质上是波长的函数。

以下是两种处理颜色的方法:

  • RGB 渲染:最简单的方法是为红、绿、蓝三个通道分别计算辐射量。这假设光在这三个波段是独立的。
  • 光谱渲染:更准确的方法是沿路径对多个波长进行采样,计算每个波长样本的辐射量,得到光谱分布 S(λ)。最终颜色通过颜色匹配函数积分得到:C = ∫ S(λ) * \bar{c}(λ) dλ,其中 \bar{c}(λ) 是颜色匹配函数。

光谱渲染能更精确地处理色散、荧光等与波长密切相关的现象。

颜色空间

颜色空间是定义颜色数值表示的系统。最常见的颜色空间是 RGB,但还有许多其他空间(如 XYZ, sRGB, CIELAB)。

  • XYZ 颜色空间:由 CIE 在1931年定义,基于人类视觉的颜色匹配实验。它是许多其他颜色空间的基础。
  • 颜色空间转换:不同颜色空间之间可以通过一个 3x3 的线性变换矩阵进行转换。这是因为光谱分布可以近似为基函数的线性组合。

本节课中我们一起学习了微表面模型的原理及其如何用于推导 Cook-Torrance BRDF,了解了次表面散射的基本概念及其重要性,并探讨了在渲染中处理颜色的两种方法(RGB 与光谱渲染)以及颜色空间的基础知识。这些内容是构建现代物理渲染器的核心组成部分。

010:神经渲染与体渲染

在本节课中,我们将学习神经渲染的基本概念,特别是如何利用体渲染方程从2D图像集合中合成新的3D视角图像。我们将从传统的3D到2D渲染出发,探讨其逆向问题——从2D观测重建3D,并重点介绍神经辐射场(NeRF)这一里程碑式的工作,它通过结合神经网络的表示能力和经典的体渲染方程,实现了高质量的新视角合成。


从3D到2D与从2D到3D

在传统的计算机图形学中,我们通常关注如何从虚拟的3D场景生成2D图像。这个过程涉及定义虚拟物体、光照和材质属性,并通过物理模拟(如光线追踪)将3D信息投影到2D平面上。

然而,从计算机视觉的角度看,一个核心问题是:如何从真实场景拍摄的一组2D图像中重建出3D结构?这可以看作是图形学渲染过程的逆向问题。本节课将更多地从视觉视角出发,探讨如何从2D图像进行3D重建,并展示这一过程如何与渲染管线相互交织。

新视角合成的目标

神经渲染的一个核心目标是新视角合成。假设我们拥有从多个已知视角拍摄的一组2D图像,我们的目标是合成一个从未见过的新相机视角下的图像。这不仅仅是3D重建,更是为了生成逼真的新视图。

一个典型的例子是,给定离散的2D图像样本,我们可以生成相机平滑移动的连续视频。这构成了神经渲染的原始驱动力。

这里的关键假设是,我们只有2D图像作为训练数据,没有任何关于3D场景的直接监督信息(如深度图、3D模型)。挑战在于,如何仅凭2D图像就能合成新视角的图像?

神经渲染的基本思想

在机器学习框架下,一个朴素的想法是构建一个“黑盒”神经网络。该网络以相机位姿(如相机矩阵)作为输入,直接输出对应的2D图像。我们可以用已知图像-位姿对来训练这个网络,使用L2损失等函数比较输出图像与真实图像。

然而,直接训练这样一个网络来精确预测新视角图像是极具挑战性的。神经渲染的关键洞见在于:我们不希望网络是一个不可解释的黑盒解码器,而是希望它通过一个可解释的、基于3D表示的渲染过程来生成图像。

换句话说,神经渲染的目标是构建一个图像解码器,它从3D表示出发,利用渲染方程来生成2D图像。这使得系统更具可解释性,并且当结合图形学中成熟的渲染方程时,通常能获得比纯黑盒网络更好的效果。

早期3D重建方法的局限

为了实现上述目标,我们需要从2D图像中获取或生成3D表示。早期尝试包括直接从2D图像预测3D网格。

例如,“像素到网格”类的工作从一个模板网格(如人体)开始,通过神经网络迭代变形网格,使其投影与输入图像的轮廓对齐。这类方法存在多种局限:

  • 拓扑限制:难以改变网格的基本拓扑结构(如从球体变成环状)。
  • 未见区域:对于被遮挡的区域,难以生成合理的几何。
  • 细节缺失:通过变形来表现薄结构或复杂细节较为困难。
  • 收敛缓慢:在优化过程中,每个像素通常只更新网格上的一个交点,导致学习效率低下。

隐式表示的兴起

人们发现,使用隐式函数来表示3D形状更具优势。隐式函数(如符号距离函数SDF)为空间中的任意点输出一个值(如该点到最近表面的有符号距离,或一个表示内部/外部的占用值)。

隐式表示的好处包括:

  • 灵活性:可以表示任意拓扑的形状。
  • 细节丰富:能够捕捉复杂的几何细节。
  • 分辨率无关:表示是连续的,不依赖于像体素那样的离散分辨率。

然而,问题随之而来:如何渲染这种隐式表示? 我们需要将隐式函数转换为2D图像以便与输入图像比较,从而进行训练。

球体追踪及其挑战

渲染隐式函数(如SDF)的一种经典方法是球体追踪。其基本思想是:从射线起点出发,查询该点的SDF值(即到最近表面的距离)。由于这个距离内保证没有表面,我们可以安全地沿射线前进该距离。在新点重复此过程,直到到达表面或满足停止条件。

虽然有效,但球体追踪在神经渲染框架中存在挑战:

  • 不可微性:追踪过程中的决策步骤(如判断是否击中)通常不可微,不利于基于梯度的神经网络训练。
  • 计算量大:对于接近射线方向的表面或射线未击中的情况,可能需要很多次迭代,计算开销大。

体渲染:打破物理假设的解决方案

有趣的是,解决方案来自于打破“物体是实心固体”的物理假设。与其将物体视为具有明确表面的实体,不如将其视为一种体积(或“云雾”)。我们假设光线可以穿透这个体积,并与其中的粒子发生交互。

这样,我们就可以利用计算机图形学中研究了数十年的体渲染方程。体渲染不寻找第一个交点,而是考虑光线穿过整个体积时,沿途所有点对最终颜色的累积贡献。这带来了两个关键优势:

  1. 计算高效:避免了迭代式的球体追踪。
  2. 梯度友好:整个过程可以设计为完全可微的,便于神经网络训练。
  3. 全局更新:一次优化可以更新3D空间中沿整条射线的许多点,而不仅仅是第一个交点。

神经渲染的最新进展表明,即使目标是重建固体物体,使用体积表示也能获得更优的结果。

DeepVoxels:混合编码与渲染

在深入NeRF之前,我们先看一个早期工作DeepVoxels。它采用了混合策略:

  • 编码阶段:将输入2D图像通过CNN提取特征,然后通过光线投射,将这些2D特征“涂抹”到3D体素网格中。
  • 解码阶段:对于新视角,从3D体素网格中沿着新相机光线聚合特征,再通过解码器网络生成图像。
  • 遮挡处理:使用一个额外的神经网络来预测每个体素沿某条光线的可见性概率,用于加权聚合特征。

DeepVoxels展示了结合神经网络与经典图形学操作(3D投影)的潜力,并能合成合理的新视图。但它也有局限:

  • 内存消耗大:3D体素网格存储高维特征,内存开销高。
  • 物理不一致:其可见性预测网络不保证物理正确性(例如,远处体素的可见性可能被错误地预测得比近处遮挡物还高)。

NeRF:神经辐射场

神经辐射场(NeRF) 针对DeepVoxels的局限进行了关键改进,成为神经渲染的里程碑。

NeRF的核心是用一个多层感知机(MLP)神经网络来表示一个连续的3D场景。这个网络学习两个隐式函数:

  1. 体积密度 σ(x):输入一个3D坐标点 x,输出一个标量密度。密度表示该点处无限小粒子存在的概率,决定了光线在此处被终止(即“碰撞”)的可能性。
  2. 视角相关颜色 c(x, d):输入一个3D坐标点 x 和观察方向 d(单位向量),输出该点从方向 d 看过去的RGB颜色。这模拟了如镜面高光等视角相关的外观。

体渲染方程

给定一条从相机出发穿过像素的光线 r(t) = o + t do为原点,d为方向),其最终颜色 C(r) 通过体渲染方程计算:

C(r) = ∫ T(t) σ(r(t)) c(r(t), d) dt

其中:

  • σ(r(t)) 是光线在 t 处的密度。
  • c(r(t), d) 是该点处的颜色。
  • T(t)透射率,表示光线从起点传播到 t 而未被终止的概率。它由密度沿路径的积分决定:
T(t) = exp( -∫ σ(r(s)) ds )   [积分从 0 到 t]

物理意义:方程 T(t) σ(r(t)) 给出了光线恰好终止在 t 处微小区间的概率。因此,整个积分计算的是沿光线所有点颜色的期望值。透射率 T(t) 是一个单调非增函数,这自然地保证了遮挡的物理正确性:如果一个点被遮挡,其透射率必然很低,它后面的点对颜色的贡献也会被大幅衰减。

离散化与分层采样

为了计算积分,NeRF在光线近远边界 [tn, tf] 内进行离散采样。它将积分区间划分为N段,采用一种更精确的离散化方式(而非简单的蒙特卡洛求和)。最终像素颜色的近似公式为:

Ĉ(r) = Σ Ti (1 - exp(-σi δi)) ci

其中:

  • i 是样本索引。
  • Ti = exp( -Σ σj δj ) [j 从 1 到 i-1] 是到达第 i 个样本前的透射率。
  • σici 是第 i 个样本处的密度和颜色。
  • δi 是相邻样本间的距离。
  • (1 - exp(-σi δi)) 可理解为光线在第 i 个区间内被终止的概率。

为了高效采样,NeRF使用了分层采样策略:先用一个“粗”网络在光线上均匀采样,预测一组密度;然后根据这些密度分布(重要性采样),在可能包含物体的区域进行更密集的“细”采样。最终颜色由“细”网络的采样结果计算。

NeRF的优势

  • 连续表示:MLP提供无限分辨率,内存效率远高于体素网格。
  • 物理正确的渲染:体渲染方程保证了遮挡和颜色累积的物理合理性。
  • 高质量细节:能够重建出非常精细的几何和外观细节。

总结

本节课我们一起学习了神经渲染的核心思想与发展脉络。我们从图形学(3D→2D)与视觉(2D→3D)的双重视角出发,探讨了新视角合成问题。早期基于网格和体素的方法存在各种限制。而神经辐射场(NeRF) 通过将场景表示为神经隐式函数(密度场和辐射场),并利用可微的体渲染方程进行图像合成,实现了重大突破。它结合了神经网络的表示能力和经典图形学渲染模型的物理正确性,生成了高质量的新视角图像,为后续的3D重建与生成研究奠定了基础。

NeRF之后,研究朝着更高效的混合表示(如点云、高斯泼溅)等方向发展,我们将在后续课程中探讨。

011:高斯泼溅 (Gaussian Splatting) 🎯

在本节课中,我们将学习一种名为“高斯泼溅”的3D场景表示与渲染技术。这是一种结合了显式与隐式表示的混合方法,旨在实现高质量、高速度的实时神经渲染。


上一节我们讨论了神经辐射场等隐式表示方法。本节中,我们来看看一种更高效的显式表示方法——高斯泼溅。

核心概念与动机

高斯泼溅的基本思想是使用3D高斯椭球体作为基本图元来表示场景,而非传统的点、三角形或体素。每个高斯椭球体具有位置、协方差(控制形状和大小)、不透明度以及颜色(或视角相关的辐射率)等属性。

以下是高斯泼溅希望解决的核心问题:

  • 高质量渲染:渲染结果需与真实图像高度匹配。
  • 实时渲染速度:目标达到甚至超过每秒60帧。
  • 内存高效:模型应足够轻量,以便在移动设备等平台上运行。
  • 易于集成:能够方便地集成到现有的图形管线(如Unity、虚幻引擎)中。

高斯泼溅的灵感来源于20多年前的基于点的渲染技术。当时,由于GPU能高速处理海量点数据,且高精度3D扫描仪产生了密集的点云,研究者开始探索直接渲染点云而非网格。每个点被扩展为具有法线和半径的“盘状”图元,称为表面泼溅。

神经渲染的成功表明,体渲染比表面渲染更适合表示复杂的3D场景。因此,高斯泼溅将“表面泼溅”升级为“体泼溅”,即使用3D高斯椭球体作为体渲染的基本单元。

高斯泼溅的优势

以下是采用这种泼溅表示法的主要优势:

  1. 渲染管线兼容性:由于使用显式图元,可以直接利用现有的光栅化管线进行渲染,无需沿射线进行密集采样和积分,极大降低了计算量。
  2. 初始化便利性:可以从运动恢复结构等传统算法输出的稀疏点云直接初始化高斯椭球体,为后续的神经优化提供了一个良好的起点,加速了重建过程。

接下来,我们将深入探讨如何定义这些高斯泼溅,并利用体渲染方程进行渲染。

体泼溅的定义与渲染方程

1. 高斯椭球体的定义

每个体泼溅(高斯椭球体) i 在物体坐标系(世界坐标系)中定义,包含以下参数:

  • 中心位置p_i
  • 协方差矩阵Σ_i (一个3x3的对称半正定矩阵,控制椭球的形状和方向)
  • 不透明度α_i
  • 颜色c_i (可以是常数,也可以是视角相关的函数 c_i(d))

该椭球体在空间中定义一个3D高斯核函数,用于衡量空间任意一点 x 受该泼溅影响的程度(权重):

权重_i(x) = exp(-0.5 * (x - p_i)^T Σ_i^{-1} (x - p_i))

2. 坐标变换

渲染时,需要将高斯泼溅从物体坐标系变换到射线坐标系(一种特殊的2D图像平面坐标系)。这涉及两次变换:

  1. 模型变换 (Model Transformation):从物体坐标系到相机坐标系。这是一个仿射变换,包含线性部分 W 和平移部分 T
    x' = W * x + T
    
    在此变换下,高斯参数变换为:
    p'_i = W * p_i + T
    Σ'_i = W * Σ_i * W^T
    
  2. 投影变换 (Projection Transformation):从相机坐标系到射线坐标系。标准的透视投影不是仿射变换。为了保持高斯形式,论文在每个高斯泼溅的中心点 p'_i 处对投影变换进行一阶泰勒展开,将其近似为一个仿射变换(雅可比矩阵 J_i)。
    x'' ≈ J_i * (x' - p'_i) + 投影(p'_i)
    
    最终,在射线坐标系下的近似高斯参数为:
    p''_i = 投影(p'_i)
    Σ''_i = J_i * W * Σ_i * W^T * J_i^T
    

3. 离散体渲染方程

在射线坐标系下,对于像素 (x, y),我们沿其深度 z 方向进行积分。原始的体渲染方程离散化后为:

C = Σ_{i=1}^{N} (c_i * α_i * T_i)
其中,T_i = Π_{j=1}^{i-1} (1 - α_j)

这里 T_i 是累积透射率,表示光线到达第 i 个样本前未被阻挡的概率。

在高斯泼溅中,我们将不透明度 α 替换为与高斯权重相关的项。经过一系列推导和近似(包括局部支撑假设、一阶指数展开等),最终得到用于渲染的简化公式:

C = Σ_{i∈N} c_i * α_i * Π_{j=1}^{i-1} (1 - α_j)

其中,α_i 现在与变换到射线坐标系下的2D高斯权重 权重_i(x'', y'') 成正比,N 是按深度排序后对该像素有贡献的高斯泼溅集合。

渲染流程简述

  1. 给定相机姿态,将所有高斯泼溅变换到射线坐标系。
  2. 对于每个像素,快速收集并深度排序所有投影到该像素范围内的2D高斯泼溅。
  3. 按照上述简化公式,从前到后进行Alpha混合,计算像素最终颜色。

4. 训练与优化

高斯泼溅模型的训练也是一个可微分的优化过程:

  1. 初始化:从运动恢复结构得到的稀疏点云初始化高斯泼溅的中心位置 p_i。协方差矩阵初始化为各向同性。
  2. 优化:通过比较渲染图像与真实图像,计算损失(如L1、SSIM损失),并通过反向传播同时优化所有高斯泼溅的参数(位置、协方差、颜色、不透明度)。
  3. 自适应控制:在训练过程中,会动态地克隆(用于欠重建区域)或分裂(用于过重建区域)高斯泼溅,以更好地捕捉场景的几何细节。

总结

本节课中,我们一起学习了高斯泼溅这一先进的3D场景表示与渲染技术。我们从其源于“基于点的渲染”的历史讲起,探讨了它如何通过使用3D高斯椭球体作为显式图元,结合体渲染原理,实现了高质量、实时的神经渲染。

我们详细剖析了其核心渲染方程,了解了如何通过坐标变换(特别是投影变换的雅可比近似)将3D高斯投影到2D图像平面,并利用简化的Alpha混合公式进行高效渲染。最后,我们概述了其通过可微分优化进行模型训练和自适应细化的过程。

高斯泼溅因其在速度、质量和实用性方面的卓越平衡,已成为当前神经渲染领域的重要基石,并被广泛集成到各种图形应用和引擎中。

posted @ 2026-03-29 09:18  绝不原创的飞龙  阅读(2)  评论(0)    收藏  举报