计算机图形学入门28:相机、透镜和光场

1.前言

相机(Cameras)透镜 (Lenses) 和**光场(Light Fields)**都是图形学中重要的组成部分。在之前的学习中,都是默认它们的存在,所以现在也需要单独拿出来学习下。

2.成像方法

计算机图形学有两种成像方法,即合成(Synthesis)捕捉(Capture) 。前面学过的光栅化成像光线追踪成像 这两种成像都属于合成(Synthesis) 的成像方法,在现实中并不存在。把现实中存在的变成照片属于**捕捉(Capture)**方法来成像,例如相机。如下图所示。

3.相机

3.1 小孔成像

用一个带有小孔的板遮挡在墙体与物之间,墙体上就会形成物的倒立实像,我们把这样的一种现象叫小孔成像 。如果右边放一个传感器,记录到某个胶片上,那么就可以得到一张相片。使用这种原理的相机叫做针孔相机。如下图所示。

当然,我们最常见的还是下图这种这种带棱镜的相机。

3.2 相机部件

3.2.1 相加构成

如上图所示,是一张相机的截面图。相机内部有很多镜头、很多棱镜组成、有感光元件、快门、传感器等。

3.2.2 快门

控制光能否进入机身的部件就是快门(Shutter) ,并控制光能在1/n秒内进入摄像机。

3.2.3 传感器

光进入相机,相机需要被捕捉到,捕捉的原件叫做传感器(Sensor) 。它记录的就是我们之前所说的Irradiance。注意:本篇我们不区分胶片和传感器的概念,但实际上它们是不同的。

如果没有棱镜或者没有针孔,那么相机就不能拍摄一张照片,原因也很简单。如下图所示,如果没有针孔/棱镜,那么传感器上的任何一个点都可能接收人来自四面八方的光线,而传感器本身又不区分方向,所以每个点都收集的是综合起来的信息,所以收集的都是Irradiance信息,看起来都是模糊的。

3.3 针孔相机

小孔成像的现象在很早就被人们发现了,直到今天,我们仍然可以利用小孔成像原理来拍摄照片,使用小孔成像原理的相机叫做针孔相机(Pinhole Camera)。如下图所示,为使用针孔相机拍摄画面。但是小孔成像的照片没有深度,成像的任何一个位置都是锐利的不是虚化的,在光线追踪的时候用的也是针孔相机原理模型。

3.4 视场(FOV)

视场(Field of View) 表示的是我们能看到多大的范围,所谓广角镜头 也就是FOV更大的镜头。什么因素决定视场呢?我们先从小孔成像理解(忽略棱镜),我们把传感器的高度定义为 h ,传感器到小孔的距离定义为 f。如下图所示。

根据三角形关系可以得到FOV=2·arctan(h/2f)

我们就可以根据内部设计 hf 的参数来调节FOV 。如下图所示,通过改变 f来调整视场大小。

由于历史原因,通常用35mm 格式胶片**(36 x 24mm)** 上来定义视场,也就是上面说的传感器大小 h 固定了,那么我们只需要通过定义 f 的不同就可以定义视场的大小,在透镜相机里,f 就是相机的焦距(Focal Length) 。所以,焦距短,视场就大,反之视场就小视场越小,我们能看到的就越远 。如下图所示。注意:我们说所有相机都是用35mm的胶片大小,并不是真的所有相机它的胶片大小都是35mm,这里指的是一种等效的大小。

同样的,传感器尺寸也会对视场大小有影响。只不过一般情况下,都是固定传感器大小,调整焦距。如下图所示,当传感器更小的时候(虚线部分),视场也就越小。

对于手机,虽然它的传感器大小小于相机,但是人们通过缩小它的焦距,可以达到和相机一样的视场大小,只不过更大的传感器也就有更大的分辨率。如下图所示。

3.5 曝光

曝光(Exposure) ,计算公式Exposure =Time x **Irradiance。**也就是说如果对着明亮的场景拍照会拍到一个明亮的照片,如果对着一个暗的环境拍照,但是按下的快门时间很长,我们也可以得到一个比较明亮的照片。也就是说一个是进了多少光,一个是进光进了多长时间,我们将它们累积起来就可以得到曝光度。照相和辐射度量学不同,我们在辐射度量学中总是定义单位时间,但是照相并不是单位时间内发生的,它记录的是总共的能量。

