程序员的数学游戏-图形学篇

注意:非教科书内容,拿这里的定义去考试的话会挂科的哦!

状态:草稿


目录

  • 图形与图像
  • 色彩空间
  • 仿射变换
  • 表面渲染
  • 体积渲染
  • 反失真
  • 特效

第一节 图形与图像

基本概念

先用简单的一句话对两个概念做个简单宽泛的描述:

图形:对几何形体的数学描述。

图像:对空间的离散数据阵列形式的描述。

一个比较直观的理解方式就是把图形理解成矢量图,图像理解成位图。

举个例子:

我们来表达一个线段

图形描述可能是:

{"type":"segment","factors":{"begin":[0,0], "end":[2,2]}}

图像描述的方式则是:

[[1,0,0],[0,1,0],[0,0,1]]

当然这个二维数组也可以直接用图片来表示(也许更多人喜欢反过来说,图片可以用二维数组来表示),就是这个样子:

图的显示

对于大部分程序员来说图像要比图形接触的频率高得多,因为我们每天面对的电脑显示器都是基于像素阵列去展示的,当你趴在显示器或者电视机前仔细看的时候,你可能会看到类似这种细节:

(该图来自于网络,如有侵权请与我联系)

当然随着显示器的像素密度(PPI)越来越高,很多设备的像素点已经不是肉眼可以直接看到的了。但是不管你看到或者看不到,像素点就在那里。。。

当然凡事总有例外,并非所有的显示设备都是基于像素的。比如这家伙:

(该图来自于网络,如有侵权请与我联系)

示波器,通过X及Y方向上施加的连续的偏转电场,让粒子束画出连续的曲线。

有些人自然会问:既然不是基于像素阵列,那么是基于图形?

呃……其实我也没说图形和图像是非此即彼的关系,图像也可以精确的描述部分几何形体嘛。

不过既然抛出了这个问题,那么我们还是试着描述一下:

示波器画出的东西可以表达成:
P(t) = (X(t), Y(t))
其中P(t)是时刻t描绘的点,X(t)和Y(t)分别是两个连续的输入信号

对图片里的示波器来说X(t)是模拟电路产生的扫描电压,Y(t)是红线和黑线之间的交流电压。

爱找茬的读者又问了,可是这个式子只是表述了位置和时间的关系,并不是静态的图啊。嗯……给你点提示自己动动脑子吧。

小练习:
假设电子束打出的是半径为r的圆点,打出的点残留时间是d,请从数学上描绘时刻T显示屏上的图形/图像。

回到显示设备的话题上,刚才讨论的话题其实是随机扫描显示器(random-scan display)(示波器一类)和光栅扫描显示器(raster-scan display)(普通显示器一类)的对比,感兴趣请自行搜索。

现在我们接触的大部分2D显示设备都是光栅扫描显示器了,所以我们后面的章节没有意外的话就不再提及其他类型的显示设备了。

等等,为什么说2D呢?因为在一些空气投影设备上我又看到了随机扫描的身影。因为从2D到3D的拓展意味着像素数量又高了几个量级,在硬件性能还没有跟上的时候,随机扫描更擅长于平滑的描绘简单图形。

设计师的需要

对于不专门搞像素风格的设计师们来说,他们很多时候更偏爱使用图形。他们会说:

  • 左侧1/6区域用作菜单
  • 右上角放一个1cm*3cm的红色按钮
  • 底部展示一个半径2cm的球形气泡

(是的,我刻意使用cm而不是px作为单位,因为像素其实通常并不是真正关注的因素)

那么问题来了,我们需要将设计师定义的图形描述转换成显示器可以展示的图像。这个时候我们终于聊到了计算机图形学的重头戏:渲染(rendering)

渲染:根据模型生成图像的过程。

这里说模型而不是图形是因为我们生成图像时通常除了需要定义好几何形状和颜色外,还需要材质、光照等等其他参数,我们后面的小节里会详细讨论。


第二节 色彩空间

在讨论渲染之前我们先来聊聊色彩。

色彩:空间无关的视觉感知属性。

首先,这个定义是我自己瞎写的。你可以去各种词典和教科书上找到各种官方的定义。不过在这里我们做个这样简单的定义也无妨。

好的,让我们来复习一下基本的物理学和生物知识,复习完这一节的内容也就基本讲清楚了。

光即电磁辐射,通常特指可见光(即波长约400–700纳米,在人类视网膜感知范围内的电磁辐射),具有显著的波粒二象性。电磁波是横波。

宏观上,光在真空及均匀介质中沿直线传播,在不同介质表面会发生反射,散射与偏折;在非均匀介质中的传播路径请自行解波动方程;在各种情形下非发散性的光路可逆。再次强调,只是宏观近似。

