使用Instancing渲染复杂场景

在游戏中,经常会遇到要渲染的场景中物体数量巨大.如草,漫山遍野的树木.成群结队的敌人等.

最早遇到这个问题是一个项目:**大学要给那个劳民伤财的**会做一个编排系统,用于开闭幕式的演出编排.即先编排好演员的动作,移动路径等,然后实时模拟整个场馆内所有演员的表演.这样就要求同时渲染数千人,而且是带动画的.他们使用的某款虚拟现实引擎从性能上(包括渲染能力,交互性,界面)无法达到要求,想试一下Torque引擎.

我们用TGE1.5,TGEA1.0.3测试,无法达到要求,扔了六百个的player,帧率在10fps以下.进行了各种优化,仍收效甚微.研究发现其实瓶颈不在于总的面数上,而在于batch上(每次调用DrawPrimitives).

要优化.就得把batch数降下来,在每次的draw中,往buffer里填充尽可能多的模型,然后将矩阵计算,动画计算等移至shader中进行.找了很多种解决方法,因为当时对TGEA的架构不熟,水平有限,并且TGEA本身的耦合度很高,这些优化难于整合到TGEA中,只能另想别的办法.

最后是采用分屏的办法:让多台PC各自显示场景中的某一块,然后再把这几台显示器拼起来,3000人可以达到15帧左右,基本可以满足要求.这样又带了网络更新的问题,多台客户端各自渲染场景的一部分,各个客户端的位置和动画计算的同步要求很高,更新和网络的问题一直没有找到很理想的解决方法.这个项目也因为技术的不成熟和一些商务的问题没有继续下去.

闲扯了一堆,呵呵.后来一直耿耿于怀,想找到比较好的方法来解决这个问题.言归正传...

DirectX10中的Instancing大意就是通过一个或几个模型来复制出它们的很多实例.其实不是什么新技术,在dx9中就已经有了,只是限制较多.

前面提到,优化batch,实质是往buffer中填入多个模型,同时要在shader中处理矩阵变换,光照,动画计算(动画计算的原理与矩阵变换类似.具体实现以后再说)等,要将用于变换的矩阵传入shader中.在DX9中,主要是通过现两种方法来实现:1  Hardware Instancing.使用多流,将每个实例要使用的特殊信息(如矩阵,灯光等)放在第二个vertex buffer中.2 使用VS的常量缓冲区来传递数据.具体的实现参见DirectX9sdk中的"Instancing Sample".另外,在gpu gem2第三章"Inside Geometry Instancing"也是篇很好的文章.

在Directx10中,instancing技术大体上原理同DirectX9 sdk中一样,借助于dx10的强大性能,有一些提升.主要有:1 DirectX10的常量寄存器多达16×4096个,而DirectX9中的仅256个,这样可以传递的矩阵等数据大大增多,而不必都用多流.2 新加入的GS使显卡具有动态生成顶点的功能.这些一些简单的物体可以使用shader生成,不必使用模型. 3 Texture Arrays使使用同一个模型的实例可以有自己的纹理,再配合动态shader分支,这样就不会像DirectX9里的那样所有的实例都长的一个样.具体的实现可以参见DX10 sdk中的"Instancing10 Sample",写的很详细.

这些方法都很好.但是问题就是,不好整合进TGEA中.曾经想把TGEA1.7的图形层改写为DX10(TGEA使用了一个抽象图形层,支持DX8,DX9,目前支持opengl的也公布了,不过只能在mac上使用).进行了一部分后放弃:一是工作量太大,二是引擎是一个整体,在TGEA现有的架构和算法的基础上要想发挥出DX10的优势是比较困难的.只是简单的把图形api换成DX10,是没什么实际意义的,除了自己学习研究以外.唉.只能等待官方的TGEA升级了..

posted on 2009-02-01 15:34  chsaov  阅读(1463)  评论(1编辑  收藏  举报

导航