那么有哪些决定决定曝光呢?首先是光圈大小(Aperture size) ,光圈的大小决定了进光的多少,而它实际上是一个仿生学的设计,仿照的是人的瞳孔。第二个就是快门(Shutter) ,快门开放的时间,开放时间越长进光自然也就越多。还有一个是ISO感光度(ISO Gain),它相当于是一个后期处理,简单的说就是接受到的能量我们将它放大多少倍,也就是乘上一个数。

以下详细介绍三者影响曝光的情况。

3.5.1 ISO(Gain)

ISO就是一个后期处理,在最后的图片上乘以一个数,并且是线性的。但是ISO虽然能提升画面的曝光度,但是会导致噪声放大的问题,如下图所示。

从信号的角度理解,我们拍出的照片一定是有噪声的,但是最终我们ISO的操作只是简单的在最后结果上乘了一个数,信号虽然被放大了,但是噪声同样的也被放大了。所以ISO在一定范围内是可以用的,但是过大就会导致噪声问题。

3.5.2光圈大小---F stop

描述光圈的大小有一个专门的数,叫F数 ,或者F stop 。它有两种写法,一个是FN ,另一个是F/ N**。N** 是我们关心的数,我们可以简单的理解为N 就是光圈直径的倒数,N越大光圈直径越小。

3.5.3 快门

快门时间除了会影响曝光度,还会影响一个现象叫做运动模糊。因为按下快门键,快门从关闭状态到打开状态是有一个过程的,它并不是瞬间打开的,而运动模糊的产生就是在快门从开始打开的时候物体开始运动,到快门完全打开的时候它已经运动了一段时间而产生的。因此,曝光时间越长,运动模糊就会越严重,而如果曝光时间相同,那么运动的越快的物体越容易产生运动模糊。如下图所示,快门的时间越长,越模糊。

运动模糊产生也不一定是坏事,比如可以产生物体在移动的效果,或者类似反走样的效果。

快门时间还会造成一种Rolling shutter问题,如下图所示,我们发现飞机的螺旋桨扭曲了。这同样是快门时间导致的,快门打开的过程中,传感器的有些地方先接收到了光,有些地方后接收到了光,于是导致了这种现象。

通过调节影响曝光度的不同因素,我们可以取到很多不同参数而达到相同曝光度的参数。如下图所示,调整每个参数基本都能达到相同的曝光度。

当然它们只是曝光度相同,至于景深,噪声,运动模糊仍具有各自参数的影响。

当用极短的快门时间,通过调大光圈或更大ISO来达到正常曝光度,用来拍摄下高速运动的效果,这就是高速摄影(High-Speed Photography)。如下图所示。

相反的就是用很长的曝光时间和小光圈来拍摄,会产生拉丝的效果,实际上就是运动模糊,能拍摄出显现长时间积累的效果,这就是低速摄影 ,又叫延时摄影。如下图所示。

4.透镜

4.1 理想薄透镜

实际的 **镜(Lens)**是非常复杂的,包括相机和手机,它们都是用一组各种各样的透镜组来实现的。如下图所示。

还有一些透镜如下图,它一半是凸的一半是平的,也就是说它不可能把光聚到一块。我们这里讨论的是一种理想化的薄透 镜(Ideal Thin Lens)

关于理想薄透镜有几个性质,如下所示。

1.平行光穿过一定会被聚焦到一个点上,称为焦点

2.焦点到透镜中心的距离就叫做焦距,同时光路可逆也就意味着一个聚光从焦点发散打到透镜会被变成许多平行光。

3.我们认为这个薄透 镜的焦距是可以随时更改,但实际上薄透镜的焦距是已经固定了的,但是我们这里仍然人为它可以更改,因为我们近似的是相机的透镜组,相机的透镜组可以改变组合形式来改变焦距。

如下图所示。

