I decided to take a small spinoff in the weekend and add some basic particle rendering to my game engine. Right now the particles are rendered as billboards, built by the CPU. Eventually I want to try GPU acceleration with Transform Feedback and rendering volumetric particles.
The particle billboards are build in one of two ways, one is the traditional camera plane facing billboard:
//
// Faces the camera plane.
//
void CreateBillboardCameraFacing(const Vec3 & up, const Vec3 & right,
const Vec3 & origin, const Vec2 & size,
Vec3 points[4])
{
const Vec3 halfWidth = (size.width * 0.5f) * right; // X
const Vec3 halfHeigh = (size.height * 0.5f) * up; // Y
points[0] = origin + halfWidth + halfHeigh;
points[1] = origin - halfWidth + halfHeigh;
points[2] = origin - halfWidth - halfHeigh;
points[3] = origin + halfWidth - halfHeigh;
}
And another possible method, which can produce better results for larger billboards is the camera position facing billboard:
//
// Faces the camera world position.
//
void CreateBillboardFacingCameraPos(const Vec3 & up, const Vec3 & cameraPos,
const Vec3 & origin, const Vec2 & size,
Vec3 points[4])
{
const Vec3 Z = normalize(cameraPos - origin);
const Vec3 X = normalize(cross(up, Z));
const Vec3 Y = cross(Z, X);
const Vec3 halfWidth = (size.width * 0.5f) * X;
const Vec3 halfHeigh = (size.height * 0.5f) * Y;
points[0] = origin + halfWidth + halfHeigh;
points[1] = origin - halfWidth + halfHeigh;
points[2] = origin - halfWidth - halfHeigh;
points[3] = origin + halfWidth - halfHeigh;
}
Both methods are well explained in Eric Lengyel’s book Math for 3D Game Programming and CG.
Following are some screenshots of what I did so far.