# Phong shading in OpenGL: line of light from the center of the world

I implemented a Phong shader in GLSL, but there is a bug.

What you are (supposed) to see down below:

• A point light source rotating around the center of the world,

• with a radiance of (0, 100, 0)
• A textured quad with kd of (1, 0, 0).

The problem is:

• Why is there a a green line to the center of the world instead of a green spot light where the quad is lit? (where the center of the point light source is)

• (Btw in this case there would be only a yellow spot of light, because red + green = yellow)

#version 330

uniform mat4 ModelMatrix, ViewMatrix, ProjectionMatrix;

uniform vec4 wLiPos[5];       // pos of light source
uniform vec3 wEye;         // pos of eye
uniform int lightSize;      //number of lights

layout(location = 0) in vec3 vtxPos;
layout(location = 1) in vec3 vtxNorm;
layout(location = 2) in vec2 vtxUV;

out vec2 texCoord;
out vec3 wNormal;           // normal in world space
out vec3 wView[5];             // view in world space
out vec3 wLight[5];            // light dir in world space

void main() {
gl_Position = ProjectionMatrix * ViewMatrix * ModelMatrix * vec4(vtxPos, 1);
texCoord = vtxUV;
vec4 wPos = ModelMatrix * vec4(vtxPos, 1);
wNormal = (vec4(vtxNorm, 0) * inverse(ModelMatrix)).xyz;
for(int i = 0; i < lightSize; i++) {
wView[i] = wEye * wPos.w - wPos.xyz;
wLight[i] = wLiPos[i].xyz * wPos.w - wPos.xyz * wLiPos[i].w;
}
}


#version 330

uniform sampler2D samplerUnit;

uniform vec3 kd, ks, ka;   // diffuse, specular, ambient ref
uniform vec3 La, Le[5];    // ambient and point source rad
uniform float shininess;    // shininess for specular ref
uniform int lightSize;

in vec2 texCoord;
in vec3 wNormal;       // interpolated world sp normal
in vec3 wView[5];         // interpolated world sp view
in vec3 wLight[5];        // interpolated world sp illum dir

layout(location = 0) out vec4 fragmentColor;

void main() {
vec3 color = vec3(0, 0, 0);
for(int i = 0; i < lightSize; i++) {
vec3 N = normalize(wNormal);
vec3 V = normalize(wView[i]);
vec3 L = normalize(wLight[i]);
vec3 H = normalize(L + V);
float cost = max(dot(N,L), 0);
float cosd = max(dot(N,H), 0);
color += ka * La + (kd * cost + (ks * pow(cosd, shininess)) * Le[i]) / pow(length(wLight[i]), 2);
}
vec3 gamma = vec3(1.0/2.2);
fragmentColor = vec4(pow(color * vec3(texture2D(samplerUnit, texCoord)), gamma), 1);
}

• Also, why are multiplying the light position by the w component of the position?
– aces
May 8, 2017 at 4:08
• I was about to comment the same thing. Division by W is typical for things that have had a perspective matrix performed on them. It should not be needed for the world positions of lights. May 8, 2017 at 6:23
• wLiPos is a vec4, and I have to avoid dividing by zero, so I cross multiplied in the formula. May 8, 2017 at 6:45
• Now I multiple by the transpose of the inverse of the modelMatrix, but nothing changed. wNormal = (vec4(vtxNorm, 0) * transpose(inverse(ModelMatrix))).xyz; May 8, 2017 at 6:46
• You don't need the W component for world transformations. You can truncate the vec4*mat4 result to a vec3. May 8, 2017 at 9:25