除了上面的性质,还有一个性质就是,光线从透镜中心穿过不改变方向 。同时我们定义物体到透镜的距离 z0 (物距),成像到透镜的距离 zi (像距),焦距 f,就可以得出如下的规律等式关系。

推导过程如下。

首先找出两组相似三角形,可得出如下。

然后,将h0hi挪到一边,因为这两个值不知道,如下。

由此可得。

进一步推导后,得到结果。如下所示。

通过这个薄透镜可以解释很多问题,不需要到实际的透镜组。接下来会介绍这些问题。

4.2 散焦模糊

散焦模糊(Defocus Blur) 可以解释景深 的问题,我们引入一个概念叫COC (Circle of Confusion ) 。所谓COC就是远处如果有一个平面Focal Plane ,这个平面所有的光通过透镜后会聚焦到一点(最锐利的成像平面),如果要拍摄的物体不在Focal Plane 上,如下图所示,物体在后面,那么这个物体就会模糊。因为物体的光通过透镜在成像平面前面就焦距了(薄透镜公式算出),而光线并不会停止前进,而是继续前进而发散,会在成像平面上形成一个圆,这个圆就是COC (Circle of Confusion )

COC的大小也很好计算,同样根据相似三角形得出下面的式子。如果我们固定这个值,我们会发现,COC的大小和透镜的直径大小A有关。

这也就告诉我们,大光圈会看到更模糊的图像,而小光圈的照片更清晰,如下图所示。

现在我们来明确一下光圈的F 数的明确定义,它是焦距/光圈的直径 ,和我们之前说的光圈直径的倒数有关系,但是它和焦距也有关系。如上图的 f/1.4f/22

以下是真实镜头常见的光圈值(F stops)。注意:f 值为2 有时写成 f/2

明确了F 数的定义,那么我们之前说COC大小和A 有关,而N 又等于f/A ,那我们也可以得出另外一个计算COC大小的式子,也就是把A 换成f/N 。也就是说COC和F数有一个反比关系。如下图所示。

4.3 薄透镜光线追踪

我们之前所说的Path Tracing实际上是默认了小孔成像的模型。而根据我们前面的介绍,我们知道光线是如何与透镜作用的,那我们自然可以模拟透镜去做渲染。如下图所示。

首先我们先定义一些关于透镜的参数,比如成像平面的大小,透镜的焦距,光圈的大小。然后规定透镜放到离场景中的某个平面的物距z0 。根据透镜公式,我们自然知道像距zi。如下图所示。

那么,这样就可以进行Path Tracing的操作了。

