rendering multiple billboards at once

Started by
10 comments, last by Chaucer 20 years, 6 months ago
How would you go about rendering multiple billboards at once? Since in order to render them correctly, the world would have to be rotated to make them face the camera OR the vertices would have to be changed to face the camera each frame, I see the only way to do it is with a dynamic vertex buffer. Thanks.
Thanks!
Advertisement
You don''t need to rotate the world nor modify the vertices. You just need to apply an apropriate world matrix transformation that would make every billboard vertex face the camera. There are plenty of tutorials out there that explain how to do this.



Mariano Ruggiero
Lead Programmer
ONIRIC GAMES
I think one of the fastest ways is to keep a matrix that represents the position of your camera, the camera matrix.

When it comes time to render your billboards extract the X and Y orthonormals from your matrix, ie if you have a row majour matrix, then the X and Y orthonormals will be the first and second row.

You can then build your billboards using quads and the vectors, and they will automatically face the camera, or away from the camera depending on your triangle winding, so you may need to swap a fiew signs untill you get it right.

heres some code

    //right is the x axis, as viewed from the end of the z axis    Vector right(cameraOrientationMatrix.m11 * halfWidth,   		cameraOrientationMatrix.m21 * halfWidth,		cameraOrientationMatrix.m31 * halfWidth);    //and y is conveniently up, unless you''re an engineer    Vector up(cameraOrientationMatrix.m12 * halfHeight,		cameraOrientationMatrix.m22 * halfHeight,		cameraOrientationMatrix.m32 * halfHeight);        glBegin(GL_TRIANGLE_STRIP);        //top right                        glTexCoord2f(1.0,0.0);        gVertex(right + up + location);        //top left        glTexCoord2f(0.0,0.0);        gVertex(-right + up + location);        //bottom right        glTexCoord2f(1.0,1.0);        gVertex(right - up + location);        //bottom left        glTexCoord2f(0.0,1.0);        gVertex(-right - up + location);    glEnd();
Your code would not allow me to use a static vertex buffer.

My current billboard rendering code:
	D3DXMATRIX viewMatrix, worldMatrix;	D3DXMATRIX inverseMatrix, scaleMatrix;		//scale the billboard	D3DXMatrixScaling(&scaleMatrix, m_Scale.x, m_Scale.y, m_Scale.z);		//make billboard face camera		m_pd3dDevice->GetTransform(D3DTS_VIEW, &viewMatrix);	D3DXMatrixInverse(&inverseMatrix,NULL, &viewMatrix);  	//translate it to the desired position	inverseMatrix._41 = m_Position.x;	inverseMatrix._42 = m_Position.y;	inverseMatrix._43 = m_Position.z;			D3DXMatrixMultiply(&worldMatrix, &scaleMatrix, &inverseMatrix);		m_pd3dDevice->SetTransform(D3DTS_WORLD, &worldMatrix); 		//set texture	m_pd3dDevice->SetTexture(textureStage, m_pTexture);			//draw the bilboard	m_pd3dDevice->SetStreamSource(0, m_pVertexBuffer, sizeof(BILLBOARD_VERTEX));	m_pd3dDevice->SetVertexShader(D3DFVF_BILLBOARD_VERTEX);	m_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP,0,2);		//clear the texture	m_pd3dDevice->SetTexture(textureStage, NULL);	//load identity matrix		D3DXMatrixIdentity(&worldMatrix);	m_pd3dDevice->SetTransform(D3DTS_WORLD, &worldMatrix);


I''m sorry but I don''t understand how I can apply a world matrix transformation that will work for every billboard.
Thanks!
Sorry, I misunderstood your question. I was talking about the way you are doing billboarding now...

So, you want to make just one DrawPrimitive() call for all your billboards... Well, in that case I think you''re right. You''ll need a dynamic VB. But I don''t think that''ll be better than what you''re doing now.



Mariano Ruggiero
Lead Programmer
ONIRIC GAMES
You''re right, but I don''t see much need for a static vertex buffer when you''re talking about just four verticies.

The method shown was just an optimisation to avoid having to perform several matrix multiplications per billboard. By performing the camera transformation, and then calculating each vertex position within world space, so that they ended up facing the camera.

But you are right, I think you would need a dynamic vertex buffer, so that you could modify each vertex to take account of the camera location.
If I have over a thousand billboards, over 1000 drawprim calls, it begins to slow it down pretty quick.
Thanks!
For more than a few billboards you should definitely use a dynamic vertex buffer, and transform them to face the camera.

You can actually use a static buffer if you do the billboard calculations within a vertex shader or use point sprites though.

But wouldn''t the output be the same, since you call just as many DP()s and do the same amount of calculations?

--
You''re Welcome,
Rick Wong
- sitting in his chair doing the most time-consuming thing..
If you transform the vertices into world space yourself then you only need one DP call, since there are no world matrix changes. The output will be the same (or should be), but it''ll be much faster.

This topic is closed to new replies.

Advertisement