Rendering: Difference between revisions

From wowdev
Jump to navigation Jump to search
(Added first bits of information about fog)
 
(37 intermediate revisions by the same user not shown)
Line 1: Line 1:
This page covers general rendering concerns that are not specific to model formats.
This page contains general information about functions, logic, and data used in the various rendering code paths of the World of Warcraft game client.


= Model Specific Rendering =
== Rendering Resources ==


More information about rendering specific model formats can be found at the following pages:
Information specific to model formats and other rendering code paths can be found at the links below:


* [[M2/Rendering|M2 Rendering]]
=== Model Loading ===


= Screen Effects =
Learn more about what happens to on-disk data when specific model formats are loaded by the client:


== EffectGlow ==
* [[M2/Loading|M2 Loading]]
* [[WMO/Loading|WMO Loading]]


This fullscreen effect controls both the bloom-style glow effect used by the game, and player state driven blur effects like inebriation.
=== Model Rendering ===


To apply the effect, the game creates 4 new render targets:
Learn more about rendering specific model formats used by the client:


* <tt>RT 0</tt>: Already exists, and holds the output of rendering the given world scene
* [[ADT/Rendering|ADT Rendering]]
* [[M2/Rendering|M2 Rendering]]
* [[WMO/Rendering|WMO Rendering]]


* <tt>RT 1</tt>: Created by passing <tt>RT 0</tt> through the <tt>FFXBox4</tt> shader (2x2 box blur)
=== Other Rendering ===


* <tt>RT 2</tt>: Created by passing <tt>RT 1</tt> through the <tt>FFXGauss4</tt> shader (4-tap gaussian blur)
More information about other logic, systems, or techniques involved in rendering in the client can be found at the following pages:


* <tt>RT 3</tt>: Created by passing <tt>RT 2</tt> through the <tt>FFXGauss4</tt> shader (second pass)
* [[Rendering/DayNight|DayNight]]
* [[Rendering/ScreenEffects|Screen Effects]]


* <tt>RT 4</tt>: Created by passing <tt>RT 0</tt> and <tt>RT 3</tt> through the <tt>FFXGlow</tt> shader (both targets are sampled)
== Vertex Buffers ==


The blurred render targets (<tt>RT 1</tt>, <tt>RT 2</tt>, and <tt>RT 3</tt>) are sized at 1/4 of the width and 1/4 of the height of the original render target (<tt>RT 0</tt>).
=== EGxVertexBufferFormat ===


=== FFXBox4 Shaders (7.x) ===
{| class="wikitable sortable"
|-
! EGxVertexBufferFormat
! Attribute Count
! Size (per Vertex)
! Attribute Names / Order
|-
| <tt>GxVBF_P</tt>
| <tt>1</tt>
| <tt>0x0C</tt>
| <tt>position</tt>
|-
| <tt>GxVBF_PN</tt>
| <tt>2</tt>
| <tt>0x18</tt>
| <tt>position</tt>, <tt>normal</tt>
|-
| <tt>GxVBF_PNC</tt>
| <tt>3</tt>
| <tt>0x1C</tt>
| <tt>position</tt>, <tt>normal</tt>, <tt>color</tt>
|-
| <tt>GxVBF_PNT</tt>
| <tt>3</tt>
| <tt>0x20</tt>
| <tt>position</tt>, <tt>normal</tt>, <tt>tc</tt>
|-
| <tt>GxVBF_PNCT</tt>
| <tt>4</tt>
| <tt>0x24</tt>
| <tt>position</tt>, <tt>normal</tt>, <tt>color</tt>, <tt>tc</tt>
|-
| <tt>GxVBF_PNT2</tt>
| <tt>4</tt>
| <tt>0x28</tt>
| <tt>position</tt>, <tt>normal</tt>, <tt>tc[2]</tt>
|-
| <tt>GxVBF_PNCT2</tt>
| <tt>5</tt>
| <tt>0x2C</tt>
| <tt>position</tt>, <tt>normal</tt>, <tt>color</tt>, <tt>tc[2]</tt>
|-
| <tt>GxVBF_PC</tt>
| <tt>2</tt>
| <tt>0x10</tt>
| <tt>position</tt>, <tt>color</tt>
|-
| <tt>GxVBF_PCT</tt>
| <tt>3</tt>
| <tt>0x18</tt>
| <tt>position</tt>, <tt>color</tt>, <tt>tc</tt>
|-
| <tt>GxVBF_PCT2</tt>
| <tt>4</tt>
| <tt>0x20</tt>
| <tt>position</tt>, <tt>color</tt>, <tt>tc[2]</tt>
|-
| <tt>GxVBF_PT</tt>
| <tt>2</tt>
| <tt>0x14</tt>
| <tt>position</tt>, <tt>tc</tt>
|-
| <tt>GxVBF_PT2</tt>
| <tt>3</tt>
| <tt>0x1C</tt>
| <tt>position</tt>, <tt>tc[2]</tt>
|-
| <tt>GxVBF_PBNT2</tt>
| <tt>6</tt>
| <tt>0x30</tt>
| <tt>position</tt>, <tt>blendWeight</tt>, <tt>blendIndices</tt>, <tt>normal</tt>, <tt>tc[2]</tt>
|-
| <tt>GxVBF_PNC2T2</tt>
| <tt>6</tt>
| <tt>0x30</tt>
| <tt>position</tt>, <tt>normal</tt>, <tt>color[2]</tt>, <tt>tc[2]</tt>
|}


