Written by Robert Dunlop Microsoft DirectX MVP

http://www.mvps.org/vbdx/articles/billboards/

 Related Articles of Interest: Improved Ray Picking Projecting a Ray from 2D Screen Coordinates

## Introduction

Billboarding techniques are utilized in 3D applications to orient a polygon to always face the user.  This allows the application of a 2D image, such as a lens flare or images of foliage, into a 3D scene.  By applying an image in this way, the illusion of complex objects or effects can be applied with a minimum of overhead.

## Viewing a Matrix as a Group of Vectors

To understand the method that we will use here, we need to take an alternate look at our 4x4 viewing matrix.  Ignoring the fourth column, we can divide a matrix into four vectors:

 Rotation Vectors Translation Vector Right Vector Up Vector Forward Vector M14 M24 M34 M44 M11 M21 M31 M12 M22 M32 M13 M23 M33 M41 M42 M43

With this knowledge in hand, we can calculate the location for each corner of a billboard so that it is perpendicular to the field of view, i.e. facing the viewer.

## Extracting the Vectors

To begin with, we will need to retrieve  the current viewing matrix and extract the Right and Up vectors from the matrix.  The vectors will then be normalized, so that we can readily scale them to the desired size.  The vectors will then be scaled to one half of the billboard size, so that they represent a distance from the center of the billboard:

D3DMATRIX mat;
lpDevice->GetTransform(D3DTRANSFORMSTATE_VIEW,&mat);
D3DVECTOR rightVect=Normalize(D3DVECTOR(mat._11,mat._21,mat._31))*size*0.5f;
D3DVECTOR upVect=Normalize(D3DVECTOR(mat._12,mat._22,mat._32))*size*0.5f;

## Creating the Billboard

All that remains, once we have these vectors, is to create the vertices for the billboard.  In this example, we will use a diamond shaped billboard, which can be rendered as a triangle strip:

 verts[0]=D3DLVERTEX(loc-rightVect, color, 0, 0.0f, 0.0f); verts[1]=D3DLVERTEX(loc+upVect, color, 0, 0.0f, 1.0f); verts[2]=D3DLVERTEX(loc-upVect, color, 0, 1.0f, 0.0f); verts[3]=D3DLVERTEX(loc+rightVect, color, 0, 1.0f, 1.0f);

That's it!  This code will of course have to be repeated every time the view matrix changes, which normally means every frame.  However, the math is pretty light, and the effects that can be added with just two alpha blended polygons is a considerable payoff.

Enjoy!

 Related Articles of Interest: Improved Ray Picking Projecting a Ray from 2D Screen Coordinates

 This site, created by DirectX MVP Robert Dunlop and aided by the work of other volunteers, provides a free on-line resource for DirectX programmers. Special thanks to WWW.MVPS.ORG, for providing a permanent home for this site.

Visitors Since 1/1/2000:
Last updated: 07/26/05.