Можно ли объявлять массив выходных данных большого размера в фрагментном шейдере и оставлять некоторые индексы неиспользованными? - PullRequest
0 голосов
/ 04 сентября 2018

Некоторый контекст:

Я ищу простой способ запуска «старых» шейдеров (скажем, #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];, поэтому предположительно то, что я делаю, нормально и не требует дополнительных затрат.
Но я также знаю, что встроенный gl_FragData в некотором роде «магический», и подобное предоставленное пользователем объявление может иметь другой эффект.

TL; DR:

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

Немного широка, но: Имеет ли присутствие этих неиспользуемых индексов какие-либо нежелательные эффекты или накладные расходы в распространенных реализациях?

1 Ответ

0 голосов
/ 08 сентября 2018

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

Вам всегда разрешено не записывать ни в какие выходные переменные, независимо от того, используются они или нет.

Поскольку вы используете #version 150, я имею в виду спецификацию GLSL 1.50 . Раздел 4.3.6 «Выходы» гласит (выделено мое):

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

Если вы объявите переменную и никогда не будете писать в нее, у вас будет неопределенное значение , но не неопределенное поведение . Это также подтверждается спецификацией основного профиля OpenGL 3.2 , раздел 3.9 «Фрагментные шейдеры», подраздел «Выходы шейдеров»

Любые цвета или цветовые компоненты, связанные с фрагментом, которые не записаны фрагментом. шейдеры не определены.

Более современные версии спецификации GL, например, Профиль ядра OpenGL 4.6 , еще яснее об этом (Раздел 17.4 «Операции с полным кадровым буфером»):

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

Спецификация GLSL 1.50 продолжается:

Только выходные переменные, которые читаются на следующем этапе конвейера, должны быть записаны; разрешено иметь лишние объявления выходных переменных.

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

Ваш второй вопрос немного сложнее:

Имеет ли присутствие этих неиспользуемых индексов какие-либо нежелательные эффекты или накладные расходы на общие реализации?

Спецификация GL никогда не дает таких гарантий. Я могу сказать только две вещи:

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