0

I've succeeded to create a window with openTK and draw triangles on the screen, but I'm having an issue with lighting and shaders.

To light my cube, I would like the color of the faces to be function of the dot product between the face normal and the light direction. However, in the cube mesh, normals of my vertices are folowing the vector center_of_the_cube - vertex, so they can be shared for each of the 3 edge that share that vertex. See the code of my cube mesh :

vertices = new Vertex[8]
{
    new Vertex(new Vector3(-1, -1, -1), new Vector3(-1, -1, -1), new Vector2(0, 0)),
    new Vertex(new Vector3(+1, -1, -1), new Vector3(+1, -1, -1), new Vector2(0, 0)),
    new Vertex(new Vector3(+1, +1, -1), new Vector3(+1, +1, -1), new Vector2(0, 0)),
    new Vertex(new Vector3(-1, +1, -1), new Vector3(-1, +1, -1), new Vector2(0, 0)),
    new Vertex(new Vector3(-1, +1, +1), new Vector3(-1, +1, +1), new Vector2(0, 0)),
    new Vertex(new Vector3(+1, +1, +1), new Vector3(+1, +1, +1), new Vector2(0, 0)),
    new Vertex(new Vector3(+1, -1, +1), new Vector3(+1, -1, +1), new Vector2(0, 0)),
    new Vertex(new Vector3(-1, -1, +1), new Vector3(-1, -1, +1), new Vector2(0, 0)),
};

triangles = new uint[36] {
    0, 2, 1, //face front
    0, 3, 2,
    2, 3, 4, //face top
    2, 4, 5,
    1, 2, 5, //face right
    1, 5, 6,
    0, 7, 4, //face left
    0, 4, 3,
    5, 4, 7, //face back
    5, 7, 6,
    0, 6, 7, //face bottom
    0, 1, 6
};

So when I use my vertex shader and fragment shader :

Vertex Shader :

#version 330

layout(location=0) in vec3 inPos;
layout(location=1) in vec3 inNormal;
layout(location=2) in vec2 inTextCoords;

uniform mat4 projectionMat;
uniform mat4 viewMat;
uniform mat4 modelMat;

out vec3 FragPos;  
out vec3 Normal;
  
void main()
{
    gl_Position = projectionMat * viewMat * modelMat * vec4(inPos, 1.0);
    FragPos = vec3(modelMat * vec4(inPos, 1.0));
    Normal = vec3(modelMat * vec4(inNormal, 1.0));
}

Fragment :

#version 330

uniform vec3 mainLightPosition;
uniform vec4 mainLightColor;
uniform vec4 ambiantLightColor;
uniform vec3 cameraPosition;

in vec3 FragPos;  
in vec3 Normal;

out vec4 FragColor;

void main()
{
    vec3 norm = normalize(Normal);
    vec3 lightDir = normalize(mainLightPosition - FragPos);
    float diff = max(dot(norm, lightDir), 0.0);
    vec3 diffuse = diff * mainLightColor.xyz;
    vec3 result = (ambiantLightColor.xyz + diffuse);
    FragColor = vec4(result, 1.0);
}

The normal is interpolated for each pixel of the screen, and the faces of the cube do not have a uniform color.

Here you can see an exemple (yellow-ish light above the cube, blue-ish weak light as ambiant)

exemple

There is also this weird artifact were it seems that I can see the back faces.

So how could I tell openGL to not interpolate for the normals, but instead always take the mean values?

genpfault
  • 49,394
  • 10
  • 79
  • 128

0 Answers0