当我入门虚拟现实的时候,我学了什么?


摘要:虚拟现实是一个新兴的研究方向,综合了多种领域的知识。本文通过一些经典课程,专业书籍和顶会论文,对虚拟现实的一些基础技术内容进行了总结和探讨。其中包括计算机图形学方向的图形渲染管线、辐射度量学、物理引擎和数字几何处理,还包括计算机视觉方向的深度学习和 SLAM。在讨论中,本文对多种理论,知识和方法进行了比较,最后给出了其在虚拟现实领域的应用。

关键字:图形渲染管线,辐射度量学,物理引擎,数字几何处理,深度学习,SLAM


引言

     作者初入虚拟现实方向,对虚拟现实的整体研究没有一个明确的认识,故通过与其相关的多个领域的学习和总结,希望可以更加深入地了解虚拟现实的支撑基础。其中包括计算机图形学方向的图形渲染管线、辐射度量学、物理引擎和数字几何处理,还包括计算机视觉方向的深度学习和 SLAM。作者通过对多个经典课程,专业书籍和顶会论文的学习和总结,对多个研究方向的方法和理论进行了比较和探讨,最后给出了其在虚拟现实领域的应用。


计算机图形学

图形渲染管线

     在图形渲染管线的学习历程中,主要使用的学习资料为 OpenGL 教程,闫令琪的 Games 101 计算机图形学基础课程和图形学的经典书籍《Real Time Rendering》。

     首先表示,图形渲染管线并不是特指 OpenGL,但是学习图形渲染管线一般从 OpenGL 开始,在对渲染管线有了一个整体的认识和了解之后,完全可以脱离 OpenGL 实现自己的简易版图形渲染管线。而 OpenGL 一般被认为只是是一个 API(Application Programming Interface, 应用程序编程接口),包含了一系列可以操作图形、图像的函数。在更广泛的意义上,OpenGL 本身仅仅是一个由Khronos 组织制定并维护的规范。

     在本节中,首先简述 OpenGL 的图形渲染管线如何使用,然后对图形渲染管线的思路和流程进行总结。

     为了更方便地使用 OpenGL,我们往往需要借助一些其他的工具类库。其中最重要的两个分别是 glad 和 glfw。glad 和 glew 的作用都是帮助在开发 OpenGL 时简化其在运行时获取函数的内存地址并将其保存在一个函数指针中供以使用的流程,其作用可以看作早期的 gl 和 glu 的加和,而 glad 比 glew 更加完善。而 glfw 是一个专门针对 OpenGL 的 C 语言库,它提供了一些渲染物体所需的最低限度的接口,它允许用户创建OpenGL上下文,定义窗口参数以及处理用户输入,通过 glfw,我们才能通过 C 语言调用底层的 OpenGL。更加具体的 C 语言下 OpenGL 的 CMake 配置可以参考链接。

     在 OpenGL 中,任何事物都在 3D 空间中,而屏幕和窗口却是 2D 像素数组,这导致 OpenGL 的大部分工作都是关于把 3D 坐标转变为适应屏幕的 2D 像素。OpenGL 的图形渲染管线可以被划分为两个主要部分:第一部分把你的 3D 坐标转换为2D坐标,第二部分是把 2D 坐标转变为实际的有颜色的像素。在 OpenGL 中,主要是通过顶点着色器,几何着色器和片段着色器来实现的。

     在实现自己的简易版图形渲染管线时,其主要的流程为:

  1. 通过坐标变换完成三角面片从模型坐标到世界坐标的变换、从模型坐标到相机坐标的转换、从相机坐标到屏幕坐标的投影变换。
  2. 对光栅化完成对三角面片的离散化和深度测试、抗锯齿等操作。
  3. 使用光照模型进行着色,并应用纹理映射。

     图形渲染管线的并行渲染特性使其仍然是现在虚拟现实系统所使用的渲染技术的主流。

