【问题标题】:Mipmapping with compute shader使用计算着色器进行 Mipmapping
【发布时间】:2016-09-29 18:03:38
【问题描述】:

我有我的体素化场景的颜色、法线和其他数据的 3D 纹理,因为其中一些数据不能只是平均,我需要自己计算 mip 级别。 3D 纹理大小为 (128+64) x 128 x 128,额外的 64 x 128 x 128 用于 mip 级别。

因此,当我采用第一个 mip 级别时,它位于 (0, 0, 0) 处,大小为 128 x 128 x 128,并且只需将体素复制到位于 (128, 0, 0) 处的第二个级别数据出现在那里,但是一旦我将 (128, 0, 0) 的第二级复制到 (128, 0, 64) 的第三级,数据就不会出现在第三级。

着色器代码:

#version 450 core

layout (local_size_x = 1,
        local_size_y = 1,
        local_size_z = 1) in;

layout (location = 0) uniform unsigned int resolution;
layout (binding = 0, rgba32f) uniform image3D voxel_texture;

void main()
{
    ivec3 index = ivec3(gl_WorkGroupID);
    ivec3 spread_index = index * 2;

    vec4 voxel = imageLoad(voxel_texture, spread_index);
    imageStore(voxel_texture, index + ivec3(resolution, 0, 0), voxel);

    // This isn't working
    voxel = imageLoad(voxel_texture, spread_index + 
                      ivec3(resolution, 0, 0));
    imageStore(voxel_texture, index + ivec3(resolution, 0, 64), voxel);
}

着色器程序被调度

glUniform1ui(0, OCTREE_RES);

glBindImageTexture(0, voxel_textures[0], 0, GL_TRUE, 0, GL_READ_WRITE, 
                   GL_RGBA32F);

glDispatchCompute(64, 64, 64);

我不知道我是否错过了一些基本的东西,这是我的第一个计算着色器。我也尝试使用内存屏障,但并没有改变任何事情。

【问题讨论】:

    标签: c++ opengl compute-shader


    【解决方案1】:

    你不能指望你的第二个 imageLoad 像这样读取你刚刚在第一个商店中编写的纹素。

    而且没有办法同步“本地”工作组之外的访问。

    你需要:

    • 使用内核的多次调用来执行每一层
    • 重写着色器逻辑,以便始终从“原始”区域获取。

    【讨论】:

    • 对,我认为障碍在全球范围内起作用...您知道使用一个具有 128x128x128 本地工作组的单个“全局”工作组是否比您的 2 个选项效率低吗?
    • @FamZ:您假设 128x128x128 的工作组大小是可能的。 largest number of work items in a group that is supported by any hardware is 1536。这很像 128^3。你想要的根本不可能。最好重新构建您的算法和可能的数据,以适应合理的工作组规模。
    猜你喜欢
    • 2011-04-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多