This shader implements a simple 2x2 [https://en.wikipedia.org/wiki/Box_blur box blur].
=== EGxVertexAttrib ===


The client appears to precompute the texture coordinates on the CPU.
{| class="wikitable sortable"
|-
! EGxVertexAttrib
! Size
|-
| <tt>GxVA_Position</tt>
| <tt>0x0C</tt>
|-
| <tt>GxVA_BlendWeight</tt>
| <tt>0x04</tt>
|-
| <tt>GxVA_BlendIndices</tt>
| <tt>0x04</tt>
|-
| <tt>GxVA_Normal</tt>
| <tt>0x0C</tt>
|-
| <tt>GxVA_Color0</tt>
| <tt>0x04</tt>
|-
| <tt>GxVA_Color1</tt>
| <tt>0x04</tt>
|-
| <tt>GxVA_TexCoord0</tt>
| <tt>0x08</tt>
|-
| <tt>GxVA_TexCoord1</tt>
| <tt>0x08</tt>
|}


'''Vertex Shader'''
== Pixel Blending ==


The vertex shader used for <tt>FFXBox4</tt> is a simple full screen vertex shader, and can be found in <tt>FullScreen.bls</tt> in the appropriate vertex shader directory.  
When drawing geometry (batches, meshes, etc) into a framebuffer, the interaction between the pixels of the incoming geometry and the pixels already present in the framebuffer is controlled by something called blending.


'''Pixel Shader'''
In World of Warcraft, blending states are predefined, and are referenced by the <tt>EGxBlend</tt> enum.


The same source render target (the output of <tt>RT 0</tt>) is bound 4 times. Each of the 4 coordinate pairs is 'slipped' such that the addition of each sampled color results in the box blur.
Note that pixel blending is separate from texture blending. Texture blending controls how multiple textures for the same geometry are blended together, prior to the geometry being drawn into the framebuffer. In other words, texture blending happens before pixel blending. It has its own section on this page.


The coordinate pairs in <tt>in_tc0</tt> through <tt>in_tc3</tt> are offset as follows:
=== EGxBlend ===


* <tt>in_tc0</tt>: reference
The table below is up to date with all blending modes present in the 7.1.0.22996 retail client. Not all blending modes are used, particularly in older clients.
* <tt>in_tc1</tt>: shifted right vs <tt>in_tc0</tt>
* <tt>in_tc2</tt>: shifted up vs <tt>in_tc0</tt>
* <tt>in_tc3</tt>: shifted right and up vs <tt>in_tc0</tt>


<syntaxhighlight lang="glsl">
Wrath of the Lich King and Cataclysm do not use separate alpha blending. Legion does use separate alpha blending. It's currently unknown if Mists of Pandaria or Warlords of Draenor use separate alpha blending.
#version 420


layout(location = 1) in vec2 in_tc0;
<tt>GxBlend_BlendAdd</tt> was added at some point after Cataclysm.
layout(location = 2) in vec2 in_tc1;
layout(location = 3) in vec2 in_tc2;
layout(location = 4) in vec2 in_tc3;


layout(location = 0) out vec4 out_result;
Blend function enums are for OpenGL, but each has a Direct3D equivalent. Most pairings should be obvious, except: in Direct3D, <tt>CONSTANT_ALPHA</tt> is <tt>BLEND_FACTOR</tt> and <tt>ONE_MINUS_CONSTANT_ALPHA</tt> is <tt>INV_BLEND_FACTOR</tt>. See [https://gist.github.com/Warpten/f9350f8015860671c02354312b252c4e  this gist] for code that converts OpenGL constants to Direct3D (excerpt from Chrome).


uniform sampler2D pt_texture0;
{| class="wikitable sortable"
uniform sampler2D pt_texture1;
|-
uniform sampler2D pt_texture2;
! Idx
uniform sampler2D pt_texture3;
! EGxBlend
! Blending Enabled?
! Src Color
! Dest Color
! Src Alpha
! Dest Alpha
|-
| <tt>0</tt>
| <tt>GxBlend_Opaque</tt>
| No
| <tt>GL_ONE</tt>
| <tt>GL_ZERO</tt>
| <tt>GL_ONE</tt>
| <tt>GL_ZERO</tt>
|-
| <tt>1</tt>
| <tt>GxBlend_AlphaKey</tt>
| No
| <tt>GL_ONE</tt>
| <tt>GL_ZERO</tt>
| <tt>GL_ONE</tt>
| <tt>GL_ZERO</tt>
|-
| <tt>2</tt>
| <tt>GxBlend_Alpha</tt>
| Yes
| <tt>GL_SRC_ALPHA</tt>
| <tt>GL_ONE_MINUS_SRC_ALPHA</tt>
| <tt>GL_ONE</tt>
| <tt>GL_ONE_MINUS_SRC_ALPHA</tt>
|-
| <tt>3</tt>
| <tt>GxBlend_Add</tt>
| Yes
| <tt>GL_SRC_ALPHA</tt>
| <tt>GL_ONE</tt>
| <tt>GL_ZERO</tt>
| <tt>GL_ONE</tt>
|-
| <tt>4</tt>
| <tt>GxBlend_Mod</tt>
| Yes
| <tt>GL_DST_COLOR</tt>
| <tt>GL_ZERO</tt>
| <tt>GL_DST_ALPHA</tt>
| <tt>GL_ZERO</tt>
|-
| <tt>5</tt>
| <tt>GxBlend_Mod2x</tt>
| Yes
| <tt>GL_DST_COLOR</tt>
| <tt>GL_SRC_COLOR</tt>
| <tt>GL_DST_ALPHA</tt>
| <tt>GL_SRC_ALPHA</tt>
|-
| <tt>6</tt>
| <tt>GxBlend_ModAdd</tt>
| Yes
| <tt>GL_DST_COLOR</tt>
| <tt>GL_ONE</tt>
| <tt>GL_DST_ALPHA</tt>
| <tt>GL_ONE</tt>
|-
| <tt>7</tt>
| <tt>GxBlend_InvSrcAlphaAdd</tt>
| Yes
| <tt>GL_ONE_MINUS_SRC_ALPHA</tt>
| <tt>GL_ONE</tt>
| <tt>GL_ONE_MINUS_SRC_ALPHA</tt>
| <tt>GL_ONE</tt>
|-
| <tt>8</tt>
| <tt>GxBlend_InvSrcAlphaOpaque</tt>
| Yes
| <tt>GL_ONE_MINUS_SRC_ALPHA</tt>
| <tt>GL_ZERO</tt>
| <tt>GL_ONE_MINUS_SRC_ALPHA</tt>
| <tt>GL_ZERO</tt>
|-
| <tt>9</tt>
| <tt>GxBlend_SrcAlphaOpaque</tt>
| Yes
| <tt>GL_SRC_ALPHA</tt>
| <tt>GL_ZERO</tt>
| <tt>GL_SRC_ALPHA</tt>
| <tt>GL_ZERO</tt>
|-
| <tt>10</tt>
| <tt>GxBlend_NoAlphaAdd</tt>
| Yes
| <tt>GL_ONE</tt>
| <tt>GL_ONE</tt>
| <tt>GL_ZERO</tt>
| <tt>GL_ONE</tt>
|-
| <tt>11</tt>
| <tt>GxBlend_ConstantAlpha</tt>
| Yes
| <tt>GL_CONSTANT_ALPHA</tt>
| <tt>GL_ONE_MINUS_CONSTANT_ALPHA</tt>
| <tt>GL_CONSTANT_ALPHA</tt>
| <tt>GL_ONE_MINUS_CONSTANT_ALPHA</tt>
|-
| <tt>12</tt>
| <tt>GxBlend_Screen</tt>
| Yes
| <tt>GL_ONE_MINUS_DST_COLOR</tt>
| <tt>GL_ONE</tt>
| <tt>GL_ONE</tt>
| <tt>GL_ZERO</tt>
|-
| <tt>13</tt>
| <tt>GxBlend_BlendAdd</tt>
| Yes
| <tt>GL_ONE</tt>
| <tt>GL_ONE_MINUS_SRC_ALPHA</tt>
| <tt>GL_ONE</tt>
| <tt>GL_ONE_MINUS_SRC_ALPHA</tt>
|}


void main()
Table Credits: Deamon, for unearthing blending mode names and laying out the original table; relaxok, for checking D3D state at runtime; schlumpf, for the initial reversing work; fallenoak, for mapping Deamon's table to OpenGL enums and verifying values across several expansion clients.
{


  float blurWeight = 0.25;
== Texture Blending ==


  vec3 color0 = texture(pt_texture0, in_tc0).rgb;
Texture blending controls how multiple textures are combined prior to being drawn to the framebuffer.
  vec3 color1 = texture(pt_texture1, in_tc1).rgb;
  vec3 color2 = texture(pt_texture2, in_tc2).rgb;
  vec3 color3 = texture(pt_texture3, in_tc3).rgb;


  vec3 finalColor = vec3(0.0);
=== EGxTexBlend ===


  finalColor += color0 * blurWeight;
{| class="wikitable sortable"
  finalColor += color1 * blurWeight;
|-
  finalColor += color2 * blurWeight;
! Idx
  finalColor += color3 * blurWeight;
! EGxTexBlend
! ColorOp
! AlphaOp
|-
| <tt>0</tt>
| <tt>GxTexBlend_Opaque</tt>
| <tt>GxTexOp_Mod</tt>
| <tt>GxTexOp_PassThru</tt>
|-
| <tt>1</tt>
| <tt>GxTexBlend_Mod</tt>
| <tt>GxTexOp_Mod</tt>
| <tt>GxTexOp_Mod</tt>
|-
| <tt>2</tt>
| <tt>GxTexBlend_Decal</tt>
| <tt>GxTexOp_Decal</tt>
| <tt>GxTexOp_PassThru</tt>
|-
| <tt>3</tt>
| <tt>GxTexBlend_Add</tt>
| <tt>GxTexOp_Add</tt>
| <tt>GxTexOp_Add</tt>
|-
| <tt>4</tt>
| <tt>GxTexBlend_Mod2x</tt>
| <tt>GxTexOp_Mod2x</tt>
| <tt>GxTexOp_Mod2x</tt>
|-
| <tt>5</tt>
| <tt>GxTexBlend_Fade</tt>
| <tt>GxTexOp_Fade</tt>
| <tt>GxTexOp_PassThru</tt>
|-
| <tt>6</tt>
| <tt>GxTexBlend_Mod2xNA</tt>
| <tt>GxTexOp_Mod2x</tt>
| <tt>GxTexOp_PassThru</tt>
|-
| <tt>7</tt>
| <tt>GxTexBlend_AddNA</tt>
| <tt>GxTexOp_Add</tt>
| <tt>GxTexOp_PassThru</tt>
|}


  out_result = vec4(finalColor.rgb, 1.0);
=== EGxTexOp ===


}
{| class="wikitable sortable"
</syntaxhighlight>
|-
! Idx
! EGxTexOp
! Op
! Scale
! Arg0
! Arg1
! Arg2
|-
| <tt>0</tt>
| <tt>GxTexOp_Mod</tt>
| <tt>GL_MODULATE</tt>
| <tt>1.0f</tt>
| <tt>GL_PREVIOUS</tt>
| <tt>GL_TEXTURE</tt>
| <tt>GL_CONSTANT</tt>
|-
| <tt>1</tt>
| <tt>GxTexOp_Mod2x</tt>
| <tt>GL_MODULATE</tt>
| <tt>2.0f</tt>
| <tt>GL_PREVIOUS</tt>
| <tt>GL_TEXTURE</tt>
| <tt>GL_CONSTANT</tt>
|-
| <tt>2</tt>
| <tt>GxTexOp_Add</tt>
| <tt>GL_ADD</tt>
| <tt>1.0f</tt>
| <tt>GL_PREVIOUS</tt>
| <tt>GL_TEXTURE</tt>
| <tt>GL_CONSTANT</tt>
|-
| <tt>3</tt>
| <tt>GxTexOp_PassThru</tt>
| <tt>GL_REPLACE</tt>
| <tt>1.0f</tt>
| <tt>GL_PREVIOUS</tt>
| <tt>GL_TEXTURE</tt>
| <tt>GL_CONSTANT</tt>
|-
| <tt>4</tt>
| <tt>GxTexOp_Decal</tt>
| <tt>GL_INTERPOLATE</tt>
| <tt>1.0f</tt>
| <tt>GL_PREVIOUS</tt>
| <tt>GL_TEXTURE</tt>
| <tt>GL_TEXTURE</tt>
|-
| <tt>5</tt>
| <tt>GxTexOp_Fade</tt>
| <tt>GL_INTERPOLATE</tt>
| <tt>1.0f</tt>
| <tt>GL_TEXTURE</tt>
| <tt>GL_PREVIOUS</tt>
| <tt>GL_TEXTURE</tt>
|}


=== FFXGauss4 Shaders (7.x) ===
=== ColorOp FFP State ===


This shader implements a 4-tap gaussian blur. It's typically applied by the client in 2 passes (possibly: horizontal, then vertical).
When rendering is done using the fixed function pipeline code path, the following calls are made to set the texture blending color op:


'''Pixel Shader'''
<syntaxhighlight lang="cpp">
 
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, op);
The same source render target is bound 4 times.
glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE,  scale);
 
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, arg0);
<syntaxhighlight lang="glsl">
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, arg1);
#version 420
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB, arg2);
 
