The modulation case assumes that the results of each pass are being multiplied together, and we wish to fog the final result:
cdst = Fog(Pci) where ci is the color entering the fog unit in pass i
This case occurs most commonly when applying light maps to a scene, and is more complex to implement than the additive case. Here is the procedure for the three-pass case; it can be generalized by induction. We wish to obtain:
cdst = Fog(c1c2c3) = fcfog + (1-f)( c1c2c3)
For the first pass, choose either GR_FOG_WITH_TABLE or GR_FOG_WITH_ITERATED_ALPHA as the fog mode and OR in GR_FOG_ADD2, as shown in Table Special Effects.2 and demonstrated in Example Special Effects.6. Set the source and destination alpha blending factors to GR_BLEND_ONE and GR_BLEND_ZERO, respectively. After the first pass,
cdst = 1·Fog(c1) + 0·cdst
= Fog(c1)
= (1-f)c1
For the second pass (and all intermediate passes in the general case), disable fogging (grFogMode(GR_FOG_DISABLE)) and set the source and destination alpha blending factors to GR_BLEND_DST_COLOR and GR_BLEND_ZERO, respectively. (Using source and destination factors of GR_BLEND_ZERO and GR_BLEND_SRC_COLOR, respectively, will work as well.) After the second pass we have:
cdst = cdst·cin + 0·cdst
= cdst·c2
= (1-f)c1c2
For the final pass, enable fogging again, choosing either GR_FOG_WITH_TABLE or GR_FOG_WITH_ITERATED_ALPHA , and OR in GR_FOG_MULT2, which causes the blended pixel term to be suppressed. Set the source and destination alpha blending factors to GR_BLEND_ONE and GR_BLEND_PREFOG_COLOR, respectively. The result is:
Fog(c3) = fcfog
cdst = 1·Fog(c3) + c3·cdst
= fcfog + c3·(1-f)c1c2
= fcfog + (1-f)c1c2c3
Example Special Effects.6 Three-pass modulation fogging.
The code segment below assumes that a fog table has been defined.
const GrFog_t fog[GR_TABLE_SIZE];
int i;
/* load the fog table */
grFogTable(fog);
/* set a fog color - how about smoke? */
grFogColorValue(0);
/* set fog mode and alpha blending function for pass 1*/
grFogMode(GR_FOG_WITH_TABLE | GR_FOG_ADD2);
grAlphaBlendFunction(GR_BLEND_ONE, GR_BLEND_ZERO, GR_BLEND_ONE, GR_BLEND_ZERO);
/* draw pass 1 */
…
/* set fog mode and alpha blending function for pass 2*/
grFogMode(GR_FOG_DISABLE);
grAlphaBlendFunction(GR_BLEND_DST_COLOR, GR_BLEND_ZERO, GR_BLEND_ONE, GR_BLEND_ZERO);
/* draw pass 2 */
…
/* set fog mode and alpha blending function for final pass */
grFogMode(GR_FOG_WITH_TABLE | GR_FOG_MULT2);
grAlphaBlendFunction(GR_BLEND_ONE, GR_BLEND_PREFOG_COLOR, GR_BLEND_ONE, GR_BLEND_ZERO);
/* draw pass 3 */
…
Share with your friends: |