Vertex Fog
When the system performs vertex fogging, it applies fog calculations at each vertex in a polygon, and then interpolates the results across the face of the polygon during rasterization. Vertex fog effects are computed by the Microsoft Direct3D lighting and transformation engine. For more information, see Fog Parameters.
If an application does not use Direct3D for transformation and lighting, the application must perform fog calculations. In this case, place the fog factor that is computed in the alpha component of the specular color for each vertex. Any formula can be used—range-based, volumetric, or otherwise. Direct3D uses the supplied fog factor to interpolate across the face of each polygon. Applications that perform their own transformation and lighting also must perform their own vertex fog calculations. As a result, such an application need only enable fog blending and set the fog color through the associated render states, as described in Fog Blending and Fog Color.
Note: When using a vertex shader, vertex fog must be used. This is accomplished by using the vertex shader to write the per-vertex fog intensity to the oFog register. After the pixel shader completes, the oFog data is used to linearly interpolate with the fog color. This intensity is not available in a pixel shader.
Range-Based Fog
Note: Direct3D uses range-based fog calculations only when using vertex fog with the Direct3D transformation and lighting engine. This is because pixel fog is implemented in the device driver, and no hardware currently exists to support per-pixel range-based fog. If an application performs its own transformation and lighting, it must perform its own fog calculations, range-based or otherwise.
Sometimes, using fog can introduce graphic artifacts that cause objects to be blended with the fog color in nonintuitive ways. For example, imagine a scene in which there are two visible objects: one distant enough to be affected by fog, and the other near enough to be unaffected. If the viewing area rotates in place, the apparent fog effects can change, even if the objects are stationary. The following illustration shows a top-down view of such a situation.
Range-based fog is another, more accurate, way to determine the fog effects. In range-based fog, Direct3D uses the actual distance from the viewpoint to a vertex for its fog calculations. Direct3D increases the effect of fog as the distance between the two points increases, rather than the depth of the vertex in the scene, thereby avoiding rotational artifacts.
If the current device supports range-based fog, it sets the SupportsFogRange property in the RasterCaps member of the Caps structure that is returned by a call to the Manager.GetDeviceCaps method. To enable range-based fog, set the RenderStateManager.RangeFogEnable property to true.
Range-based fog is computed by Direct3D during transformation and lighting. Applications that do not use the Direct3D transformation and lighting engine also must perform their own vertex fog calculations. In this case, provide the range-based fog factor in the alpha component of the specular component for each vertex.
Using Vertex Fog
Use the following steps to enable vertex fog in an application.
- Enable fog blending by setting RenderStateManager.FogEnable to true.
- Set the fog color in the RenderStateManager.FogColor property.
- Choose the desired fog formula by setting the RenderStateManager.FogVertexMode property to a member of the FogMode enumerated type.
- Set the fog parameters as desired for the selected fog formula in the render states.
The following C# code example shows what these steps might look like in code.
[C#]
// For the purposes of this example, device is a valid Device object.
//
void SetupVertexFog(Color color, FogMode mode, bool bUseRange, float fDensity)
{
float Start = 0.5f; // Linear fog distances.
float End = 0.8f;
// Enable fog blending.
device.RenderState.FogEnable = true;
// Set the fog color.
device.RenderState.FogColor = color;
// Set fog parameters.
if (mode == FogMode.Linear)
{
device.RenderState.FogVertexMode = mode;
device.RenderState.FogStart = Start;
device.RenderState.FogEnd = End;
}
else
{
device.RenderState.FogVertexMode = mode;
device.RenderState.FogDensity = fDensity;
}
// Enable range-based fog if desired (only supported for
// vertex fog). For this example, it is assumed that bUseRange
// is set only if the driver exposes the
// RasterCaps.SupportsFogRange capability.
// Note: This is slightly more performance-intensive
// than non-range-based fog.
if (bUseRange)
device.RenderState.RangeFogEnable = true;
}