</syntaxhighlight>
layout(location = 1) in vec2 in_tc0;
layout(location = 2) in vec2 in_tc1;
layout(location = 3) in vec2 in_tc2;
layout(location = 4) in vec2 in_tc3;
 
layout(location = 0) out vec4 out_result;
 
uniform sampler2D pt_texture0;
uniform sampler2D pt_texture1;
uniform sampler2D pt_texture2;
uniform sampler2D pt_texture3;
 
void main()
{
 
  vec2 blurWeight = vec2(0.125, 0.375);
 
  vec4 color0 = texture(pt_texture1, in_tc0);
  vec4 color1 = texture(pt_texture1, in_tc1);
  vec4 color2 = texture(pt_texture1, in_tc2);
  vec4 color3 = texture(pt_texture1, in_tc3);
 
  vec4 finalColor = vec4(0.0);


  finalColor += color0 * blurWeight.x;
=== AlphaOp FFP State ===
  finalColor += color1 * blurWeight.y;
  finalColor += color2 * blurWeight.y;
  finalColor += color3 * blurWeight.x;


  out_result = finalColor;
When rendering is done using the fixed function pipeline code path, the following calls are made to set the texture blending alpha op:


}
<syntaxhighlight lang="cpp">
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, op);
glTexEnvf(GL_TEXTURE_ENV, GL_ALPHA_SCALE,  scale);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, arg0);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA, arg1);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA, arg2);
</syntaxhighlight>
</syntaxhighlight>


