Shading Technique - Glow Mapping

From Horde3D Wiki
Jump to: navigation, search

I'm in the process of writing this article - come back later!

Contents

Overview

For an in-depth overview of this technique, see the Gamasutra article Real-Time Glow by By Greg James and John O’Rorke.

Temporary code dump

Until I finish writing this article, here's the undocumented code ;)

Pipeline changes

Setup the RenderTargets. If this is for HDR, then these RenderTargets will already exist, so just change depthBuf to "true" on the first one
  1. <Setup>
    
  2.         <RenderTarget id="BLURBUF1" depthBuf="true"  numColBufs="1" format="RGBA8" bilinear="true" scale="0.25" />
    
  3.         <RenderTarget id="BLURBUF2" depthBuf="false" numColBufs="1" format="RGBA8" bilinear="true" scale="0.25" />
    
  4. </Setup>
    


insert this new stage after the "Geometry" stage.
  1. <stage id="Glow">
    
  2.         <SwitchTarget target="BLURBUF1" />                      
    
  3.         <ClearTarget depthBuf="true" colBuf0="true" />
    
  4.         <DrawGeometry context="GLOWMASK" />
    
  5.  
    
  6.         <!-- Repeat these steps as many times as you like, it makes the bloom softer -->
    
  7.         <SwitchTarget target="BLURBUF2" />
    
  8.         <BindBuffer texUnit="0" target="BLURBUF1" bufIndex="0" />
    
  9.         <DrawQuad   material="postGlow.material.xml" context="BLURV" />
    
  10.         <SwitchTarget target="BLURBUF1" />
    
  11.         <BindBuffer texUnit="0" target="BLURBUF2" bufIndex="0" />
    
  12.         <DrawQuad   material="postGlow.material.xml" context="BLURH" />
    
  13.  
    
  14.         <SwitchTarget target="BLURBUF2" />
    
  15.         <BindBuffer texUnit="0" target="BLURBUF1" bufIndex="0" />
    
  16.         <DrawQuad   material="postGlow.material.xml" context="BLURV" />
    
  17.         <SwitchTarget target="BLURBUF1" />
    
  18.         <BindBuffer texUnit="0" target="BLURBUF2" bufIndex="0" />
    
  19.         <DrawQuad   material="postGlow.material.xml" context="BLURH" />
    
  20.  
    
  21.         <SwitchTarget target="BLURBUF2" />
    
  22.         <BindBuffer texUnit="0" target="BLURBUF1" bufIndex="0" />
    
  23.         <DrawQuad   material="postGlow.material.xml" context="BLURV" />
    
  24.         <SwitchTarget target="BLURBUF1" />
    
  25.         <BindBuffer texUnit="0" target="BLURBUF2" bufIndex="0" />
    
  26.         <DrawQuad   material="postGlow.material.xml" context="BLURH" />
    
  27.  
    
  28.         <!-- In the HDR version, target should be set to "HDRBUF" -->
    
  29.         <SwitchTarget target="" />
    
  30.         <BindBuffer texUnit="0" target="BLURBUF1" bufIndex="0" />
    
  31.         <DrawQuad material="postGlow.material.xml" context="FINALPASS" />
    
  32. </stage>
    


New shader code

