D3D Hardware Instance
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; };
// 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
#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.
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了