почему бы не использовать более быстрое деление на 256?
Целочисленное деление на 256 будет быстрее, но вы не делаете целочисленное деление, не так ли? Деление с плавающей запятой, как правило, не имеет ярлыков, основанных на таких конкретных значениях Если вам нужно выполнить деление с плавающей запятой, вы оплачиваете стоимость деления с плавающей запятой.
Этот пример Godbolt показывает, что Clang при высоких оптимизациях не находит способа сделать деление на 256.0f быстрее 255. GCC и MSVC действительно получают одну небольшую оптимизацию: они заменяют деление умножением на вычисленное во время компиляции значение 1 / 256.0f, которое является точным числом с плавающей запятой. Но вы можете сделать то же самое, если ваш код явно умножить на (1 / 255.0f)
, так что, опять же, нет никакого преимущества.
Теперь, есть теоретически более быстрые способы нормализовать целое число без знака в число с плавающей точкой. Но, как правило, они основаны на прямом манипулировании битами значения с плавающей запятой и не могут на самом деле быть быстрее, чем просто математика с плавающей запятой. Вам придется профилировать его при определенных обстоятельствах, в которых вы собираетесь их использовать, чтобы заставить его работать.
каковы реальные последствия немного более низких значений с плавающей запятой? Что-нибудь на самом деле различимо?
Последствия могут быть что угодно . Что касается современного OpenGL, то значение каждого значения, которое вы предоставляете OpenGL, полностью определяется вашим кодом. Действительно, ваш код может добавить деление на 0,996, чтобы изменить масштаб числа, и, таким образом, не будет никакой реальной разницы.
Легко написать фрагмент кода шейдера, который сломается, если вы откажетесь передавать правильно нормализованное значение с плавающей запятой (все, что делает if(value == 1.0f)
, что необходимо, чтобы быть верным, если вы правильно выполнили нормализацию). Я могу так же легко написать код, который не заботится. Там нет общего ответа; все зависит от того, что вы делаете с ним.
Совместимость OpenGL по сути одинаков: все зависит от того, что вы делаете с ним . Это может быть фиксированная функция, а не шейдеры, но у вас еще достаточно места, чтобы определить значение этого числа.
Поскольку жизнеспособность результата основана на информации, которую вы не можете знать на уровне простой функции normalizeIntegerToFloat
, вам нужно предоставить вызывающей стороне функции выбор. Укажите точную версию и версию с потерями. То, что вы абсолютно не должны делать, это сделать версию с потерями по умолчанию. Если пользователь функции видит проблему с производительностью, он может переключиться на использование версии с потерями, чтобы помочь облегчить ее.