2 三维绘图:Rendering Rendering,Render,这两个单字实在有太多的中文翻译,有称之为算图、绘制、着色演算...等许许多多说法,所以我倾向使用原文来说明。Render的原义指的是「表现、表演、绘制」等等许多意思,意即是如何表现出一个主题的过程。而在3D绘图中我们理解为「由Scene投影到screen,决定颜色」的过程。在3DComputer Graphics领域中的两个主题:Modeling与Rendering,分别是决定了从虚拟的场景概念到Vertex与Mesh,以及从Vertex与Mesh到屏幕上的pixel color这两个阶段。
2.1 那么,怎么做Rendering呢?
第一种技术,很直觉的我们想到仿真眼睛的投影模式。因为有光进入眼睛所以产生了颜色,这个光是符合光学理论,随着各种反射、折射、散射,经过了各种物体的吸收、反射等等过程,最后进入我们的眼睛。于是我们反过来看,当我要计算屏幕上一个点的颜色时,从投影点(Camera)连到该像素的位置,成为一个向量(vector)。记得吗?在上一篇我们提到已知投影点的位置,也就是在空间坐标系中的坐标、以及一个在空间中抽像的投影矩形(事实上它就是近平面near),也就是对应到屏幕的矩形。根据两者我们便知道在空间坐标系中,从投影点到像素的向量,我们把这个称作一条Ray。
延着这条Ray看过去,直到撞到一个物体--我并不打算在「浅论」中谈论过多的数学方法,因此我会省略大部份的演算而只讲一个概念,虽然只提概念会有些事情没办法解释得清楚,但我会尽量说明。
当视线(ray)撞到一个物体的某个面,这个面对于光会有许多种属性反应,这些数据或者记录在形成这个面的三个Vertex上,或者记录在其他全局变量里。总而言之,我们可以知道被视线(ray)所撞到的这个面,会使得ray产生怎么样的变化。我们从法向量(Normal)算出反射与折射,于是得到了新的ray,再度沿着这些新的ray走下去。
因此我们提到的这个Rendering方式,概念上就是沿着光线到达投影面上的点的路径反推回去,根据一路上碰到的物体或光源来得知该点的颜色。
这个方法就是所谓的Ray-tracing。
第二个技术稍微复杂一点,称作Radiosity,这是一个基于辐射的光照算法。首先,将每个surface分解为patch(因为计算上的理由,要将较大的surface分解为具有固定的max-size的patch)。每个patch都有一个光照图(lightmap)来表示patch上光照的分布。接着根据环境光源来设定每个patch上的光照初始值,接着进行1. 从每个patch上的光照值算出应该辐射出去的光照,搜寻过所有从这个patch可见的其他patch,根据这个patch辐射出的光照值来计算其他patch会接收到的新光照值 . 2. 若是某个patch需要辐射的能量小于某个事先定下的threshold(不设threshold的话,这算法会跑不完),则这个patch就不用再运算下去。否则,重复第一步骤直到所有patch应该辐射的能量都小于threshold。 从概念上来说,Radiosity算法,就是实际的计算光源对于整个场景的影响,计算出整个场景的光照之后再根据算好的光影效果绘制到画面上。在这里绘制的方法一样是类似ray-tracing,从每个pixel对应的ray去检查究竟看到的是场景中的哪个面。差别是不用再沿着反射ray或折射ray追踪下去,因为光照的效果已经由Radiosity计算好了。
第三个技术,称作Rasterizing(光栅化)。Rasterize指的是由Vector graphics(向量图形)转换为Raster graphics(光栅图形)的过程。 首先我们来了解这两个名词:所谓的光栅图形,就是由像素(Pixel)紧密排列形成的图形,也就是我们在屏幕上看到的形式,所谓的「位图」。而向量图形,是由几何模型(Geometry Model)所组成的图形。
举例来说,在白色画面上有一个红色的圆。光栅图形的表现方式就是用红色与白色的像素排列出一个圆形,而向量图形的表现方式是决定圆心、半径、圆的颜色,来表示一个圆。而我们之前所提到的Vertex与Mesh这个结构,便是一种向量图形。但是这个向量图形中只有点、线与三角形三种基本的Geometry Model。因此我们要以光栅图形显示在屏幕上时,便要对向量图形进行光栅化(Rasterizing)来得到光栅图形。
Rasterizing的实作方法,最简单的方式是scan-line,也就是对一个投影在平面上的三角形,水平检查每个像素点来决定它是在三角形内,或者是三角形外。然后将三角形内的点都涂上三角形该有的颜色--这当然是很简化的说法,在之后讨论3D pipeline时会有更进一步的说明。
|