How do you make specific parts of a material glow with a bloom effect?

I want to jump back into the game engine and try to revive and improve on some of my old projects long lost. But I have run into a bump in the road. How do you make a material or part of a material glow? I was hoping to use a texture with some details around the edges that will be meant to glow, but I ONLY want those details to glow, and have a bloom like effect. Here’s an example from one of my favorite games of what I want to try and make. See how only the gold actually highlights?
http://thatgamecompany.com/wp-content/themes/thatgamecompany/_include/img/journey/journey-game-screenshot-12.jpg

I am also interested in this to use for a tron like game I working on. I believe you could do it with a custom filter. I was planning to program the filter later in production. I was planning on doing it by having a second material which would be black everywhere it is to render normal and have it white wherever it should be a “light”. The filter would check the second material (as it would with a bump map) and would basically render those areas as shadeless and add some bloom. I haven’t put too much thought into it though so I am interested to know if there is a easier way.

So, my first idea was they have a bloom filter set up to perform only on saturated colors with a bright luminescence (1.0 brightness), but that would make other colors bloom as well.

My second idea is that they’re using a GLSL shader on the characters to change the color of their cloaks fringes in-game. Then, they render the bright parts of the meshes (basically duplicate meshes, but only with a ‘bloom map’ texture applied, or just the ‘to-be-bloomed’ parts of the meshes) out to an off-screen buffer, which gets the effect applied and then gets drawn over the scene.

Started working on getting this kind of result with shaders and here is what I have so far, just a bit more to go. I will post the final code sometime soon and how to use it. I have never worked with shaders before yesterday so it’s probably not going to be too great coding-wise, but its better than nothing. Still have to add bloom.



Edit:
I ended up not adding the bloom because it has to great a frame rate drop so here is the code I am using:


import bge
 
cont = bge.logic.getCurrentController()
 
VertexShader = """
         varying vec4 position; 
            // position of the vertex (and fragment) in view space 
         varying vec3 varyingNormalDirection; 
            // surface normal vector in view space
         //FREV    
         varying vec4 texCoords; // texture coordinates
 
 
         void main()
         {                              
            position = gl_ModelViewMatrix * gl_Vertex; 
            varyingNormalDirection = 
               normalize(gl_NormalMatrix * gl_Normal);
               
            texCoords = gl_MultiTexCoord0;//EDIT               
 
            gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
         }
"""
 
FragmentShader = """
         const int numberOfLights = gl_MaxLights; 
            // up to gl_MaxLights (often 8)
 
         varying vec4 position; 
            // position of the vertex (and fragment) in view space 
         varying vec3 varyingNormalDirection; 
            // surface normal vector in view space
         varying vec4 texCoords; // texture coordinates
         uniform sampler2D base;
         uniform sampler2D base_LMap;
 
         void main()
         {
            vec3 normalDirection = normalize(varyingNormalDirection);
            vec3 viewDirection = -normalize(vec3(position)); 
            vec3 lightDirection = vec3(0.0, 0.0, 0.0);
            float attenuation = 20.0;
 
            // initialize total lighting with ambient lighting
            vec3 totalLighting = vec3(gl_LightModel.ambient) 
               * vec3(gl_FrontMaterial.emission);
 
            for (int index = 0; index < numberOfLights; index++) 
               // for all light sources
            {
               if (0.0 == gl_LightSource[index].position.w) 
                  // directional light?
               {
                  attenuation = 1.0; // no attenuation
                  lightDirection = 
                     normalize(vec3(gl_LightSource[index].position));
               } 
               if (0.0 != gl_LightSource[index].position.w 
                  && gl_LightSource[index].spotCutoff > 90.0) 
                  // point light? 
               {
                  vec3 positionToLightSource = 
                     vec3(gl_LightSource[index].position - position);
                  float distance = length(positionToLightSource);
                  attenuation = 1.0 / distance; // linear attenuation                    
                  lightDirection = normalize(positionToLightSource);
               }
               if (0.0 != gl_LightSource[index].position.w 
                 && gl_LightSource[index].spotCutoff <= 90.0) 
                 // spotlight?
               {
                  vec3 positionToLightSource = 
                     vec3(gl_LightSource[index].position - position);
                  float distance = length(positionToLightSource);
                  attenuation = 1.0 / distance; // linear attenuation 
                  lightDirection = normalize(positionToLightSource);
 
                  float clampedCosine = max(0.0, dot(-lightDirection, 
                     gl_LightSource[0].spotDirection));
                  if (clampedCosine < gl_LightSource[0].spotCosCutoff) 
                     // outside of spotlight cone?
                  {
                     attenuation = 0.0;
                  }
                  else
                  {
                     attenuation = attenuation * pow(clampedCosine, 
                        gl_LightSource[0].spotExponent);   
                  }
               }
 
               vec3 diffuseReflection = attenuation 
                  * vec3(gl_LightSource[index].diffuse) 
                  * vec3(gl_FrontMaterial.emission)
                  * max(0.0, dot(normalDirection, lightDirection));
 
               vec3 specularReflection;
               if (dot(normalDirection, lightDirection) < 0.0) 
                  // light source on the wrong side?
               {
                  specularReflection = vec3(0.0, 0.0, 0.0); 
                     // no specular reflection
               }
               else // light source on the right side
               {
                  specularReflection = attenuation 
                     * vec3(gl_LightSource[index].specular) 
                     * vec3(gl_FrontMaterial.specular) 
                     * pow(max(0.0, dot(reflect(-lightDirection, 
                     normalDirection), viewDirection)),  
                     gl_FrontMaterial.shininess);
               }
 
               totalLighting = totalLighting + diffuseReflection + specularReflection*3;
            }
            //EDITED by DrFrev
            vec3 realCol = vec3(texture2D(base, vec2(texCoords)));
            if (realCol[0] > 0.95 | realCol[1] > 0.95 | realCol[2] > 0.95) {
                gl_FragColor = vec4(realCol, 1.0);
            } else {
                gl_FragColor = vec4(realCol*totalLighting+totalLighting, 1.0);
            }
            //gl_FragColor = vec4(totalLighting*5, 1.0);
         }
"""
 
 
mesh = cont.owner.meshes[0]
for mat in mesh.materials:
    shader = mat.getShader()
    if shader != None:
        if not shader.isValid():
            shader.setSource(VertexShader, FragmentShader, 1)

It mostly comes from http://en.wikibooks.org/wiki/GLSL_Programming/Blender. It will make any color that has a value of 242 or higher for either the red, green, or blue component. Not the best code, but oh well.