Billboarding
Because I chose to use Z as the up direction in my world, I couldn’t use XNA’s built-in Matrix.CreateBillboard function (since it thought that (0,1,0) was up). This meant that yet again, I had to roll my own. I thought the code might be useful for anyone trying to do their own billboarding (or doing something special with billboarding, like centering the object around a point not within the object), so I decided to post it. This is viewpoint-based billboarding, so it has to be done for each object, and could be expensive. I like the effect though, so I’ll probably come up with a way to speed it up later.
// Find the directional vector pointing from the camera to the object
Vector3 diff = Vector3.Normalize(CameraPosition – Position);
// Find the axis of rotation
Vector3 axis;
if (Vector3.UnitZ == diff) axis = Vector3.Zero;
else axis = Vector3.Normalize(Vector3.Cross(Vector3.UnitZ, diff));
// Find the degree by which to rotate
float ang = (float)Math.Acos(Vector3.Dot(Vector3.UnitZ, diff));
// Create the billboard transformation
Matrix BillboardTransformation = Matrix.CreateFromAxisAngle(axis, ang);
Basically, this rotates the object around an arbitrary axis, with the axis and amount of rotation always set up such that the object will be facing the camera. This creates true billboarding, as opposed to cheap billboarding (where all objects are aligned with the viewing plane), so it will be a little more expensive.
This is useful for some things like volume rendering using slicing planes, because you can rotate the whole volume around a central point, and have all of the planes still lined up. Also note that I’ve used Vector3.UnitZ – that is my world’s “up” direction. You could replace it with UnitY if you like, or whatever direction you like to have as up.
February 15th, 2007 at 10:45 am
For simple gfxs, instead of using a texture-mapped quad facing the camera you could use pointsprites (http://blogs.msdn.com/shawnhar/archive/2007/01/03/point-sprites-on-xbox.aspx).