=== FFXGlow Shaders (7.x) ===
== Texture Formats ==
 
'''Vertex Shader'''
 
The vertex shader used for <tt>FFXGlow</tt> is a simple full screen vertex shader, and can be found in <tt>FullScreen.bls</tt> in the appropriate vertex shader directory.


'''Pixel Shader'''
Over the years, the client has used a plethora of texture formats for various rendering features. Formats are defined by the <tt>EGxTexFormat</tt> enum. Earlier clients support fewer texture formats than later clients.


* <tt>pc_blurAmount.z</tt>: controls how much of the final blur output (<tt>RT 3</tt>) is carried over in the final output; this is used to manage effects like blurring the screen due to inebriation
=== EGxTexFormat ===


* <tt>pc_blurAmount.w</tt>: controls how much bloom-style glow is applied to the screen; this typically is sourced from the <tt>LightParams</tt> client database: <tt>LightParamsRec->m_glow</tt>
{| class="wikitable sortable"
|-
! EGxTexFormat
! Oldest Known Support
|-
| <tt>GxTex_Unknown</tt>
| <tt>0.5.3.3368</tt>
|-
| <tt>GxTex_Abgr8888</tt>
| <tt>?</tt>
|-
| <tt>GxTex_Argb8888</tt>
| <tt>0.5.3.3368</tt>
|-
| <tt>GxTex_Argb4444</tt>
| <tt>0.5.3.3368</tt>
|-
| <tt>GxTex_Argb1555</tt>
| <tt>0.5.3.3368</tt>
|-
| <tt>GxTex_Rgb565</tt>
| <tt>0.5.3.3368</tt>
|-
| <tt>GxTex_Dxt1</tt>
| <tt>0.5.3.3368</tt>
|-
| <tt>GxTex_Dxt3</tt>
| <tt>0.5.3.3368</tt>
|-
| <tt>GxTex_Dxt5</tt>
| <tt>0.5.3.3368</tt>
|-
| <tt>GxTex_Uv88</tt>
| <tt>?</tt>
|-
| <tt>GxTex_Gr1616F</tt>
| <tt>?</tt>
|-
| <tt>GxTex_R32F</tt>
| <tt>?</tt>
|-
| <tt>GxTex_D24X8</tt>
| <tt>?</tt>
|}