光的最小单位是光子,速度的大小恒定为介质中的光速,无静止质量但具有动量及能量,且能量与频率成正比,不同频率、不同偏振方向的光在介质中的传播速度不同,而折射率与光速成反比,因而会发生色散。光的偏振属性还影响光在介质中及介质表面的传播路径及透射比例,一些介质(如液晶)可以改变光的偏振方向。

上面已经比较全面地描述的光本身的行为,如果理解上有困难,那就只理解下划线部分吧,不钻研相关领域也还是基本够用的。

视网膜与视觉

光作用于视网膜上产生神经冲动,并传导到大脑产生视觉,其中与空间无关的部分就是色彩。

大部分人的视网膜上主要包含两类(四种)视觉相关细胞:视杆细胞和三种视锥细胞(分别对不同频率的光线有不同的敏感度),且在视网膜上的分布非均匀分布(视锥细胞更集中于视力轴线中央附近)。(你或许还知道视网膜上的其他类型的细胞,不过那些和我的话题关系不大,就不作讨论了)

另外人眼有个bug:盲点。其实就是视神经穿过视网膜的一个洞,没体会过的朋友可以自行实验一下。

取一张白纸,左右画上两个足够清晰的黑点(推荐间隔7cm以上);
遮住自己的左(或右)眼;
用右(左)眼盯着左(右)侧的黑点;
调整纸到眼睛的距离,在某个距离上你会发现另一个黑点消失了。

 

这个实验可以让你直观的感知到视觉盲点的位置。

但更重要的是,你要注意到,当盲点区域内的光线无法被视网膜感知时,大脑内的视觉图像仍然是完整的。你仍然认为纸是完整、可见的(而不是破损的或者部分消失的),而盲区内就是纯白色,并没有被画上黑点。

进一步的(这里每个人的感觉可能不同),当我用一支笔贴着纸慢慢横穿视觉盲区时,一开始我会感觉到笔尖的消失,但是当笔尖通过盲区以后,我忽然间就感觉自己看到了完整的笔,而处在盲区内的部分笔身也并没有消失。是的,大脑将消失的部分补全了,而且在不仔细观察的情况下完全感知不到任何异样。

是的,大脑的视觉中枢对自己进行了欺骗。不过没什么好奇怪的,在多媒体领域我最喜欢说的一句话就是:

多媒体技术就是欺骗感官的艺术。

让我们把话题再带回到我们的色彩吧。

如果你研究使用的显示设备视角不够宽,或者你涉及的不是昏暗的恐怖题材,那么让我们也暂时忘记擅长感受弱光的视杆细胞吧。这样我们终于回到了由三种视锥细胞所衍生出的三原色的色彩空间。

三种视锥细胞最为敏感的颜色分别为红色、绿色和蓝色,这也是通常显示器中三种光源的颜色。

于是很多地方就对颜色给出了这样简单的说法:

任意颜色可以用(R,G,B)三元组来描述。

这种说法并没有什么的错误,但是往往我们在接受这件事情时容易忽略一些细节。

首先我们脑海中应该有两个三元组,一个代表大部分显示器上三种光源的强度,我们记为:

另一个代表人眼同一区域内三种感知色彩的视细胞所受到的刺激强度,我们记为:

如果你脑中自然地认为C=c,那么你犯了一些小错误。

首先这两个量的单位根本不同,直接划等号本身就不合适。其次,即使我们忽略了单位,那么光源强度和刺激程度也很难严格保持线性关系,所以你至少应该想到这样的关系:

在有限的范围内线性近似往往是好用的,那么我们干脆简化成这样:

 

如果你再耍些数学把戏,给R、G、B分别定义不同系数的单位,可以刚好把三个系数a统一,变成C=a·c;甚至你可以令a=1,那么我们又回到了C=c。

虽然回到了原点,但是我们至少在过程中明确地意识到我们的描述是在有限范围内的、近似的和包含了一些“数学把戏”的。

在你开始庆幸原先的理解只是小小的偏差前,让我们再泼一次冷水:上面的模型对事实的描述仍然忽略着重要的细节。

试想在你得显示器上显示一个纯色(r,0,0),那么你眼睛接收到的刺激是什么?

(ar·r,0,0)?不对。

(fr(r),0,0)?仍然没有说道重点。

重点其实在于后面的两个0,(frR(r),frG(r),frB(r))是一个不错的答案。

为什么我明明是红光,视神经却同时收到了另外两种信号呢?首先我们的显示设备所用光源并非完全的单色光源,即使你输入的数字信号是(r,0,0),但他输出的频谱却不是漂亮的尖刺,比如LED显示器的频谱可能是这样:

(该图来自于网络,如有侵权请与我联系)

