<p>I forgot to set the <strong>wEye uniform</strong>, so it was always <strong>(0, 0, 0)</strong>.</p>

CC BY-SA 3.0
2017-05-09T09:48:45.650Z
2017-05-09T09:48:45.650Z
Tudvari
<p>I implemented a Phong shader in GLSL, but there is a bug.</p>

<p><strong>What you are (supposed) to see down below:</strong></p>

<ul>
<li><p>A point light source rotating around the center of the world,</p>

<ul>
<li>with a <strong>radiance of (0, 100, 0)</strong></li>
</ul></li>
<li><p>A textured quad with <strong>kd of (1, 0, 0)</strong>.</p></li>
</ul>

<p><strong>The problem is:</strong></p>

<ul>
<li><p>Why is there a a <strong>green line to the center of the world</strong> instead of a <strong>green spot light where the quad is lit</strong>? (where the center of the point light source is)</p>

<ul>
<li>(Btw in this case there would be only a yellow spot of light, because red + green = yellow)</li>
</ul></li>
</ul>

<p><a href="https://i.sstatic.net/oPH5d.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/oPH5d.png" alt="enter image description here"></a></p>

<p><strong>Vertex Shader:</strong></p>

<pre><code>#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 &lt; lightSize; i++) {
        wView[i] = wEye * wPos.w - wPos.xyz;
        wLight[i] = wLiPos[i].xyz * wPos.w - wPos.xyz * wLiPos[i].w;
    }
}
</code></pre>

<p><strong>Fragment shader:</strong></p>

<pre><code>#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 &lt; 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);
}
</code></pre>

CC BY-SA 3.0
2017-05-08T04:08:37.453Z
Also, why are multiplying the light position by the w component of the position?
aces
CC BY-SA 3.0
2017-05-08T06:23:44.060Z
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
CC BY-SA 3.0
2017-05-08T06:45:19.170Z
wLiPos is a vec4, and I have to avoid dividing by zero, so I cross multiplied in the formula.
Tudvari
CC BY-SA 3.0
2017-05-08T06:46:51.617Z
Now I multiple by the transpose of the inverse of the modelMatrix, but nothing changed.
wNormal = (vec4(vtxNorm, 0) * transpose(inverse(ModelMatrix))).xyz;
Tudvari
CC BY-SA 3.0
2017-05-08T09:25:20.640Z
You don't need the W component for world transformations. You can truncate the vec4*mat4 result to a vec3.
PaulHK
CC BY-SA 3.0
2017-05-08T10:03:56.980Z
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
CC BY-SA 3.0
2017-05-08T10:06:37.417Z
Or you mean that wPos? But if yes, then the w component is always 1, so that multiplication shouldn't change anything.
Tudvari
CC BY-SA 3.0
2017-05-08T10:34:28.327Z
but if I just write eye - pos and LightPos - pos, everything stays the same.
Tudvari
CC BY-SA 3.0
2017-05-09T06:12:25.200Z
How does it look if you remove the distance attenuation?  (*le[i] and / pow(length(wLight[i]), 2)  )
PaulHK
CC BY-SA 3.0
2017-05-09T09:21:26.297Z
Didn't fix it. https://i.gyazo.com/814598d0d3afea8d9e83b6c4abb84854.png
Tudvari
CC BY-SA 3.0
2017-05-09T09:28:14.450Z
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
CC BY-SA 3.0
2017-05-09T09:37:48.657Z
It's something about the 'cosd'
Tudvari
<opengl><shader><glsl>
Phong shading in OpenGL: line of light from the center of the world
Tudvari
# Phong shading in OpenGL: line of light from the center of the world

(Asked by: username_0 on 2017-05-05)

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](https://i.sstatic.net/oPH5d.png)](https://i.sstatic.net/oPH5d.png)

**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);
}

```

**Tags:** opengl, shader, glsl

> **Comments:**
> **username_1**: Also, why are multiplying the light position by the w component of the position?  
> **username_2**: 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.  
> **username_0**: wLiPos is a vec4, and I have to avoid dividing by zero, so I cross multiplied in the formula.  
> **username_0**: Now I multiple by the transpose of the inverse of the modelMatrix, but nothing changed. wNormal = (vec4(vtxNorm, 0) * transpose(inverse(ModelMatrix))).xyz;  
> **username_2**: You don't need the W component for world transformations. You can truncate the vec4*mat4 result to a vec3.  
> **username_0**: Oh yes, that's a typo. wLightPos is not in world, it's a vec4, so it can be in the infinity for example.  
> **username_0**: Or you mean that wPos? But if yes, then the w component is always 1, so that multiplication shouldn't change anything.  
> **username_0**: but if I just write eye - pos and LightPos - pos, everything stays the same.  
> **username_2**: How does it look if you remove the distance attenuation?  (*le[i] and / pow(length(wLight[i]), 2)  )  
> **username_0**: Didn't fix it. https://i.gyazo.com/814598d0d3afea8d9e83b6c4abb84854.png  
> **username_0**: 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  
> **username_0**: It's something about the 'cosd'  

---

## 1 answers

### Answer by username_0 on 2017-05-09. Score: 2 | Accepted answer

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


---

