Использовать типы матриц как вывод фрагмента шейдера в OpenGL - PullRequest
1 голос
/ 24 апреля 2019

В OpenGL матрица занимает несколько мест в шейдере (по одному на каждый столбец). Поэтому при использовании матрицы в вершинном шейдере в качестве входных данных необходимо вызывать glVertexAttribPointer() несколько раз.

Мне интересно, возможно ли сделать что-то подобное для матричных типов в качестве выходных данных во фрагментном шейдере при рендеринге в несколько кадровых буферов. То есть у меня было бы 4 различные текстуры в буфере кадров, привязанные к цветным вложениям от 0 до 3, и тогда я мог бы иметь layout(location = 0) out matrix4 out_mat, в который я мог бы писать с помощью фрагментного шейдера.

Правильно ли я считаю, что это будет работать?

Ответы [ 2 ]

4 голосов
/ 24 апреля 2019

Для вывода фрагментного шейдера недопустим тип данных матрицы:

См. Язык затенения OpenGL 4.60 Спецификация - 4.3.6.Выходные переменные , стр. 54:

Фрагмент выводит выходные данные для каждого фрагмента и объявляется с использованием квалификатора хранения out.Это ошибка времени компиляции для использования вспомогательных квалификаторов хранения или интерполяционных квалификаторов в выходном объявлении фрагментного шейдера. Ошибка времени компиляции объявлять фрагментный шейдерный выход с или имеющим любой из следующих типов :

  • Логический тип
  • Aскаляр или вектор двойной точности (double, dvec2, dvec3, dvec4)
  • непрозрачный тип
  • тип матрицы
  • структура

Но выходной фрагментный шейдер может быть массивом:

например,

layout (location = 0) out vec4 fragOut[4];

void main()
{
    mat4 m = [...];

    fragOut[0] = m[0];
    fragOut[1] = m[1];
    [...]
}

Матрица может быть назначена массивуконструктором массива (см. 4.1.13. Массивы , стр. 36):

layout (location = 0) out vec4 fragOut[4];

void main()
{
    mat4 m = [...];

    fragOut = vec4[4](m[0], m[1], m[2], m[3]);
}
1 голос
/ 24 апреля 2019

В спецификации GLSL сказано (Версия 4.5, 4.3.6 Выходные переменные):

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

...

  • Любой тип матрицы

Поэтому

layout(location = 0) out mat4 out_mat;

незаконно.

Вместо этого вы должны вывести элементы матрицы на четыре отдельных выхода:

 layout(location = 0) out vec4 out_mat0;
 layout(location = 1) out vec4 out_mat1;
 layout(location = 2) out vec4 out_mat2;
 layout(location = 3) out vec4 out_mat3;

 void main() {
     mat4 M = ...;
     out_mat0 = M[0]; // column 0
     out_mat1 = M[1]; // column 1
     out_mat2 = M[2]; // column 2
     out_mat3 = M[3]; // column 3
 }
...