Glow         A glow compositor method using 'Glow masks'

This page explains how to add glow to your scene. As example of what we mean some before/after pictures are below.

If you are looking for stencil glow, have a look at this topic: http://www.ogre3d.org/forums/viewtopic.php?f=11&t=27477

Examples


Glow_overview.jpg

a=texture, b=glow mask, c=result

Glow_off.png

Glow (and HDR) disabled

Glow_on.png

Glow and HDR on

Files

You will need to add these files to your resources:

glow.compositor

compositor Glow
{
	technique
	{
		texture rt0 target_width target_height PF_A8R8G8B8
		texture glowMap target_width target_height PF_A8R8G8B8
		texture AtoB target_width target_height PF_A8R8G8B8

		//Fetch scene contents.
		target rt0
		{
			input previous
		}

		//Get scene rendered with 'Glow' scheme
		target glowMap
		{
			input none
			material_scheme glow

			pass clear
			{
			}

			pass render_scene
			{
			}
		}

		//Blur it along X.
		target AtoB
		{
			input none

			pass clear
			{
			}

			pass render_quad
			{
				material GlowCompositorMat/GlowA
				input 0 glowMap
			}
		}

		//Blur along Y, add to original, and output.
		target_output
		{
			input none
			pass render_quad
			{
				material GlowCompositorMat/GlowB
				input 0 rt0
				input 1 AtoB
			}
		}
	}
}

glow.cg

//A.
float4 GlowA_fp
	(
		float2 uv: TEXCOORD0,

		uniform sampler2D scene: register(s0),
		uniform float4 invTexSize
		//uniform float time
	) : COLOR
#define RENDER_SCENE 1
#define BLUR_RADIUS 2
{
	float4 colour = float4(0);
	float blurSize = BLUR_RADIUS * invTexSize.x;

	//X-blur.
	colour += tex2D(scene, float2(uv.x - 4.0*blurSize, uv.y)) * 1.0/25.0;
	colour += tex2D(scene, float2(uv.x - 3.0*blurSize, uv.y)) * 2.0/25.0;
	colour += tex2D(scene, float2(uv.x - 2.0*blurSize, uv.y)) * 3.0/25.0;
	colour += tex2D(scene, float2(uv.x - blurSize, uv.y)) * 4.0/25.0;
	colour += tex2D(scene, float2(uv.x, uv.y)) * 5.0/25.0;
	colour += tex2D(scene, float2(uv.x + blurSize, uv.y)) * 4.0/25.0;
	colour += tex2D(scene, float2(uv.x + 2.0*blurSize, uv.y)) * 3.0/25.0;
	colour += tex2D(scene, float2(uv.x + 3.0*blurSize, uv.y)) * 2.0/25.0;
	colour += tex2D(scene, float2(uv.x + 4.0*blurSize, uv.y)) * 1.0/25.0;

	return colour;
}

//B.
float4 GlowB_fp
	(
		float2 uv: TEXCOORD0,

		uniform sampler2D scene: register(s0),
		uniform sampler2D blurX: register(s1),
		uniform float4 invTexSize,
		uniform float time
	) : COLOR
{
	float4 colour = float4(0);
	float blurSize = BLUR_RADIUS * invTexSize.y;

	//Y-blur.
	colour += tex2D(blurX, float2(uv.x, uv.y - 4.0*blurSize)) * 1.0/25.0;
	colour += tex2D(blurX, float2(uv.x, uv.y - 3.0*blurSize)) * 2.0/25.0;
	colour += tex2D(blurX, float2(uv.x, uv.y - 2.0*blurSize)) * 3.0/25.0;
	colour += tex2D(blurX, float2(uv.x, uv.y - blurSize)) * 4.0/25.0;
	colour += tex2D(blurX, float2(uv.x, uv.y)) * 5.0/25.0;
	colour += tex2D(blurX, float2(uv.x, uv.y + blurSize)) * 4.0/25.0;
	colour += tex2D(blurX, float2(uv.x, uv.y + 2.0*blurSize)) * 3.0/25.0;
	colour += tex2D(blurX, float2(uv.x, uv.y + 3.0*blurSize)) * 2.0/25.0;
	colour += tex2D(blurX, float2(uv.x, uv.y + 4.0*blurSize)) * 1.0/25.0;

	//Add this to original, return.
	return
#if RENDER_SCENE
		tex2D(scene, uv) +
#endif
		colour * 4;
}


glow.program

fragment_program GlowA_fp cg
{
	source glow.cg
	entry_point GlowA_fp

		default_params
		{
			param_named_auto invTexSize inverse_texture_size 0
			//param_named_auto time time_0_2pi 1
		}

	profiles ps_2_0 arbfp1
}

material GlowCompositorMat/GlowA
{
	technique
	{
		pass
		{
			cull_hardware none
			cull_software none
			depth_func always_pass

			fragment_program_ref GlowA_fp
			{
			}

			texture_unit map
			{
					tex_coord_set 0
					tex_address_mode clamp
					filtering trilinear
			}
		}
	}
}

fragment_program GlowB_fp cg
{
	source glow.cg
	entry_point GlowB_fp

		default_params
		{
			param_named_auto invTexSize inverse_texture_size 0
			param_named_auto time time_0_2pi 4
		}

	profiles ps_2_0 arbfp1
}

material GlowCompositorMat/GlowB
{
	technique
	{
		pass
		{
			cull_hardware none
			cull_software none
			depth_func always_pass

			fragment_program_ref GlowB_fp
			{
			}

			texture_unit scene
			{
					tex_coord_set 0
					tex_address_mode clamp
					filtering trilinear
			}

			texture_unit map
			{
					tex_coord_set 0
					tex_address_mode clamp
					filtering trilinear
			}
		}
	}
}

