Instancing 渲染
在渲染重复的顶点数目很少的小物体时,使用Instancing渲染方法能大量减少对绘制函数的调用,从而达到提高效率的目的。在GPU GEMS2中以及DX9 SDK的Sample中对该方法有详细的描述。
在GPU GEMS2中将Instancing渲染技术分成了4个种类:
l 静态批次
l 动态批次
l 顶点常量实例化
l 几何体实例API批次
书中对4中技术阐述的十分清楚,以下只针对DX SDK中的Sample中的三种做法进行叙述。
Stream Instancing
Stream Instancing使用2个VB Buffer,1个IB。一个存放数据的顶点,一个存放所有实例的属性。以绘制1000个立方体为例,一个VB存放一个立方体24个顶点(6个面,每个面4个顶点),一个IB存放36个索引(6个面,每个面2个三角形,每个三角形3个顶点)。另外一个VB存放所有1000个立方体的实例数据,包括:颜色,位置,方位角等等。
设置好各个Buffer后即可渲染。渲染的时候一次只能渲染一个立方体,每次DrawIndexedPrimitive之前都需要调用SetStreamSource设置实例在第二个VB中的偏移量即可。显然对于每个物体都调用DrawIndexedPrimitive的做法肯定对效率影响很大。
这种方法算是一种比较静态的方法,不过和GPU GEMS2中的静态方法不太一样。GPU GEMS2中的静态方法只使用一个大的VB和一个大的IB,这个VB中存放转换好的几何实例信息,IB中存放每一个实例的索引,然后使用一个DrawIndexedPrimitive绘制出所有的几何体。这种方法需要耗费大量的储存器且不能支持骨骼运算,对CPU的消耗十分的大。
Shader Instancing
Shader Instancing需要一个大的VB和一个大的IB以容纳所有的实例的顶点和索引。另外几何体实例的所有信息存放在系统的内存中。和前面的方法不同的是,并不需要在创建VB的时候将几何体实例的信息Lock到VB中去,而是在渲染的时候通过顶点常量传递进去。由于顶点常量的个数有限,所以一批几何体可能需要渲染几次才能全部完成。
这个方法和GPU GEMS2中的顶点常量实例化的方法很相似,不过由于GPU GEMS2中的这个方法将所有的顶点常量拿来做Instancing运算,无法进行骨骼运算。为了解决这个问题DX SDK中的Sample中并没有使用全部的顶点常量。
HW Instancing
这种方法是DX SDK里面强烈推荐的方法,不过需要硬件支持vs3_0。前面2种方法都只是需要硬件支持vs1_1即可。
HW Instancing的方法和前面说的Stream Instancing的方法如出一辙,所不同的是,HW Instancing使用了DX SDK提供的API:SetStreamSourceFreq()。通过这个API,就可以不需要在渲染的时候指定实例在VB中的偏移量,所以使用这个方法可以自动的将所有的实例使用一个DrawIndexedPrimitive绘制完毕。