The additive case assumes that the results of each pass are being added together, and we wish to fog the final result:
cdst = Fog(Sci) where ci is the color entering the fog unit in pass i
Here is the procedure for the two-pass case. This can be generalized to multiple passes by induction. We wish to obtain:
cdst = Fog(c1 + c2) = fcfog + (1-f)(c1 + c2)
For the first pass, choose either GR_FOG_WITH_TABLE or GR_FOG_WITH_ITERATED_ALPHA as the fog mode and 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)
= fcfog + (1-f)c1
For the second pass, add GR_FOG_ADD2 to the fog mode, causing the blended fog term to be suppressed (if you forget to do this, the cfog term will occur twice). Set the source and destination alpha blending factors to GR_BLEND_ONE and GR_BLEND_ONE, respectively. Thus,
Fog(c2) = (1-f)c2
cdst = 1·cin + 1·cdst
= (1-f)c2 + (fcfog + (1-f)c1)
= fcfog + (1-f)(c1 + c2)
Example Special Effects.5 Two-pass additive fogging.
The code segment below assumes that a fo 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 mode to fog table */
grFogMode(GR_FOG_WITH_TABLE);
grAlphaBlendFunction(GR_BLEND_ONE, GR_BLEND_ZERO, GR_BLEND_ONE, GR_BLEND_ZERO);
/* draw the first pass */
…
/* set mode to fog table */
grFogMode(GR_FOG_WITH_TABLE | GR_FOG_ADD2);
grAlphaBlendFunction(GR_BLEND_ONE, GR_BLEND_ONE, GR_BLEND_ONE, GR_BLEND_ZERO);
/* draw the second pass */
…
Share with your friends: |