2016-05-31 126 views
4

我有我的体素化场景的颜色,法线和其他数据的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)的第三级,数据不会出现在第三级。使用计算着色器进行Mipmapping

shader代码:

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

派出我不知道如果我错过了一些基本的东西,这是我第一次计算着色器。我也试图使用记忆障碍,但它并没有改变一件事情。

回答

2

那么你不能指望你的第二个imageLoad读取你刚才在第一家商店写到的texels。

并且没有办法在“本地”工作组以外同步访问。

您将需要:

  • 要使用内核多调用做每一层
  • 要重写你的着色器逻辑,这样你总是从“原始”区获取。
+0

对,我认为障碍在全球范围内工作......你知道如果使用一个单一的“全球”工作组与128x128x128本地工作组,那么你的2个选项效率会降低吗? – FamZ

+0

我的意思是1个本地工作组,大小为128x128x128 – FamZ

+2

@FamZ:你认为128x128x128的工作组大小是可能的。 [任何硬件支持的组中最大数量的工作项目是1536](http://opengl.gpuinfo.org/gl_stats_caps_single.php?listreportsbycap=GL_MAX_COMPUTE_WORK_GROUP_SIZE)。这很像128^3。你想要的只是不可能的。最好重构你的算法和数据,以适应合理的工作组大小。 –