Выходные данные нескольких текстур в фрагментном шейдере - PullRequest
0 голосов
/ 17 мая 2018

Я пытаюсь использовать графический процессор для решения алгоритма, и я использую шейдеры для этого (не вычислительные шейдеры, а только вершинные и фрагментные шейдеры).Для этого мне нужно, чтобы в моем фрагментном шейдере были две выходные переменные для извлечения данных, у меня нет проблем с входными данными (это прекрасно работает), но до сих пор я не смог заставить их работать с двумя выходными переменными, потому что фактически работает только одна из нихили что-то странное случается между ними обоими.

Я также хотел бы, чтобы этот вопрос был как справка для этой практики (несколько выходов в фрагментном шейдере для GPGPU), поскольку то, что я видел до сих пор, - это только конкретные случаи.Сначала у меня есть две текстуры, которые я загружаю только один раз так:

Первая Текстура

glBindTexture(GL_TEXTURE_2D, texture[4]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_R32I, width, height,
    0, GL_RED_INTEGER, GL_INT, 0);

Вторая Текстура

glBindTexture(GL_TEXTURE_2D, texture[5]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_R32I, width, height,
    0, GL_RED_INTEGER, GL_INT, 0);

Эти две текстуры должны хранить мои выходные данные (каждая текстура должна иметь переменную out). В обоих случаях я использую красный компонент для хранения данных какinteger.

Теперь я создаю кадровый буфер и связываю эти две текстуры с кадровым буфером, каждая текстура в свойстве color_attachment.

glGenFramebuffers(1, &resultFBO); // frame buffer id
glBindFramebuffer(GL_FRAMEBUFFER, resultFBO);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
    GL_TEXTURE_2D, texture[4], 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1,
    GL_TEXTURE_2D, texture[5], 0);

Теперь, что касается фрагментного шейдера, я устанавливаю местоположениевыходные переменные, подобные этому:

layout(location = 0) out int resultFlow;
layout(location = 1) out int resultAccumFlow;

Наконец, я просто вызываю DrawArrays () (в цикле рендеринга) после того, как связываю тот же самый кадровый буфер:

    glBindFramebuffer(GL_FRAMEBUFFER, resultFBO);
    // Render
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

Я почти уверен, что это последнеешаг тот, который не «работает», но, может быть, мне нужно что-то еще.Я пытался найти его, но я не нашел никакой документации, в любом случае, если есть какая-то статья, связанная с этим, это было бы очень полезно.

1 Ответ

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

... но до сих пор я не смог заставить его работать с двумя выходными переменными, потому что фактически работает только одна из них ...

Если вы хотите выполнить запись в несколько целей в фрагментном шейдере, то последний шаг, который вы пропустили, состоит в том, чтобы указать список цветовых буферов, в которые вы будете рисовать. Это можно сделать с помощью glDrawBuffers:

glBindFramebuffer(GL_FRAMEBUFFER, resultFBO);

GLenum drawBuffers[]={GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1};
glDrawBuffers(2, drawBuffers);

glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

Подсказка: вы можете использовать glClearBuffer для очистки отдельных буферов кадрового буфера


См. Спецификация профиля ядра API OpenGL 4.6; 17.4.1. Выбор буферов для записи; страница 513 :

17.4.1 Выбор буферов для записи

.....

Набор буферов объекта framebuffer, для которого все цвета фрагмента написано контролируется с помощью команд

void DrawBuffers( sizei n, const enum *bufs );
void NamedFramebufferDrawBuffers( uint framebuffer, sizei n, const enum *bufs );

.....

Для объектов кадрового буфера в начальном состоянии буфер отрисовки для нулевой цвет фрагмента - COLOR_ATTACHMENT0. для обоих кадровых буферов по умолчанию и объекты кадрового буфера, начальное состояние буферов отрисовки для цветов фрагмента, отличных от нуля, равно NONE.

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