略谈手机3D开发要点

写几个非常有用的要点:

0 杜绝浮点运算
因为ARM CPU一般不具备FPU协处理器,需要软件方式模拟,经常需要数千个时钟周期才能完成浮点数的加减计算,所以必须使用定点数。
这个大家都知道,但是要提一下的是,如果能够为定点数提供封装,然后作为内置类型使用,以后一定会方便很多。
再有一个就是精度问题,软件渲染中会为定点数精度的问题头疼的地方会有很多。最好能在不同的场合使用不同小数位精度。一般来说,16:16与8:24是最常用的选择。


1 内存读写绝对是最浪费时间的操作
大多数手机都使用一条16位BUS来获取指令和数据。由于所有指令都是32位的,BUS速度就应当是CPU速度的两倍,才能满足需要。但实际上BUS速度要比CPU慢,速度比在1:2到1:4之间。为了解决这个问题,大多数ARM CPU都有一个指令cache和一个数据cache,通常这两个cache的大小均为8K。只要cache中出现请求的指令或数据,CPU就能以全速直接获得它们,而一旦需要访问尚未加载到cache中的代码和数据,就必须通过BUS访问内存。并且每次读取一个尚未到达cache的字节时,CPU都要先填充一整条cache line,一条cache line可能是64 byte。由于BUS是16位的,因此它将被占用 32个周期,而如果BUS速度只有CPU的一半,CPU将会延迟64个周期。
因此,要确保内存尽可能紧密,同时还要检查内存访问模式,以判断是否可以调整结构以使运行效率更高。如果需要定期访问某一结构中的一个数据成员并要处理大量这样的结构,则要考虑将这个特殊的数据成员移到它自己的数组中。基于同样的原因,应该尽可能使用字节或双字,而且尽可能使用无符号类型。
但要注意的是,使用一系列LDR指令读取连续内存块的速度,要优于使用同样数量的LDRB或LDRH指令,间断地读取这块内存的速度。也就是说,读取一个word的速度可能快于读取一个byte!(实际测试过的确如此)


