Facing Beams

One way to render particles, tracers, light-sabers, laser beams and light beams is with so called 'facing beams'. Where regular facing particles are aligned perpendicular to the viewing direction vector, facing beams are aligned to both the viewing vector and a specified direction vector (e.g. a motion vector of a particle).

It will not render perfectly in all situations (e.g. when the viewing direction is parallel to the beam alignment vector) but will generally look acceptable:



The code is surprisingly simple:
void DrawFacingBeam(float3 p1, float3 p2, float3 eyepos, float width)
{
 // compute vector from eye to point
 float3 vec1 = eyepos - p1;
     
 // compute vector along line length
 float3 vec2 = p1 - p2;
     
 // cross product
 float3 vec = Normalize( CrossProduct(vec1, vec2) ) * width;
 
 // compute vertices
 float3 v1 = p2 + vec;
 float3 v2 = p2 - vec;
 float3 v3 = p1 - vec;
 float3 v4 = p1 + vec;
 
 // render quad
 glBegin(GL_QUADS);
  glTexCoord2i(0, 0); glVertex3fv(v1);
  glTexCoord2i(0, 1); glVertex3fv(v2);
  glTexCoord2i(1, 1); glVertex3fv(v3);
  glTexCoord2i(1, 0); glVertex3fv(v4);
 glEnd();
}
Where p1 and p2 are the two points of the line segment, and width is the thickness of the beam.

You can easily modify this to render things like smoke/vapor trails or light trails, by looping through a number of points instead of just two. You will need to do the calculation per point. Ideally you will render this with a single triangle strip.
Email: martijn AT bytehazard DOT com
Page created: 2007-12-23