在《图片是怎么画到屏幕上的?》一文里,我们把图片想象成一个围棋盘,棋盘上每个格子都有自己的颜色,而颜色是可以表达成三个数字的,所以图片最终被表达成一系列的数值。在绘制图片的时候,游戏会把图片的数值告诉屏幕,屏幕根据这些数值把这张图片绘制出来。
这篇文章说说3D模型是怎么表达成一系列数值的,以及怎么把这些数值告诉屏幕,从而实现3D模型的绘制。
先以《水果忍者》里的西瓜为例说下什么是3D模型。
假设我们到水果摊上买了一个西瓜(真正能吃的西瓜),完了拿一根针在西瓜皮上戳洞,每戳一下,相当于在西瓜表面上挑选一个点,戳了一个小时后,我们得到了成百上千的点,然后我们再耐着性子,把邻近的点用直线连起来,使它们之间形成一个个的小三角形,等把全部点连完,我们就大功告成了。这些戳出来的点叫做3D模型的顶点,它们之间的直线叫做3D模型的边,而那些三角形叫做3D模型的面。这些点、边、面一起构成了一个非常复杂的多面体,这就是西瓜的几何模型。大家看看下边这个海豚的模型就会有个直观的感受。
显然,戳出来的点越多,多面体的面就会越多,整个模型也就越贴近真实的西瓜。如果你还记得《声音是如何播放出来的?》一文里所提到的数字信号的采样过程,你会发现,这个血腥残忍的西瓜戳洞过程其实就相当于对西瓜表面位置信息的一次采样,采样率越高,模型自然就越真实。
现在,我们得记录下每个点的位置以及每个面的颜色。点的位置容易理解,面的颜色得解释一下。出于简单考虑,我们定一个规则:如果这个面的三个点都戳在了黑色瓜纹上,我们就把这个面定成黑色,否则我们把它定成绿色。记录好后,我们就得到了这个西瓜模型的数值表述:这里面不仅有几何位置,还有颜色。
接着,我们说说怎么把3D模型画到屏幕上。我们依然可以把这个绘制的过程看做是给屏幕上的每个像素格子赋予一个颜色值的过程,只不过如今赋值的方式会稍微复杂一些。
我们把西瓜的模型放在屏幕后方的某个地方,然后在屏幕前方选一个点,这个点叫做焦点(下图中蓝色的点)。我们知道两点可以决定一条直线,因此屏幕上的每个像素格子都可以和这个焦点一起,决定一条直线,如果这条直线和西瓜模型的某个面相交了,我们就把这个面的颜色(绿色或黑色)赋值给这个像素格子;如果这条直线没有和西瓜模型相交,我们就把背景的颜色(比如灰色)赋值给这个像素。这样,等所有像素格子都扫过一遍,我们就画出一个灰色背景下的西瓜了。
在《水果忍者》里,一个西瓜飞上来的时候,它除了飞行以外,还在翻滚。每一帧,游戏都得根据它的物理规则,计算出模型上的每个顶点的位置,然后按照上面所说的方法把模型渲染出来。由于每一帧都需要重新渲染,所以我们说这个3D模型是通过即时渲染的方式绘制出来的。
最后得特别说明一下,本文并不是在叙述具体的建模过程,实际上从原画、建模到贴图、动作是一个十分繁复的流程;而渲染时除了位置和颜色外,还涉及到材质、光源等许多因素。跟本系列的其它文章一样,本文还是希望以易读为目的,不周全之处大家见谅。
下一篇《再谈游戏状态的改变》