My uniforms variable change of value at each frames

Hi! I’m trying to render shadows but I’ve a problem some of the shadows pixels are flickering this is due to my uniform variable here :

const std::string perPixShadowVertexShader = R"(#version 460
                                                                   layout (location = 0) in vec3 position;
                                                                   layout (location = 1) in vec4 color;
                                                                   layout (location = 2) in vec2 texCoords;
                                                                   layout (location = 3) in vec3 normals;
                                                                   layout (location = 4) in mat4 worldMat;
                                                                   layout (location = 8) in mat4 shadowProjMat;
                                                                   layout (location = 12) in uint textureIndex;
                                                                   layout (location = 14) in uint l;
                                                                   uniform mat4 projectionMatrix;
                                                                   uniform mat4 viewMatrix;
                                                                   uniform mat4 lviewMatrix;
                                                                   uniform mat4 lprojectionMatrix;
                                                                   uniform mat4 depthBiasMatrix;
                                                                   uniform mat4 textureMatrix[)"+core::conversionUIntString(Texture::getAllTextures().size())+R"(];
                                                                   out vec4 shadowCoords;
                                                                   out vec4 frontColor;
                                                                   out vec2 fTexCoords;
                                                                   out uint texIndex;
                                                                   out uint layer;
                                                                   void main() {
                                                                       gl_Position = projectionMatrix * viewMatrix * shadowProjMat * worldMat * vec4(position, 1.f);
                                                                       fTexCoords = (textureIndex != 0) ? (textureMatrix[textureIndex-1] * vec4(texCoords, 1.f, 1.f)).xy : texCoords;
                                                                       frontColor = color;
                                                                       shadowCoords = depthBiasMatrix * lviewMatrix * lprojectionMatrix *  worldMat * vec4(position, 1);
                                                                       texIndex = textureIndex;
                                                                       layer = l;
                                                                   }
                                                                  )";

I printed the values of my uniform matrices and the values of gl_FragCoord and they are changing at each frame!!! (They don’t change on the CPU but only on the GPU)

So sometimes pixels are displayed in front of my heightmap but this is not good because my shadow is behind the slope of my heightmap.