辐射度量学

     图形渲染管线能完成实时的渲染,但是因为其在某些实现,尤其是光照模型上的简化,使得图形渲染管线的渲染效果有待改进。辐射度量学是渲染另一个分支,其使用光线跟踪的方法,可以实现高质量的真实感渲染,但是由于其算法复杂性,很难实现高质量的实时渲染。

     在辐射度量学的学习历程中,主要使用的学习资料为经典论文 The Rendering Equation,闫令琪的 Games 101 计算机图形学基础课程和真实感渲染的经典书籍《Physically Based Rendering: From Theory to Implementation》和 《ray tracing in one weekend/one week/the rest of life》

     在辐射度量学中,使用辐射强度和辐照度等物理概念,对真实感渲染进行了最大程度的物理仿真。通过蒙特卡洛方法,对各个像素点的辐射或亮度进行了统计意义上的计算和处理,从而得到了理论上的真实感渲染。

     在对各个材质的建模和渲染中,广泛使用了双向反射分布函数(BRDF)的概念,定义给定入射方向上的辐射照度如何影响给定出射方向上的辐射率。更笼统地说,它描述了入射光线经过某个表面反射后如何在各个出射方向上分布这可以是从理想镜面反射到漫反射、各向同性或者各向异性的各种反射。通过数据驱动的双向反射分布函数,可以对各种材质进行最大限度的真实感渲染。在双向反射分布函数的基础上,还提出了双向散射分布函数和次表面散射分布函数的概念,常用于皮肤、毛发等特殊材质的真实感渲染。

     基于光源的重要性采样的蒙特卡洛路径追踪算法的伪代码如下所示,其代码实现参见:基于蒙特卡洛方法的路径追踪实现。

shade(p, wo)
  # Contribution from the light source.
  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

物理引擎

     在虚拟现实系统中,除了需要真实感的渲染之外,还需要符合一个物理定律的引擎,即物理引擎。

     在物理引擎的学习历程中,主要使用的学习资料 Games 201 Taichi 和物理引擎,胡渊明。

     在物理引擎中,有两种主要的实现方法,分别是拉格朗日方法和欧拉方法。

     其中拉格朗日表述侧重于“质点”(或者叫“流体微元”),把流体的性质按着质点/流体微元来逐个定义;而欧拉表述侧重于“场”,把流体的性质(质量密度、速度、温度、熵、焓,甚至单位流体中的磁通量,等等)定义为空间位置和时间的函数。

     两种方法各有优劣,分别用于模拟不同的场景:

  • 拉格朗日方法:弹簧质点系统(太极源码)
  • 欧拉方法:PIC, APIC 和 MPM(太极源码)

     在物理引擎中,最终的结果往往是求解一个偏微分矩阵方程的问题,或者说是泊松方程。常使用数值计算的解法,常用算法有:

  1. 雅克比迭代法
  2. 高斯赛德尔迭代法
  3. 共轭梯度迭代法
  4. Multigrid 方法

     本人开发的,基于 Go 的线性代数库 Singular 已开源,实现了基础的数值分析算法。

     在使用物理引擎进行相关模拟后,往往还需要将模拟结果渲染到网格模型上,常用的方法有 MeshCube 等。

数字几何处理

     任何渲染都离不开网格模型的处理,即数字几何处理。

     在数字几何处理的学习历程中,主要使用的学习资料为《Polygon Mesh Processing》和《计算共形几何》书籍,数字几何处理,傅孝明和计算共形几何,顾险峰课程,以及Libigl 教程。

     在数字几何处理中,主要使用的网格模型为半边模型,其基础理论为离散微分几何,主要使用的微分量为法向量、梯度算子、拉普拉斯算子和曲率。

     其中最重要的即为拉普拉斯算子,通过根据拉普拉斯算子构造的能量函数进行优化处理,即可完成大部分的网格处理操作,包括但不限于:网格平滑,网格参数化,网格变形,网格修复,网格映射,网格简化,纹理映射和重新网格化。其求解的本质也是对一个偏微分矩阵方程,或者泊松方程进行求解。其基础概念为数字几何处理 基础,另有数字几何处理库 Libigl,其部分代码为Libigl 教程代码。


计算机视觉

