iOS Металл.Почему простое изменение colorPixelFormat приводит к более ярким изображениям? - PullRequest
0 голосов
/ 18 января 2019

В Metal на iOS по умолчанию colorPixelFormat имеет значение bgra8Unorm. Когда я изменяю формат на rgba16Float, все изображения становятся ярче. Почему?

Пример:

Работа

enter image description here

MTKView с форматом bgra8Unorm. Текстурный четырехугольник. Текстура создана с помощью SRGB=false.

enter image description here

MTKView с форматом rgba16Float. Текстурный четырехугольник. Текстура создана с SRGB=false.

enter image description here

Почему все ярче с rgba16Float. Насколько я понимаю, SRGB=false подразумевает, что без гамма-коррекции не выполняется при импорте иллюстраций. Предполагается, что к иллюстрации приложено без гаммы

Что здесь происходит?

1 Ответ

0 голосов
/ 30 апреля 2019

Если ваша работа имеет гамму (она соответствует первому загруженному изображению), вы должны преобразовать ее в линейную гамму, если хотите использовать ее в линейном пространстве.

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

НО: читая некоторые ваши комментарии, текстура - это не изображение, а .svg ?? Вы конвертировали значения цвета в линейное пространство?

Вот в чем дело: Значения RGB являются бессмысленными числами, если только вы не определяете, как эти значения RGB относятся к данному пространству.

# 00FF00 в sRGB отличается от цвета # 00FF00 в Adobe98, например. В твоем случае ты идешь линейно, но какие праймериз? Все еще используете праймериз sRGB? P3 Primaries? Я не вижу реального смещения оттенка, поэтому я предполагаю, что вы используете основные цвета sRGB и линейную кривую передачи для второго примера.

ЭТО СКАЗАЛ, что значение RGB зеленой рубашки верхнего среднего ребенка равно # 8DB54F, нормализовано до 0-1, то есть 0,553 0,710 0,310. Эти числа сами по себе не знают, закодированы ли они гамма или нет.

ОТНОШЕНИЕ МЕЖДУ sRGB, Y и Light:

Для целей этого обсуждения мы будем считать ПРОСТУЮ гамму sRGB 1 / 2.2, а не кусочную версию. То же самое для L *

В sRGB, # 8DB54F при отображении на мониторе sRGB с гамма-кривой sRGB, яркость (Y) составляет 39

Это может быть найдено

(0.553^2.2)*0.2126 + (0.710^2.2)*0.7152 + (0.310^2.2)*0.0722

или 0.057 + 0.33 + 0.0061 = 0.39 and 0.39 * 100 = 39 (Y)

Но если управление цветом говорит, что значения линейны, то гамма-коррекция отбрасывается и (более или менее):

0.553*0.2126 + 0.710*0.7152 + 0.310*0.0722

или 0.1175 + 0.5078 + 0.0223 = 0.65 and 0.65 * 100 = 65 (Y)

(Предполагается, что используются одинаковые коэффициенты.)

Яркость (Y) линейна, как свет. Но человеческое восприятие не таково, равно как и ценности sRGB.

Y - это линейная яркость от CIEXYZ, в то время как она спектрально взвешена на основе реакции глаза на различные длины волн, она НЕ однородна с точки зрения яркости. По шкале от 0 до 100 18,4 воспринимается как середина.

L * - легкость восприятия от CIELAB (L * a * b *), это (упрощенная кривая):

L* = Y^0.42 По шкале от 0 до 100 L * 50 - это «воспринимаемое среднее» значение. Таким образом, зеленая рубашка для Y 39 - это L * 69, когда интерпретируется и отображается как sRGB, а Y 65 - для L * 84 (эти цифры основаны на математике, вот значения для средства выбора цвета на моем MacBook):

sRGB Green Shirt linear green shirt

sRGB - это сигнал с гамма-кодированием, созданный для наилучшего использования ограниченной битовой глубины 8 бит на канал. Эффективная гамма-кривая аналогична человеческому восприятию, поэтому для определения более темных областей используется больше битов, поскольку человеческое восприятие более чувствительно к изменениям яркости в темных областях. Как отмечено выше, это упрощенная кривая:

sRGB_Video = Linear_Video^0.455 (И следует отметить, что МОНИТОР добавляет показатель порядка 1,1)

Таким образом, если 0% - черный, а 100% - белый, то средний серый, точка, которую большинство людей скажет, находится в диапазоне от 0% до 100%:

Y 18.4%. = L* 50% = sRGB 46.7%

То есть шестнадцатеричное значение sRGB # 777777 будет отображать яркость 18,4 Y, что эквивалентно воспринимаемой яркости 50 л *. Средний серый.

НО ЖДУ, ТАМ БОЛЬШЕ

Итак, что происходит, вы говорите MTKView, что отправляете ему данные изображения, которые ссылаются на линейные значения. Но вы на самом деле отправляете sRGB значения, которые легче из-за примененной гамма-коррекции. И затем управление цветом принимает линейные значения и преобразует их в необходимые значения для вывода на экран.

Управление цветом должно знать, что означают , к какому цветовому пространству они относятся. Когда вы устанавливаете SRGB=false, вы говорите, что отправляете линейные значения, а не значения, закодированные в гамма-диапазоне.

НО вы явно отправляете гамма-кодированные значения в линейное пространство без преобразования / декодирования значений в линейное. Линеаризация не произойдет, если вы не сделаете это неявно.

РЕШЕНИЕ

Линеаризовать данные изображения ИЛИ установить флаг SRGB=true

Пожалуйста, дайте мне знать, если у вас есть дополнительные вопросы. Кроме того, вы можете посмотреть Poynton Gamma FAQ или также FAQ по цвету для уточнения.

Также, для вашего серого: Линейное значение 0,216 эквивалентно значению sRGB (0-1) 0,500

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...