<syntaxhighlight lang="glsl">
== Texture Targets ==
#version 420


layout(location = 1) in vec2 in_screenCoord;
=== EGxTexTarget ===
layout(location = 2) in vec2 in_blurCoord;


layout(location = 0) out vec4 out_result;
{| class="wikitable sortable"
|-
! Idx
! EGxTexTarget
! OpenGL
|-
| <tt>0</tt>
| <tt>GxTex_2d</tt>
| <tt>GL_TEXTURE_2D</tt>
|-
| <tt>1</tt>
| <tt>GxTex_CubeMap</tt>
| <tt>GL_TEXTURE_CUBE_MAP</tt>
|-
| <tt>2</tt>
| <tt>GxTex_Rectangle</tt>
| <tt>GL_TEXTURE_RECTANGLE</tt>
|-
| <tt>3</tt>
| <tt>GxTex_NonPow2??</tt>
| <tt>GL_TEXTURE_2D</tt>
|-
| <tt>4</tt>
| <tt>GxTex_Volume</tt>
| <tt>GL_TEXTURE_3D</tt>
|-
| <tt>5</tt>
| <tt>GxTex_Internal??</tt>
| <tt>GL_ZERO</tt>
|}


layout(std140) uniform ps_cb0
== Fog ==
{
  vec4 pc_blurAmount;
};


