Why colors is not continuous (layers) in my sample game with lighting?

Viewed 56

I'm testing Sokol library (https://github.com/floooh/sokol) to create a simple game sample with lighting in OpenGL, D3D11 and Metal. I'm using shaders similar from LearnOpenGL tutorials (https://learnopengl.com/Lighting/Light-casters).

This is part of my frag shader:

vec3 lightDir = normalize(light.position - v_position);
float diff = max(dot(normal, lightDir), 0.0);
diffuse = vec3(1.0,1.0,1.0) * diff * vec3(texture(u_diffuse, v_uv)); 

The colors in ground aren't continuous, you can see the color layers (look red lines).

Red light in color layers

Here is another sample using PBR shaders. Again, color in ground is not continuous.

Red light in color layers again

Why this happens? How can I create a perfect plane ground?

1 Answers

The "bands" you see just differ by 1 in one of the color channels. You are just reaching the actual limit of 8 bit per channel color precision, there is just no other presentable color in between these two bands. Depending on the display and display settings you use, it will be more or less perceptible. There are 3 possible solutions:

  • The effects are especially visible because your floor is colored in one solid color. The human eye will be most sensitive to such changes (see also mach band effect). By adding some structure / texture to it, it won't be perceivable any more.
  • Use a display with more then 8 bit per channel of color precision. HDR Displays nowadays do allow 10 or more bits.
  • Apply some dithering to the image to conceal the visible bands. Ordered dithering with some bayer pattern can be easily implemented in a GLSL shader.
Related