gpt4 book ai didi

opengl - OpenGL 计算着色器中的样本深度缓冲区

转载 作者:行者123 更新时间:2023-12-04 02:09:56 25 4
gpt4 key购买 nike

我正在尝试将深度纹理采样到计算着色器中并将其复制到其他纹理中。

问题是当我从深度纹理中读取时我没有得到正确的值:

我试图检查深度纹理的初始值是否正确(使用 GDebugger),它们是正确的。因此,检索错误值的是 imageLoad GLSL 函数。

这是我的 GLSL 计算着色器:

layout (binding=0, r32f) readonly uniform image2D depthBuffer;
layout (binding=1, rgba8) writeonly uniform image2D colorBuffer;

// we use 16 * 16 threads groups
layout (local_size_x = 16, local_size_y = 16) in;

void main()
{
ivec2 position = ivec2(gl_GlobalInvocationID.xy);
// Sampling from the depth texture
vec4 depthSample = imageLoad(depthBuffer, position);
// We linearize the depth value
float f = 1000.0;
float n = 0.1;
float z = (2 * n) / (f + n - depthSample.r * (f - n));
// even if i try to call memoryBarrier(), barrier() or memoryBarrierShared() here, i still have the same bug
// and finally, we try to create a grayscale image of the depth values
imageStore(colorBuffer, position, vec4(z, z, z, 1));
}

这就是我创建深度纹理和颜色纹理的方式:
// generate the deth texture
glGenTextures(1, &_depthTexture);
glBindTexture(GL_TEXTURE_2D, _depthTexture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, wDimensions.x, wDimensions.y, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);

// generate the color texture
glGenTextures(1, &_colorTexture);
glBindTexture(GL_TEXTURE_2D, _colorTexture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, wDimensions.x, wDimensions.y, 0, GL_RGBA, GL_FLOAT, NULL);

我用深度值填充深度纹理(将其绑定(bind)到帧缓冲区并渲染场景),然后以这种方式调用我的计算着色器:
_computeShader.use();

// try to synchronize with the previous pass
glMemoryBarrier(GL_ALL_BARRIER_BITS);
// even if i call glFinish() here, the result is the same

glBindImageTexture(0, _depthTexture, 0, GL_FALSE, 0, GL_READ_ONLY, GL_R32F);
glBindImageTexture(1, _colorTexture, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA8);

glDispatchCompute((wDimensions.x + WORK_GROUP_SIZE - 1) / WORK_GROUP_SIZE,
(wDimensions.y + WORK_GROUP_SIZE - 1) / WORK_GROUP_SIZE, 1); // we divide the compute into groups of 16 threads

// try to synchronize with the next pass
glMemoryBarrier(GL_ALL_BARRIER_BITS);

和:
  • wDimensions = 上下文(和帧缓冲区)的大小
  • WORK_GROUP_SIZE = 16

  • 你知道为什么我没有得到有效的深度值吗?

    编辑:

    这是我渲染球体时颜色纹理的样子:

    enter image description here

    似乎 glClear(GL_DEPTH_BUFFER_BIT) 没有做任何事情:
    即使我在 glDispatchCompute() 之前调用它,我仍然有相同的图像......
    这怎么可能?

    最佳答案

    实际上,我发现即使使用 readonly 关键字,您也无法将深度纹理作为图像发送到计算着色器。

    所以我已经更换了:

    glBindImageTexture(0, _depthTexture, 0, GL_FALSE, 0, GL_READ_ONLY, GL_R32F);

    经过:
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, _depthTexture);

    在我的计算着色器中:
    layout (binding=0, r32f) readonly uniform image2D depthBuffer;

    经过:
    layout (binding = 0) uniform sampler2D depthBuffer;

    并对其进行采样,我只写:
    ivec2       position = ivec2(gl_GlobalInvocationID.xy);
    vec2 screenNormalized = vec2(position) / vec2(ctxSize); // ctxSize is the size of the depth and color textures
    vec4 depthSample = texture2D(depthBuffer, screenNormalized);

    它像这样工作得很好

    关于opengl - OpenGL 计算着色器中的样本深度缓冲区,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21384972/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com