September 21, 2012

Let There Be Light!

"And George said unto Collapse, "let there be light," and there was, and George saw that it was good."

Edit (2.1.2012): My lighting shader has changed quite a bit since this post; I opted for a multi-pass shader, rather than maxing out the shader variables.

After several weeks of reading about shaders, learning GLSL, learning about lighting, observing other projects, finally writing my own, and spending hours debugging, tweaking, and improving, it's finally done. My shader supports multiple lights, and gets re-written on the fly to support larger and larger amounts, due to GLSL loop limitations. Whenever I want to increase the amount of lights I use, I merely say:

    LightingShader.SetMacro("NUM_LIGHTS", ++lights);

Which will then re-write, re-compile, and re-link the shader with a new light count. Though I was considering not releasing the shader source code, here it is anyway:

#define MAX_LIGHTS 10 // Re-written on the fly
/**
* @file
* Fragment shader for lighting.
* Per-pixel point light lighting is done in this shader.
*
* @author me
* @addtogroup Shaders
* @{
*/
uniform sampler2D tex; // Active texture
uniform int scr_height; // Screen height
uniform vec2 light_pos[MAX_LIGHTS]; // Light position
uniform vec3 light_col[MAX_LIGHTS]; // Light color
uniform vec3 light_att[MAX_LIGHTS]; // Light attenuation
uniform float light_brt[MAX_LIGHTS]; // Light brightness
void main()
{
vec2 pixel = gl_FragCoord.xy;
pixel.y = scr_height - pixel.y;
vec3 lights;
for(int i = 0; i < MAX_LIGHTS; ++i)
{
vec2 light_vec = light_pos[i] - pixel;
float dist = length(light_vec);
float att = 1.0 / ( light_att[i].x +
(light_att[i].y * dist) +
(light_att[i].z * dist * dist));
lights += light_col[i] * att * light_brt[i];
}
vec4 texel = texture2D(tex, gl_TexCoord[0].st) * gl_Color;
gl_FragColor = texel * vec4(lights, 1.0);
}
/** @} */
view raw Lighting.c hosted with ❤ by GitHub
Here are some screen-shots of lighting:


Original shader - one light (in-game)

Final shader - multiple lights (test zone)

No comments:

Post a Comment