3
\$\begingroup\$

I'm writing a simple 3D renderer and while the model loads fine, the colors are off. Quite a few fragments in the model show no color at all.

Here is the render: enter image description here

The locations of the blacked out fragments change everytime I move my camera. From another angle:

enter image description here

Vertex shader:

#version 330 core
layout (location = 0) in vec3 pos;
layout (location = 1) in vec3 normal;
layout (location = 2) in vec2 uvCoords;

out vec2 texCoords;
out vec3 normCoords;
out vec3 fragmentPos;

uniform mat4 viewMatrix;
uniform mat4 projMatrix;
uniform mat4 modelMatrix; // Just an identity matrix for now

void main()
{
    normCoords = normal;
    fragmentPos = pos;

    texCoords = uvCoords;    

     gl_Position = projMatrix * viewMatrix * modelMatrix * vec4(pos, 1.0);
}

Fragment shader:

#version 330 core

out vec4 frag_color;

in vec2 texCoords;
in vec3 normCoords;
in vec3 fragmentPos;

struct Light
{
    vec3 lightPos;
    vec3 lightColor;
};

uniform Light light;
uniform vec3 modelColor;

bool checkInf(in vec3 vect)
{
    return (isinf(vect.x) || isinf(vect.y) || isinf(vect.z));
}

bool checkNan(in vec3 vect)
{
    return (isnan(vect.x) || isnan(vect.y) || isnan(vect.z));
}

void main()
{    
    float ambientValue = 0.05;
    vec3 ambientColor = ambientValue * light.lightColor;

    vec3 result;
    vec3 normalizedNormal = normalize(normCoords);
    vec3 lightDir = normalize(light.lightPos - fragmentPos);

    if(checkInf(normalizedNormal) || checkInf(lightDir) || checkNan(normalizedNormal) || checkNan(lightDir))
        result = vec3(0.5,0.5,0.5);

    else
    {
        float diffuseValue = max(dot(normalizedNormal, lightDir), 0.0);
        vec3 diffuseColor = diffuseValue * light.lightColor;

        result = (diffuseColor + ambientColor) * modelColor;
    }
    frag_color = vec4(result, 1.0);
}

After some playing around, I realized that the blacked out fragments were due to the diffuse lighting calculations. After some searching on the internet, I found this answer: answer that suggested it may be caused by normalized vector being Nan or infinity. To test that, I decided to check each normalized vector to see if it was Nan or infinity and if it was, set it to a grey color. But that didn't work.

Any help would be appreciated.

\$\endgroup\$
3
  • 1
    \$\begingroup\$ Looks to me like backfacing triangles, and if it's flickering when you move then I'd suspect that you're drawing each tri as both a front and a back, and you're getting z-fighting \$\endgroup\$
    – A C
    Jun 29, 2019 at 2:36
  • 2
    \$\begingroup\$ This is definitely Z-Buffer problem, artifacts seem to resolve at a distance closer to the viewer, where precision is supposed to be higher. \$\endgroup\$
    – Ocelot
    Jun 29, 2019 at 3:39
  • \$\begingroup\$ @Ocelot that was the problem! Thank you. I solved it by increasing the distance of the near plane from 0.0001 to 0.1. You should put it as an answer so I could mark this question solved. \$\endgroup\$
    – Rish
    Jun 29, 2019 at 8:36

1 Answer 1

2
\$\begingroup\$

This is definitely Z-Buffer problem, artifacts seem to resolve at a distance closer to the viewer, where precision is supposed to be higher.

It is worth knowing, that exactly this problem has been covered on the OpenGL wiki:

As the zNear clipping plane is set increasingly closer to 0.0, the effective precision of the depth buffer decreases dramatically.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .