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

保罗

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

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

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

这是我的GLSL Compute着色器:

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);

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

_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);

与:

  1. wDimensions =上下文(和帧缓冲区)的大小
  2. WORK_GROUP_SIZE = 16

您是否知道为什么我没有获得有效的深度值?

编辑:

这是渲染球体时颜色纹理的外观:

在此处输入图片说明

而且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);

这样效果很好

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

从片段着色器访问深度缓冲区

来自分类Dev

无法从Compute着色器读取深度缓冲区

来自分类Dev

OpenGL:着色器存储缓冲区映射/绑定

来自分类Dev

OpenGL计算着色器缓冲区分配失败

来自分类Dev

OpenGL-从顶点着色器访问缓冲区中的下3个顶点

来自分类Dev

金属着色器在缓冲区中插入值

来自分类Dev

用于着色器资源视图到深度模板缓冲区资源的哪种格式?

来自分类Dev

深度缓冲区不适用于多个着色器程序

来自分类Dev

GLSL错误:尽管已定义,但计算着色器中的未定义布局缓冲区变量

来自分类Dev

运行OpenGL着色器以修改现有的纹理/帧缓冲区

来自分类Dev

OpenGL 3.0:无法在着色器中使用帧缓冲区对象(黑色)

来自分类Dev

OpenGL 3.0:无法在着色器中使用帧缓冲区对象(黑色)

来自分类Dev

打开gl计算着色器和帧缓冲区

来自分类Dev

打开gl计算着色器和帧缓冲区

来自分类Dev

具有进出一维数据缓冲区的金属计算着色器?

来自分类Dev

如何修复“缓冲区预加载失败”计算着色器性能问题?

来自分类Dev

在OpenGL中查看深度缓冲区

来自分类Dev

着色器存储缓冲区对象:字节序?

来自分类Dev

不同大小的着色器存储缓冲区内容“转移”到阵列缓冲区

来自分类Dev

opengl:基于着色器的渲染到帧缓冲区,然后进行固定管线渲染

来自分类Dev

如何使用顶点缓冲区将计算着色器结果输入到不包含顶点着色器的顶点中?

来自分类Dev

如何使用顶点缓冲区将计算着色器结果馈入不包含顶点着色器的顶点中?

来自分类Dev

Vulkan 计算着色器仅读取统一缓冲区的一部分

来自分类Dev

DirectX HLSL-像素着色器中恒定缓冲区为空,但顶点着色器中为空

来自分类Dev

在GLSL顶点着色器中,您不仅可以访问顶点缓冲区,还可以访问索引缓冲区中顶点的索引吗?

来自分类Dev

具有乒乓缓冲区的多步着色器中的条带问题,在 ShaderToy 中不会发生

来自分类Dev

Vulkan - 读取缓冲区中浮点着色器颜色值到 uchar 值的奇怪映射

来自分类Dev

imageStore在计算着色器中以深度纹理

来自分类Dev

OpenGL:glLoadMatrix和深度缓冲区

Related 相关文章

  1. 1

    从片段着色器访问深度缓冲区

  2. 2

    无法从Compute着色器读取深度缓冲区

  3. 3

    OpenGL:着色器存储缓冲区映射/绑定

  4. 4

    OpenGL计算着色器缓冲区分配失败

  5. 5

    OpenGL-从顶点着色器访问缓冲区中的下3个顶点

  6. 6

    金属着色器在缓冲区中插入值

  7. 7

    用于着色器资源视图到深度模板缓冲区资源的哪种格式?

  8. 8

    深度缓冲区不适用于多个着色器程序

  9. 9

    GLSL错误:尽管已定义,但计算着色器中的未定义布局缓冲区变量

  10. 10

    运行OpenGL着色器以修改现有的纹理/帧缓冲区

  11. 11

    OpenGL 3.0:无法在着色器中使用帧缓冲区对象(黑色)

  12. 12

    OpenGL 3.0:无法在着色器中使用帧缓冲区对象(黑色)

  13. 13

    打开gl计算着色器和帧缓冲区

  14. 14

    打开gl计算着色器和帧缓冲区

  15. 15

    具有进出一维数据缓冲区的金属计算着色器?

  16. 16

    如何修复“缓冲区预加载失败”计算着色器性能问题?

  17. 17

    在OpenGL中查看深度缓冲区

  18. 18

    着色器存储缓冲区对象:字节序?

  19. 19

    不同大小的着色器存储缓冲区内容“转移”到阵列缓冲区

  20. 20

    opengl:基于着色器的渲染到帧缓冲区,然后进行固定管线渲染

  21. 21

    如何使用顶点缓冲区将计算着色器结果输入到不包含顶点着色器的顶点中?

  22. 22

    如何使用顶点缓冲区将计算着色器结果馈入不包含顶点着色器的顶点中?

  23. 23

    Vulkan 计算着色器仅读取统一缓冲区的一部分

  24. 24

    DirectX HLSL-像素着色器中恒定缓冲区为空,但顶点着色器中为空

  25. 25

    在GLSL顶点着色器中,您不仅可以访问顶点缓冲区,还可以访问索引缓冲区中顶点的索引吗?

  26. 26

    具有乒乓缓冲区的多步着色器中的条带问题,在 ShaderToy 中不会发生

  27. 27

    Vulkan - 读取缓冲区中浮点着色器颜色值到 uchar 值的奇怪映射

  28. 28

    imageStore在计算着色器中以深度纹理

  29. 29

    OpenGL:glLoadMatrix和深度缓冲区

热门标签

归档