Sign in to follow this  
bignose_game

Question about hardware instancing in Directx 9.0c

Recommended Posts

bignose_game    122
In Directx sdk instancing sample, it shows how to use hardware instancing to draw many boxes.
I want to use light map for each box, but I have the problem about the additional light map texture coordinate.

This is my vertex declaration. The additional texture coordinate is in stream 2

D3DVERTEXELEMENT9 g_VertexElemHardware[] =
{
{0,0,D3DDECLTYPE_FLOAT3,D3DDECLMETHOD_DEFAULT,D3DDECLUSAGE_POSITION,0},
{0,3*4,D3DDECLTYPE_FLOAT3,D3DDECLMETHOD_DEFAULT,D3DDECLUSAGE_NORMAL,0},
{0,6*4,D3DDECLTYPE_FLOAT2,D3DDECLMETHOD_DEFAULT,D3DDECLUSAGE_TEXCOORD,0},
{1,0,D3DDECLTYPE_D3DCOLOR,D3DDECLMETHOD_DEFAULT,D3DDECLUSAGE_COLOR,0},
{1,4,D3DDECLTYPE_D3DCOLOR,D3DDECLMETHOD_DEFAULT,D3DDECLUSAGE_COLOR,1},

//texture coordinate for light map
{2,0,D3DDECLTYPE_FLOAT2,D3DDECLMETHOD_DEFAULT,D3DDECLUSAGE_TEXCOORD,1},
D3DDECL_END()
};


struct BOX_VERTEX_TEXTURECOORD
{
float u,v;
};
IDirect3DVertexBuffer9 *g_pVBBoxTextureCoordinate=0;




I fill all texture coordinate into vertex buffer "g_pVBBoxTextureCoordinate".
Each instance's light map uv are differences.
Then use "SetStreamSourceFreq" to perform hardware instancing.


V( pd3dDevice->SetStreamSource( 0, g_pVBBox, 0, sizeof(BOX_VERTEX)) );
V( pd3dDevice->SetStreamSourceFreq( 0, D3DSTREAMSOURCE_INDEXEDDATA | g_NumBoxes ) ); //g_NumBoxes: number of box to draw

V( pd3dDevice->SetStreamSource( 1, g_pVBInstanceData, 0, sizeof( BOX_INSTANCEDATA_POS ) ) );
V( pd3dDevice->SetStreamSourceFreq( 1, D3DSTREAMSOURCE_INSTANCEDATA | 1ul ) );

V( pd3dDevice->SetIndices( g_pIBBox ) );

//set the additional light map texture coordinate
V( pd3dDevice->SetStreamSource( 2, g_pVBBoxTextureCoordinate, 0, sizeof( BOX_VERTEX_TEXTURECOORD ) ) );

//how to set the light map texture coordinate instance data?
//V( pd3dDevice->SetStreamSourceFreq(2,D3DSTREAMSOURCE_INDEXEDDATA | 1ul));
//V( pd3dDevice->SetStreamSourceFreq(2,D3DSTREAMSOURCE_INDEXEDDATA | 24ul)); //the number 24 means one box have 24 vertices
//V( pd3dDevice->SetStreamSourceFreq(2,D3DSTREAMSOURCE_INSTANCEDATA | 1ul ) );
//V( pd3dDevice->SetStreamSourceFreq(2,D3DSTREAMSOURCE_INSTANCEDATA | 24ul ) );


V( g_pEffect->SetTechnique( g_HandleTechnique ) );

V( g_pEffect->Begin( &cPasses, 0 ) );
for( iPass = 0; iPass < cPasses; iPass++ )
{
V( g_pEffect->BeginPass( iPass ) );

V( g_pEffect->SetTexture( g_HandleTexture, g_pBoxTexture ) );
V( g_pEffect->CommitChanges() );

V( pd3dDevice->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, 0, 4 * 6, 0, 6 * 2 ) );

V( g_pEffect->EndPass() );
}
V( g_pEffect->End() );



But the box still get the wrong box light map uv coordinate.
This is my code.
1.

V( pd3dDevice->SetStreamSource( 2, g_pVBBoxTextureCoordinate, 0, sizeof( BOX_VERTEX_TEXTURECOORD ) ) );
V( pd3dDevice->SetStreamSourceFreq(2,1ul)); //all box use the first uv


2.

V( pd3dDevice->SetStreamSource( 2, g_pVBBoxTextureCoordinate, 0, sizeof( BOX_VERTEX_TEXTURECOORD ) ) );
//do not use SetStreamSourceFreq
//all box use the first uv



3.

V( pd3dDevice->SetStreamSource( 2, g_pVBBoxTextureCoordinate, 0, sizeof( BOX_VERTEX_TEXTURECOORD ) ) );
V( pd3dDevice->SetStreamSourceFreq(2,D3DSTREAMSOURCE_INSTANCEDATA|1ul));
//uv error



4.

V( pd3dDevice->SetStreamSource( 2, g_pVBBoxTextureCoordinate, 0, sizeof( BOX_VERTEX_TEXTURECOORD ) ) );
V( pd3dDevice->SetStreamSourceFreq(2,D3DSTREAMSOURCE_INDEXEDDATA|24ul));
//all box use the first uv



Does anyone try to add the addition uv coordinate when using hardware instancing?
I want to use hardware instancing to draw trees, and each tree has their own light map.

Thanks!

Share this post


Link to post
Share on other sites
skytiger    294
[edit] how many vertices in stream2 ?

the problem with creative use of stream frequencies is that once the instance pointer for a given stream reaches the end - you get random data coming back

there isn't much useful you can do beyond standard instancing

which is really annoying - if the pointers simply wrapped back to 0
it would open up a whole world of multiple instancing techniques

either put the texcoord into the stream0 vertex buffer
or put it in a texture and read it with vtf

the best pattern I found for instancing is to use an instance data texture
which is incrementally updated by flushing an update queue using dup

diagram of what I mean

0a0
1a1
2a2
0b*
1b*
2b*



* = junk

Share this post


Link to post
Share on other sites
bignose_game    122
To skytiger:

How many vertices in stream2 ?
=> Stream 2 is the light map texture coordinate. The total number of vertices is (Box's total vertices)*(Box instance number).

the problem with creative use of stream frequencies is that once the instance pointer for a given stream reaches the end - you get random data coming back
=>Does it mean that I can't use "SetStreamSourceFreq" with difference frequency at the same time?

Thanks a lot!

Share this post


Link to post
Share on other sites
skytiger    294
I don't think it is possible to do this:

0 a 00
1 a 01
2 a 02
0 a 03
2 a 04
3 a 05
0 b 06
1 b 07
2 b 08
0 b 09
2 b 10
3 b 11

you will either get this:

0 a 00
1 a 01
2 a 02
0 a 00
2 a 02
3 a 03
0 b 00
1 b 01
2 b 02
0 b 00
2 b 02
3 b 03

or this:

0 a 00
1 a 00
2 a 00
0 a 00
2 a 00
3 a 00
0 b 01
1 b 01
2 b 01
0 b 01
2 b 01
3 b 01

neither of which helps you

your choice for each stream is:

- don't set frequency
- set index frequency
- set instance frequency

which will result in:

- don't set frequency
- set index frequency
your second vertex buffer will be indexed :-(

- set instance frequency
your second vertex buffer will be repeated :-(

on xbox360 it would be easy using vfetch

you could store you texture coordinates in a texture
and read the with Vertex Texture Fetch
you will have enough information to calculate the offsets

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this