先在成像平面上个找一点 x' ,然后在透镜上找一点x'' ,根据公式我们就知道,这条经过透镜的光线会打到哪一个点 x''' ,然后我们连线 x''x''' ,得到它的Radiance,最后记录在**x'**上就可以了。

4.4 景深

COC会导致模糊,也就是大光圈会导致大的COC,也就会更模糊,但是总有一些地方是不模糊的,模糊有一个范围,那么怎么定义这个范围呢?这就需要景深(Depth of Field )

在拍摄的物体前后有一段深度,它相应的在成像平面附近也会形成一片区域,这片区域的COC足够小,小到和我们成像的像素差不多,也就是我们看上去是清晰的不模糊的,那么物体前后那段深度就叫做景深。如下图所示。

景深的计算公式推导如下。

5.光场

5.1 我们看到的是什么

如上图所示,人从房间向窗户外面看过去,能够看到右图所示的2D画面。

那么,如果在房间中间放块幕布,这块幕布能够严格模拟看到的光线从一点到另一点的强度。然后,让这块幕布完全显示出刚才看到的画面,这时候人从看过去完全体会不到与真实世界有区别的,就好像在真正房间里看向窗户外面。因为人眼接收的光没有发生任何变化,这就是虚拟现实的原理。如下图所示。

所以我们看到的东西实际上就是光线,我们的眼睛并不关心光线从多远进来或者从什么地方进来。

5.2 全光函数

全光函数(The Plenoptic Function) 用来描述我们看到的所有东西。它是怎么做的呢?我们先从简单的开始说起,假设我们的函数现在是定义了我们在某一个位置往任何方向看到的东西,那么我们可以用P(θ,Φ),用一个球的极坐标表示任何一个方向,我们当然可以定义这么一个函数。如下图所示。

接下来加入一个变量 λ ,它表示波长,也就是颜色信息,那我们就能看到彩色的东西了,于是我们的函数变成了P(θ,Φ,λ) ,我们再加入时间 t ,我们的函数就变成了P(θ,Φ,λ,t) ,引入时间 t之后等于我们能看到动态的东西了,之前我们只能看到静帧,现在我们能看到动画/电影,也就是可以动的画面。如下图所示。

最后再拓展一个三维空间中的坐标,代表人可以在空间中任何位置朝任何方向看,那也就变成了全息电影,于是函数就变成了P(θ,Φ,λ,t,Vx,Vy,Vz)。如下图所示。

最终我们就得到了这么一个函数,它可以让我们在任何位置朝任何方向在任何时间看不同的颜色,而这就是我们看到的所有东西,一个七个维度的函数,这个七维的函数就是全光函数

可以从全光函数中提取一部分信息,用来表示更复杂的光。就是在一个点往任何一个方向看,记录了来自各个方向光的信息,所谓**光场(Light Field / Lumigraph)**就是记录稍微多一些,那么光场就是全光函数的一个小部分。

5.3 光场的定义

5.3.1 光线

定义光场之前,我们先来定义一下光线 ,就是一个起点一个方向 ,一个起点**(Vx,Vy,Vz)** 。一个方向**(θ** ,Φ)。如下图所示。

当然不止只有一种定义光线的方式,还有其他办法。如下图所示,我们用两个点来定义一根光线,当然前提是我们知道方向正负。

5.3.2 光场

对于我们看到的任何一个物体,我们都可以理解为它在一个包围盒里,那我们在任何位置的任何方向都能看到这个物体。又因为光路是可逆的,想要描述这个物体被看到的所有情况,就是可以表示物体在包围盒上在任何位置往任何方向的光线。把这个事情描述清楚,就可以得到从任何一个位置看向这个物体应该是什么样的。如下图所示。

当我们看向物体,包围盒上一个点,观测位置一个点,两个点确定一条光线,又知道方向,这样就可以查询记录的函数。这个函数记录的正是这个物体的任意一个位置朝各个方向发出光的强度 ,而这就是我们描述的光场

光场 正是全光函数 的一小部分,因为它只有二维的位置二维的方向 。二维的位置指的是物体表面的坐标**(u,v)** ,二维的方向指的是**(θ,Φ)**。

如果我们有了如下图所示一个物体的光场,我们从任意一个位置往物体光场上去看(紫色线),都可以知道看到的什么,这就是光场的好处。

通过一个四维的光场,我们完全可以描述我们在任何位置看到物体表面的任何光的信息,我们之前说的包围盒就是这个意思,我们可以想象用一个黑盒把物体包起来,通过我们之前记录的光场,我们完全不需要知道里面的物体是什么,这和我们一开始说的幕布是一个意思。如下图所示。

1. 这种方式也可以这样理解:如果想描述一个光场,我们只需要给定一个平面,平面右边是发光的物体,发出的光穿过平面,我们只需要知道平面左边是什么就可以。也就是对于平面上任何一个点,知道任意一个方向就可以了 。这也符合我们之前说的第一种光线的定义,给一个点**(u,v)** 和一个方向**(θ,Φ)**。如下图所示。

**2.**那么我们也可以用第二种光线的定义来描述一个光场,我们用两个点,那也就是两个平面,两个平面上各自取一个点,就能确定一条光线,因为我们已经知道了光线一定是朝外的。如下图所示。

两个平面的坐标分别用**(u,v)** 和**(s,t)** 表示,我们发现这并没有本质的区别,因为它们都是四维的,这是个经典的参数化表示方法。如下图所示。

我们对刚才的两个平面定义的光场有两种不同的理解形式。

第一种情况,我们在**(u,v)** 上取不同的坐标,看向**(s,t)**平面,这也就相当于我们不固定盯着物体的某一个点看,就像相机一样,我们举到哪里相机就拍到哪里,然后我们从各个不同的角度去看向这个物体。如下图所示。

第二种情况,从**(s,t)** 平面的不同位置看向**(u,v)** 平面,或者说从**(u,v)** 平面一侧的不同方向看向**(s,t)**平面的某个位置,这就相当于我们看物体只盯着物体的某一个点看,即使我们移动了位置,但是我们就盯着那一个固定的点看。如下图所示。

当然上面说的只是一种通俗的理解,自然界中的确有从**(s,t)** 平面看向**(u,v)** 平面的例子,就是苍蝇的复眼。复眼的结构非常复杂,它们由许多独立的更小的眼睛组成,这就好像有一个摄像机矩阵一样,每个复眼将不同方向的光分开记录到不同的位置,如下图左图所示。而这种情况下我们看向一个像素,我们看到的实际是许多的Radiance 而不再是Irradiance了。

5.4 光场相机

光场相机 (Light Field Camera) 就是利用前面提到的光场原理,它把每个像素都替换成了透镜(微透镜),这个透镜可以把来至不同方向的光分开,然后记录下来,每个像素存储Radiance。如下左图所示。右图是拍摄的原始照片。

最重要的功能是**支持后期重新调整聚焦,**就是先拍照,然后再考虑聚焦或者其他。如下图所示,就是光场相机。

我们拍摄完一张光场照片后,如果想恢复原来的普通照片该怎么做?很简单,只需在每个微透镜上都取来自同一方向的光即可。如下图所示,每个透镜选一个方向的光线,这就好像相机放某个位置向这个方向去照。

如果每个透镜选中间方向的光线,那相机就好像放在中间位置往左边方向照。这就说明有了这个光场之后,就可以虚拟移动相机的位置。也就是说光场相机从一个角度和位置就可以拍摄出许多不同角度和位置的照片。因为光场相机记录整个光场的信息,而整个光场就是进入相机的所有信息,包括位置和方向。

缺点:光场相机通常有分辨率不足的问题。因为原本一个像素记录一个像素的信息,现在需要用更多的像素(微透镜)记录一个像素的信息,因为方向被分开了。也就是原本胶片的分辨率变成原本照片的分辨率乘以方向上的分辨率,方向上分配的像素多,那原本照片的分辨率就低了。所以对胶片的分辨率非常高,微透镜也是十分精密的器件,生产起来成本很高,所以光场相机的成本自然也很高。

由此得到一个体会:如果要记录更精密的方向信息,比如10*10不够,要100*100,这样位置信息就会丢失的更多(留给记录位置的像素就更少了)。所以整个计算机图形学就是关于各方面的权衡。

相关推荐
refineiks20 小时前
three.js使用3DTilesRendererJS加载3d tiles数据
前端·3d·图形渲染·webgl
Padid1 天前
文章-深入GPU硬件架构及运行机制 学习后记
笔记·学习·硬件架构·图形渲染·着色器
Padid4 天前
OpenGL GLFW OIT 实现
c++·笔记·学习·图形渲染·着色器
玖er悠4 天前
Unity Shader实现简单的各向异性渲染(采用各向异性形式的GGX分布)
unity·图形渲染
米芝鱼7 天前
UnityShader自定义属性特性
开发语言·游戏·unity·游戏引擎·图形渲染·着色器
米芝鱼8 天前
UnityShaderGraph 卡通水面效果
游戏·unity·游戏引擎·图形渲染·着色器
知心宝贝8 天前
【小程序 - 大智慧】深入微信小程序的核心原理
开发语言·javascript·算法·微信小程序·小程序·前端框架·图形渲染
2401_856652218 天前
高清无损!探索PDF转JPG的最佳实践工具
图像处理·学习·自然语言处理·pdf·图形渲染
是jin奥11 天前
Ubuntu 搭建 GLFW 环境及其相关测试 demo
linux·ubuntu·图形渲染
3DCAT实时渲染云14 天前
视频云流化与PaaS平台解决方案详细介绍
云计算·图形渲染