【图形学与游戏编程】开发笔记-入门篇1:3D游戏是怎样炼成的

(本系列文章由pancy12138编写,转载请注明出处:http://blog.csdn.net/pancy12138)

这是我在csdn上发的第一篇博客,因为在大学一直在学习图形学,directx以及opengl相关的知识,也写过一些简易的游戏引擎和游戏神马的,中间也遇到了很多的困难。在这里我打算来开一个版块来从最基础的部分开始讲解怎么利用C++,图形学,图形API来编写3D游戏所需要的各种效果,因为我也算是边学边写,所以难免会有一些错误,大家在实践的时候如果发现了bug以及错误神马的.....可以多靠自己的努力去修缮(修缮完了记得给我说一下就好deth大笑,是不是显得我太懒了)。目前我想在以后的文章里用到的API应该是以directx11为主的,然后参考书目就是第四版的龙书吧,当然喜欢openGL的同学也可以来看看,我也会尽量提及到每一种技术的opengl下的实现思路的。

好了接下来就是正文,我想能来看这个博客的应该都是计算机或者软件方向的学生吧,或者对这方面感兴趣并且有一定程序基础的学生。首先我们来谈谈当年为什么会选择区学习计算机呢,我想大部分人应该不会是因为诸如“我就是以后要做云计算,大数据的研究”或者“我要成为优秀的前端/后端工程师”,亦或是“我要成为一个伟大的嵌入式工程师”一类的原因而选的这个方向生气。所以根据老衲多年的经验(雾),大家如果大学里选了计算机这个专业的话,那么大部分人估计是因为下面的这些原因:

中二少年1号:“我从小玩游戏玩到大的,以后学了计算机.....下一个魔兽肯定就是我开发的,以后肯定吊炸天羡慕”。

中二少年2号:“我这以后学了计算机成了黑客是不是就能想黑谁的机子就黑谁的机子,想要什么来什么......这个技能太酷炫了羡慕”。

中二少年3号:“学计算机嘛,以后工作就是坐着空调房,手捧笔记本,边工作边玩游戏.....肯定是个清闲的工作羡慕”。

...

中二少年n号:“..............”。

这些理由是不是看上去靠谱多了生气,当然.....我就属于中二少年一号的类型,那么等我们进入大学之后呢.....就开始第一次接触编程了(当然,高中就接触oi竞赛的或者其他原因提前就会编程的不算,我就在高中的时候参加过学校的高中程序竞赛培训,学过一段时间的编程)。大家会第一次看到自己写的c语言程序在黑框框里面成功的运行,然后打印出类似于“hello world”的东西。之后就是大一各种各样的基础课......如果你属于勤加练习的那部分人的话,你会很快的熟悉c语言这个神奇的东西,你会发现这个黑框框可以帮你解题,可以帮你处理文件,可以帮你干很多很多跟数学有关系的事情。接下来就是各个学校都在学习的数据结构与算法了。如果你这个时候依然属于勤加练习的那一部分人的话,经过大量的训练你会了解很多算法,数据结构,开始了解时间复杂度,树,图,快排,搜索,dp等常见的问题解决方案。然后这个时候你可能就会开始思索,如何才能跳出黑框框,编一个带图形界面的小游戏呢,即便是最简单的扫雷,连连看好歹也算是有个画面了.....于是这个时候你可能会开始了解到MFC,C# winform,java一类的拖控件编程机制。一旦发现了这块新大陆,你会发现虽然现在你只会一些简单的语法和一些数据结构啊算法啊的知识,但是仿写一个扫雷或者连连看这些2D的游戏似乎是一件很容易的事情,于是你带着极大的兴趣开始拖控件,写代码,完成了几个简易的2D游戏。看上去似乎一切都很圆满。这个时候你估计就开始思索了,既然2D游戏这么容易就写出来了,那是不是应该仿写一个简单的3D游戏试试。然后.....你就发现,似乎这件事情没有之前写2D游戏那么容易了,因为此时的你面对的是一大堆的疑问,诸如:

1,2D游戏把人物,景物等等资源都是存在图片里面的,那3D游戏也是这么存储的吗,如果是的话那我得要多少图片才能存完?

2,2D游戏里面的东西如果要移动的话,改变图片的屏幕坐标xy就好了。但是3D游戏里面的东西如果移动的话,屏幕坐标怎么改,图片怎么移?

这些问题如果你在之前没有学过图形学的话,一般来说是很难自己凭空想出来一些解决方案的,那么接下来就是本篇文章的重点部分了,也就是我们这篇文章的标题《3D游戏是怎样炼成的》(你猜的没错,前面的话都是铺垫.....)。

首先,提到3D游戏设计,我们自然要提到渲染管线。那么神马是渲染管线呢?渲染管线就是一环套一环的几个算法,这些算法解决了上面困扰我们的一大堆问题,并且告诉计算机如何将一个3D场景建立并显示出来。没错,说起来就是这么简单,不过做起来确实是不容易,下面我们来将一套最基本的渲染管线算法是如何一步步绘制出3D游戏的。


3D游戏的目标是描述一个贴近真实的虚拟世界,并将它展示在屏幕上。首先我们怎么才能建立这个虚拟世界呢。在光栅图形学的算法里,我们将场景分解成一个个的物体,如人,动物,房子,车子。这一步和2D游戏是相似的。但是3D游戏使用“网格模型”这种数据结构来存储每一个物体,而不是使用“图片”来存储物体。神马是网格模型呢,很简单,比如说你要表示一个立方体,那么你需要存储立方体的八个顶点的坐标(x,y,z),以及每个面是由哪几个顶点按照什么顺序存起来的,这样开一个数组来存储所有的顶点,再开一个数组存储每个顶点之间的关系,你就存下了这个立方体。当然立方体的几何形状非常直观,因此很好描述。大部分几何形状不好描述的物体我们会使用一个网格来模拟它,比如下面这个崎岖的表面,我们就得用一个密密麻麻的网格来描述这个物体,然后将网格上的顶点以及顶点之间的关系存储在数组里面。


这样说起来场景的建立实际上就已经完成了,我相信大家现在肯定有疑问。我们用几何体和网格的概念来描述场景确实是非常不错的方法,但是这只是一种逻辑上的场景建立,这种存在两个数组里面的逻辑场景如何才能画到屏幕上呢?我们最终还是要告诉电脑哪个像素点绘制神马颜色的,这一大堆三维逻辑点显然是不能够用于绘制的。这个时候我们需要引入一个大家经常听说的词→投影。我们知道照相机可以把现实世界的东西绘制到照片上,这也就是说我们也可以借助类似的手段把之前存在于逻辑上的场景绘制到屏幕上,这一部分的知识我们会在之后正式讲解的时候提到,这里先说一个大概,我们虽然建立场景的时候用三维点和点之间的关系来模拟网格的形状最终建立起了一个逻辑上的场景,但是当这个场景建立完之后,我们可以依靠一个投影方程将这些点一一对应到屏幕上去,这样三维就变成了二维,我们就可以轻易的将其绘制在屏幕上了。当然虽然我说的很简单,但是这中间经过了至少三个过程,其一是T&L也就是几何变换与光照,其二就是投影,其三是光栅化,下面我们来简单的谈一下这三个过程中的一些新元素:

首先依然是之前的那个第二个问题,我们如何能让三维游戏里的元素“动”起来,现在有了前面我所介绍的知识之后大家肯定能很容易的解决这个问题了,要动起来的话,我们修改建模的时候的数组里面的三维顶点的信息,然后重新投影出来一张图片就好了。而修改逻辑顶点的位置的方法就叫做几何变换。也就是通过三个变换矩阵(平移,旋转,缩放)来快速修改每个顶点的位置信息。

接下来我们来谈光照,大家玩游戏的时候经常看到光照这个词,那么光照是做什么用的呢。这里我们说当投影完成之后,事实上我们得到的图片是一张如上图所示的网格图,那么接下来要面临的问题就是如何给这张图片上色。注意这里其实就跟我们绘画非常相似了,只不过绘画师依靠自己的经验来上色,而我们希望能够教会电脑根据一些固定的公式来上色,而这个公式就是对自然界的光照进行模拟。所以我们在这里提到的光照指的就是这个公式。具体的公式我们会在后面讲解的时候提到,这里我们先大概了解一下,具体的公式涉及到光源,光照类型,环境光等很多相关的知识。

最后我们再提一下光栅化,注意这一部分知识是大部分大学的图形学课本上介绍的最为详细的部分,但是事实上在我们编程的时候这一部分是为数不多的已经被硬件完全封装的一部分(其他的还有曲面细分部分,后面的文章会讲到),神马是光栅化呢,注意我们把网格投影到平面上的时候所得到的平面图片是一张矢量图,而光栅化的意思就是将这张矢量图光栅化成像素图,因为只有像素图才能被电脑屏幕所显示。当然这一部分虽说是被封装了,但是我们不能忘记他的存在,因为很多算法的优化会利用到这一点,像phong光照以及ssao用到的3D重建等。至于他是如何将矢量图光栅化的我们倒是可以不关心。不过大学的课本里介绍的比较详细,大家有兴趣可以看看那些画点,划线,填充等算法。

ok,这样我们就完全讲完了一个简单的3D渲染管线的知识,我想大家如果之前不知道一个3D游戏如何能用程序写出来的话,现在应该有一个比较清晰的思路了。如果能够让大家有这种感觉的话这篇文章的目的也算是达成了。不过思路归思路,具体到细节部分还是需要更多的知识的,如果你对这些知识感兴趣的话,请继续关注本系列博客,3q 米娜桑。

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值