Answers
大家都喜欢讨论次世代的技术,但是,有意义的讨论似乎不多。我觉得,这是因为玩家普遍缺乏技术背景知识的缘故。如果对基本的概念一知半解,不用说次时代了,恐怕就连SS、PS、N64等老式主机也不能有一个正确的了解。同时,也容易被一些业余的新闻所误导。
这里介绍基础的3D主机游戏的背景技术知识。基本可以弄懂世嘉土星的基本3D图形技术,并且学会分析机能;搞定ps,再到n64,dreamcast,再到ps2,再到本世代,日积月累,弄懂次世代也不是问题。
什么是3D模型?
我们都知道,3D游戏世界中的人物和物体都是3D模型(3D model)。我们肯定还都听说过,一个模型有多少多边形(Polygon)这种说法,比如gt5每辆车用了50万多边形之类的说法。那么,3D模型到底是什么?多边形的说法真的科学吗?
拿最简单的例子来说,我们要在游戏中显示一个立方体,该怎么办呢?
答案是:首先,游戏需要知道这个立方体的所有顶点(Vertex)。中学课本告诉我们,立方体有八个顶点。对应到三维坐标系中,我们可以如此描述一个多边形:
顶点1:(0, 0, 0)
顶点2:(1, 0,0)
顶点3:(1, 1, 0)
顶点4:(0, 1, 0)
顶点5:(0, 0, 1)
顶点6:(1, 0, 1)
顶点7:(1, 1, 1)
顶点8:(0, 1, 1)
现在大家思考一个问题,有了所有的顶点数据(Vertex data),就可以描述清楚一个物体了吗?
答案是否定的。因为,根据顶点之间连线的不同,它们可以组成完全不同的形状。
所以,游戏还需要知道顶点之间是怎么连接的。这就是索引数据(Index data)。
我们再把物体简化一下,我们要画一个其中的一面吧。根据小学课本,一个正方形有四个顶点。
顶点数据:
顶点1:(0, 0)
顶点2:(1, 0)
顶点3:(1, 1)
顶点4:(0, 1)
索引数据: 123 134
索引数据的意思就是:顶点123组成一个三角形,顶点134组成一个三角形。于是,我们就有了一个正方形。
不管是士官长也好,还是德雷克也好,他们的形状都是由这两套数据构成的。当然,复杂的物体,顶点数会非常多,成千上万个很正常。
现在我们再来思考一个问题,平常我们说的多边形到底是什么?看看上面的索引数据,3D模型明明是用三角形来描述的呀!
没错,三角形的数量才是描述一个3D模型复杂度的标准。显卡处理的是三角形,而不是多边形。据说,多边形是早期绘图软件所使用的标准,后来不知道为什么被沿用了而已。
那么,第一天的内容就结束了。明天我们来看一下,什么是贴图(Texture)?最后,我们来复习一下,3D模型由什么数据组成的?
如果想知道一些技术细节,可以去读一下这一篇:http://en.wikipedia.org/wiki/Triangle_strip
三天学会分析SS的3D机能。次世代不遥远。
贴图(Texture Mapping)
最近都在忙光照模型和动态光源呢,以后应该会讲到这一块。
今天要讲贴图了,这个词也是A9众常用的词,那么贴图到底是什么呢?
好,有了昨天的知识,我们就知道游戏里的物体究竟是什么了。比如说一个海豚,我们知道其实是长这样的:
但是,它没有皮肤呢。那怎么办呢?简单,蒙一张彩色的皮上去就可以了。
在游戏里面,这张皮,叫做纹理(Texture)。
我其实蛮讨厌这个译名的,它有点让人摸不着头脑。实际上它很简单,就是一张图片,跟常见的PNG、JPG图片没有本质区别。当然,具体的编码肯定不一样。
最常见的纹理是.dds文件,里面的编码是dxt1、dxt5等等,格式非常多,每一个都有特别的用途。
顺便一提,ps4推荐的格式是BC7。当然这还是dds文件了。这个BC7编码很强,质量非常高,图像的损失很小。
其实啊,现代的显卡其实可以允许你直接用png和jpg图片的,那我们为什么不用这些简单的格式呢?
那是因为,dds文件是为显卡量身定做的,显卡处理它们最高效了!
你可以想象一张图片,上面画了海豚的皮肤,我们把这张图片蒙上这个线框模型(Wire-frame model)就可以了。
不过,游戏怎么知道该怎么蒙?什么方向?什么位置?
这就需要一种新的数据了,叫做UV数据(UV data)。每一个顶点(Vertex),都会有一个对应的UV。
那么,UV数据到底是什么?长什么样?
不得不说,这些概念一个比一个简单,阿猫阿狗都会把。UV就是很普通的二维坐标。之所以叫uv,是因为xy已经被用掉了,所以就改叫uv了。还有的游戏或者引擎叫它st,那都是一个东西。
举个栗子:顶点1,要对应到纹理的左下角,那uv数据就是(0, 0)。顶点2,要对应到纹理的最中间,那uv数据就是(0.5, 0.5)。每一个顶点,都指定一个坐标就可以了。
聪明的玩家肯定要问,这只是顶点而已啊!那顶点之间的线呢?线和线之间的空间呢?
这些就是显卡的工作了,显卡会自动做插值运算(Interpolation)。
简单来说,你告诉显卡顶点怎么处理就行了,其它的点显卡都会自动计算。这张皮就能正确的蒙到海豚上去。
当然,插值运算(Interpolation)有很多种实现方式,这个非常重要,我们以后再细讲。
把皮蒙上去的过程,我们叫做UV Mapping,或者texture mapping。我个人认为,我们常说的贴图,指的就是texture mapping。贴图应当是一个动作,而不是一个名词。
好了,现在你们已经会初步分析SS的机能了!
最后,大家稍微复习一下:要完成贴图,需要哪几种数据呢?
实战SS机能分析:显存(Video Memory)
实战分析世嘉土星(Sega Saturn)的3D机能。
(注意,这里说的不是2D机能。SS的2D机能非常强!Saturn is a 2D monster!)
世嘉当年的宣传是,SS每秒可以处理20万个有纹理的多边形,或者50万个多边形。那么,事实真的是如此吗?
山内一典说过:“GT5的精细高模车用了50万个多边形”。这样的话,岂不是SS也可以描绘出那种精细的车体了?
想必大家已经有了第一印象:这不科学!
首先一个不科学的地方是,我们不知道他们说的多边形是几边型,这个我在第一天里也提到了。单位不同,如何比较?
还有,这里的时间单位是每秒,这也是很有误导意义的。这个多边形数和场景复杂度是不同的。
好吧,那我们退一步,给SS1秒钟(30-60帧),它可以描绘出如此精细的物体吗?
我们想一想,处理50万个多边形,需要什么条件?
- 显存可以装的下所需要的数据。(粮草)
- 3D图像处理器有能力及时处理这些数据。(兵力)
- 数据传输速度足够快,保证不拖图像处理器的后腿。(运输队)
要想打赢一场仗,粮草、运输队和兵力,缺一不可。
今天,我们先来看看SS有没有足够的粮草。
大家复习一下前几课的内容,游戏中的物体和场景是由哪些基本数据组成的?
顶点数据(Vertex Data)
索引数据(Index Data)
UV数据(UV Data)
纹理(Texture)
这里,我们需要记住一个重要的事实:以上数据,在游戏运行中,一定是在显存(Video Memory)里的。
什么是显存呢?显存就算显卡专用的存储器。在传统游戏主机里,显存和内存(cpu专用)是分开的。只有xbox 360,wii u,ps4和xbox one是特例。
我们把话题拉回来,这些数据分别需要占用多少空间呢?
顶点是三维坐标,索引是一个数字,uv是二维坐标。单算一个的话,它们分别占用12个字节,4个字节和8一个字节。(因为SS是32位机)
纹理这里,我们可以放点水,假设它用了超小的图吧,几乎不占空间。我就不统计了~(其实在现代的视频游戏里,这恰恰是数据量最大的部分。)
然后,它们的数量分别又是多少呢?
答案:索引大致是顶点的1-3倍(想想为什么?),uv一定是跟顶点一样多(想想为什么?)。
我们再放点水吧~假设索引跟顶点一样多。
如此计算的话,一个顶点要占用多少空间呢?
根据小学课本,这里应该使用加法!12+4+8=24(字节)
好,我们再来看看有多少容量来装这些数据。
其实SS的存储器非常多,也非常复杂。好在只有一块存储器是用作3D图像的,它的容量是512KB。
512KB可以存储多少顶点呢?
根据小学课本,这里应该使用除法!512 X 1024 / 24 约等于 2.2万。
那么,2.2万个顶点可以组成多少三角形呢?
我们第三次放水,就当是2万吧。实机可能1万都不到。
下一个问题,我们不知道他们说的多边形是几边型,姑且就放水算作四边形吧。
这样,多边形的量最多是1万。
我们不排除SS使用了很先进的压缩算法。但是,再压也不会有数量级的飞跃,满打满算不会超过10万的。
所以我们得到了结论:即便放水无数次,SS游戏的场景复杂度绝对不是十万级别的。
我个人估计,如果屏幕上有一万的三角形,就已经很不错了。多数游戏应该只有几千吧。
以下是世嘉的第一方大作Virtua Fighter 2,算是SS上3D画面相当好的游戏了。
好了,明天我们再来看一看SS的兵力和运输队吧。大家明天见!
实战SS机能分析2:显卡
聊一聊显卡,或者更准确的说法,是3D图像处理器(现代的硬件通常叫做GPU)。
在A9经常看到很多热心的玩家,天天讨论显卡,这个特性那个特性,一个比一个高级。不过我相信,还是会有不少玩家,会真正好奇,显卡究竟是怎么工作的?
今天我们就来聊这个问题!
下面要说的,是一个十几年没变过的道理。显卡的主要工作有两个:
- 根据显存中3D模型中的顶点坐标、以及CPU给的信息,把它们转化成屏幕上的位置。
- 给顶点之间的线和面上色。
那么,既然有了顶点数据,为什么要再算位置呢?
因为我们第一天说的顶点数据,那些坐标是相对于物体自己的坐标。
那么,又关cpu什么事呢?因为我们游戏里不同的物体会有不同的运动轨迹,当然就需要单独控制了。
动画数据和人工智能是由cpu来计算的。(严谨的说,这是有特例的,不过大家暂时不必理会那些复杂的技术。即便在次世代,这个表述也通常是成立的。)
拿到了顶点数据、以及它们转化的方式,图像处理器(GPU)就能知道每个顶点对应屏幕上的位置了。
关于第二点,想必大家已经在第二天的文章中理解了。
顶点之间的线和面,除了可以蒙上纹理(Texture),也可以用更简单的方法,或者更复杂的方法上色。
就SS的图形处理器的特性来说,简单的蒙上纹理已经是最高级的方式了。
最后,大家再记住一个重要的结论:
- 顶点的处理,它的复杂度跟顶点的数量有关(A9众:废话)
- 像素的着色,它的复杂度跟屏幕上的像素的数量有关(A9众:又是废话。。。)
如果大家能这么想,我的目的就达到了,哈哈。
其实想要了解主机游戏的技术,并没有什么太深奥的地方。SS的硬件非常简单,我可以直接抽丝剥茧,大家用最直观的方式理解问题就好了。
不过,要想真正深入的理解,还是需要想一想,是不是所有细节问题都能解释呢?这就是留给大家的思考题了。
如此一来,显卡的工作,几句话就讲完了。
我估计,今天A9众的意见会比较分化,也许有些人觉得太简单, 有些人觉得难以理解。尤其是顶点的转换。
觉得还不够爽的同学,可以看这篇: http://robertokoci.com/world-view-pro...
觉得一头雾水的同学,欢迎回帖提问。
最后我给大家爆个料:其实SS的显卡是处理四边形(Quad)的。
A9众:你不是说显卡只能处理三角形吗!!!我再也不相信爱情了!
其实啊,SS的显卡是唯一的特例,而且对我们分析问题也是没有影响的。如果我们不在一开始就统一标准,那我们就不能来做精确计算了。
多数的SS游戏的素材,都是三角形组成的,最后转化成四边形而已。一些第一方的游戏除外。后来的dreamcast就不用这么奇葩的方式了,改为处理标准的三角形了。
而且,即便是四边形,仍旧可以拆成三角形来分析,结论是一样的。
好了,明天我们来入门3D机能的最后一方面:带宽。而且会对SS的机能做一个结论,大家明天见!
实战SS机能分析3:带宽(Bandwidth)
首先,我决定把对SS的总结延后,直到跟ps和n64做比较时再来说明。
对的,以后会有SS vs. PS vs. N64的3D机能大对决!三个宿敌的命运对决会是什么样的呢?这就需要大家每天认真读一读,不然到了那天就看不懂了。
有人回帖说,:楼主你有很多东西没有讲到!SS有两个cpu你怎么不提啊,你是不是专门来黑世嘉的啊?!
其实SS可不止两个cpu,还有两个图形处理器,两个声音处理器等等,还有10种不同的存储器。那么,我为什么之前都没提到呢?
假如我要是把这些错综复杂的东西都讲了,那估计也就半年以后啦~也没几个人能理清思路的。
讲解问题就是越简单越好。大家想一想,为什么我选择从SS开始呢?就是因为SS的处理器和存储器,它们的数量虽然多,但是功能恰恰都是分开的。所以在分析SS的3D机能时,只需要考虑一块处理器和一块存储器就可以了。非常适合教学,也不会不严谨。
这样一来,在众多的信息中,我就可以抽丝剥茧,来讲解重点了。其余的内容,等以后需要用到时,我们再继续聊。
今天,我们来看决定3D机能的最后一个要素,运输队(带宽)。
首先,究竟什么是带宽?
根据前几天学到的知识,数据是需要在存储器和处理器之间传输的。
所谓带宽,就是你传输数据有多快。如果运输队运输的太慢了,即便处理器的速度很快,它也拿不到足够的数据来处理不是?整体的运算速度就下来了。
数据传输主要有如下几种:
- 显卡从显存拿数据的速度。
- CPU从内存拿数据的速度。
- 显存和内存之间通讯的速度。
(再一次注意,今天讲的所有原则,不完全适用于xbox 360、Wii U、PS4、xbox one这四台主机。)
其中,在较为现代的游戏主机中,拖3D图形性能后腿的,就是第一条和第三条!特别是xbox 360和ps3这个时代。这个事实非常重要。
而较为古典的游戏主机中,只要第一点不出问题,就不会影响3D图形性能了。
以SS的情况来说,因为没有什么特效需要处理,所以带宽是不存在任何问题的。
那么,上面每一条的具体含义什么呢?它们分别是用作什么的呢?我们就来仔细的聊一聊吧。
第一条,其实我们之前讲过。显卡的工作,多半就是顶点转换和像素着色。而顶点和纹理都是在显存里的。(以前有讲过喔)
所以,大家应该很容易理解才对。
第二条,跟第一条是类似的。CPU需要从内存拿它需要处理的数据。
那么这些数据都是什么呢?
大家记住,通常,游戏的动画控制,人工智能,物理效果,这些东西所需要的数据都是在内存里面的,也都是需要CPU负责处理的。所以,CPU当然要从内存拿数据了。
第三条,情况就稍微复杂一点了。
我们顺着第二条的思路,CPU计算出了第二条中列出的效果,是需要把这些结果告诉GPU的。
那么,究竟怎么通讯呢?
我们知道,CPU只能读写内存,GPU只能读写显存。这样一来,真相就只有一个了!
内存和显存之间,需要通讯。
很多玩家肯定会问了:你说的这些通讯的数据量,应该会很小吧?你想啊,主要的显示数据不是已经在显存里了吗?
是的,对应SS这样的主机,这些数据量很小,肯定不会拖后腿的。可是后来的主机会利用这条带宽,做出非常出色的效果,这些技术就对带宽要求很高了。
虽然现在讲解这一点并不合适,但是我还是可以跟大家稍微提一下,这条带宽可以用来做什么。
其实就包括了我们经常听到的名词:光照和阴影,粒子效果,全屏反锯齿,HDR,Bloom,SSAO,景深效果,等等,不计其数。
这些高级的技术,还会在显存中创建非常多的数据,因此,第一条中显卡和显存之间带宽的需求,也会急速膨胀。大家暂时有一个大致印象就好了,我们以后会仔细解释的。
如此一来,我们用了三天的时间,大家就已经掌握了分析3D机能的基本方法了!
很多玩家又要问了:这些东西可以用来拿来分析SS,但是对次世代主机也适用吗?
答案是,基本思想肯定是适用的!但是,因为很多技术细节发生了变化,所以分析起来需要更多的步骤。
最后,大家复习一下,决定游戏主机3D机能的三大因素是什么?
我们就要开始看索尼Playstation的特性了,这个一个非常激动人心的开始。大家明天见!
半透明效果(Alpha Blending)
playstation上核弹级别的游戏:Metal Gear Solid。
虽然我以前也通关了好几回,但是这一次,我认真的观察了这个游戏所使用的技术。
首先,我注意到,游戏中是使用了大量的半透明效果:呼吸的白气,手雷的爆炸和烟雾,枪口的火花,灯光效果等等。
然后,这个游戏的人物,居然都是有光照的!
人物走到灯光下面,身体面向灯光的一面,会被照亮。这种定向光照(Directional Light)还是非常准确的。
当然,这种效果不能和现在的游戏比较了。
由此,我们知道,Playstation游戏中的很多效果,和土星是不一样的。
今天,我们就来聊一聊第一个不同:半透明效果(Alpha blending)。
在那之前,我们先来讲一下基础的RGB知识。想必多数电脑用户是知道这个的。
电脑中的颜色是由红色(R)、绿色(G)、蓝色(B)这三个通道组成的。通过组合RGB这三个数值,就能得到游戏中的五颜六色了。
如果还是不理解的话,就先看看这篇文章吧:http://zh.wikipedia.org/wiki/%E4 ... 9%E6%A8%A1%E5%BC%8F
好,我们进入正题。大家看下面的图。
怎样才能把半透明的圆圈叠加到方块上面呢?显卡是怎样决定最终的RGB值呢?
我们需要知道三个信息:
- 背景像素的RGB值
- 叠加的半透明像素的RGB值
- 叠加的半透明像素的半透明值(Alpha value),范围是0-1。0代表完全透明,1代表完全不透明。
具体的公式是: 最终的RGB值 = 背景像素的RGB值 X (1 - 半透明值) + 半透明像素的RGB值 X 半透明值
假如觉得有点绕的话,可以这样理解:假如半透明值是0,那最终的RGB值就跟背景像素一样。假如半透明值是1,那最终的RGB值就跟叠加的像素一样。
任何中间的情形,就是半透明效果了。
很多玩家肯定会问:这只是2D游戏的情况啊,那3D游戏呢?
3D游戏是完全一样的。看下面的图:
显卡的决定最后像素的时候,就是叠加两个RGB值而已。
玩家肯定又问了:这只是两层的情况啊,那三层和更多层是怎么处理的呢?
也许有人会不相信这个答案:有几层就要算几次。
为什么显卡这么笨呢?
因为这是唯一正确决定最后像素RGB值的方法。以后我们讲到物体排序(Sorting)的时候,再详细解答。
那么,这种半透明效果,对显卡的要求高不高呢?
答案是,高!
我来举一个顽皮狗的栗子吧!
神秘海域1大家知道吧?那个游戏里面的手雷烟雾,是完全没有透明效果的!不做特别优化的话,连PS3的显卡都处理不来。
是不是有点匪夷所思呢?
更加匪夷所思的是,按说ps vita的机能不如ps3,为什么vita版的神秘海域没有这个问题呢?
明天我就会详细讲解,为什么顽皮狗一开始搞不定这么简单的效果?而在神秘海域2中是怎么解决半透明效果这个难题的?
深度缓冲(Depth buffer或者Z-buffer)、帧缓冲(Framebuffer)以及像素填充率(Fillrate)
大家是不是很好奇?为什么顽皮狗在神秘海域1中搞不定手雷烟雾的半透明效果?
为了解答这个问题,我们必须引出一个概念,叫做深度缓冲(Depth buffer或者Z-buffer)。
首先,这个深度缓冲是啥呢?
我们在屏幕上看到的一个一个像素,它们除了有颜色的RGB值以外,还有一个深度值(Depth Value)。
这个深度值是什么呢?大家想想看,3D游戏的物体都是有三维坐标的,对不对?那投射到屏幕上肯定也是一个三维坐标,对不对?比如说,树木在前面,就会挡住人物。
这里我们暂时不讨论3D电视。因此,我们的屏幕都是二维的,要想存储一个像素所有的信息,就必须要有额外的信息,那就是深度值。
而所谓的深度缓冲,就是帧缓冲(Framebuffer)中的所有像素的深度值。
那什么又是帧缓冲呢?我先从最简单的情况入手吧。
在高清游戏主机中,帧缓冲的内容,就是你在屏幕上看到的所有像素的颜色值和半透明值(Alpha value)。
对于大多数的情况,像上面这样理解就可以了,完全没有问题。
不过,在比较传统的主机中,帧缓冲和屏幕上的像素还是有点区别的。因为主机的帧缓冲会比屏幕范围稍微大一点。实际显示的区域,要比显存中的帧缓冲要小一点。
对了,帧缓冲和深度缓冲都是在显存里面的。这是一个重要的事实。
世嘉青:那楼主我太感谢你了啦!你在分析土星机能的时候,居然没有把Framebuffer算进去耶!这样就能存更多的四边形了啦!
可不是我偏袒SS啊,因为SS有专门的两块存储器(2 X 256KB)来放帧缓冲,所以那块512KB的显存就可以专门用来放3D数据了。
细心的玩家肯定发现了:居然有两个framebuffer!
通常情况下,会有两到三个的。以后我们讲到垂直同步的时候,再详细聊一聊吧。
好,现在大家来复习一下:帧缓冲(Framebuffer)里面有什么?深度缓冲(Depth buffer或者Z-buffer)里面有什么?
现在要进入正题了。这个深度缓冲到底有什么用呢?
大家想象一下,我们先画了一个人物。如果一棵树也在同一个像素位置有像素,那么GPU就会比较两者的深度值。如果这个像素在人物后面,就不用画树的像素了;如果在人物的前面,在帧缓冲里面,这个新像素的颜色值就会替代人物像素的颜色值,深度值也会更新。
比较近的物体遮挡比较远的物体。这个显卡处理的硬件优化过程叫作Z消隐(Z-culling)。
以后,等我讲到排序(Sorting)的时候,就会讲到一个重要的事实。大家暂时先记住: Z消隐(Z-culling)这个优化,只能应用在没有半透明的场景里。
如果所有物体都没有半透明效果的话,那么可以保证屏幕上的像素基本没有任何重画。屏幕上有多少像素,显卡就需要画多少像素。
如果物体有半透明的效果,那么显卡的工作就会繁重很多了。这个物体在屏幕上占据多少像素,这个区域所有的像素都需要重新计算一遍。
神秘海域1里面的手雷烟雾,经常是会占据一大半屏幕的。假如有半透明效果的话,屏幕上的像素就都需要处理两三遍。这就击中了PS3的显卡RSX的一个很大的软肋,像素填充率(Fillrate)太低。
所谓像素填充率,就是显卡画像素的速度。
严谨的说,并没有一个统一的标准来衡量它。究竟是画一块单色的像素的速度呢?还是画一块有纹理有光照的像素呢?它们之间的区别很大。
但是经过实践,业界是有共识的。RSX处理有纹理有半透明效果的像素,速度确实不理想。
因为,即便是顽皮狗,也只好让烟雾没有半透明效果。这样子,RSX就可以做Z 消隐了。
PS Vita的显卡,虽然运算速度不如RSX,但是,它却没有像素填充率的软肋!所以,包括我在内的很多游戏开发者,都松了一口气。
那么,在神秘海域2中,这个问题是怎么得到解决的呢?这就是CELL处理器的威力了,等我们以后解析PS3的时候,再说吧。
明天我们应该会开始光照的入门话题,大家明天见!
最后,向大家求一个图床。很多人说看不到图呢。。。
屏幕撕裂(Screen Tearing)、垂直同步(V Sync)和双重缓冲(Double buffering)
既然昨天讲到帧缓冲(Framebuffer)了,不如我们就趁热打铁,讲一些相关的概念。
大家肯定经常看到垂直同步这个概念吧?PC游戏中也经常看到这个选项。
我们也都知道,开启垂直同步之后,游戏画面就不会撕裂了,但是游戏的帧数会降低不少。这又是什么原理呢?
首先,我们需要了解屏幕撕裂是怎么发生的。
为了让大家看的更清楚,我特意选了这张很明显的图。这张图也许是后期合成的,但是对于我们讲解概念非常方便。
在游戏主机中,除了用帧缓冲(Framebuffer)来存储屏幕上的像素之外,通常还会有一到两个后端缓冲(Back buffer)。
大家想啊,如果只有帧缓冲的话,如果显卡在上面绘制的时候,屏幕在一边不断的刷新(通常是每秒60次),岂不是会出现不断闪烁的情况?所以,所有的游戏主机都是有后端缓冲的。
有了后端缓冲,就可以完全避免屏幕闪烁了。显卡只在后端缓冲上绘制图像,等到屏幕刷新的时候,我们把后端缓冲跟帧缓冲交换(或者复制),这样就可以显示新图像了。
如果后端缓冲画到一半的时候,屏幕刷新了,会发生什么呢?
屏幕上一半是新图像、一半是旧图像,这就是所谓的屏幕撕裂(Screen tearing)了。
现在,大家思考一下:为什么早期的游戏,这种情况就很少见呢?
因为老游戏分辨率很低。像素的数量越少,就越不容易出现来不及绘制的情况。
接下来,有没有方法来避免屏幕撕裂呢?这时候,我们的垂直同步就登场啦~
垂直同步的工作原理,是建立在电视机和显卡的通讯之上的。当电视机完成了整个屏幕的绘制时,会通知显卡。(比如,显像管电视会有刷新率的概念,最新的数字接口HDMI有VBLANK的概念。它们都是用来通知显卡的。)
显卡在收到电视机的通知之前,不会进行下一帧的绘制。这个技术,就是所谓的垂直同步(Vertical Synchronization)了。
细心的玩家肯定会问了:明明是整个屏幕,为什么叫垂直同步?
其实,这都是在沿用以前模拟电视的概念。
以前的电视都是有扫描线的。一个扫描线就是一个水平的行。(以前描述分辨率都是240线、480线等等。)
相反的,垂直、自然就包含了全部的扫描线。垂直同步就是等待整个画面了。
这里我不得不提一下水平同步(Horizontal Synchronization)。它的字面意思是,等待一行绘制完的意思。但是在游戏主机中,水平同步通常就是不开启垂直同步。它往往不会做任何同步,而是尽快的让后端缓冲交换(或者复制到前端)。
以上就是游戏主机的特别之处了,跟传统显像管电视、或者pc游戏的情形都不同。毕竟针对游戏这种特别的任务,水平同步本身是没有意义的。
所以,大家可以直接理解为:水平同步就是没有同步,垂直同步就是防止图像撕裂。
像这样的两个帧缓冲的配置,叫做双重缓冲(Double buffering)。
学有余力的玩家,可以参考这篇: http://en.wikipedia.org/wiki/Verticalblankinginterval
最后,给大家留一个思考题:为什么在主机游戏中(战争机器3、GT5等等),屏幕撕裂通常发生在屏幕的上方呢?
为什么真三国无双6的帧数是在30帧和60帧之间切换呢?
三重缓冲(Triple Buffering)
我们先来看下真三国无双这个例子。
玩过的同学都知道,这个游戏的帧数非常不稳定。经过测算,356并不是普通的掉帧,而是在60帧和30帧之间切换。
基于以上的时候,我们就可以下结论了:356使用了垂直同步 + 双重缓冲,而且游戏的瓶颈是GPU。
很多玩家要说了:游戏是你做的啊?你是怎么知道的?你太嚣张了!
我当然是有根据的。我们先来看一下,双重缓冲下的垂直同步,如果游戏的帧数稍微低了一些会发生什么。
昨天我们昨天所学的内容,开启了垂直同步,后端缓冲就只能在HDMI信号的VBLANK期间跟前端缓冲交换(或者复制)了。HDMI信号的VBLANK是每秒60次,所以是60Hz。
假设我们面前只有两三个小兵,那游戏跑起来就绰绰有余了,GPU每秒处理100帧都是可能的。不过,356开启了垂直同步,游戏会等待VBLANK信号,所以帧数会稳定在每秒60帧。
这时候,有一个有脸的武将带领一大队小兵突然出现在视野里,游戏处理起来就吃力了。这时候,GPU每秒只能处理50帧了。游戏的帧数会是多少呢?
答案是30帧, 而不是50帧。
为什么呢?因为GPU错过了第一个VBLANK信号,就会等到第二个信号才会更新。所以帧数会变成30。
假如GPU的负荷又增大了,那会怎样呢?
帧数会变成20、15、12、10,60/N,以此类推。
我们再来思考一下,如果是CPU算不过来,每秒只能算50帧,那实际的帧数是多少呢?
答案是,50-30帧之间都有可能。
根据上面所学的知识,我们可以确定:356使用了垂直同步 + 双重缓冲,而且游戏的瓶颈是GPU。
现在我们都知道,在GPU是瓶颈的情况下,双重缓冲不是一个好东西了。
于是,一个叫做三重缓冲(Triple Buffering)的技术隆重登场~当当当当~
有了第二个后端缓冲,显卡就不用等待VBLANK信号了,直接在另一个缓冲上绘制就可以了。
当VBLANK信号到达的时候,一定会有一个后端缓冲是完成的状态,那么直接就显示那个就行了。
即便GPU不能在60Hz下更新,帧数也不会直接降到30了。
到了这里,帧缓冲相关的内容就结束了。
顺便提一下,SS和PS都有垂直同步的能力,但是因为存储器的容量有限,三重缓冲并不现实。所以,那个时期的游戏可以正常跳帧的并不多。
光照(Lighting)基础
首先,要跟大家说声抱歉。因为我前几天的难度没有把握好。
我这一系列文章的目的,是让普通的玩家对主机游戏的技术有所了解,并且产生兴趣。了解的程度完全是由读者来决定的。
基于这个目的,分析问题的方法就比知识重要多了。这也是为什么我讲解的都是普遍的原则,而比较少提到非常细节的知识。
比如说,现在大家都知道SS是不用三角形的,但是我还是坚持,在结论准确的情况下,统一标准使用三角形来计算和分析问题。互联网上流传的错误结论很多,只有掌握了分析的能力,才能去伪存真。
而前两天的文章有点本末倒置,细节太多,方法太少。我会注意回归正轨,更好的满足普通玩家的需求。
当然,也非常欢迎各位看管踊跃讨论和指正。
今天要开始聊最基础的光照(Lighting)。
首先我们来复习一下,之前学过哪几种数据?
顶点(Vertex),索引(Index),UV,纹理(Texture)。
而为了实现最基本的光照,我们还需要一种额外的数据,叫做法线(Normal)数据。
很多玩家肯定要说了:我听说过!法线贴图是吧!
我想他们指的是Normal Map,这跟我们的法线数据是两回事。
法线数据是用来记录每个三角形的指向的。它也是一个xyz三维坐标。
每个三角形都在一个平面上,它的法线的方向就是垂直于这个平面的方向。
不过,需要注意的是,游戏中的法线数据是跟顶点对应的。每一个顶点对应一个法线数据。
这个法线数据的值,是它周围所有三角形法线数据的平均值。
有了所有顶点的法线数据,显卡就可以计算出任意一个像素所属三角形的方向了。就像我们以前说过的,这也是插值运算(Interpolation),是属于显卡的工作。
有了法线数据,显卡就可以做最简单的光照效果了。
我们来想象一下最简单的一个平面,当光线的方向和法线的方向完全一致是,光线是垂直射入的。这时候平面最亮了。
当光线的方向慢慢变化,它跟法线的夹角越大,平面能接受的光线就越少,就会越来越暗。
当光线和这个平面完全平行时,就接受不到任何光照了。
再转下去,平面就会背对光线,还是没有任何光照。
合金装备1里面人物的光照就是基于这么简单的原理。
具体的计算方法,就是简单的向量的点乘。把法线向量和光线向量乘起来,再乘以光源本身的强度,就得到了能接受光照的量了。
当光照的量最大时,这个像素的颜色就是纹理本身的颜色。
当光照的量是0时,这个像素的颜色就是黑色。
任何的中间情况都是可能的。
细心的玩家肯定要问:光源的颜色不同怎么办?如果有好几个光源怎么办?
当光源不是纯白色的时候,我们再乘以光源的RGB值就是最终的像素值了。
多个光源就是把RGB值加起来。
这些就都是很细节的内容。
今天我们说的这种最最基础的光照叫方向光照(Directional Lighting),因为光照的强度只跟光线的方向有关。以后我们会逐渐提到更复杂的光照技术。
光照需要哪一种数据?
后记
我们已经学会了3D游戏的各种数据类型,我们还学会了最基础的分析机能的方法,以及一些初级的特效。虽然主机和主机之间具体的实现方法有很大的不同,但是它们都是基于这些基本原则来工作的。
基于这些普遍的标准构成的抽象方式,机能的比较才成为可能。
最后,我昨天看到一个链接:http://club.tgfcer.com/viewthrea ... e%3D1&frombbs=1
我先摘录一些有价值的评论。
看作者写了一堆SS,PS什么的,基本可以肯定作者既没看过(或看懂)PS的SDK也没看过(懂)SS的SDK。还alpha混合与深度缓存呢……
他讲的这种3D流水线结构,只适应于N64和之后的Console。并不适应之前的。 比如PS和SS都没有Z-buffer,自然也没有Z-test,自然贴图也没有透视矫正。 关于Alpha-Blending,无论PS还是SS,都没有所谓的Alpha混合,而是半加,半减之类的方式,所以当初这个功能叫做半透明,是有道理的。说确切的话,它们根本没有alpha通道这个概念,而是用color key来表示纹理透明/不透明。SS最高支持到24bit,而PS支持到16bit(1555格式)。 此外,它关于UV,Index,Vertex等等的描述,也不符合PS/SS的形式,它们不使用浮点数,顶点基本是以UInt16这种16bit定点数来表示。另外SS没有UV的概念,它都是sprite,至于Vertex Index,PS/SS硬件和API本身是没这个概念的。 直接总结的话 SS本质就是一台2D机器:3D顶点变换靠CPU硬算,fragment部分就是一纯2D硬件。半透明受限是源于SS对变形sprite的绘制方式不支持半透明。 PS本质是一台增强了部分3D性能的2.xD机器:它有一个矢量运算加速器GTE,因此顶点变换等操作要快速得多。但它的fragment部分,依然只能算一个2D绘制硬件,比SS强的部分是2D贴图功能的增强,至少支持了UV mapping这种形式而不只是SS那种sprite形式。也正因为如此,它的半透明功能限制较少。
这个作者语气让人不爽,动不动就是对不对,对不对?娘炮 和每句话后都要加 是不是这个道理? 不是差不多。
本来是讲ss,所以去看的,结果作者根本不懂ss硬件,分析ss带宽一点数据都没有,各个总线频率带宽都没有,这就是个**,搞到底他就不懂ss和ps的硬件。。。
RSX有22.8GB/S的独立带宽,PSV带宽多大?感情PSV跟PS2一样有嵌入式DRAM?当然就以目前PSV一般480P甚至都不到的分辨率来说,说像素填充率不是瓶颈倒也可以理解
看文章就知道这作者只了解现代光栅化的软硬件体系,还非要拿这个去套90年代3D古早期的设备,最后结果只能是关公战秦琼 给完全不了解的人补补常识还可以,深究就不行了
其实哪怕在2000年以后,模型的顶点位置存储,不使用FP32,使用16位的一些格式之类,也不罕见,所以他一上来就按FP32x3来算Pos内存占用,按32bit算Index内存占用(16bit的Index现在都还有用啊),FP32x2算UV内存占用实在是无厘头。更何况后两个根本和SS没什么关系,再辅以‘小学加法’等耸而无力的语言描述,实在让人那个啥,扼腕叹息啊……感受一下是不是这个道理?