#opengl #glsl #shader
#opengl #glsl #шейдер
Вопрос:
В OpenGL матрица занимает несколько местоположений в шейдере (по одному для каждого столбца). Таким образом, при использовании матрицы в вершинном шейдере в качестве входных данных необходимо вызвать glVertexAttribPointer()
несколько раз.
Мне интересно, возможно ли сделать что-то подобное для типов матриц в качестве выходных данных в фрагментном шейдере при рендеринге в несколько фреймбуферов. То есть у меня было бы 4 разные текстуры в буфере кадров, привязанные к цветным вложениям с 0 по 3, и тогда у меня могла бы быть layout(location = 0) out matrix4 out_mat
, в которую я мог бы записывать с помощью фрагментного шейдера.
Прав ли я, предполагая, что это сработает?
Комментарии:
1.Вы можете преобразовать столбец матрицы в другую цель (плоскость) буфера.
out0 = m[0];
out1 = m[1];
…2. Значит ли это, что это не работает?
3. @InformationAether: » В OpenGL матрица занимает несколько местоположений в шейдере » Матрицы занимают более одного местоположения только при использовании в качестве входных данных вершинного шейдера . Во всех других случаях, когда они могут быть использованы (переменные ввода / вывода внутри шейдера, униформы), они занимают только одно местоположение.
Ответ №1:
Для выходных данных фрагментного шейдера матричный тип данных недопустим :
Смотрите Спецификацию OpenGL Shading Language 4.60 — 4.3.6. Выходные переменные, стр. 54:
Fragment выводит данные для каждого фрагмента и объявляется с использованием
out
спецификатора хранилища. Использование вспомогательных квалификаторов хранилища или квалификаторов интерполяции в объявлении выходных данных фрагментного шейдера является ошибкой времени компиляции. Объявление выходных данных фрагментного шейдера с любым из следующих типов или содержащего их является ошибкой времени компиляции:
- Логический тип
- Скаляр или вектор двойной точности (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. Вы знаете, разрешены ли массивы векторов? Не удалось найти это в спецификации.
2. @ybungalobill Это явно не запрещено. В общем случае выходной переменной может быть массив. Я только что попробовал это, и это работает.
Ответ №2:
В спецификации 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
}