uniform sampler2D pt_screenTex;
=== ViewSettings::s_fogInfo ===
uniform sampler2D pt_blurTex;
 
void main()
{
 
  float blurFactor = pc_blurAmount.z;
  float glowFactor = pc_blurAmount.w;
 
  vec4 screenColor = texture(pt_screenTex, in_screenCoord);
  vec3 blurColor = texture(pt_blurTex, in_blurCoord).rgb;
 
  // Mix screen and blur color (to handle effects like inebriation)
  vec4 finalColor = vec4(mix(screenColor.rgb, blurColor, vec3(blurFactor)), 0.0);
 
  // Calculate the glow color
  vec3 glowColor = (blurColor * blurColor) * glowFactor;
 
  // Add the glow color
  finalColor.rgb += glowColor;
 
  out_result = vec4(finalColor.rgb, screenColor.a);
 
}
</syntaxhighlight>
 
=== FFXGlow Shaders (3.x) ===
 
= Fog =
 
== ViewSettings::s_fogInfo ==


There are 4 types of fog defined in <tt>ViewSettings::s_fogInfo</tt>
There are 4 types of fog defined in <tt>ViewSettings::s_fogInfo</tt>
Line 193: Line 519:
* <tt>2</tt>: Exterior underwater fog
* <tt>2</tt>: Exterior underwater fog
* <tt>3</tt>: Interior underwater fog
* <tt>3</tt>: Interior underwater fog
== Liquid ==
=== Liquid::s_waterDetail ===
Liquid rendering quality. From http://wow.gamepedia.com/Console_variables#Graphics:
* <tt>0</tt>: Old water
* <tt>1</tt>: Screen space reflection
* <tt>2</tt>: Dynamic reflection

Latest revision as of 01:38, 16 November 2017

This page contains general information about functions, logic, and data used in the various rendering code paths of the World of Warcraft game client.

Rendering Resources

Information specific to model formats and other rendering code paths can be found at the links below:

Model Loading

Learn more about what happens to on-disk data when specific model formats are loaded by the client:

Model Rendering

Learn more about rendering specific model formats used by the client:

Other Rendering

More information about other logic, systems, or techniques involved in rendering in the client can be found at the following pages:

Vertex Buffers

EGxVertexBufferFormat

