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?
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.