深度学习

     深度学习是当今计算机视觉的一个重要研究方向,通过神经网络系统,可以处理很多其他算法无法解决的问题,例如图片分类、实例分隔等。

     在深度学习的学习历程中,主要使用的学习资料为 Pytorch 书籍 《深度学习之PyTorch物体检测实战》。

     在本节中,首先简述神经网络的搭建和训练过程,然后对深度学习的训练加速和准确度提升作进一步的讨论。

     在神经网络的搭建中,首先需要确定输入变量和输出变量,一般需要将图片的二维向量展平成一维向量;之后需要在输入变量和输出变量之间建立网络映射关系,确定隐含层中的神经元数目和隐含层的深度;还需要确定各个隐含层之间的连接关系,以及各个连接使用的激活函数。至此,一个基础的神经网络就搭建完毕,其中池化、卷积的细节在此不再赘述。

     在神经网络的训练中,其最关键的就是需要一个训练数据集,如果实验条件允许,还可以划分出测试训练集和验证训练集。神经网络训练的过程,实质上就是对网络各层之间的映射关系的参数的确定。需要事先选定一个损失函数,最小化损失即作为参数的优化目标,在逐步优化参数的过程中,一般随机选取训练数据集的一部分作为此次优化迭代使用的训练数据,称为批训练;而优化参数的方法处理常用的梯度下降方法外,还有很多各种计算方法优化器,例如 Momentum,RMSprop,Adam 等,其细节在此不再赘述。

     神经网络的训练一般是一个非常耗时的过程,每一轮迭代都涉及到大量参数的更新,每个训练周期又要涉及多次迭代,所以如何对神经网络的训练进行加速,也是一个研究的重要课题。由于神经网络局部运算的简单性和运算之间的重复性,常常使用 GPU 对神经网络的训练过程进行加速。GPU 有一套很好的并行运算体系,可以大幅减少神经网络的训练时间。

     在深度学习中一个重要的问题就是过拟合和。过拟合是指神经网络在训练数据集上的拟合准确度很高,但是在测试数据集或验证数据集上的拟合准确度很低。一般的解决方法有三个:

  1. 增大数据量:大部分过拟合产生的原因是因为数据量太少了,但是很多时候增大数据量很难,故采用其他方法。
  2. 正规化:使用正规化可以限制参数的变化范围,从而在一定程度上避免过拟合。
  3. Dropout:其思想是随机忽略掉一些神经元和神经联结,从而使神经网络变得不完整,而使得神经网络没办法过度依赖参数,从而起到避免过拟合的效果。

     另外,针对训练数据集分布不均的问题,可以使用批次标准化进行处理,此处不再赘述。

SLAM

     在计算机视觉中,常用的两个方法就是基于神经网络的深度学习和基于几何的 SLAM。没有 SLAM,虚拟现实终将只能停留在座椅上。

     在 SLAM 的学习历程中,主要使用的学习资料为书籍:《视觉 SLAM 十四讲》,《多视图几何》,《概率机器人》,《计算机视觉中的数学方法》,《增强现实:原理,算法与应用》。和 Prof. D. Cremers 的多视图几何课程,Cyrill Stachniss 的 SLAM 课程, SLAM 技术与应用暑期学校,从零开始一起学习 SLAM 教程。相关代码为:SLAM 基础,SLAM 系统。

     在 SLAM 系统中,分为前端和后端,其中主要讲述前端的有 《多视图几何》和《计算机视觉中的数学方法》,主要讲述后端的有《概率机器人》。

     前端的主要功能是实现视觉里程计,即首先完成完成视频中各帧中的关键点提取,之后进行视频中各帧之间的匹配操作,主要目的就是确定完成视频中各帧之间的相机相对位姿,其主要方法为:

  1. 2D-2D:对极约束
  2. 3D-3D:ICP 迭代最近点
  3. 2D-3D:PNP 相机位姿求解

     后端的主要功能是实现相机位姿的优化,其主要方法为基于滤波的方法和基于图优化的方法。基于滤波的方法主要使用的是卡尔曼滤波,基于图优化的方法主要使用 g2o 框架,在此不再赘述。