2 杜绝除法
ARM CPU不支持除法,需要软件方式模拟,这会消耗数千个时钟周期。132-MHz的ARM在理论上可以每秒执行1.32亿条指令(或者2.64亿条指令,如果其中一半运算是移位运算)。但是每秒7万次的除法运算就会超过CPU的最大能力。也就是说,如果游戏运行速度是每秒60帧,则每一帧仅做1000次除法就会达到CPU的极限。
大家都知道,所有除法都可以都替换成移位和乘法运算。但是,最好的方式还是用查找表。但如果分子和分母都是32位整数,所需的查找表就远远超出了可用的内存容量。一种解决方案就是缩小数据的范围。因为a / b = a * ( 1 / b ,那么实际上只需要一个倒数表。再假设在大多数情况下16位精度就已经足够,那么查找表只需要65536项。当然输入输出数据必须进行移位来保证正确的范围,但最差的情况也将少于100个时钟周期。


3 使用查找表完成所有可能的任务
典型的查找表有倒数、三角函数、Alpha混合,光照等。也许还可以想到更多。


4 使用最高效的场景管理办法,哪怕它最不灵活。
对于室内场景(其实非标准的室外场景也适用)BSP绝对是最好的选择。场景数据不要使用3DS MAX或者其他的什么东西建模,自己写一个CSG的工具,用Brush建模是最高效的选择。
如果可能,不要使用实时的Portal Engine,预计算的PVS是最高效的,不要为那稍显漫长的编译时间耿耿于怀。要确保Split Plane选取得最好,要采用2-Pass的BSP树创建,要检查Visibility计算直至绝对没有任何问题,而且要采用一切可以提速的手段,比如为Su***ce打上Hide,Black的标签,并且使用Occluder。
不要忘了使用BSP对碰撞检测加速,如果出现BUG,看看是不是忘了加Epsilon和Brush Hull。
BSP对于网络传输和AI计算等等也有很大帮助,BSP也可以通过Radiosity计算LightMap而极大提高场景的视觉效果。如果觉得方方正正的场景过于枯燥,你还可以导入3D模型。别忘了导入模型也可以利用PVS的,而且也可以参与LightMap计算。
榨干BSP的能力,同时不要理会别人对于BSP不灵活性的指责,手机上做3D最关心的还是效率。


5 仅在必需时使用透视纹理映射
大部分多边形只需要仿射映射就足够了,特别是手机的屏幕那么小。但的确有些时候透视校正是必需的,比如当一块很大的面距离镜头很近而且法线几乎和视线垂直。那么为了效果就去坚决校正它吧,但要把这个判断条件写得尽可能精巧。
提醒一下,每16个点才校正一次,效果是还可以接受的。而且有时候把过大的三角形切分一下,也是不错的做法。
忘记Constant Z-Slope或者分块算法或者别的什么,它们太不成熟,如果研究就意味着浪费时间。


6 必须使用Z-Buffer
不要因为昂贵的内存访问而抛弃Z-Buffer,无论你怎么Sort Object,最后效果一定很差,而你也一定会在犹豫和挣扎中痛苦。
为了实现商业级游戏的深度测试,Z-Buffer绝对是唯一的选择。
但是Z-Sort(画家算法)并不是没有用了,尤其是开着Z-Test的时候,我们可以用Z-Sort来优化。


7 把Frame-Buffer和Z-Buffer合并
这样会显著减少光栅化器访问内存的次数。其实这个方法实现起来很简单,关键是你是否能想到?


8 不要做Frustum Clipping
除了NearClip以外,不要做其它的Clip,因为NearClip是在Div-W之前做的,所以(被迫)不存在透视校正问题。而一般来说其它的Clip因为效率问题都希望放在ScreenSpace下进行,这就会带来透视校正问题。
如果检查底层贴图扭曲的BUG但很久没找到原因,那应该立即看看是不是Frustum Clipping的问题。


9 Vertex Pipeline的规划很重要
把各种Transform,Lighting,BackFace Culling,Div-W,Clipping等等的顺序认真思考一下,仔细排一排,而且减少不必要的步骤和计算,你会发现效率起码提高几倍。


10 使用BoundingBox做Clip
不要用Sphere,它的形状日后会成为追求最高效率极限的障碍。Box Clip同样可以写得很高效,提示一下就是用accept point和reject point,别忘了这个算法也可以用在Clip BspNode的时候。


11 可以做影子,甚至是真正的影子,但是别企图完美
忘了Shadow Volume/Map,Soft Shadow之类的东西,它们不是我们能承受的。当然,利用LightMap实现的效果除外。


12 即使是真正的3D游戏,也可以使用伪3D的技术。
各种Billboard,Z-Buffered 2D-Sprite,2D-Skybox等等,如果能够聪明的使用,效果可能比用多边形还要好。


13 做一些亮点
诸如Paricle Group,Texture Scroll,Environment Mapping,Montion Blur,很多Post-Proccess等等都是可以实现的,对效率也没有太多的损失,却会让画面与众不同。
实现它们,这不会花掉太多时间。同时记住为特定的游戏,定制特定的效果,才是最聪明的做法。


14 记住有时候你不得不面对的,几个S级的效率杀手
糟糕的场景规划(这个主要考验关卡设计师的能力)
过多的透视校正
过多的Alpha混合(即使你已经用了查找表)
大面积的Dynamic Lightmap(动态光照图)


15 不要犹豫使用汇编
当算法级别的优化已经到达极致,不要畏惧于大规模的ARM汇编优化,即使你以前只懂得PC汇编。
虽然没有很多特殊的指令,但是大部分ARM指令都很有特点,先研究它们,然后再把每一个关键函数的优化都做到极致。
实践证明,ARM汇编优化对效率的提高绝对是非常显著的。


16 先竭尽全力去把引擎做到最强,然后再忘记它的能力
最终游戏的画面要看整个团队的努力和实力,无论多么强大的引擎也无法掩饰糟糕的游戏和美术设计。
多和策划和美术讨论,不要太快对他们的某个设计下结论。同时不要认为他们会以程序的角度思考问题,我们需要足够的细心和耐心去沟通。
努力把特效,贴图,调色板,多边形数量,骨骼动画,以及各种设计做到最优。那么最终的效果一定会让人怀疑他真的在拿着一个没有任何硬件加速,不是专为游戏设计的,普普通通的手机。
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值