Запись в изображение с помощью imageStore в OpenGL - PullRequest
0 голосов
/ 14 мая 2018

В настоящее время я пытаюсь записать изображение, используя imageStore в OpenGL.Однако, используя renderdock в качестве отладчика, я нахожу только черную текстуру после запуска моей программы.

Я создаю и привязываю изображение для записи следующим образом:

glGenTextures(1, &textureID);
glBindTexture(target, textureID);
glObjectLabel(GL_TEXTURE, textureID, -1, "\"3D Texture\"");
glTexStorage3D(target, 1, GL_RGBA8, width, height, depth);

glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

Затем загружаютекстуру для программы, выполнив:

glBindImageTexture(0, textureID, 0, GL_TRUE, 0, GL_READ_WRITE, GL_RGBA8);
GLuint location = glGetUniformLocation(programID, uniform);
glUniform1i(location,0);

И, наконец, я отрисовываю, вызывая glDrawArrays ().

Мой фрагментный шейдер выглядит так:

#version 440

out vec3 f_pos;
out vec3 f_norm;
out vec2 f_uv;

layout(RGBA8) uniform image3D volumeMap;

void main()
{
    imageStore(volumeMap, ivec3(0,0,0),
        vec4(0,1,1,0));
}

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

Я успешно загрузил и прочитал из сэмплеров с помощью вызова texture ().

Я не уверен, что пропускаю шаги или неправильно выполняю свои действия.

РЕДАКТИРОВАТЬ:

Я изменил свой код, чтобы не полагаться на RenderDoc, чтобыпроверьте цвет.

Итак, я отрисовываю вещи следующим образом

Final Fragment Shader:

#version 440

out vec4 fragment_color;

layout(binding=3, RGBA8) uniform image3D vMap;

void main()
{
    fragment_color = imageLoad(vMap, ivec3(0,0,0));
}

C ++

glUseProgram(Program1);
/*load texture as above*/
draw();
glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);

glUseProgram(Program2);
/*load texture as above*/
draw();

Draw просто настраиваетсягеометрия буферизуется, а затем вызывает glDrawArrays ().

В результате получается черная сетка, где я ожидаю, что голубая сетка

1 Ответ

0 голосов
/ 14 мая 2018

Операции загрузки / сохранения изображений работают по правилам некогерентного доступа к памяти .Это означает, что записи в них не видны для последующего чтения, если вы явно не сделаете что-то, чтобы сделал их видимыми.Обычно это вызов glMemoryBarrier.

Всегда помните, что glMemoryBarrier указывает, как вы намереваетесь получить доступ к записанному значению, а не как вы его записали.В этом случае механизм одинаков в любом случае: GL_SHADER_IMAGE_ACCESS_BARRIER_BIT.Эта команда должна быть помещена после команды, которая записывает данные, и перед той, которая их читает.

Кроме того, я не могу сказать, имеет ли этот шейдер неопределенное поведение или нет.У вас есть несколько вызовов, которые все записывают в одну и ту же область памяти.Но в вашем случае они пишут одинаковое значение.Из описания в описании неясно, является ли это подлинным UB или это нормально.Конечно, было бы UB, если вызовы записывали разные данные, но я не знаю, существует ли какое-то исключение для них, записывающих одни и те же данные.

Однако я бы очень не согласился с этим.

...