Постоянные значения поплавка в шейдерах GLSL - любая причина использования униформы?

Я смотрю на источник приложения OpenGL, использующего шейдеры. Один конкретный шейдер выглядит следующим образом:

uniform float someConstantValue;
void main()
{
    // Use someConstantValue
}

Единица устанавливается один раз из кода и никогда не изменяется во время выполнения приложения.

В каких случаях я хочу объявить someConstantValue как uniform а не как const float?

Изменить: просто для уточнения, постоянное значение является физической константой.

Ответ 1

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

Если вы не хотите устанавливать униформу в свой код, вы можете указать значение по умолчанию в GLSL:

uniform float someConstantValue = 12.5;

Тем не менее, нет оснований не использовать const для чего-то вроде pi, где было бы мало смысла в его модификации....

Ответ 2

Огромная причина:

Ошибка: индекс цикла нельзя сравнивать с непостоянным выражением.

Если я использую:

uniform float myfloat;
...
for (float i = 0.0; i < myfloat; i++)

Я получаю сообщение об ошибке, потому что myfloat не является constant expression.


Однако это совершенно верно:

const float myfloat = 10.0;
...
for (float i = 0.0; i < myfloat; i++)

Зачем?

Когда GLSL (и HLSL, если на то пошло) компилируются в инструкции по сборке GPU, циклы разворачиваются в очень подробном (но оптимизированном с использованием переходов и т.д.) Пути. Значение myfloat используется во время компиляции для разворачивания цикла; если это значение uniform (т.е. может изменить каждый вызов рендеринга), то этот цикл не может быть развернут до времени выполнения (а графические процессоры не делают такую компиляцию JustInTime, по крайней мере, не в WebGL).

Ответ 3

Я могу думать о двух причинах:

  1. Разработчик повторно использует библиотеку шейдеров в нескольких приложениях. Поэтому вместо настройки каждого шейдера для каждого приложения разработчик пытается сохранить их в общем.

  2. Разработчик ожидает, что эта переменная позже будет настраиваться пользователем. Таким образом, объявить его единообразным - это подготовка к этой предстоящей функции.

Если бы я был разработчиком, и ни одно из вышеизложенного не применимо, я бы объявил его как "const", потому что он может дать преимущество в производительности, и мне не нужно будет устанавливать форму из моего кода.