const std::string perPixShadowFragmentShader = R"(#version 460
                                                                          #extension GL_ARB_bindless_texture : enable
                                                                          in vec4 shadowCoords;
                                                                          in vec4 frontColor;
                                                                          in vec2 fTexCoords;
                                                                          in flat uint texIndex;
                                                                          in flat uint layer;
                                                                          uniform sampler2D texture;
                                                                          uniform sampler2D stencilBuffer;
                                                                          uniform sampler2D depthBuffer;
                                                                          uniform sampler2D alphaBuffer;
                                                                          uniform float haveTexture;
                                                                          uniform vec3 resolution;
                                                                          layout (std140, binding = 0) uniform ALL_TEXTURES {
                                                                              sampler2D textures[200];
                                                                          };
                                                                          layout (location = 0) out vec4 fColor;
                                                                          layout(rgba32f, binding = 0) uniform image2D img_output;
                                                                          layout(binding = 0, offset = 0) uniform atomic_uint nextNodeCounter;

                                                                         /*Functions to debug, draw numbers to the image,
                                                                          draw a vertical ligne*/
                                                                          void drawVLine (ivec2 position, int width, int nbPixels, vec4 color) {
                                                                              int startY = position.y;
                                                                              int startX = position.x;
                                                                              while (position.y < startY + nbPixels) {
                                                                                 while (position.x < startX + width) {
                                                                                    imageStore(img_output, position, color);
                                                                                    position.x++;
                                                                                 }
                                                                                 position.y++;
                                                                                 position.x = startX;
                                                                              }
                                                                          }
                                                                          /*Draw an horizontal line*/
                                                                          void drawHLine (ivec2 position, int height, int nbPixels, vec4 color) {
                                                                              int startY = position.y;
                                                                              int startX = position.x;
                                                                              while (position.y > startY - height) {
                                                                                 while (position.x < startX + nbPixels) {
                                                                                    imageStore(img_output, position, color);
                                                                                    position.x++;
                                                                                 }
                                                                                 position.y--;
                                                                                 position.x = startX;
                                                                              }
                                                                          }
                                                                          /*Draw digits.*/
                                                                          void drawDigit (ivec2 position, int nbPixels, vec4 color, uint digit) {
                                                                              int digitSize = nbPixels * 10;
                                                                              if (digit == 0) {
                                                                                  drawVLine(position, digitSize / 2, nbPixels, color);
                                                                                  drawHLine(position, digitSize, nbPixels, color);
                                                                                  drawHLine(ivec2(position.x + digitSize / 2 - nbPixels, position.y), digitSize, nbPixels, color);
                                                                                  drawVLine(ivec2(position.x, position.y - digitSize + nbPixels), digitSize / 2, nbPixels, color);
                                                                              } else if (digit == 1) {
                                                                                  drawHLine(ivec2(position.x + digitSize / 2 - nbPixels, position.y), digitSize, nbPixels, color);
                                                                              } else if (digit == 2) {
                                                                                  drawVLine(position, digitSize / 2, nbPixels, color);
                                                                                  drawHLine(ivec2(position.x, position.y), digitSize / 2 + nbPixels / 2, nbPixels, color);
                                                                                  drawVLine(ivec2(position.x, position.y - digitSize / 2 + nbPixels / 2), digitSize / 2, nbPixels, color);
                                                                                  drawHLine(ivec2(position.x + digitSize / 2 - nbPixels, position.y - digitSize / 2 + nbPixels / 2), digitSize / 2 + nbPixels / 2, nbPixels, color);
                                                                                  drawVLine(ivec2(position.x, position.y - digitSize + nbPixels), digitSize / 2, nbPixels, color);
                                                                              } else if (digit == 3) {
                                                                                  drawHLine(ivec2(position.x + digitSize / 2 - nbPixels, position.y), digitSize, nbPixels, color);
                                                                                  drawVLine(position, digitSize / 2, nbPixels, color);
                                                                                  drawVLine(ivec2(position.x, position.y - digitSize / 2 + nbPixels / 2), digitSize / 2, nbPixels, color);
                                                                                  drawVLine(ivec2(position.x, position.y - digitSize + nbPixels), digitSize / 2, nbPixels, color);
                                                                              } else if (digit == 4) {
                                                                                  drawHLine(ivec2(position.x, position.y - digitSize / 2), digitSize / 2 + nbPixels / 2, nbPixels, color);
                                                                                  drawHLine(ivec2(position.x + digitSize / 2 - nbPixels, position.y), digitSize, nbPixels, color);
                                                                                  drawVLine(ivec2(position.x, position.y - digitSize / 2 + nbPixels / 2), digitSize / 2, nbPixels, color);
                                                                              } else if (digit == 5) {
                                                                                  drawVLine(position, digitSize / 2, nbPixels, color);
                                                                                  drawHLine(ivec2(position.x, position.y - digitSize / 2 + nbPixels / 2), digitSize / 2 + nbPixels / 2, nbPixels, color);
                                                                                  drawVLine(ivec2(position.x, position.y - digitSize / 2 + nbPixels / 2), digitSize / 2, nbPixels, color);
                                                                                  drawHLine(ivec2(position.x + digitSize / 2 - nbPixels, position.y), digitSize / 2 + nbPixels / 2, nbPixels, color);
                                                                                  drawVLine(ivec2(position.x, position.y - digitSize + nbPixels), digitSize / 2, nbPixels, color);
                                                                              } else if (digit == 6) {
                                                                                  drawVLine(position, digitSize / 2, nbPixels, color);
                                                                                  drawHLine(ivec2(position.x + digitSize / 2 - nbPixels, position.y), digitSize, nbPixels, color);
                                                                                  drawVLine(ivec2(position.x, position.y - digitSize / 2 + nbPixels / 2), digitSize / 2, nbPixels, color);
                                                                                  drawHLine(position, digitSize / 2 + nbPixels / 2, nbPixels, color);
                                                                                  drawVLine(ivec2(position.x, position.y - digitSize + nbPixels), digitSize / 2, nbPixels, color);
                                                                              } else if (digit == 7) {
                                                                                  drawVLine(ivec2(position.x, position.y - digitSize + nbPixels), digitSize / 2, nbPixels, color);
                                                                                  drawHLine(ivec2(position.x + digitSize / 2 - nbPixels, position.y), digitSize, nbPixels, color);
                                                                              } else if (digit == 8) {
                                                                                  drawHLine(position, digitSize, nbPixels, color);
                                                                                  drawHLine(ivec2(position.x + digitSize / 2 - nbPixels, position.y), digitSize, nbPixels, color);
                                                                                  drawVLine(position, digitSize / 2, nbPixels, color);
                                                                                  drawVLine(ivec2(position.x, position.y - digitSize / 2 + nbPixels / 2), digitSize / 2, nbPixels, color);
                                                                                  drawVLine(ivec2(position.x, position.y - digitSize + nbPixels), digitSize / 2, nbPixels, color);
                                                                              } else if (digit == 9) {
                                                                                  drawVLine(position, digitSize / 2, nbPixels, color);
                                                                                  drawHLine(ivec2(position.x + digitSize / 2 - nbPixels, position.y), digitSize, nbPixels, color);
                                                                                  drawVLine(ivec2(position.x, position.y - digitSize / 2 + nbPixels / 2), digitSize / 2, nbPixels, color);
                                                                                  drawHLine(ivec2(position.x, position.y - digitSize / 2 + nbPixels / 2), digitSize / 2 + nbPixels / 2, nbPixels, color);
                                                                                  drawVLine(ivec2(position.x, position.y - digitSize + nbPixels), digitSize / 2, nbPixels, color);
                                                                              }
                                                                          }
                                                                          void drawSquare(ivec2 position, int size, vec4 color) {
                                                                              int startY = position.y;
                                                                              int startX = position.x;
                                                                              while (position.y > startY - size) {
                                                                                 while (position.x < startX + size) {
                                                                                    imageStore(img_output, position, color);
                                                                                    position.x++;
                                                                                 }
                                                                                 position.y--;
                                                                                 position.x = startX;
                                                                              }
                                                                          }
                                                                          void drawPunt(ivec2 position, int nbPixels, vec4 color) {
                                                                              int puntSize = nbPixels * 2;
                                                                              drawSquare(position, puntSize, color);
                                                                          })" \
                                                                          R"(ivec2 print (ivec2 position, int nbPixels, vec4 color, double number) {
                                                                              int digitSize = nbPixels * 10;
                                                                              int digitSpacing = nbPixels * 6;
                                                                              if (number < 0) {
                                                                                 number = -number;
                                                                                 drawVLine(ivec2(position.x, position.y - digitSize / 2 + nbPixels / 2), digitSize / 2, nbPixels, color);
                                                                                 position.x += digitSpacing;
                                                                              }
                                                                              int pe = int(number);
                                                                              int n = 0;
                                                                              uint rpe[10];
                                                                              do {
                                                                                 uint digit = pe % 10;
                                                                                 pe /= 10;
                                                                                 if (n < 10) {
                                                                                    rpe[n] = digit;
                                                                                 }
                                                                                 n++;
                                                                              } while (pe != 0);
                                                                              if (n >= 10)
                                                                                n = 9;
                                                                              //drawDigit(position, nbPixels, color,0);
                                                                              for (int i = n-1; i >= 0; i--) {
                                                                                 drawDigit(position, nbPixels, color, rpe[i]);
                                                                                 //drawDigit(position, nbPixels, color,n-i-1);
                                                                                 position.x += digitSpacing;
                                                                              }
                                                                              double rest = fract(number);
                                                                              if (rest > 0) {
                                                                                  drawPunt(position, nbPixels, color);
                                                                                  position.x += digitSpacing;
                                                                                  do {
                                                                                     rest *= 10;
                                                                                     int digit = int(rest);
                                                                                     rest -= digit;
                                                                                     drawDigit(position, nbPixels, color, digit);
                                                                                     position.x += digitSpacing;
                                                                                  } while (rest != 0);
                                                                              }
                                                                              return position;
                                                                          }
                                                                          ivec2 print (ivec2 position, int nbPixels, vec4 color, mat4 matrix) {
                                                                              int numberSpacing = 10;
                                                                              for (uint i = 0; i < 4; i++) {
                                                                                 for (uint j = 0; j < 4; j++) {
                                                                                    position = print(position, nbPixels, color, matrix[i][j]);
                                                                                    position.x += numberSpacing;
                                                                                 }
                                                                              }
                                                                              return position;
                                                                          }
                                                                          ivec2 print (ivec2 position, int nbPixels, vec4 color, vec4 vector) {
                                                                              int numberSpacing = 10;
                                                                              for (uint i = 0; i < 4; i++) {
                                                                                position = print(position, nbPixels, color, vector[i]);
                                                                                position.x += numberSpacing;
                                                                              }
                                                                              return position;
                                                                          }
                                                                        void main() {
                                                                            uint fragmentIdx = atomicCounterIncrement(nextNodeCounter);
                                                                            vec2 position = (gl_FragCoord.xy / resolution.xy);
                                                                            vec4 depth = texture2D(depthBuffer, position);
                                                                            vec4 alpha = texture2D(alphaBuffer, position);
                                                                            vec4 texel = (texIndex != 0) ? frontColor * texture2D(textures[texIndex-1], fTexCoords) : frontColor;

                                                                            float color = texel.a;
                                                                            vec3 projCoords = shadowCoords.xyz / shadowCoords.w;
                                                                            vec4 stencil = texture2D (stencilBuffer, projCoords.xy);
                                                                            float z = gl_FragCoord.z;
                                                                            vec4 visibility;
                                                                            uint l = layer;
                                                                            if (l > stencil.y || l == stencil.y && stencil.z < projCoords.z) {
                                                                                if (depth.z > z) {
                                                                                    visibility = vec4 (1, 1, 1, alpha.a);
                                                                                } else {
                                                                                    visibility = vec4 (0.5, 0.5, 0.5, color);
                                                                                }
                                                                            } else {
                                                                                visibility = vec4 (1, 1, 1, 1);
                                                                            }
                                                                            if (fragmentIdx == 0)
                                                                                print(ivec2(200, 100), 1, vec4(1, 0, 0, 1), vec4(depth.z, z, stencil.z, projCoords.z));
                                                                            fColor = visibility;
                                                                          }
                                                                          )";

