<p>The normals were indeed wrong. Which was crazy, because I had even checked in Blender that they were correct (and they were). Turns out, when loading the mesh, I was passing the normal as color and vice versa. Valletin's normal visualization shader was great (<a href="https://vallentin.dev/2015/02/16/visualizing-normals" rel="nofollow noreferrer">https://vallentin.dev/2015/02/16/visualizing-normals</a>).</p>

<p>Thanks for your help!</p>

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

CC BY-SA 4.0
2020-01-22T08:46:36.273Z
2020-01-22T09:00:47.623Z
2020-01-22T09:00:47.623Z
Ohkomonkiainen
<p>A point light is illuminating only a half of a scene in my small 3D renderer. It happens on every scene I've tried (conference room, cornell box, etc). </p>

<p>How do I go about debugging this? What could be wrong?</p>

<p><a href="https://i.sstatic.net/RF9YY.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/RF9YY.png" alt="sponza scene"></a></p>

<p>Here are the shaders. I'm not doing anything out of the ordinary. Light is positioned at (0, 1.0, 0) in world space.</p>

<pre><code>//
// VERT SHADER
//
#version 410 core

uniform mat4 M;
uniform mat4 V;
uniform mat4 P;

layout (location = 0) in vec3 position;
layout (location = 1) in vec3 normal;
layout (location = 2) in vec3 color;
layout (location = 3) in vec2 texCoords;

out vec3 fWorldPos;
out vec3 fNormal;
out vec3 fColor;
out vec2 fTexCoords;

void main()
{
    mat4 normalMatrix = transpose(inverse(M));

    fWorldPos = vec3(M * vec4(position, 1.0));
    fNormal = normal; // also tested multiplying with normal, M, and MV matrices
    fColor = color;
    fTexCoords = texCoords;

    gl_Position = P * V * M * vec4(position, 1);
}


//
// FRAG SHADER
//
#version 410 core
#define MAX_POINT_LIGHTS 4

struct PointLight {
    float strength;
    vec3 position;
    vec3 color;
    vec3 attenuation;
};

struct Material {
    vec3 color;
};

uniform Material material;
uniform int totalPointLights;
uniform PointLight pointLights[MAX_POINT_LIGHTS];
uniform vec3 cameraPosition;

in vec3 fWorldPos;
in vec3 fNormal;
in vec3 fColor;
in vec2 fTexCoords;

out vec4 color;

float attenuate(float dist, const PointLight light) {
    return light.strength / (light.attenuation.x + light.attenuation.y * dist + light.attenuation.z * dist * dist);
}

//
// MAIN
//
void main()
{
  vec3 normal = normalize(fNormal);

  PointLight light = pointLights[0];

  vec3 lightDir = light.position - fWorldPos;
  float lightDst = length(lightDir);
  lightDir = lightDir / lightDst;

  float att = attenuate(lightDst, light);
  float diffuseFactor = max(dot(normal, lightDir), 0.0);

  color = vec4(material.color * diffuseFactor * att, 1);
}
<span class="math-container">```</span>
</code></pre>

CC BY-SA 4.0
2020-01-21T19:33:36.923Z
is this a raytracer or something? If so can you try to disable shadows and see if it renders everything then? It happened with me once due to incorrect intersection testing and it was thinking that the lit surface was in shadow
gallickgunner
CC BY-SA 4.0
2020-01-21T19:50:17.347Z
@gallickgunner No, it's just a regular forward renderer. It loads a scene from an .obj -file and renders it using the shader above. There are no shadows yet. Thanks though.
Ohkomonkiainen
CC BY-SA 4.0
2020-01-21T22:31:44.293Z
Quick thought, it may be because of the diffuseFactor term or the att term going to zero. Did you try inverting the normals or the light direction and see how does it look then? You can also try to just set the material color and add terms one by one so as to figure out which factor is causing the problem
gallickgunner
CC BY-SA 4.0
2020-01-22T01:56:45.503Z
Wrong normals perhaps? Test with M == identity to see if that's the problem. You should transform the normal with the transpose of the inverse matrix. And then normalize it again.
Olivier
<opengl><glsl><shading>
Point light illuminating only half of a scene
Ohkomonkiainen
# Point light illuminating only half of a scene

(Asked by: username_0 on 2020-01-21)

A point light is illuminating only a half of a scene in my small 3D renderer. It happens on every scene I've tried (conference room, cornell box, etc).

How do I go about debugging this? What could be wrong?

[![sponza scene](https://i.sstatic.net/RF9YY.png)](https://i.sstatic.net/RF9YY.png)

Here are the shaders. I'm not doing anything out of the ordinary. Light is positioned at (0, 1.0, 0) in world space.

```
//
// VERT SHADER
//
#version 410 core

