Можно ли объявить слишком большой выходной массив в шейдере фрагментов и оставить некоторые индексы неиспользуемыми?
Некоторый контекст:
Я ищу простой способ запустить "старые" шейдеры (скажем,#version 120
) на "новом" GLSL (скажем, #version 150 core
).
До сих пор я придумал добавить следующий заголовок к моим шейдерам фрагментов при таргетинге #version 150
:
#version 150 core
#define texture2D texture
out vec4 _gl_FragData[gl_MaxDrawBuffers];
#define gl_FragData _gl_Fragdata
#define gl_FragColor gl_Fragdata[0]
Вопрос:
Я немного сосредоточен на этой строке:
// In a fragment shader
out vec4 _gl_FragData[gl_MaxDrawBuffers];
В большинстве шейдеров, _gl_FragData[1 ... gl_MaxDrawBuffers-1]
не используется, т. е. не записывается шейдером, и не хватает вложений буфера кадров для получения значений. Я беспокоюсь, если присутствие этих неиспользуемых элементов делает мои шейдеры плохо сформированными (или имеет какие-либо нежелательные эффекты или накладные расходы).
Спецификация GLSL 1.50 говорит, что существует неявно определенный устаревший out vec4 gl_FragData[gl_MaxDrawBuffers];
, поэтому предположительно то, что я делаю, прекрасно и не несет никаких накладных расходов.
Но я также знаю, что builtin gl_FragData
в некотором смысле "волшебный", и аналогичное пользовательское объявление может иметь другой эффект.
TL; DR:
Если мой фрагмент шейдера выход-это массив, могу ли я не записывать некоторые элементы в конце массива, учитывая, что значения этих элементов отбрасываются (не принимаются ни одной точкой присоединения буфера кадров) ?
Немного слишком широко, но: имеет ли присутствие этих неиспользуемых индексов какие-либо незначительные эффекты или накладные расходы на общие реализации?
1 ответ:
Если мои выходные данные шейдера фрагментов являются массивом, могу ли я не записывать некоторые элементы в конце массива, учитывая, что значения этих элементов отбрасываются (не принимаются ни одной точкой присоединения буфера кадров)?
Вам всегда разрешено не писать ни в какие выходные переменные, независимо от того, используются они или нет.
Поскольку вы используете
#version 150
, я имею в видуGLSL 1.50 spec . Раздел 4.3.6" результаты " гласит (Курсив мой):Вывод переменные должны быть объявлены в глобальной области видимости. Во время выполнения шейдера они будут вести себя как обычно неквалифицированные глобальные переменные. их значения копируются на следующий этап конвейера при выходе шейдера.
Если вы объявляете переменную и никогда не записываете в нее, у вас будет неопределенное значение, но не неопределенное поведение. Это также подкрепляется спецификацией профиля ядра OpenGL 3.2 , раздел 3.9 " шейдеры фрагментов", Подраздел "Выходные Данные Шейдера"
Любые цвета или компоненты цвета, связанные с фрагментом, которые не записаны фрагментом шейдеры не определены.
Более современные версии спецификации GL, например OpenGL 4.6 core profile , еще более ясны в этом пункте (раздел 17.4 "операции полного буфера кадров"):
Если шейдер фрагмента записывает в пользовательскую выходную переменную,
DrawBuffers
задает набор буферов рисования, в которые каждый из определено несколько выходных цветов по этим переменным пишутся отдельно. , Если фрагмент шейдер пишет Нет определяемые пользователем выходные переменные, значения цветов фрагмента, следующие за шейдером исполнение не определено и может отличаться для каждого фрагмента цветом. Если и есть, то нет записываются все определяемые пользователем выходные переменные, соответствующие значениям цветов фрагментов к неписаным переменным относятся также неопределенные.Спецификация GLSL 1.50 продолжает:
Необходимо записать только выходные переменные, которые считываются на следующем этапе конвейера; разрешается имеют избыточные объявления выходных переменных.
Совершенно нормально не писать в выходные переменные, которые все равно не будут использоваться.
Ваш второй вопрос немного сложнее:
Оказывает ли присутствие этих неиспользуемых индексов какое-либо незначительное влияние или накладные расходы на общие реализации?
Спецификация GL никогда не дает таких гарантий. Я могу сказать только две вещи:
- я никогда не замечал никаких негативных последствий наличия некоторых дополнительных неиспользуемых выходов FS (но я также не делал этого очень часто). Я также не ожидал бы, что разумная реализация приведет к заметным накладным расходам в таком случае.
- Если вам действительно нужно быть уверенным, вы должны проверить/профайл на реальных реализациях, которые вас интересуют.