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.