EGxVertexBufferFormat Attribute Count Size (per Vertex) Attribute Names / Order
GxVBF_P 1 0x0C position
GxVBF_PN 2 0x18 position, normal
GxVBF_PNC 3 0x1C position, normal, color
GxVBF_PNT 3 0x20 position, normal, tc
GxVBF_PNCT 4 0x24 position, normal, color, tc
GxVBF_PNT2 4 0x28 position, normal, tc[2]
GxVBF_PNCT2 5 0x2C position, normal, color, tc[2]
GxVBF_PC 2 0x10 position, color
GxVBF_PCT 3 0x18 position, color, tc
GxVBF_PCT2 4 0x20 position, color, tc[2]
GxVBF_PT 2 0x14 position, tc
GxVBF_PT2 3 0x1C position, tc[2]
GxVBF_PBNT2 6 0x30 position, blendWeight, blendIndices, normal, tc[2]
GxVBF_PNC2T2 6 0x30 position, normal, color[2], tc[2]

EGxVertexAttrib

EGxVertexAttrib Size
GxVA_Position 0x0C
GxVA_BlendWeight 0x04
GxVA_BlendIndices 0x04
GxVA_Normal 0x0C
GxVA_Color0 0x04
GxVA_Color1 0x04
GxVA_TexCoord0 0x08
GxVA_TexCoord1 0x08

Pixel Blending

When drawing geometry (batches, meshes, etc) into a framebuffer, the interaction between the pixels of the incoming geometry and the pixels already present in the framebuffer is controlled by something called blending.

In World of Warcraft, blending states are predefined, and are referenced by the EGxBlend enum.

Note that pixel blending is separate from texture blending. Texture blending controls how multiple textures for the same geometry are blended together, prior to the geometry being drawn into the framebuffer. In other words, texture blending happens before pixel blending. It has its own section on this page.

EGxBlend

The table below is up to date with all blending modes present in the 7.1.0.22996 retail client. Not all blending modes are used, particularly in older clients.

Wrath of the Lich King and Cataclysm do not use separate alpha blending. Legion does use separate alpha blending. It's currently unknown if Mists of Pandaria or Warlords of Draenor use separate alpha blending.

GxBlend_BlendAdd was added at some point after Cataclysm.

Blend function enums are for OpenGL, but each has a Direct3D equivalent. Most pairings should be obvious, except: in Direct3D, CONSTANT_ALPHA is BLEND_FACTOR and ONE_MINUS_CONSTANT_ALPHA is INV_BLEND_FACTOR. See this gist for code that converts OpenGL constants to Direct3D (excerpt from Chrome).

Idx EGxBlend Blending Enabled? Src Color Dest Color Src Alpha Dest Alpha
0 GxBlend_Opaque No GL_ONE GL_ZERO GL_ONE GL_ZERO
1 GxBlend_AlphaKey No GL_ONE GL_ZERO GL_ONE GL_ZERO
2 GxBlend_Alpha Yes GL_SRC_ALPHA GL_ONE_MINUS_SRC_ALPHA GL_ONE GL_ONE_MINUS_SRC_ALPHA
3 GxBlend_Add Yes GL_SRC_ALPHA GL_ONE GL_ZERO GL_ONE
4 GxBlend_Mod Yes GL_DST_COLOR GL_ZERO GL_DST_ALPHA GL_ZERO
5 GxBlend_Mod2x Yes GL_DST_COLOR GL_SRC_COLOR GL_DST_ALPHA GL_SRC_ALPHA
6 GxBlend_ModAdd Yes GL_DST_COLOR GL_ONE GL_DST_ALPHA GL_ONE
7 GxBlend_InvSrcAlphaAdd Yes GL_ONE_MINUS_SRC_ALPHA GL_ONE GL_ONE_MINUS_SRC_ALPHA GL_ONE
8 GxBlend_InvSrcAlphaOpaque Yes GL_ONE_MINUS_SRC_ALPHA GL_ZERO GL_ONE_MINUS_SRC_ALPHA GL_ZERO
9 GxBlend_SrcAlphaOpaque Yes GL_SRC_ALPHA GL_ZERO GL_SRC_ALPHA GL_ZERO
10 GxBlend_NoAlphaAdd Yes GL_ONE GL_ONE GL_ZERO GL_ONE
11 GxBlend_ConstantAlpha Yes GL_CONSTANT_ALPHA GL_ONE_MINUS_CONSTANT_ALPHA GL_CONSTANT_ALPHA GL_ONE_MINUS_CONSTANT_ALPHA
12 GxBlend_Screen Yes GL_ONE_MINUS_DST_COLOR GL_ONE GL_ONE GL_ZERO
13 GxBlend_BlendAdd Yes GL_ONE GL_ONE_MINUS_SRC_ALPHA GL_ONE GL_ONE_MINUS_SRC_ALPHA