This context is designed to be added to a copy of the parallax shader - parallax_glow.shader.xml
  1. <Context id="GLOWMASK"> 
    
  2.         <!-- This material does glow - output colors masked by the alpha channel -->
    
  3.         <VertexShader>
    
  4.                 <InsCode code="utilityLib/vertCommon.glsl" />
    
  5.                 <DefCode>
    
  6.                 <![CDATA[
    
  7.                         uniform vec3 viewer;
    
  8.                         attribute vec2 texCoords0;
    
  9.                         attribute vec3 normal, tangent, bitangent;
    
  10.                         varying vec3 eyeTS;
    
  11.                         varying vec2 texCoords;
    
  12.                         varying vec4 pos;
    
  13.  
    
  14.                         void main( void )
    
  15.                         {
    
  16.                                 // Transform tangent space basis
    
  17.                                 vec3 tsbTangent = normalize( calcWorldVec( tangent ) );
    
  18.                                 vec3 tsbBitangent = normalize( calcWorldVec( bitangent ) );
    
  19.                                 vec3 tsbNormal = normalize( calcWorldVec( normal ) );
    
  20.  
    
  21.                                 // Calculate world space position
    
  22.                                 pos = calcWorldPos( gl_Vertex );
    
  23.  
    
  24.                                 // Eye vector and eye vector in tangent space
    
  25.                                 eyeTS = calcTanVec( viewer - pos.xyz, tsbTangent, tsbBitangent, tsbNormal );
    
  26.  
    
  27.                                 // Calculate texture coordinates and clip space position
    
  28.                                 texCoords = texCoords0;
    
  29.                                 gl_Position = gl_ModelViewProjectionMatrix * pos;
    
  30.                         }
    
  31.                 ]]>
    
  32.                 </DefCode>
    
  33.         </VertexShader>
    
  34.  
    
  35.         <FragmentShader>
    
  36.                 <DefCode>
    
  37.                 <![CDATA[
    
  38.                         uniform sampler2D tex0;
    
  39.                         varying vec3 eyeTS;
    
  40.                         varying vec2 texCoords;
    
  41.  
    
  42.                         void main( void )
    
  43.                         {
    
  44.                                 const float plxScale = 0.03;
    
  45.                                 const float plxBias = -0.015;
    
  46.  
    
  47.                                 // Iterative parallax mapping
    
  48.                                 vec3 newCoords = vec3( texCoords, 0 );
    
  49.                                 vec3 eye = normalize( eyeTS );
    
  50.                                 for( int i = 0; i < 4; ++i )
    
  51.                                 {
    
  52.                                         vec4 nmap = texture2D( tex0, texCoords.st );
    
  53.                                         float height = nmap.a * plxScale + plxBias;
    
  54.                                         newCoords += (height - newCoords.p) * nmap.z * eye;
    
  55.                                 }
    
  56.  
    
  57.                                 vec4 glow = texture2D( tex0, newCoords.st ).rgba;
    
  58.                                 glow *= glow.a;
    
  59.  
    
  60.                                 gl_FragColor = glow;
    
  61.                         }
    
  62.                 ]]>
    
  63.                 </DefCode>
    
  64.         </FragmentShader>
    
  65. </Context>
    


This is a new shader, called postGlow.shader.xml
  1. <Shader>
    
  2.  
    
  3.         <Context id="BLURH">
    
  4.                 <RenderConfig writeDepth="false" />
    
  5.                 <VertexShader>
    
  6.                         <DefCode>
    
  7.                         <![CDATA[
    
  8.                                 varying vec2 texCoord;
    
  9.                                 void main( void )
    
  10.                                 {
    
  11.                                         texCoord = gl_MultiTexCoord0.st; 
    
  12.                                         gl_Position = gl_ProjectionMatrix * gl_Vertex;
    
  13.                                 }
    
  14.                         ]]>
    
  15.                         </DefCode>
    
  16.                 </VertexShader>
    
  17.                 <FragmentShader>
    
  18.                         <InsCode code="utilityLib/fragPostProcess.glsl" />
    
  19.                         <DefCode>
    
  20.                         <![CDATA[
    
  21.                                 uniform sampler2D tex;
    
  22.                                 uniform vec2 frameBufSize;
    
  23.                                 varying vec2 texCoord;
    
  24.                                 void main( void )
    
  25.                                 {       
    
  26.                                         float halfPixel = 0.5 / frameBufSize.x;
    
  27.                                         vec4 col  = texture2D( tex, texCoord + vec2( halfPixel,   0.0 ) );
    
  28.                                              col += texture2D( tex, texCoord - vec2( halfPixel,   0.0 ) );
    
  29.                                              col += texture2D( tex, texCoord + vec2( halfPixel*3.0, 0.0 ) );
    
  30.                                              col += texture2D( tex, texCoord - vec2( halfPixel*3.0, 0.0 ) );
    
  31.                                         gl_FragColor = col * 0.25; 
    
  32.                                 }
    
  33.                         ]]>
    
  34.                         </DefCode>
    
  35.                 </FragmentShader>
    
  36.         </Context>
    
  37.         <Context id="BLURV">
    
  38.                 <RenderConfig writeDepth="false" />
    
  39.                 <VertexShader>
    
  40.                         <DefCode>
    
  41.                         <![CDATA[
    
  42.                                 varying vec2 texCoord;
    
  43.                                 void main( void )
    
  44.                                 {
    
  45.                                         texCoord = gl_MultiTexCoord0.st; 
    
  46.                                         gl_Position = gl_ProjectionMatrix * gl_Vertex;
    
  47.                                 }
    
  48.                         ]]>
    
  49.                         </DefCode>
    
  50.                 </VertexShader>
    
  51.                 <FragmentShader>
    
  52.                         <InsCode code="utilityLib/fragPostProcess.glsl" />
    
  53.                         <DefCode>
    
  54.                         <![CDATA[
    
  55.                                 uniform sampler2D tex;
    
  56.                                 uniform vec2 frameBufSize;
    
  57.                                 varying vec2 texCoord;
    
  58.                                 void main( void )
    
  59.                                 {       
    
  60.                                         float halfPixel = 0.5 / frameBufSize.y;
    
  61.                                         vec4 col  = texture2D( tex, texCoord + vec2( 0.0, halfPixel   ) );
    
  62.                                              col += texture2D( tex, texCoord - vec2( 0.0, halfPixel   ) );
    
  63.                                              col += texture2D( tex, texCoord + vec2( 0.0, halfPixel*3.0 ) );
    
  64.                                              col += texture2D( tex, texCoord - vec2( 0.0, halfPixel*3.0 ) );
    
  65.                                         gl_FragColor = col * 0.25;
    
  66.                                 }
    
  67.                         ]]>
    
  68.                         </DefCode>
    
  69.                 </FragmentShader>
    
  70.         </Context>
    
  71.  
    
  72.         <Context id="FINALPASS">
    
  73.                 <RenderConfig writeDepth="false" blendMode="ADD" />
    
  74.  
    
  75.                 <VertexShader>
    
  76.                         <DefCode>
    
  77.                         <![CDATA[
    
  78.                                 varying vec2 texCoord;
    
  79.  
    
  80.                                 void main( void )
    
  81.                                 {
    
  82.                                         texCoord = gl_MultiTexCoord0.st; 
    
  83.                                         gl_Position = gl_ProjectionMatrix * gl_Vertex;
    
  84.                                 }
    
  85.                         ]]>
    
  86.                         </DefCode>
    
  87.                 </VertexShader>
    
  88.  
    
  89.                 <FragmentShader>
    
  90.                         <DefCode>
    
  91.                         <![CDATA[
    
  92.                                 uniform sampler2D tex0, tex1;
    
  93.                                 uniform vec2 frameBufSize;
    
  94.                                 uniform vec4 hdrParams;
    
  95.                                 varying vec2 texCoord;
    
  96.  
    
  97.                                 void main( void )
    
  98.                                 {
    
  99.                                         gl_FragColor = texture2D( tex0, texCoord );     // Glow color
    
  100.                                 }
    
  101.                         ]]>
    
  102.                         </DefCode>
    
  103.                 </FragmentShader>
    
  104.         </Context>
    
  105. </Shader>
    


