3

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)

enter image description here

Vertex Shader:

#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;
    }
}

Fragment shader:

#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);
}
Tudvari
  • 313
  • 1
  • 3
  • 13
  • Also, why are multiplying the light position by the w component of the position? – aces May 08 '17 at 04: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. – PaulHK May 08 '17 at 06:23
  • wLiPos is a vec4, and I have to avoid dividing by zero, so I cross multiplied in the formula. – Tudvari May 08 '17 at 06:45
  • Now I multiple by the transpose of the inverse of the modelMatrix, but nothing changed. wNormal = (vec4(vtxNorm, 0) * transpose(inverse(ModelMatrix))).xyz; – Tudvari May 08 '17 at 06:46
  • You don't need the W component for world transformations. You can truncate the vec4*mat4 result to a vec3. – PaulHK May 08 '17 at 09:25
  • Oh yes, that's a typo. wLightPos is not in world, it's a vec4, so it can be in the infinity for example. – Tudvari May 08 '17 at 10:03
  • Or you mean that wPos? But if yes, then the w component is always 1, so that multiplication shouldn't change anything. – Tudvari May 08 '17 at 10:06
  • but if I just write eye - pos and LightPos - pos, everything stays the same. – Tudvari May 08 '17 at 10:34
  • How does it look if you remove the distance attenuation? (*le[i] and / pow(length(wLight[i]), 2) ) – PaulHK May 09 '17 at 06:12
  • Didn't fix it. https://i.gyazo.com/814598d0d3afea8d9e83b6c4abb84854.png – Tudvari May 09 '17 at 09:21
  • If I comment out the kd part in the color: https://i.gyazo.com/0006479371f58a9931250b2d03dcd244.png So the specular part causes it. With only ka and kd: https://i.gyazo.com/e9630d77a2dc443aa17412a2d2cc486a.png – Tudvari May 09 '17 at 09:28
  • It's something about the 'cosd' – Tudvari May 09 '17 at 09:37

1 Answers1

2

I forgot to set the wEye uniform, so it was always (0, 0, 0).

Tudvari
  • 313
  • 1
  • 3
  • 13