Skip to main content
GameDev.net gamedev.net
🔒 Locked

batching billboards

Started by Cybird Mar 9, 2003 at 8:42 AM 9 replies 6.1k views
Original Post
Cybird
Cybird
How can i batch billboards wich share the same picture to draw them all with only one DrawPrimitive call? i tried to transform them with a single matriz but it dont works. Having them to transform each one each frame and render them individually kills fps VERY badly. Thx for your advices
Cybird
Cybird
bump
Matt Halpin
Matt Halpin
1)
Use dynamic vertex (and index) buffers and do the billboarding on the cpu. 1 drawprim call, and dynamic vertex data is actually pretty quick (*much* quicker than individual drawprim calls).

2)
Use vertex shaders to do the billboarding - 4 verts per billboard, store camera right and up vectors in the constant data, then store a 2d component for each of the 4 vertices: (-1,-1), (-1,1), (1,-1), (1,1). In the vertex shader, multiply the camera right and up vectors by the component x and y values, add them together, and add the vertex position. Then output this...

HTH

Matt Halpin
Cybird
Cybird
THAT is the problem.

i set my world matrix before rendering the big VB.

the billboards are well rendered, but they are also moving along with camera, wich is obviously not a desired effect.

I think it have to do with translation, as all my vertices in my VB represent the WORLD location and not the LOCAL location.

Well thx...
Matt Halpin
Matt Halpin
You can''t do billboarding with the standard matrix setup. You *have* to write in the dynamic vertex data, or use a vertex shader (or possibly some over matrix palette stuff - I don''t know).

Is that what you''re doing (dynamic vertex data)?

Set your world matrix to the identity matrix, then set up your camera etc matrices as usual. Then update the vertex data to calculate the billboarded world space coordinates.

Matt Halpin
Cybird
Cybird
No, I Currently use static VB...

I know how to use dynamic VB, but how is done the manual transformation of vertices?

it appears that each billboard need a local rotation transformations only...

but it''s still unclear how to do it.

suppose i have a billboard at

(0,150,0)

and a camera at (0 150 -30) facing it...

what component of the dynamic VB i have to update each frames?
Matt Halpin
Matt Halpin
You need to update the position component of each of the 4 vertices that make up each billboard quad.

Think about how the billboard appears in *world* space. This is what you''re trying to generate.

The camera has an ''up'' and ''right'' vector (these define how the screen is oriented in world space). The ''at'' vector points into the screen.

So, for a billboard at (0,150,0) and a camera at (0,150,-30) facing the billboard:

camera ''at'' : (0,0,1)
camera ''up'' : (0,1,0)
camera ''right'' : (-1,0,0)

Now, the vertex of the billboard that will be in the top-left of the screen will be generated like this:

(0,150,0) + (-1 * ''right'') + (1 * ''up'').

This takes the billboard centre, moves to the left, then moves up.

You generate the other 3 vertices by changing the -1 and 1.
NB, you can change the size of the billboard by changing those 2 numbers to -size and size.

So you''re actually generating world space vertex positions. This means your local matrix should be the identity.

HTH

Matt Halpin
Cybird
Cybird
Thanx alot!


i''ll try it.

So this is supposed to be much faster than drawing them individually?

Because Dynamic Buffers are usually slower...
Matt Halpin
Matt Halpin
Yup, it should be much faster.

A single Dynamic buffer update and render will be slower than a single static buffer render (with same primitive counts etc).

But that''s not what is being compared.

A single dynamic buffer update and render should be much faster than lots of individual drawprim calls...

You obviously need to do your dynamic buffer updates correctly: use discard and nooverwrite flags at the correct times; sequential writes etc. btw, the sequential writes (and nooverwrite/discard flags) means that you will have to fill in the whole vertex rather than just the position (unless you''re using different streams).

HTH

Matt Halpin
Cybird
Cybird
I''ve done it, but right now my billboards are "rotating" when i move the mouse.

they are not exactly facing the camera.

this is my code, hope this help


  
//Dimension du billboard

float fSize = 25;


D3DXMATRIX mat;
g_pDevice->GetTransform(D3DTS_VIEW,&mat);

//D3DXMatrixInverse(&mat,NULL, &mat);

D3DXVECTOR3 vctRight(mat._11,mat._21,mat._31);
D3DXVec3Normalize(&vctRight, &vctRight);



D3DXVECTOR3 vctUp(mat._12,mat._22,mat._32);
D3DXVec3Normalize(&vctUp, &vctUp);



//Scaling des vertices

D3DXVec3Scale(&vctUp, &vctUp, fSize * 0.5);
D3DXVec3Scale(&vctRight, &vctRight, fSize * 0.5);

//Locking du VB

sBillboardSetVertex *pVertices;
m_pVertexBuffer->Lock(0,0, (void **)&pVertices, D3DLOCK_DISCARD);


//Recreation du VB

DWORD iVertex = 0L;
D3DCOLOR col = D3DCOLOR_RGBA(255,255,255,255);

D3DXVECTOR3 vctTemp;
for(DWORD i = 0; i < m_dwNbBillboards; i++)
{
//Recreation des 6 vertex du VB

D3DXVECTOR3 loc = m_pPositions[i];

MakeVertex(&pVertices[iVertex], loc-vctRight + vctUp, col,0.0f,0.0f);
iVertex++;

MakeVertex(&pVertices[iVertex], loc+vctRight + vctUp, col, 1.0f, 0.0f);
iVertex++;

MakeVertex(&pVertices[iVertex], loc+vctRight - vctUp, col,1.0f,1.0f);
iVertex++;

MakeVertex(&pVertices[iVertex], loc+vctRight - vctUp, col,1.0f,1.0f);
iVertex++;

MakeVertex(&pVertices[iVertex], loc-vctRight - vctUp, col,0.0f,1.0f);
iVertex++;

MakeVertex(&pVertices[iVertex], loc-vctRight + vctUp, col,0.0f,0.0f);
iVertex++;

}
m_pVertexBuffer->Unlock();

//Setting du Vertex Buffer

g_pDevice->SetStreamSource( 0, m_pVertexBuffer, 0, sizeof( sBillboardSetVertex ) );
g_pDevice->SetFVF( BILLBOARDSETFVF );

//Setting de la texture

g_pDevice->SetTexture(0, m_pTexture->GetTexture() );

//Update de la matrice de transfo


//Setting de la matrice world a identity

D3DXMATRIX matWorld;
D3DXMatrixIdentity(&matWorld);
g_pDevice->SetTransform(D3DTS_WORLD, &matWorld);


g_pDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2 * m_dwNbBillboards);

[/source[
Matt Halpin
Matt Halpin
Hmmm, that looks alright. Could you post screenshots of the problem?

Matt Halpin

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.