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
a=texture, b=glow mask, c=result
Glow (and HDR) disabled
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