The material to go with the postGlow shader - postGlow.material.xml
  1. <Material>
    
  2.         <Shader source="postGlow.shader.xml"/>
    
  3. </Material>
    


This context is designed to be added to the original skinning shaders - skinning.shader.xml and skinning_metal.shader.xml
  1. <Context id="GLOWMASK"> 
    
  2.         <!-- This material does not glow - output black pixels -->
    
  3.         <VertexShader>
    
  4.                 <InsCode code="utilityLib/vertCommon.glsl" />
    
  5.                 <InsCode code="utilityLib/vertSkinning.glsl" />
    
  6.                 <DefCode>
    
  7.                 <![CDATA[
    
  8.                         void main( void )
    
  9.                         {
    
  10.                                 // Calculate skinning matrices
    
  11.                                 mat4 skinningMat = calcSkinningMat();
    
  12.                                 mat3 skinningMatVec = getSkinningMatVec( skinningMat );
    
  13.                                 // Calculate world space position
    
  14.                                 vec4 pos = calcWorldPos( skinPos( gl_Vertex, skinningMat ) );
    
  15.                                 // Calculate clip space position
    
  16.                                 gl_Position = gl_ModelViewProjectionMatrix * pos;
    
  17.                         }
    
  18.                 ]]>
    
  19.                 </DefCode>
    
  20.         </VertexShader>
    
  21.  
    
  22.         <FragmentShader>
    
  23.                 <InsCode code="utilityLib/fragLighting.glsl" />
    
  24.                 <DefCode>
    
  25.                 <![CDATA[
    
  26.                         void main( void )
    
  27.                         {
    
  28.                                 gl_FragColor.rgb = vec3(0,0,0);
    
  29.                         }
    
  30.                 ]]>
    
  31.                 </DefCode>
    
  32.         </FragmentShader>
    
  33. </Context>
    


Example Result

Click here to view

To-Do List for this Article

- Write the article, describe the code and pipeline changes required
- Add pictures
- Ask for permission to upload a ZIP of my finished xml/tga files ;)

Technique - Glow
File:Todo.jpg
Using an alpha channel to add emissive bloom.
Version: 1.0
Compatible with Horde3D: 1.0 beta
Release date: 2008-08-06
Author(s): DarkAngel
Personal tools