Billboard

   In [1]3D [2]computer graphics billboard is a flat image placed in the
   scene that rotates so that it's always facing the camera. Billboards used
   to be greatly utilized instead of actual [3]3D models in old [4]games
   thanks to being faster to render (and possibly also easier to create than
   full 3D models), but we can still encounter them even today and even
   outside retro games, e.g. [5]particle systems are normally rendered with
   billboards (each particle is one billboard). Billboards are also commonly
   called [6]sprites, even though that's not exactly accurate.

   By axis of rotation there are two main types of billboards:

     * Ones rotating only about vertical axis, i.e. billboards that change
       only their [7]yaw, they only face the camera in a top-down view of the
       scene. Such sprite may deform on the screen (when the camera is at
       different height level) just like 3D models do and when viewed
       completely from above will disappear completely. This may in some
       situations look better than other options (e.g. in [8]games enemies
       won't appear lying on their back when seen from above).
     * Freely rotating ones, i.e. ones that change all three [9]Euler angles
       so that they ALWAYS face the camera from any possible angle.

   Furthermore there is another subdivision into two main types by HOW the
   billboards rotate:

     * Projection plane aligned: These billboards always align their
       orientation with the camera's projection plane (they simply rotate
       themselves in the same way as the camera) which always end up on the
       screen as an undeformed and unrotated image. This is simple to
       implement, we can simply [10]blit a 2D image on the rendered 3D view.
     * Camera position facing: These billboards face themselves towards the
       camera's position and copy the camera's [11]roll.

   Though the two types above may seem like two same things at first glance,
   they are in fact not, for the latter we need to know the camera and
   billboard's positions, for the former we only need the camera's rotation.
   For simplicity we usually choose to implement the former (projection plane
   aligned), though the latter may result in look closer to that which would
   be produced by an actual 3D model of the object.

     projection plane aligned                           position facing

                  |                                          \
                  |                                           |
                  |                                            \

         _.'|                |                       _.'|                |
       <:_  |                |                     <:_  |                |
          '.|                |                        '.|                |
       camera                                      camera
                       |                                            /
                       |                                           |
               |       |                                     _    /
               |                                         _.-'
               |

   Projection plane aligned vs position facing billboards.

   Some billboards also choose their image based on from what angle they're
   viewed (e.g. an enemy in a game viewed from the front will use a different
   image than when viewed from the side, as seen e.g. in [12]Doom). Also some
   billboards intentionally don't scale and keep the same size on the screen,
   for example health bars in some games.

   In older software billboards were implemented simply as image
   [13]blitting, i.e. the billboard's scaled image would literally be copied
   to the screen at the appropriate position (this would implement the freely
   rotating billboard). Nowadays when rendering 3D models is no longer really
   considered harmful to performance and drawing pixels directly is less
   convenient, billboards are more and more implemented as so called
   [14]textured [15]quads, i.e. they are really a flat square 3D model that
   may pass the same pipeline as other 3D models (even though in some
   frameworks they may actually have different [16]vertex shaders etc.) and
   that's simply rotated to face the camera in each frame (in [17]modern
   frameworks there are specific functions for this).

   [18]Fun fact: in the old games such as [19]Doom the billboard images were
   made from photographs of actual physical models from clay. It was easier
   and better looking than using the primitive 3D software that existed back
   then.

Implementation Details

   The following are some possibly useful things for implementing billboards.

   The billboard's position on the screen can be computed by projecting its
   center point in [20]world coordinates with [21]modelview and
   [22]projection matrices, just as we project vertices of 3D models.

   The billboard's size on the screen shall due to [23]perspective be
   multiplied by 1 / (tan(FOV / 2) * z) where FOV is the camera's [24]field
   of view and z is the billboard's distance from camera's projection plane
   (which is NOT equal to the mere distance from the camera's position, that
   would create a [25]fisheye lens effect -- the distance from the projection
   plane can be obtained from the above mentioned [26]projection matrix). (If
   the camera's FOV is different in horizontal and vertical directions, then
   also the billboard's size will change differently in these directions.)

   For billboards whose images depends on viewing angle we naturally need to
   compute the angle. We may do this either in 2D or 3D -- most games resort
   to the simpler 2D case (only considering viewing angle in a single plane
   parallel to the floor), in which case we may simply use the combination of
   [27]dot product and [28]cross product between the [29]normalized
   billboard's direction vector and a normalized vector pointing from the
   billboard's position towards the camera's position (dot product gives the
   [30]cosine of the angle, the sign of cross product's vertical component
   will give the rest of the information needed for determining the exact
   angle). Once we have the angle, we [31]quantize (divide) it, i.e. drop its
   precision depending on how many directional images we have, and then e.g.
   with a [32]switch statement pick the correct image to display. For the 3D
   case (possible different images from different 3D positions) we may first
   transform the sprite's 3D facing vector to [33]camera space with
   appropriate matrix, just like we transform 3D models, then this
   transformed vector will (again after quantization) directly determine the
   image we should use.

   When implementing the free rotating billboard as a 3D quad that's aligning
   with the camera projection plane, we can construct the [34]model matrix
   for the rotation from the camera's normalized directional vectors: R is
   camera's right vector, U is its up vector and F is its forward vector. The
   matrix simply transforms the quad's vertices to the coordinate system with
   bases R, U and F, i.e. rotates the quad in the same way as the camera.
   When using [35]row vectors, the matrix is following:

 R.x R.y R.z 0
 U.x U.y U.z 0
 F.x F.y F.z 0
 0   0   0   1

Links:
1. 3d.md
2. graphics.md
3. 3d_model.md
4. game.md
5. particle_system.md
6. sprite.md
7. yaw.md
8. game.md
9. euler_angle.md
10. blit.md
11. roll.md
12. doom.md
13. blit.md
14. texture.md
15. quad.md
16. vertex_shader.md
17. modern.md
18. fun.md
19. doom.md
20. world_space.md
21. modelview.md
22. projection.md
23. perspective.md
24. fov.md
25. fisheye.md
26. projection.md
27. dot_product.md
28. cross_product.md
29. normalization.md
30. cos.md
31. quantization.md
32. switch.md
33. camera_space.md
34. model_matrix.md
35. row_vector.md