I have an issue when using textures in OpenGL, strange artifacts occur where geometry overlaps, but not always.
Video Reference. I am using a GL_TEXTURE_2D
with GL_ARB_image_load_store
to make a custom depth test shader that stores material data for opaque and transparent geometry. The video given shows the artifacts occur where the support structure for a table is occluded behind the top of the table, but strangely, not occurring where the base of the table is occluded by the support.
#version 450 core
in VS_OUT {
vec3 Position;
vec3 Normal;
vec2 TexCoords;
mat3 TanBitanNorm;
} fs_in;
// Material data
uniform sampler2D uAlbedoMap;
uniform sampler2D uNormalMap;
uniform sampler2D uMetallicMap;
// Material info out
layout(rgba16f) coherent uniform image2D uAlbedoDepthOpaque;
layout(rgba16f) coherent uniform image2D uNormalMetallicOpaque;
layout(rgba16f) coherent uniform image2D uAlbedoDepthTransparent;
layout(rgba16f) coherent uniform image2D uNormalAlphaTransparent;
// Depth info in/out
layout(r8) uniform image2D uDepthBufferOpaque;
layout(r8) uniform image2D uDepthBufferTransparent;
void main() {
vec3 n_tex = texture(uNormalMap, fs_in.TexCoords).xyz;
n_tex = n_tex * 2.0f - 1.0f;
ivec2 tx_loc = ivec2(gl_FragCoord.xy);
const float opaque_depth = imageLoad(uDepthBufferOpaque, tx_loc).r; // Stored depth of opaque
const float trans_depth = imageLoad(uDepthBufferTransparent, tx_loc).r; // Stored depth of transparent
// Depth processing
if (gl_FragCoord.z > opaque_depth) {
bool tran = false;
if (trans_depth > opaque_depth)
tran = trans_depth > gl_FragCoord.z;
else
tran = true;
// Transparent
if (texture(uAlbedoMap, fs_in.TexCoords).a < 1.0f && tran) {
imageStore(uDepthBufferTransparent, tx_loc,
vec4(gl_FragCoord.z));
imageStore(uAlbedoDepthTransparent, tx_loc,
vec4(texture(uAlbedoMap, fs_in.TexCoords).rgb, gl_FragCoord.z));
imageStore(uNormalAlphaTransparent, tx_loc,
vec4(abs(length(n_tex) - 1.0f) > 0.1f ? fs_in.Normal : normalize(fs_in.TanBitanNorm * n_tex), texture(uAlbedoMap, fs_in.TexCoords).a));
}
// Opaque
else {
imageStore(uDepthBufferOpaque, tx_loc,
vec4(gl_FragCoord.z));
imageStore(uAlbedoDepthOpaque, tx_loc,
vec4(texture(uAlbedoMap, fs_in.TexCoords).rgb, gl_FragCoord.z));
imageStore(uNormalMetallicOpaque, tx_loc,
vec4(abs(length(n_tex) - 1.0f) > 0.1f ? fs_in.Normal : normalize(fs_in.TanBitanNorm * n_tex), texture(uMetallicMap, fs_in.TexCoords).r));
}
}
if (opaque_depth == 0.0f) {
imageStore(uDepthBufferOpaque, tx_loc,
vec4(0.125f));
}
else {
imageStore(uDepthBufferOpaque, tx_loc,
vec4(0.125f + opaque_depth));
}
}
Render with overlapping geometry shows that artifacts still occur outside of reading from the texture. Also in the video, I move the camera back and forth (with orthographic projection) and the artifacts become brighter and darker. Render with overlapping geometry w/out depth processing shows that the brighter/darker values were from the depth test.
Any ideas on why this occurs, and how can I fix it?