8.4 The Blender in 2-Cycle Mode (Fog)

Next let's bring up the topic of Fog, which can be realized when the Blender operates in 2-Cycle mode. In the Fog process, the fog parameter is calculated based on the Z value of each vertex, and the fog color and pixel color are then blended according to this parameter. The Fog process is not very difficult to use, but it is important to remember to follow the procedures described below.

8.4.1 Set the Geometry Mode

When implementing the Fog process on a polygon, you must change the thickness of the fog to correspond to the distance between the polygon and the camera. In order to do this, you need to make use of the geometry information of the polygon. Polygon geometry calculations are the job of the RSP, so when you enable the Fog function you also need to do this in the RSP.

List 8-3

  /* Fog mode */
  gSPSetGeometryMode(glistp++, G_FOG | G_ZBUFFER | G_SHADE |
                                       G_SHADING_SMOOTH | G_CULL_BACK);

8.4.2 Set the Pipeline Mode to 2-Cycle Mode

In order to perform Fog processing you must set the pipeline mode to 2-Cycle mode.

List 8-4

  /* Set the RDP cycle type */
  gDPSetCycleType(glistp++, G_CYC_2CYCLE);

8.4.3 Set the Appropriate Rendering Mode x

When rendering with fog, the fog is blended in the Blender in the first cycle and in the framebuffer in the second cycle. For the first cycle, the rendering mode should be specified as either of the following:

-G_RM_FOG_SHADE_A
  Blend fog using the shade alpha
-G_RM_FOG_PRIM_A
  Blend fog using the fog alpha (the fog color register's alpha value)

If you use the latter of these two rendering modes, a uniform fog effect will be implemented on pixels of differing depth. For the second cycle, you should set the rendering mode the same way you would for 1-Cycle mode, using either G_RM_AA_ZB_OPA_SURF2 or G_RM_AA_ZB_XLU_SURF2.

List 8-5

  /* Fog - transparent - anti-aliasing - Z buffering  */
  gDPSetRenderMode(glistp++, G_RM_FOG_SHADE_A, G_RM_AA_ZB_XLU_SURF2);

8.4.4 Determine Fog Color and Fog Location & Thickness

If you follow the procedure up to this point, you are just about ready to use the Fog process. However, you still need to specify the essential elements of fog color, position and thickness. Setting the fog color is a simple process of using the gDPSetFogColor command to set the RGBA components in the RDP's fog color register. This command works exactly like gDPSetEnvColor and gDPSetBlendColor, so we will not provide a very in depth explanation.

  gDPSetFogColor(Gfx *gdl, u32 r, u32 g, u32 b, u32 a)
   gdl-- Display list pointer
   r-- Red component of RGBA color (8bit precision, 0 - 255)
   g-- Green component of RGBA color (8bit precision, 0 - 255)
   b-- Blue component of RGBA color (8bit precision, 0 - 255)
   a-- Alpha component of RGBA color (8bit precision, 0 - 255)

This sets the RDP's fog color. Fog color is a general-use color register inside the Blender (BL). For details, see the N64 Programming Manual, Chapter 12.7.3, "BL Internal Color Registers."

Use the gSPFogPosition command to specify the effective distance for fog and the fog thickness. The gSPFogPosition command takes two arguments in addition to the display list pointer. These two arguments specify, respectively, the fog's starting point and the fog's saturation point. Both can take any value between 0 and 1000, with 0 being the near clipping plane and 1000 being the far clipping plane. The fog's starting point is the point at which fog effects become valid, so any part in front of that point will not take a fog effect. Any part behind the fog saturation point will be completely filled with the fog color.

  gSPFogPosition(Gfx *gdl, s32 min, s32 max)
   gdl -- Display list pointer
   min -- Where fog starts (takes value of 0 (near plane) to 1000 (far plane))
   max -- Where fog saturates (takes value of 0 (near plane) to 1000 (far plane))

This specifies where the fog starts and where it saturates. Fog changes the color of an object based on its Z position. Normally, the farther away an object is from the viewpoint, the more it is mixed with the "fog color" (see gDPSetFogColor), becoming closer in color to the fog color.

List 8-6

  gDPSetFogColor(glistp++,
               __FOG_INTENSITY__,
               __FOG_INTENSITY__,
               __FOG_INTENSITY__,
               255);
  gSPFogPosition(glistp++, 700, 1000);

To enable this fog process in the gfx8.c sample program, define __FOG__ on line 26.