最终频谱的尖锐程度也从一方面影响了显示设备效果的好坏,比如饱和度。

但是,即使我们的显示设备真的采用了单色光源,我们仍然无法感知到C=(R,0,0)形式的单纯的色彩,因为视细胞所能接收的频率范围仍然是有交叠的:

(该图来自于网络,如有侵权请与我联系)

好了,既然我们的眼睛已然如此,那么我们就坦然接收这个事实吧。

继续前请思考:色彩感知的公式现在变成了什么样子?

嗯,应该是这样:

唉?和你想像的有出入吗?对,我用了R=fR(r,g,b) 而不是R=frR(r)+fgR(g)+fbR(b),没人说过三种光源对同一种视细胞的刺激是可以直接叠加的。虽然没有去查阅科学证据,为了让我们的讨论简化到可以进行下去,我们姑且假设他们是可叠加的吧。这样,式子就变成了很多人首先想到的形式:

在继续做一次前面的线性假设,就变成了C=A·c;其中,A为矩阵:

在需要进一步简化模型的时候,可以认为矩阵对角线元素明显大于(或许还够不上数学里习惯称之为“远大于”的程度)其他元素,那么干脆把非对角线元素都置为0吧。这样我们又回到了前面的形式:

因而可以同样进一步简化成C=c。

好了,现在我们可以继续使用C=c的模型讨论问题了。但是如果当你某天发现这个模型无法处理实际的情况,希望你还记得起刚刚我们做了多少的近似、假设、简化与省略。

色彩空间

 如前所述,人类视觉的色彩可以用一个三元组(R,G,B)来表示,其中R、G、B均为非负数,即可以映射到三维空间中的一个象限。

用于描述色彩的坐标系统,我们称之为色彩模型。
色彩模型所能表述的色彩集合,我们称之为色彩空间。

 正像一个平面空间可以用直角坐标系或者极坐标系等不同方式去描述,色彩空间也有不同的表述形式,他们也分别有自己的长处。比如RGB模型更易于显示器的显示,CMYK模型更易于应用于印刷,HSV和HSL模型更易于描述人的视觉感受。

在规定不同色彩模型之间的色彩坐标转换时会发现,不同模型所能表述的色彩空间并不完全相同。即使同样是RGB模型,当我们定义从显示器坐标到视细胞坐标的转换时就会发现,视细胞坐标中的(1,0,0)在显示器坐标中是找不到对应的。(前文已经提及)

继续前请思考:色彩空间仅仅是三维吗?

如果从人类的视觉本身来看这个问题,三维够用了。但是如果不局限于我们开头对色彩的定义,可能就有另一番答案了。

反过来想想,是什么触发了一小块视网膜区域的色觉呢?是一束光线。注意是一束而不是单个光子,这就意味着你不应用单一频率来描述这些光线,取而代之的应该是一个频率分布曲线,也就是常常提到的频谱。一旦以频谱去定义物理上的光线颜色,你就会发现它的颜色是无限多维的。只不过几乎任何观察设备都只能对其降维后再进行观察和存储(这里我们不讨论全息之类的例外情况),人眼降到三维,黑白相机降到一维,自然也有其他设备降到四维、五维或更高。

还有一个值得关注的色彩模型是单色光的模型,只有频率和亮度两个维度即可描述。它转换到其他色彩模型中通常会对应一个曲面,如果你的图形学实践是单色光相关的领域,你可能会更直观和细致地了解这个曲面的样子。


 

第三节 仿射变换

说到图形学里的数学,首先想到应该就的是仿射变换。

有些人把常用的仿射变换公式都倒背如流了,却仍然不知道仿射变换本身的定义。说明这个概念本身有点晦涩,也说明这个概念就算不理解也没什么大问题。

仿射变换:仿射空间之间保持共线关系的映射。

仿射空间:。。。尴尬了,理一理才发现从头开始定义这个概念需要引入一堆其他概念,以后单独放在抽象代数与形式化篇来讲吧~

对于图形学来说,仿射变换的定义更多时候会使用这个简化版本:

仿射变换:直角坐标系中的线性变换。

一维空间上的仿射变换

一维空间可以直观的想想成一条线,一条线有什么好变换的!虽然上来就开始自我吐槽了,但是我们要先从最简单的情况说起。人们往往更乐于去学习常用的、直观的、甚至应试的东西,但是请不要护士。一维空间上的点用一维坐标表示(x0),

 


 

第四节 表面渲染

 


 

第五节 体积渲染

 


 

第六节 反失真

 


 

第七节 特效

 


 

未完待续。。。

posted @ 2016-11-19 20:52  rainforwind  阅读(1199)  评论(0编辑  收藏  举报