I guess this is because of a float precision problem and z-Fighting but I don’t know how to solve this.
And I can’t use float 64 bits for my textures format only the GL_RGBA32f is avalaible.
Thanks.

It’s really strange for some of my fragments the z value is not good they are greater than the ones of my depthTexture even if they are behind it. (Even if my objects are near) And the values of my uniform variable change at each frame (the values of my matrices) so I don’t have the same render at each frame I don’t know what’s the problem.

The z values of m’y shadows are wrong they are too little…I Guess my shadow proj matrix is wrong When I transform my shadows they are dispayed at the right place on the screen but the depth in window coordinates is wrong.

Hi the problem is when I have something between the shadow and the camera, I tried to make a depth testing :

void main() {
           uint fragmentIdx = atomicCounterIncrement(nextNodeCounter);
                                                                            vec2 position = (gl_FragCoord.xy / resolution.xy);
                                                                            vec4 depth = texture(depthBuffer, position);
                                                                            vec4 alpha = texture(alphaBuffer, position);
                                                                            vec4 texel = (texIndex != 0) ? frontColor * texture2D(textures[texIndex-1], fTexCoords) : frontColor;

                                                                            float color = texel.a;
                                                                            vec3 projCoords = shadowCoords.xyz / shadowCoords.w;
                                                                            projCoords = projCoords * 0.5 + 0.5;
                                                                            vec4 stencil = texture (stencilBuffer, projCoords.xy);
                                                                            float z = gl_FragCoord.z;
                                                                            vec4 visibility;
                                                                            uint l = layer;
                                                                            if (l > stencil.y || l == stencil.y && stencil.z < projCoords.z) {
                                                                                if (depth.z > z) {
                                                                                    visibility = vec4 (1, 1, 1, alpha.a);
                                                                                } else {
                                                                                    visibility = vec4 (0.5, 0.5, 0.5, color);
                                                                                }
                                                                            } else {
                                                                                visibility = vec4 (1, 1, 1, 1);
                                                                            }
                                                                            /*if (fragmentIdx == 0)
                                                                                print(ivec2(200, 100), 1, vec4(1, 0, 0, 1), vec4(0, 0, depth.z, z));*/
                                                                            fColor = visibility /*vec4(0, depth.z*100, z*100, 1)*/;
                                                                          }
                                                                          )";

