# GLSL per pixel lighting with custom light type

Ok, I am having a big problem here. I just got into GLSL yesterday, so the code will be terrible, I'm sure.

Basically, I am attempting to make a light that can be passed into the fragment shader (for learning purposes). I have four input values: one for the position of the light, one for the color, one for the distance it can travel, and one for the intensity. I want to find the distance between the light and the fragment, then calculate the color from there. The code I have gives me a simply gorgeous ring of light that get's twisted and widened as the matrix is modified. I love the results, but it is not even close to what I am after.

I want the light to be moved with all of the vertices, so it is always in the same place in relation to the objects. I can easily take it from there, but getting that to work seems to be impossible with my current structure. Can somebody give me a few pointers (pun not intended)?

attribute vec4 position;
attribute vec4 color;
attribute vec2 textureCoordinates;

varying vec4 colorVarying;
varying vec2 texturePosition;
varying vec4 fposition;
varying vec4 lightPosition;
varying float lightDistance;
varying float lightIntensity;
varying vec4 lightColor;

void main() {
vec4 ECposition = gl_ModelViewMatrix * gl_Vertex;
vec3 tnorm = normalize(vec3 (gl_NormalMatrix * gl_Normal));
fposition = ftransform();

gl_Position = fposition;
gl_TexCoord[0] = gl_MultiTexCoord0;
fposition = ECposition;

lightPosition = vec4(0.0, 0.0, 5.0, 0.0) * gl_ModelViewMatrix * gl_Vertex;
lightDistance = 5.0;
lightIntensity = 1.0;
lightColor = vec4(0.2, 0.2, 0.2, 1.0);
}


varying vec4 colorVarying;
varying vec2 texturePosition;
varying vec4 fposition;
varying vec4 lightPosition;
varying float lightDistance;
varying float lightIntensity;
varying vec4 lightColor;

uniform sampler2D texture;

void main() {
float l_distance = sqrt((gl_FragCoord.x * lightPosition.x) + (gl_FragCoord.y * lightPosition.y) + (gl_FragCoord.z * lightPosition.z));
float l_value = lightIntensity / (l_distance / lightDistance);
vec4 l_color = vec4(l_value * lightColor.r, l_value * lightColor.g, l_value * lightColor.b, l_value * lightColor.a);

vec4 color;
color = texture2D(texture, gl_TexCoord[0].st);
gl_FragColor = l_color * color;
//gl_FragColor = fposition;
}


Result produced by this code:

http://i1177.photobucket.com/albums/x349/Jpdiffy/ScreenShot2012-11-16at93614PM.png

With Ken's edit:

http://i1177.photobucket.com/albums/x349/Jpdiffy/ScreenShot2012-11-17at32733PM.png

• edited my answer based on the new images – Ken Nov 17 '12 at 23:36

If you want the light to have maintain a relative position to all the objects you are rendering, then this line;

lightPosition = vec4(0.0, 0.0, 5.0, 0.0) * gl_ModelViewMatrix * gl_Vertex;


should be [after edit];

lightPosition = gl_ModelViewMatrix*vec4(0.0, 0.0, 5.0, 0.0)  ;


Also, is the l_distance meant to be the distance from the light to the fragment? Your code for l-disatnce doesn't make any gsense (to me at least). If its meant to be distance;

vec4 l_vector=gl_FragCoord-lightPosition;

float l_distance = sqrt((l_vector.x*l_vector.x) + (l_vector.y *l_vector.y) + (l_vector.z * l_vector.z));

• I tried that, but now I just get a laser-style light. I've edited the main post the illustrate it. – Justin Nov 17 '12 at 22:27
• Actually, now it seems to move with the view, not the rest of the scene. The light is always in the bottom left corner of the screen no matter what happens. Apart from that, this is working perfectly. – Justin Nov 18 '12 at 18:31
• Any idea what is wrong? – Justin Nov 19 '12 at 19:25