2
votes

I've been trying to implement a simple light / shading system, a simple Phong lighting system without specular lights to be precise. It basically works, except it has some (in my opinion) nasty artifacts.

My first thought was that maybe this is a problem of the texture mipmaps, but disabling them didn't work. My next best guess would be a shader issue, but I can't seem to find the error.

Has anybody ever experienced a similiar issue or an idea on how to solve this?

Image of the artifacts

Vertex shader:

#version 330 core

// Vertex shader
layout(location = 0) in vec3 vpos;
layout(location = 1) in vec2 vuv;
layout(location = 2) in vec3 vnormal;

out vec2 uv;        // UV coordinates
out vec3 normal;    // Normal in camera space
out vec3 pos;       // Position in camera space
out vec3 light[3];  // Vertex -> light vector in camera space

uniform mat4 mv;    // View * model matrix
uniform mat4 mvp;   // Proj * View * Model matrix
uniform mat3 nm;    // Normal matrix for transforming normals into c-space

void main() {
    // Pass uv coordinates
    uv = vuv;

    // Adjust normals
    normal = nm * vnormal;

    // Calculation of vertex in camera space
    pos = (mv * vec4(vpos, 1.0)).xyz;

    // Vector vertex -> light in camera space
    light[0] = (mv * vec4(0.0,0.3,0.0,1.0)).xyz - pos;
    light[1] = (mv * vec4(-6.0,0.3,0.0,1.0)).xyz - pos;
    light[2] = (mv * vec4(0.0,0.3,4.8,1.0)).xyz - pos;

    // Pass position after projection transformation
    gl_Position = mvp * vec4(vpos, 1.0);
}

Fragment shader:

#version 330 core

// Fragment shader
layout(location = 0) out vec3 color;

in vec2 uv;     // UV coordinates
in vec3 normal;     // Normal in camera space
in vec3 pos;        // Position in camera space
in vec3 light[3];   // Vertex -> light vector in camera space

uniform sampler2D tex;
uniform float flicker;

void main() {
    vec3 n = normalize(normal);

    // Ambient
    color = 0.05 * texture(tex, uv).rgb;

    // Diffuse lights
    for (int i = 0; i < 3; i++) {
        l = normalize(light[i]);
        cos = clamp(dot(n,l), 0.0, 1.0);
        length = length(light[i]);
        color += 0.6 * texture(tex, uv).rgb * cos / pow(length, 2);
    }
}
2
Almost looks like precision issues. What format are you loading your texture as?Colonel Thirty Two
It seems independent of the texture. I've just colored the whole room white, but the problem persists.user3413372

2 Answers

1
votes

As the first comment says, it looks like your color computation is using insufficient precision. Try using mediump or highp floats.

Additionally, the length = length(light[i]); pow(length,2) expression is quite inefficient, and could also be a source of the observed banding; you should use dot(light[i],light[i]) instead.

0
votes

So i found information about my problem described as "gradient banding", also discussed here. The problem appears to be in the nature of my textures, since both, only the "white" texture and the real texture are mostly grey/white and there are effectively 256 levels of grey when using 8 bit per color channel.

The solution would be to implement post-processing dithering or to use better textures.