欢迎光临散文网 会员登陆 & 注册

3D 成像原理

2023-01-19 01:20 作者:Zweitestock  | 我要投稿

虚拟相机是图形学实践无法回避的一个话题。

曾经有一个问题困扰过我:在 Ray Tracing 中,我们从虚拟相机发射了一条光线,光线与屏幕相交然后和进入场景之中,击中场景中的物体,再从击中点要么寻求和光源是否有直接连线,要么从击中点发出新的光线,然后以此为依据队屏幕像素进行着色。

这是一个非常合理的过程,屏幕和物体都处在合理的顺序上。但不要忘了虚拟相机和屏幕之间是有一部分间距的,要是物体位于这个间距之间呢?那我们刚刚的理论似乎说不通了,但事实是,这种情况仍然能够成像。这是为什么呢?让我们一起探讨一下成像原理吧。

相机成像

摄影的原理主要包括两个部分:

  • 将图像存储在胶片或者文件中

  • 在相机中生成图像

我们主要关心后者。现实世界中最简单的相机类型是针孔相机,图形学中的虚拟相机常常模拟的也是针孔相机的特性。当然也有更加复杂逼真的相机模型,但这并不在本文的讨论之列。

针孔相机对应的物理现象是小孔成像,其背后的光学依据是光沿直线传播。

小孔成像

所谓小孔成像,即在物体和成像平面之间放置一个带孔平面,那么成像平面上就会形成物体的倒像,如图:

针孔相机

光圈

在针孔相机中,这个小孔被称作是光圈。所有进入相机的光线都会汇聚到这一点,并在另一侧发散。

光圈的大小控制成像的清晰度:光圈越小,成像越清晰。光圈越大,成像越模糊。

如下图所示,光圈足够小时,物体上 A 点在成像平面上对应 A’,而当光圈较大时,A 点就会对应多个点(实际上是 A’A’’ 整个区域)。所以造成了成像的模糊。

光圈的大小也和物体的大小相关,当物体很大时,较大的光圈也可以生成可以接受的图像。因为对于较大的物体,我们并不苛求它的每个细节都尽善尽美。不过光圈越小,分辨率越高。

不过光圈也并不是越小越好,光圈越小,通过的光线也就越少,成像的亮度会降低,光圈太小还可能造成队成像不利的衍射反应。

曝光时间

正如上文所说,光圈越小,固定时间内通过的光线也就越少。为了到达成像所需的光量,就需要一定的曝光时间。我们希望曝光时间越短越好,所以需要在清晰度和曝光时间中折衷取舍。

透镜相机

透镜相机解决的就是曝光时间过长的问题。

其工作原理可以简单描述为在光圈处放置一个凸透镜,凸透镜可以收集进入相机的光线,然后再将其汇聚到成像平面上的一点。其成像规则遵循凸透镜成像的规则:

> 焦距:透镜的光心到光聚集之焦点的距离

  • 当物距大于2倍焦距时,则像距在1倍焦距和2倍焦距之间,成倒立、缩小的实像

  • 当物距等于2倍焦距时,则像距也在2倍焦距,成倒立、等大的实像

  • 当物距小于2倍焦距时,大于1倍焦距时,则像距大于2倍焦距,成倒立、放大的实像

  • 当物距等于1倍焦距时,则不成像,光线平行射出

  • 当物距小于1倍焦距时,则成正立、放大的虚像,此时像距大于物距,像比物大,物像同侧

现实中的相机构造并非如此简单,它一般是多个凸透镜和凹透镜的组合,而且可以实现变焦,不过整体发挥的效用跟单独的凸透镜相似。

景深

景深指的是相机对焦点前后相对清晰的的成像范围,在景深之内的成像比较清楚,在这个范围之前或者之后的成像则比较模糊。如图所示:


景深通常是由物距、镜头焦距和镜头的光圈值共同决定的。景深的精确计算请参阅景深(https://zh.wikipedia.org/wiki/%E6%99%AF%E6%B7%B1)。

然而,因为针孔相机并不使用透镜,所以它具有它一般没有景深这个概念,即物体的清晰度和它距离相机的距离无关。我们可以使用针孔相机拍出完全清晰的图像。

同理,如果我们在图形学计算中模拟针孔相机也是具有无限景深的,场景中所有的对象都非常清晰。不过我们可以通过其他手段来模拟景深。

视场角

后文我们讨论的相机类型如果没有特意指出的话都默认为针孔相机,因为我们在图形学实践中经常模拟针孔相机的一些性质,但并不完全等同于真正的针孔相机。

前文我们已经定义过了透镜相机的焦距(Focal Length),而针孔相机的焦距有所不同。针孔相机的焦距是从成像平面到光圈的距离。

关于焦距,我们可以发现以下性质:当成像平面越接近光圈时,成像越小,如下图所示:

成像平面 P’ 对应的焦距是 f1,成像平面 P 对应的焦距是 f2,前者的成像区域 l’ 小于后者 l。

与此同时,在成像平面 P’ 所能看到的场景范围要比 P 更大,因为同一物体占据了屏幕更小的范围,意味着能够容纳更多的物体。

以我个人的经验来看,这一特性在实践中经常用到,特别是在描述相机性质的时候,图形学中将其称之为视场角(Field of View,FOV)。

总结一下就是,焦距越小,视场角越大,可见的场景范围越大。

视场角在在 3D 空间中分为两种,水平视场角和垂直视场角,如图所示:

我们在具体看一下视场角和焦距之间的关系:

假设我们使得 canvas size 始终等于胶片尺寸(事实上大多数情况下也正是这样)。那么焦距,胶片尺寸,视场角这三者就是相互关联的。

虚拟相机

虚拟相机的特性

我们在图形学中经常使用的虚拟相机和上文述及的针孔相机有所不同。主要表现在以下几个方面:

  1. 如果使用光栅化技术进行渲染,那么虚拟相机会有一个近裁剪平面和远裁剪平面。只有两个裁剪平面之间的对象是可见的。

  2. 虚拟相机的成像平面位于相机光圈之前,而不是之后,所以成像也不是倒像,而是正像

现实中的相机受制于物理规则,成像平面不能位于光圈之前,而虚拟相机则不受这种限制。

而如果成像平面位于光圈之前,那么光圈的位置(也就是投影中心)就是视点的位置,也就是 Ray Tracing 中发射出射线的位置。

裁剪平面

裁剪平面是光栅化所必须的,却不是 Ray Tracing 所必须的,通常在 Ray Tracing 中并不使用裁剪平面。

裁剪平面分为近裁剪平面和远裁剪平面。二者位于虚拟相机之前,并平行于成像平面。比近裁剪平面更近或者比远裁剪平面更远的区域对相机来说是不可见的。

虚拟相机的坐标系

我们想建立关于虚拟相机的坐标系。想象一下,这个坐标系以相机位置,也就是光圈位置为原点,我们如何推导出其 x, y, z 轴?

和观察矩阵的推导类似,我们还需要一个 target 目标点和一个 up 向量。我们假设虚拟相机的坐标系是一个右手坐标系。推导过程如下:

在上面的右手坐标系中,成像平面可以位于 -w 轴上的任意位置。

而在 Ray Tracing 中,成像平面也可以位于 -w 轴上的任意位置。

当视点和成像平面之间的距离为1时可以简化运算。

观察坐标和世界坐标的相互转化

是从观察坐标转换为世界坐标还是从世界坐标转化为观察坐标,取决于我们使用的渲染方式:

  • 如果是光栅化过程,是将物体的顶点坐标从世界坐标转换为观察坐标

    • 光栅化是以对象为中心的

    • 我们需要将对象的坐标经历一系列的转换过程:局部坐标—世界坐标—观察坐标—裁剪坐标—NDC 坐标—屏幕坐标

    • 图像是由投影到图像上的”点“(并不是点,只是比喻)集合而成的

  • 而如果是 Ray Tracing,则是从观察坐标转换为世界坐标。因为我们的光线是以虚拟相机坐标系构建的

    • Ray Tracing 的运作方式与光栅化相反,是以图像为中心的

    • 不是沿着光线的自然路径从对象到相机,而是沿着相反的方向由相机到对象

UV 坐标的三维化

我们已经讨论完了 3D 成像的一些最基本的原理,尽管我们省略了很多细节。

让我们重新回到最开始的问题。

在 Ray Tracing 中,我们从一个像素的位置开始,我们所做的主要工作就是将其转换为成像平面上的一个点 P,连接视点 C 和 P 就能够确认光线的方向,视点 C 就是光线的起点。

我们拿到的是像素坐标,设这个坐标为 P,需要对其进行归一化,转换到 NDC 空间中。然而虽然我们的坐标得到了标准化,但是缺失第三个维度也就是 z 值,我们需要手动指定 z 值,正如上文所言,z 值表示成像平面距离视点的距离,只是在虚拟相机的 -w 方向的值均可。也就是说,这个值是根据虚拟相机得到的,所以 P 的坐标现在正处于相机坐标系中。我们就假设其为 1.0 好了,我们不关心 x, y 两个分量的值,所以现在 P 的坐标就是 (x, y, 1.0)。

你这时就要问了,为什么是 1.0 而不是 -1.0 呢?问得好,这个 1.0 代表的是视点到成像平面之间的距离。那这岂不是意味着我们的成像平面位于 我们的视点之后了?确实!如果我们的观察坐标系是右手系的话确实如此,因为在观察坐标系中相机的坐标始终是 (0, 0, 0),所以一旦我们指定了 P 的坐标是 (x, y, 1.0),那么在后续的变换中就不能使用上面推导的观察矩阵了,因为我们是在假设它是右手系进行推导的,我们必须使用左手系推导得到的观察矩阵。这也很简单,在计算 w 轴的时候不乘以 -1 就好了:

有了观察矩阵 cam,我们就可以将相机坐标转换为世界坐标了:cam * p(x, y, 1.0)。

如果我们固执地要使用右手坐标系推导观察矩阵,那么 P 的观察坐标就应该预设为 (x, y, -1.0)。原则就是,成像平面一定要位于视点之前。

至于为什么可以成像,让我们以一段 RayMarching 的代码为示例说明。可以看到,我们最后成像和着色的依据是 intersection 焦点,只要计算出光线和物体的交点就能够计算出着色!而这个交点即使物体在成像平面与摄像机之间也是可以计算出来的!我们亦可以用下面这段 shadertoy 代码调试上文所说的左右手系问题和视点和成像平面之间的距离问题。

本文到此结束了,感谢你的阅读。

3D 成像原理的评论 (共 条)

分享到微博请遵守国家法律