M2/Rendering

From wowdev
Jump to: navigation, search

Blending Modes

Blending modes used when drawing M2 batches can be found on the Rendering page.

M2Material Blending Mode to Pixel Blending State

In Wrath of the Lich King (and possibly other clients), the value listed in M2Material blending_mode is not a direct lookup in the pixel blending state table. The value is translated through the following mapping table: { 0, 1, 2, 10, 3, 4, 5 }

Fog Modes

Because blending modes adjust how color is applied during a draw call, fog color often has to be modified accordingly. The client maps blending modes to fog modes using s_fogModeList.

M2Material flag 0x02 causes fog mode 0 (disabled) to always be selected, regardless of blending mode.

In certain cases (possibly when the mesh or the camera is underwater), s_blendDisableUWFog may force fog mode 0 (disabled) to be selected based on blending mode. As of Mists of Pandaria, it appears this applies to Blend_Add and Blend_NoAlphaAdd.

The following fog modes were taken from Mists of Pandaria (build 15662).

Fog Mode Action Blending Modes
0 Disable fog logic in shader -
1 Use fog color (without changes) Blend_Opaque, Blend_AlphaKey, Blend_Alpha
2 Override fog color to 0x000000 (black) Blend_Add, possibly: Blend_NoAlphaAdd
3 Override fog color to 0xFFFFFF (white) Blend_Mod
4 Override fog color to 0x808080 (half white) Blend_Mod2x
5  ? submerged camera related; use ViewSettings::s_fogInfo 2 or 3 -
6  ? liquid plane related; use ViewSettings::s_fogInfo 3 or use CM2Lighting fog -

Lighting Modes

Similar to fog modes above, blending modes also impact lighting. The client maps blending modes to lighting modes using s_shadedList.

M2Material flag 0x01 always causes lighting mode 0 (disabled) to be selected.

The following lighting modes were taken from Mists of Pandaria (build 15662).

Lighting Mode Action Blending Modes
0 Disable lighting logic in shader, including local lights Blend_Mod, Blend_Mod2x
1 Enable lighting logic in shader Blend_Opaque, Blend_AlphaKey, Blend_Alpha, Blend_Add, possibly: Blend_NoAlphaAdd

M2Elements

An M2 is rendered as a series of M2Elements, which are constructed at runtime in CM2SceneRender::BeginDraw(), and sorted prior to drawing.

Element Alpha

For a given M2Element, whole-element alpha is calculated by multiplying the following things together:

  • batch->color.alpha is the M2Batch animated color track alpha value (if present)
  • batch->textureWeight is the M2Batch animated texture weight track value (if present); if batch->opCount is > 1, only the first textureWeight value is used
  • m2->alpha is overall model opacity, which can be manipulated by things like distance fading and similar effects; default: 1.0
  element->alpha = batch->color.alpha * batch->textureWeight * m2->alpha;

Element Sorting

WIP

Alpha Testing

Alpha testing is enabled for most or all M2Elements being rendered. The alpha comparison function is always D3DCMP_GREATEREQUAL, which discards pixels with alpha values lower than the provided alphaRef.

For Blend_AlphaKey blending, the alphaRef value starts at a baseline, and is multiplied by the M2Element->alpha. This multiplication prevents inappropriate pixel discards during things like fades for distance culling. See the M2Element alpha section above for details on what can modify M2Element alpha.

For all other blending modes (ie !(Blend_AlphaKey), the alphaRef value is constant.

Blending Mode alphaRef
!(Blend_AlphaKey) All 1.0 / 255.0 (constant)
Blend_AlphaKey >= Cata (128.0 / 255.0) * element->alpha
<= WotLK (224.0 / 255.0) * element->alpha

Pixel Shaders

Shader Name Tex Count Shader Logic
Combiners_Add 1 vec4 out.rgba = vec4(in.rgb + tex0.rgb, in.a + tex0.a);
Combiners_Decal 1 // TODO
Combiners_Fade 1 // TODO
Combiners_Mod 1 vec4 out.rgba = vec4(in.rgb * tex0.rgb, in.a * tex0.a);
Combiners_Mod2x 1 vec4 out.rgba = vec4(in.rgb * tex0.rgb * 2.0, in.a * tex0.a * 2.0);
Combiners_Opaque 1 vec4 out.rgba = vec4(in.rgb * tex0.rgb, in.a);

Table Notes

  • tex0.rgba, tex1.rgba, etc are vec4s containing sampled textures
  • in.rgba is a vec4 containing the color for the mesh being rendered (typically, an M2Batch)
  • out.rgba is a vec4 containing the result of texture blending
  • Tex count shows the number of textures required for the given shader
  • In the interest of clarity / brevity, no lighting or fogging operations are shown