GlowMaterialListener.h (add to your sources)

#ifndef GLOWMATERIALLISTENER_H__
#define GLOWMATERIALLISTENER_H__

#include <Ogre.h>
#include <OgreMaterialManager.h>

class GlowMaterialListener : public Ogre::MaterialManager::Listener
{
protected:
	Ogre::MaterialPtr mBlackMat;
public:
	GlowMaterialListener()
	{
		mBlackMat = Ogre::MaterialManager::getSingleton().create("mGlowBlack", "Internal");
		mBlackMat->getTechnique(0)->getPass(0)->setDiffuse(0,0,0,0);
		mBlackMat->getTechnique(0)->getPass(0)->setSpecular(0,0,0,0);
		mBlackMat->getTechnique(0)->getPass(0)->setAmbient(0,0,0);
		mBlackMat->getTechnique(0)->getPass(0)->setSelfIllumination(0,0,0);
	}

	Ogre::Technique *handleSchemeNotFound(unsigned short, const Ogre::String& schemeName, Ogre::Material*mat, unsigned short, const Ogre::Renderable*)
	{
		if (schemeName == "glow")
		{
			//LogManager::getSingleton().logMessage(">> adding glow to material: "+mat->getName());
			return mBlackMat->getTechnique(0);
		}
		return NULL;
	}
};

#endif //GLOWMATERIALLISTENER_H__

Load the compositor in your code

#include "GlowMaterialListener.h"
...
	{
		CompositorManager::getSingleton().addCompositor(mCamera->getViewport(), "Glow");
		CompositorManager::getSingleton().setCompositorEnabled(mCamera->getViewport(), "Glow", true);
		GlowMaterialListener *gml = new GlowMaterialListener();
		Ogre::MaterialManager::getSingleton().addListener(gml);
	}

Add materials that glow

Add a new glow scheme technique to your material.

Original material:

material AC3D/Box5W900/Mat004_NoTex
{
	technique
	{
		pass
		{
			emissive 1 1 1 0.3
			texture_unit
			{
				anim_texture W900_headlight_material.png 2 0
			}
		}
	}
}


New material:

material AC3D/Box5W900/Mat004_NoTex
{
	technique
	{
		pass
		{
			emissive 1 1 1 0.3
			texture_unit
			{
				anim_texture W900_headlight_material.png 2 0
			}
		}
	}
	technique
	{
		scheme glow
		pass
		{
			texture_unit
			{
			texture W900_headlight_material_1.png
			}
			ambient 1 1 1
			diffuse 1 1 1
			specular 0 0 0 1
			emissive 0 0 0
		}
	}
}


Please note that you can change the amount of the glow by modifying the ambient and diffuse values. (also during runtime)

It may help to write a 'base' material to avoid repetition. For example, if 'BaseAmbient' and 'BasePerLight' are your ambient and per-light shaders respectively:-

material BaseGlow
{ 
        set $diffuse_tex "Default.png"
        set $normal_tex "Default_NM.png"
        set $glow_tex "Default_GW.png"

        set $ambient "0.8 0.8 0.8 1"
        set $diffuse "0.9 0.9 0.9 1"
        set $specular "0.9 0.9 0.9 1"
        set $glow_amount "0.7"

        technique Shaders
        { 
                pass
                {
                        ambient $ambient
                        
                        vertex_program_ref BaseAmbient_vp
                        { 
                        }   

                        fragment_program_ref BaseAmbient_fp
                        {
                        } 
                        
                        texture_unit DiffuseMap
                        {
                                texture $diffuse_tex
                        }
                }
                pass 
                {
                        max_lights 12
                        scene_blend add
                        iteration once_per_light

                        diffuse $diffuse
                        specular $specular

                        vertex_program_ref BasePerLight_vp
                        { 
                        }   

                        fragment_program_ref BasePerLight_fp
                        {
                        } 
                        
                        texture_unit DiffuseMap
                        {
                                texture $diffuse_tex
                        }
                        
                        texture_unit NormalMap
                        {
                        }

                        texture_unit ShadowMap
                        {
                                content_type shadow
                                filtering anisotropic
                                max_anisotropy 16
                                tex_address_mode border
                                tex_border_colour 1 1 1
                        }
                }  

        }  
        technique Fallback
        { 
                pass
                {
                        ambient $ambient
                        diffuse $diffuse
                        specular $specular
                        
                        texture_unit DiffuseMap
                        {
                                texture $diffuse_tex
                        }
                }
        }  
        technique Glow
        { 
                scheme Scheme/Glow
                pass
                {
                        ambient $glow_amount $glow_amount $glow_amount 1
                        
                        vertex_program_ref BaseAmbient_vp
                        { 
                        }   

                        fragment_program_ref BaseAmbient_fp
                        {
                        } 
                        
                        texture_unit GlowMap
                        {
                                texture $glow_tex
                        }
                }
        }  
}

Then you can just do this to make a new glowing material, for example:-

material Objects/Player : BaseGlow
{
        set $diffuse_tex "Player.png"

        set $ambient "0.9 0.9 0.9 1"
        set $diffuse "0.9 0.9 0.9 1"
        set $specular "0.3 0.3 0.3 1"

        set $glow_tex "Player_GW.png"
        set $glow_amount "0.2"
}

Debugging

You can change "#define RENDER_SCENE 1" to "#define RENDER_SCENE 0" in glow.cg in order to just display glowing objects. Non-glowing objects will be black.


Written by Tdev