glsl - 使用 Vulkan 在片段着色器中缓慢获取纹理

标签 glsl vulkan ssao

我正在做一个内核大小为 64 的 SSAO 着色器。

SSAO 片段着色器:

const int kernelSize = 64;
for (int i = 0; i < kernelSize; i++) {
        //Get sample position
        vec3 s = tbn * ubo.kernel[i].xyz;
        s = s * radius + origin;
        vec4 offset = vec4(s, 1.0);
        offset = ubo.projection * offset;
        offset.xy /= offset.w;
        offset.xy = offset.xy * 0.5 + 0.5;
        float sampleDepth = texture(samplerposition, offset.xy).z;
        float rangeCheck = abs(origin.z - sampleDepth) < radius ? 1.0 : 0.0;
        occlusion += (sampleDepth >= s.z ? 1.0 : 0.0) * rangeCheck;
    }

采样位置纹理的格式为 VK_FORMAT_R16G16B16A16_SFLOAT并上传标志 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT .

我使用的是带有 nvidia K1100M 显卡的笔记本电脑。如果我在 renderdoc 中运行代码,这个着色器需要 114 毫秒 .如果我更改 kernelSize到 1,需要 1 毫秒 .

这个纹理获取时间正常吗?或者可能是我在某处设置了错误?

好像没有经过布局过渡,所以纹理在VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL而不是 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL .

最佳答案

GPU 内存依赖于大量缓存使用,如果彼此靠近的片段不采样彼此相邻的纹素,则这是非常有限的 - 也称为缺乏空间一致性。我预计随机访问纹理与线性一致访问相比,速度会降低 10 倍或更多。当使用大半径时,SSAO 很容易出现这种情况。

我建议使用较小的半径并优化纹理访问。您正在采样 4 个 16 位浮点数,但您只使用了一个。将深度分解为单独的 16 位深度图像应该可以轻松实现 4 倍加速。

关于glsl - 使用 Vulkan 在片段着色器中缓慢获取纹理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38953632/

相关文章:

glsl - 在 Vulkan 中使用 debugPrintfEXT

c++ - SSAO 阴影随相机移动很奇怪(计算 gbuffer 错误)

OpenGL : SSAO vs Shadow mapping

OpenGL NDC 和坐标

vulkan - 描述符绑定(bind)和绑定(bind)编号

c++ - 为什么我的 3d 点积在另一个方向上变黑了?

c++ - 找不到一些 lunar SDK 验证层

glsl - Babylon JS 和 GLSL 中的 SSAO 实现,使用 View 光线进行深度比较

opengl - 使用opengl围绕枢轴原点旋转

c++ - 如何正确使用 glDrawElements 和 glBindVertexArray