2016-05-31 3 views
4

У меня есть 3D-текстуры цветов, нормалей и других данных моей вокселизированной сцены, и потому что некоторые из этих данных не могут быть просто усреднены, мне нужно рассчитать уровни mip самостоятельно. Размеры 3D-текстур (128 + 64) x 128 x 128, дополнительные 64 x 128 x 128 для уровней mip.Mipmapping with compute shader

Итак, когда я беру первый уровень мип, который находится в (0, 0, 0) с размером 128 x 128 x 128 и просто копирует вокселы на второй уровень, который равен (128, 0, 0), данные появляются там, но как только я копирую второй уровень (128, 0, 0) в третий на (128, 0, 64), данные не отображаются на 3-м уровне.

код шейдера:

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

Я не знаю, если я пропустил некоторые основные вещи, это мой первый Compute Shader. Я также пытался использовать барьеры памяти, но ничего не изменил.

ответ

2

Ну, вы не можете ожидать, что ваш второй imageLoad будет читать тексели, которые вы только что написал в своем первом магазине.

И нет возможности синхронизировать доступ за пределами локальной рабочей группы.

Вам нужно либо:

  • Чтобы использовать несколько призывание вашего ядра, чтобы сделать каждый слой
  • Чтобы переписать шейдер логику, так что вы всегда получать от «оригинальной» зоне.
+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. То, что вы хотите просто, невозможно. Лучше реструктурировать свой алгоритм и, возможно, данные, чтобы вписаться в разумный размер рабочей группы. –

Смежные вопросы