平民程序 - linghuye's blog

天下风云出我辈,一入江湖岁月催。皇图霸业谈笑中,不胜人生一场醉。提剑跨骑挥鬼雨,白骨如山鸟惊飞。尘事如潮人如水,只笑江湖几人回。

随笔 - 221, 文章 - 0, 评论 - 680, 引用 - 0
数据加载中……

Geometry Instance

DirectX9.0C直接支持Geometry Instance,通过D3DDECLUSAGE_TEXCOORD多层纹理坐标流,将Instance Data数据传送到GPU,技巧在于:
pd3dDevice->SetStreamSourceFreq(0, (D3DSTREAMSOURCE_INDEXEDDATA | g_numInstancesToDraw));
pd3dDevice->SetStreamSource(0, g_VB_Geometry, 0, D3DXGetDeclVertexSize(g_VBDecl_Geometry, 0));

pd3dDevice->SetStreamSourceFreq(1, (D3DSTREAMSOURCE_INSTANCEDATA | 1));
pd3dDevice->SetStreamSource(1, g_VB_InstanceData, 0, D3DXGetDeclVertexSize( g_VBDecl_InstanceData, 1));

Stream1中的顶点数据,每g_numInstancesToDraw个顶点处理后递进一个,相当于每Instance递进一次.在HLSL中将Stream1中的数据流还原出来.

OpenGL当前不直接支持Geometry Instance,但是注意到
1.OpenGL的glDrawElements簇函数的消耗比DX的DrawIndexedPrimitives小得多.
2.OpenGL有一项DirectX所没有的能力,设置当前全局顶点数据,如glColor3f,glTexCoord,glMultiTexCoord,而且此类函数的单个调用在Driver和hardware上的消耗都极小,所以可以用glMultiTexCoord传递顶点数据到shader,而不是使用glUniformMatrix4fvARB或glLoadMatrix传递变换矩阵,此类设置GPU寄存器的函数,或者说是改变Vertex shader当前的全局处理状态的函数,很显然将等待当前GPU正在执行的Vertex process完成后才能返回,CPU将等待GPU.


The technique does not scale well to complex mesh rendering techniques like skinning; there
are not enough vertex attributes to store all of the bone transforms for each instance.
但,无论Directx9.0c或OpenGL2.1都无法传递几十个骨骼矩阵这么庞大的顶点数据单位格式(注意是一个顶点数据单位格式,OpenGL没有那么多层的glMultiTexCoord, DirectX没有那么大的顶点声明能容纳几十个矩阵),所以都无法完成带骨骼动画的Geometry Instance,只能是静态物体,或使用CPU作骨骼计算. DX10好像可以,没有显卡,没实践过.

CPU和GPU是并行结构,若使得两者完全并行运行,效率将最大化.若一方为了线性逻辑而不得不去等待另一方,效率将降低,这就好像两个线程间需要同步的数据或逻辑越多,效率就越低下.

Reference:
http://developer.download.nvidia.com/SDK/9.5/Samples/DEMOS/Direct3D9/src/HLSL_Instancing/docs/HLSL_Instancing.pdf
http://developer.download.nvidia.com/SDK/9.5/Samples/DEMOS/OpenGL/src/glsl_pseudo_instancing/docs/glsl_pseudo_instancing.pdf

posted on 2008-03-17 21:11 linghuye 阅读(3302) 评论(2)  编辑 收藏 引用 所属分类: MyWarCraftStudio3D图形学研究

评论

# re: Geometry Instance  回复  更多评论   

s
2008-07-02 13:44 | ss

# re: Geometry Instance[未登录]  回复  更多评论   

灌水咯~~~
2008-11-11 11:15 | 老狼
只有注册用户登录后才能发表评论。