D3D Hardware Instance

hardware_instance-300x238

This demo shows how D3D hardware instance works. HW Instance means call DrawIndexedPrimitive on time, but with a group of geometry rendered. Those geometries could be positioned in different place and different appearance. With this technology, you could gain a lots of performance improved than draw those group of geometry with a loop. HW Instance will split those geometry into two part, one part is shared by all geometries and the other part is specified one that hold all different properties for each. Usually, those shared part will be created on the vertex stream 0, and the other part called instance data will be placed on the vertex stream 1. So the vertex declaration will be look like this:

复制代码
static D3DVERTEXELEMENT9 _2_tex_normal_decl[] =
{
    // offsets in bytes
    {0,  0, D3DDECLTYPE_FLOAT3,     D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,   0},
    {0, 12, D3DDECLTYPE_FLOAT3,     D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,     0},
    {0, 24, D3DDECLTYPE_FLOAT2,     D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,   0},
    {1, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,     1}, // translation
    {1, 12,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,    2}, // color
    D3DDECL_END()
};
复制代码

 

Of course, two vertex buffer will be created. And they will be filled with corresponding data. At the rendering time, vertex buffers will be set up with frequency, just like following:

复制代码
Device->SetStreamSource(0, mVetexBuffer, 0, mVertexSize);

Device->SetStreamSourceFreq( 0, D3DSTREAMSOURCE_INDEXEDDATA | mNumInstance );

Device->SetStreamSource( 1, mInstanceVB, 0, mInstanceVSize );
Device->SetStreamSourceFreq( 1, D3DSTREAMSOURCE_INSTANCEDATA | 1ul ) ;

Device->SetIndices(mIndexBuffer);

Device->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0,
    mNumVertices, 0, mPrimitiveCount);
复制代码

 

Very similar with the Non HW instance rendering one.  One thing need to mention here is that HW Instance need vs 3.0 shader mode support. There is no hardware device acceleration  work with DrawPrimitve, only DrawIndexedPrimitive could do that.

 

Something More

In addition to HW Instance technology, here are something that I need to write down:

1) D3D Vertex layout or FVF.  Most of time, we will customize our vertex layout struct. For example:

struct MyVertex
{
    float3 _Pos;
    float3 _Normal;
    float2 _UV;
};

We SHULD NOT switch any two of them, that means you could not put the uv set at the first place and vertex position at last position in this struct. Their orders already defined in the D3D header file, from top to bottom means from first element to the last element. Just as what you see from the following snapt of code from D3D header files.
复制代码
// Flexible vertex format bits
//
#define D3DFVF_RESERVED0        0×001
#define D3DFVF_POSITION_MASK    0x400E
#define D3DFVF_XYZ              0×002
#define D3DFVF_XYZRHW           0×004
#define D3DFVF_XYZB1            0×006
#define D3DFVF_XYZB2            0×008
#define D3DFVF_XYZB3            0x00a
#define D3DFVF_XYZB4            0x00c
#define D3DFVF_XYZB5            0x00e
#define D3DFVF_XYZW             0×4002

#define D3DFVF_NORMAL           0×010
#define D3DFVF_PSIZE            0×020
#define D3DFVF_DIFFUSE          0×040
#define D3DFVF_SPECULAR         0×080

#define D3DFVF_TEXCOUNT_MASK    0xf00
#define D3DFVF_TEXCOUNT_SHIFT   8
#define D3DFVF_TEX0             0×000
#define D3DFVF_TEX1             0×100
#define D3DFVF_TEX2             0×200
复制代码

2) D3DFVF_TEX0 means no texture uv set. You could find the following line in D3D header files:
#define D3DFVF_TEX0             0×000

ZERO 0×000 will not give any effect for an OR operation. Do not be confused with TEXCOORD0 that appeared in the shader source code. They are two different things.

3) Try to use the same version for Vertex shader and Pixel shader. If you want to use ps_3_0 for pxiel shader, then you need to set vs_3_0 in used. I tried to use vs_3_0 for vertex shader and ps_2_0 for the pixel shader, but it did not work at all.

4) To make the HW Instance work correctly, you should at least write some code to make those instance vertex elements are used in the vertex shader or pixel shader. Otherwise, there will be nothing display on the screen. No instance data need to deal with, so no geometry need to display. It make sense.

 

The full source code could be download from here.

posted @   opencoder  阅读(377)  评论(0编辑  收藏  举报
编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示