سؤال

I have a depth texture defined as the following:

    //shadow FBO and texture
    depthFBO = new FrameBufferObject().create().bind();
    depthTexture = new Texture2D().create().bind()
            .storage2D(12, GL_DEPTH_COMPONENT32F, 4096, 4096)
            .minFilter(GL_LINEAR)
            .magFilter(GL_LINEAR)
            .compareMode(GL_COMPARE_REF_TO_TEXTURE)
            .compareFunc(GL_LEQUAL);
    depthFBO.texture2D(GL_DEPTH_ATTACHMENT, GL11.GL_TEXTURE_2D, depthTexture, 0)
            .checkStatus().unbind();
    depthTexture.unbind();

It's written in Java/LWJGL/Own small framework, but the idea should be clear.

Then I use a fragment shader at some point to visualize the data in it (fragment's depth):

#version 430 core

layout(location = 7) uniform int screen_width;
layout(location = 8) uniform int screen_height;

layout(binding = 0) uniform sampler2D shadow_tex;

out vec4 color;

void main(void) {
    vec2 tex_coords = vec2(
        (gl_FragCoord.x - 100) / (screen_width / 5),
        (gl_FragCoord.y - (screen_height - (screen_height / 5) - 100)) / (screen_height / 5)
    );
    float red_channel = texture(shadow_tex, tex_coords).r;
    if (red_channel < 0.999) {
        red_channel = red_channel / 2.0;
    }
    color = vec4(vec3(red_channel), 1.0);
}

My tex_coords and shadow_tex are correct, but I need some more clarification on reading out of a GL_DEPTH_COMPONENT32F format.

I want to read the depth and I assume it is being stored being 0.0 and 1.0 in 4 bytes of float values.

So I was thinking I can use the red channel of what texture gives me back, however I cannot see a difference in depth. Other than it not being 1.0 exactly, but somewhat lower. If I do not divide by 2.0, then everything appears white.

screenshot

Note that the floor is black at some points, but that is due to a failed shadow mapping, hence why I am visualizing it - however it is temporarily set to use the normal view MVP instead of the light's, to also make sure the depth information is saved correctly.

UPDATE: The colorization of the depth value is now working correctly with the following:

#version 430 core

layout(location = 7) uniform int screen_width;
layout(location = 8) uniform int screen_height;

layout(binding = 0) uniform sampler2D shadow_tex;

out vec4 color;

float linearize_depth(float original_depth) {
    float near = 0.1;
    float far = 1000.0;
    return (2.0 * near) / (far + near - original_depth * (far - near));
}

void main(void) {
    //calculate texture coordinates, based on current dimensions and positions of the viewport
    vec2 tex_coords = vec2(
        (gl_FragCoord.x - 100) / (screen_width / 5),
        (gl_FragCoord.y - (screen_height - (screen_height / 5) - 100)) / (screen_height / 5)
    );

    //retrieve depth value from the red channel
    float red_channel = texture(shadow_tex, tex_coords).r;

    //colorize depth value, only if there actually is an object
    if (red_channel < 0.999) {
        red_channel = linearize_depth(red_channel) * 4.0;
    }
    color = vec4(vec3(red_channel), 1.0);
}

screenshot - kind of working

I would still like clarification though if accessing the red component is correct to retrieve the depth value?

هل كانت مفيدة؟

المحلول

In GLSL 4.30?

  No.

If this is truly a depth texture (internal format = GL_DEPTH_COMPONENT[...]), then GLSL automatically samples it this way: vec4 (r, r, r, 1.0). Older versions would behave differently depending on the "depth texture mode" (which was removed from GL 3.1 / GLSL 1.30).

Now, if it is a depth texture with comparison as your code implies, then sampling it using sampler2D should be undefined. If you use sampler2DShadow though, sampling with texture (...) will return a single float unlike all other texture (...) overloads (which all return vec4).

Hopefully this is an oversight in the Java code you pasted, because your shader should be producing undefined results as it stands right now.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top