讨论

     在虚拟现实系统的设计和实现中,综合使用了上述基础理论和技术。其中虚拟现实最重要的三项技术为:

  1. 实物虚化技术
  2. 虚物实化技术
  3. 增强现实,混合现实技术

     其中实物虚化技术的主要技术点在于建模,即几何造型建模和物理行为建模,需要使用深度学习,SLAM,数字几何处理和物理引擎等相关技术。

     虚物实化技术的主要技术点在于视觉绘制,需要使用图形渲染管线和辐射度量学等相关技术。

     增强现实,混合现实技术的主要技术点在于三维注册、相机标定和人机交互,需要使用 SLAM 等相关技术。

     而虚拟现实很重要的另一个点就是为用户提供沉浸感,不仅要达到技术上的生理沉浸,还要达到艺术上的心理沉浸。其基于沉浸感的设计原则有:

  • 原则一:虚拟视点的合理性
    • 虚拟视点的高度要达到生理沉浸
  • 原则二:身体惯性与虚拟运动的匹配性
    • 视觉系统和前庭系统感知到的运动状态应该相同(眩晕感来自大脑需要处理矛盾信息)
  • 原则三:降低交互抽象性
    • 通过提高真实和虚拟动作的一致性,降低交互的抽象性,降低玩家的学习成本,提高沉浸度

     同时,虚拟现实系统的设计和实现还需要其他各方面技术的支撑,例如网络技术,软件工程相关技术等。


参考文献

  • [1] [OpenGL 教程](https://learnopengl- [1]cn.github.io/)
  • [2] [Games 101 计算机图形学基础,闫令琪](http://games- [1]cn/intro- [1]graphics/)
  • [3] 《Real Time Rendering》
  • [4] Games 101 相关代码
  • [5] OpenGL 相关代码
  • [6] Kajiya J T. The rendering equation[C]//Proceedings of the 13th annual conference on Computer graphics and interactive techniques. 1986: 143- [1]150.
  • [7] [《Physically Based Rendering: From Theory to Implementation》](http://www.pbr- [1]book/)
  • [8] 《ray tracing in one weekend/one week/the rest of life》
  • [9] 基于蒙特卡洛方法的路径追踪实现
  • [10] [Games 201 Taichi 和物理引擎,胡渊明](http://games- [1]cn/games201/)
  • [11] 弹簧质点系统
  • [12] 弹簧质点系统(太极源码)
  • [13] PIC, APIC 和 MPM(太极源码)
  • [14] 当我学数值分析时,我学到了什么?
  • [15] 基于 Go 的线性代数库 Singular
  • [16] 数字几何处理,傅孝明
  • [17] 数字几何处理 基础
  • [18] 《Polygon Mesh Processing》
  • [19] 《计算共形几何》
  • [20] 计算共形几何,顾险峰
  • [21] Libigl 教程
  • [22] Libigl 教程代码
  • [23] 《深度学习之PyTorch物体检测实战》
  • [24] 《视觉 SLAM 十四讲》
  • [25] 《多视图几何》
  • [26] 《概率机器人》
  • [27] 《计算机视觉中的数学方法》
  • [28] 《增强现实:原理,算法与应用》
  • [29] [Multiple View Geometry (Prof. D. Cremers)](https://www.youtube/watch?v=RDkwklFGMfo&list=PLTBdjV_4f- [1]EJn6udZ34tht9EVIW7lbeo4)
  • [30] SLAM Course (Cyrill Stachniss)
  • [31] SLAM 技术与应用暑期学校
  • [32] 从零开始一起学习 SLAM 教程
  • [33] SLAM 基础
  • [34] SLAM 系统
  • [35] MIT 线性代数,Gilbert Strang
  • [36] 《虚拟现实:理论、技术、开发与应用》
  • [37] 《虚拟现实:从零基础到超现实》
  • [38] 《虚拟现实导论:原理与实践》

更多推荐

当我入门虚拟现实的时候,我学了什么?