but the result is no what I exspected I havesome flickering pixels and some pixels who don’t display…
https://www.youtube.com/watch?v=p9QyER3tGBI

And I don’t know how to do that properly.

Hi!
I tried to call memoryBarrier() in the shader but that doen’t solve the problem :

#version 460
                                                                          #extension GL_ARB_bindless_texture : enable
                                                                          in vec4 frontColor;
                                                                          in vec2 fTexCoords;
                                                                          in flat uint texIndex;
                                                                          in flat uint layer;
                                                                          layout(std140, binding=0) uniform ALL_TEXTURES {
                                                                              sampler2D textures[200];
                                                                          };

                                                                          layout(binding = 0, rgba32f) uniform image2D depthBuffer;
                                                                          layout (location = 0) out vec4 fColor;

                                                                          void main () {
                                                                              vec4 texel = (texIndex != 0) ? frontColor * texture2D(textures[texIndex-1], fTexCoords.xy) : frontColor;
                                                                              float z = gl_FragCoord.z;
                                                                              float l = layer;
                                                                              vec4 depth = imageLoad(depthBuffer,ivec2(gl_FragCoord.xy));
                                                                              if (l > depth.y || l == depth.y && z > depth.z) {
                                                                                fColor = vec4(0, l, z, texel.a);
                                                                                imageStore(depthBuffer,ivec2(gl_FragCoord.xy),vec4(0,l,z,texel.a));
                                                                                memoryBarrier();
                                                                              } else {
                                                                                fColor = depth;
                                                                              }
                                                                          }