Table Credits: Deamon, for unearthing blending mode names and laying out the original table; relaxok, for checking D3D state at runtime; schlumpf, for the initial reversing work; fallenoak, for mapping Deamon's table to OpenGL enums and verifying values across several expansion clients.

Texture Blending

Texture blending controls how multiple textures are combined prior to being drawn to the framebuffer.

EGxTexBlend

Idx EGxTexBlend ColorOp AlphaOp
0 GxTexBlend_Opaque GxTexOp_Mod GxTexOp_PassThru
1 GxTexBlend_Mod GxTexOp_Mod GxTexOp_Mod
2 GxTexBlend_Decal GxTexOp_Decal GxTexOp_PassThru
3 GxTexBlend_Add GxTexOp_Add GxTexOp_Add
4 GxTexBlend_Mod2x GxTexOp_Mod2x GxTexOp_Mod2x
5 GxTexBlend_Fade GxTexOp_Fade GxTexOp_PassThru
6 GxTexBlend_Mod2xNA GxTexOp_Mod2x GxTexOp_PassThru
7 GxTexBlend_AddNA GxTexOp_Add GxTexOp_PassThru

EGxTexOp

Idx EGxTexOp Op Scale Arg0 Arg1 Arg2
0 GxTexOp_Mod GL_MODULATE 1.0f GL_PREVIOUS GL_TEXTURE GL_CONSTANT
1 GxTexOp_Mod2x GL_MODULATE 2.0f GL_PREVIOUS GL_TEXTURE GL_CONSTANT
2 GxTexOp_Add GL_ADD 1.0f GL_PREVIOUS GL_TEXTURE GL_CONSTANT
3 GxTexOp_PassThru GL_REPLACE 1.0f GL_PREVIOUS GL_TEXTURE GL_CONSTANT
4 GxTexOp_Decal GL_INTERPOLATE 1.0f GL_PREVIOUS GL_TEXTURE GL_TEXTURE
5 GxTexOp_Fade GL_INTERPOLATE 1.0f GL_TEXTURE GL_PREVIOUS GL_TEXTURE

ColorOp FFP State

When rendering is done using the fixed function pipeline code path, the following calls are made to set the texture blending color op:

glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, op);
glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE,   scale);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, arg0);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, arg1);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB, arg2);

AlphaOp FFP State

When rendering is done using the fixed function pipeline code path, the following calls are made to set the texture blending alpha op:

glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, op);
glTexEnvf(GL_TEXTURE_ENV, GL_ALPHA_SCALE,   scale);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, arg0);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA, arg1);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA, arg2);

Texture Formats

Over the years, the client has used a plethora of texture formats for various rendering features. Formats are defined by the EGxTexFormat enum. Earlier clients support fewer texture formats than later clients.

EGxTexFormat

EGxTexFormat Oldest Known Support
GxTex_Unknown 0.5.3.3368
GxTex_Abgr8888 ?
GxTex_Argb8888 0.5.3.3368
GxTex_Argb4444 0.5.3.3368
GxTex_Argb1555 0.5.3.3368
GxTex_Rgb565 0.5.3.3368
GxTex_Dxt1 0.5.3.3368
GxTex_Dxt3 0.5.3.3368
GxTex_Dxt5 0.5.3.3368
GxTex_Uv88 ?
GxTex_Gr1616F ?
GxTex_R32F ?
GxTex_D24X8 ?

Texture Targets

EGxTexTarget

Idx EGxTexTarget OpenGL
0 GxTex_2d GL_TEXTURE_2D
1 GxTex_CubeMap GL_TEXTURE_CUBE_MAP
2 GxTex_Rectangle GL_TEXTURE_RECTANGLE
3 GxTex_NonPow2?? GL_TEXTURE_2D
4 GxTex_Volume GL_TEXTURE_3D
5 GxTex_Internal?? GL_ZERO

Fog

ViewSettings::s_fogInfo

There are 4 types of fog defined in ViewSettings::s_fogInfo

  • 0: Unk (maybe: exterior above water fog)
  • 1: Unk (maybe: interior above water fog)
  • 2: Exterior underwater fog
  • 3: Interior underwater fog

Liquid

Liquid::s_waterDetail

Liquid rendering quality. From http://wow.gamepedia.com/Console_variables#Graphics:

  • 0: Old water
  • 1: Screen space reflection
  • 2: Dynamic reflection