Я установил свой кадровый буфер как SRGB с glEnable (GL_FRAMEBUFFER_SRGB);
Это не устанавливает ваш кадровый буфер в формат sRGB - он включает только преобразование sRGB , если фреймбуфер уже использует формат sRGB - они используют только состояние включения GL_FRAMEBUFFER_SRGB
, чтобы фактически отключить преобразование sRGB на фреймбарах, которые имеют формат sRGB. Вам по-прежнему необходимо специально запросить ваш кадровый буфер по умолчанию windows 'на sRGB-совместимый (или, возможно, вам удастся получить его без запроса, но это будет сильно отличаться в реализациях и платформах), или вам нужно создать текстуру sRGB или render-target, если вы визуализируете в FBO.
Преобразование значений напрямую:
for (GLubyte* pixel = image; pixel < image + size; ++pixel)
*pixel = GLubyte(pow(*pixel, 2.2f) + 0.5f);
Прежде всего pow(x,2.2)
это не правильная формула для sRGB - реальный использует небольшой линейный отрезок около 0, а для остальных - степень 2,4 - использование степени 2,2 - это всего лишь дальнейшее приближение.
Однако большая проблема с этим подходом состоит в том, что GLubyte
является 8-битный целочисленный тип без знака с диапазоном [0,255]
и выполнением pow(...,2.2)
, который возвращает значение в [0,196964.7]
, которое при преобразовании обратно в GLubyte
будет игнорировать старшие биты и в основном вычислит модуль 256, так что вы будете получить действительно бесполезные результаты. Концептуально вам нужно 255.0 * pow(x/255.0,2.2)
, что, конечно, может быть еще более упрощено.
Большая проблема здесь заключается в том, что выполняя это преобразование, вы в основном теряете большую точность из-за нелинейных искажений диапазона значений. , Если вы сделаете такое преобразование заранее, вам придется использовать текстуры с более высокой точностью для хранения линеаризованных значений цвета (например, 16-битовых половинных чисел на канал), просто сохраняя материал, так как 8-битный UNORM является полным катастрофа - и именно поэтому графические процессоры выполняют преобразование непосредственно при доступе к текстуре, чтобы вам не пришлось увеличивать объем памяти ваших текстур в 2 раза.
Так что я действительно сомневаюсь, что Ваш подход 3 будет «правильно импортировать текстуры SRGB». Это просто уничтожит любую верность, даже если все сделано правильно. Подходы 1 и 2 не имеют такой проблемы, но подход 1 просто глуп, учитывая, что аппаратное обеспечение сделает это за вас бесплатно. поэтому мне очень интересно, почему вы вообще учитываете 1 и 3.