I put it after writing to the image because before reading the api must wait that the write to the image has finished.

That was I thought… the z of some pixels is not good…

fColor = /*visibility*/ vec4(0, stencil.z*100, projCoords.z*100, 1);

It gets me green pixels where they should be blue and vis versa so the z coordinates of some shadow’s pixels are bad but I don’t know why it should work like a classic depth test and hide the shadow’s pixels if there is something between the shadow’s pixels and the camera… Here we can see that some shadow’s pixels are green or they should be blue because there are nothing between the camera and the shadow.


My matrices are good and there are the same than the ones of glm so it seems that opengl doesn’t transform the z of my pixels from projected coordinates to screen coordinates correctly…

Ok I’ve found why, it’s because I reverse the z in the projection matrix so I need to tell to opengl to change clip coordinates by calling this function :

glClipControl(GL_UPPER_LEFT, GL_NEGATIVE_ONE_TO_ONE)

Now it looks nicer, not really perfect because of the zNear which is different depending on the slope’s inclinaison. So this is really difficult to have perfect results…

Ok It seems it’s when I use an image that the z values of my depthText are not good :

#version 460
                                                                          #extension GL_ARB_bindless_texture : enable
                                                                          in vec4 frontColor;
                                                                          in vec2 fTexCoords;
                                                                          in flat uint texIndex;
                                                                          in flat uint layer;
                                                                          layout(std140, binding=0) uniform ALL_TEXTURES {
                                                                              sampler2D textures[200];
                                                                          };

                                                                          layout(binding = 0, rgba32f) uniform image2D depthBuffer;
                                                                          layout (location = 0) out vec4 fColor;

                                                                          void main () {
                                                                              vec4 texel = (texIndex != 0) ? frontColor * texture2D(textures[texIndex-1], fTexCoords.xy) : frontColor;
                                                                              float z = gl_FragCoord.z;
                                                                              float l = layer;
                                                                              vec4 depth = imageLoad(depthBuffer,ivec2(gl_FragCoord.xy));
                                                                              if (/*l > depth.y || l == depth.y &&*/ z > depth.z) {
                                                                                fColor = vec4(0, l, z, texel.a);
                                                                                imageStore(depthBuffer,ivec2(gl_FragCoord.xy),vec4(0,l,z,texel.a));
                                                                                memoryBarrier();
                                                                              } else {
                                                                                fColor = depth;
                                                                              }
                                                                          }

When I use a depthTest and when I simply write the z value it works…

I set 1 to nbLevels when binding the texture to image, pixel are not flickering anymore but the z is still not good.

It seems to be a synchronisation problem with the image and what’s is read is not what was writting before even with the call of memoryBarrier() I don’t know how to synchronize this correctly…

Ok! I’ve found the problem. I just needed to use the extension interlock and now my depthTexture is good!

const std::string buildDepthBufferFragmentShader = R"(#version 460
                                                                          #extension GL_ARB_bindless_texture : enable
                                                                          #extension GL_ARB_fragment_shader_interlock : require
                                                                          in vec4 frontColor;
                                                                          in vec2 fTexCoords;
                                                                          in flat uint texIndex;
                                                                          in flat uint layer;
                                                                          layout(std140, binding=0) uniform ALL_TEXTURES {
                                                                              sampler2D textures[200];
                                                                          };

                                                                          layout(binding = 0, rgba32f) uniform image2D depthBuffer;
                                                                          layout (location = 0) out vec4 fColor;

                                                                          void main () {
                                                                              vec4 texel = (texIndex != 0) ? frontColor * texture2D(textures[texIndex-1], fTexCoords.xy) : frontColor;
                                                                              float z = gl_FragCoord.z;
                                                                              float l = layer;
                                                                              beginInvocationInterlockARB();
                                                                              vec4 depth = imageLoad(depthBuffer,ivec2(gl_FragCoord.xy));
                                                                              if (/*l > depth.y || l == depth.y &&*/ z > depth.z) {
                                                                                fColor = vec4(0, l, z, texel.a);
                                                                                imageStore(depthBuffer,ivec2(gl_FragCoord.xy),vec4(0,l,z,texel.a));
                                                                                memoryBarrier();
                                                                              } else {
                                                                                fColor = depth;
                                                                              }
                                                                              endInvocationInterlockARB();
                                                                          }
                                                                        )";

Solved