uniform mat4 M;
uniform mat4 V;
uniform mat4 P;

layout (location = 0) in vec3 position;
layout (location = 1) in vec3 normal;
layout (location = 2) in vec3 color;
layout (location = 3) in vec2 texCoords;

out vec3 fWorldPos;
out vec3 fNormal;
out vec3 fColor;
out vec2 fTexCoords;

void main()
{
    mat4 normalMatrix = transpose(inverse(M));

    fWorldPos = vec3(M * vec4(position, 1.0));
    fNormal = normal; // also tested multiplying with normal, M, and MV matrices
    fColor = color;
    fTexCoords = texCoords;

    gl_Position = P * V * M * vec4(position, 1);
}

//
// FRAG SHADER
//
#version 410 core
#define MAX_POINT_LIGHTS 4

struct PointLight {
    float strength;
    vec3 position;
    vec3 color;
    vec3 attenuation;
};

struct Material {
    vec3 color;
};

uniform Material material;
uniform int totalPointLights;
uniform PointLight pointLights[MAX_POINT_LIGHTS];
uniform vec3 cameraPosition;

in vec3 fWorldPos;
in vec3 fNormal;
in vec3 fColor;
in vec2 fTexCoords;

out vec4 color;

float attenuate(float dist, const PointLight light) {
    return light.strength / (light.attenuation.x + light.attenuation.y * dist + light.attenuation.z * dist * dist);
}

//
// MAIN
//
void main()
{
  vec3 normal = normalize(fNormal);

  PointLight light = pointLights[0];

  vec3 lightDir = light.position - fWorldPos;
  float lightDst = length(lightDir);
  lightDir = lightDir / lightDst;

  float att = attenuate(lightDst, light);
  float diffuseFactor = max(dot(normal, lightDir), 0.0);

  color = vec4(material.color * diffuseFactor * att, 1);
}
```

```

**Tags:** opengl, glsl, shading

> **Comments:**
> **username_1**: is this a raytracer or something? If so can you try to disable shadows and see if it renders everything then? It happened with me once due to incorrect intersection testing and it was thinking that the lit surface was in shadow  
> **username_0**: @username_1 No, it's just a regular forward renderer. It loads a scene from an .obj -file and renders it using the shader above. There are no shadows yet. Thanks though.  
> **username_1**: Quick thought, it may be because of the diffuseFactor term or the att term going to zero. Did you try inverting the normals or the light direction and see how does it look then? You can also try to just set the material color and add terms one by one so as to figure out which factor is causing the problem  
> **username_2**: Wrong normals perhaps? Test with M == identity to see if that's the problem. You should transform the normal with the transpose of the inverse matrix. And then normalize it again.  

---

## 1 answers

### Answer by username_0 on 2020-01-22. Score: 3 | Accepted answer

The normals were indeed wrong. Which was crazy, because I had even checked in Blender that they were correct (and they were). Turns out, when loading the mesh, I was passing the normal as color and vice versa. Valletin's normal visualization shader was great (<https://vallentin.dev/2015/02/16/visualizing-normals>).

Thanks for your help!

[![enter image description here](https://i.sstatic.net/6Ifpz.jpg)](https://i.sstatic.net/6Ifpz.jpg)


---

