Для поддержки широкой цветовой гаммы вам необходимо установить colorPixelFormat
вашего MTKView на BGRA10_XR или bgra10_XR_sRGB. Я подозреваю, что свойство colorSpace
macOS MTKViews не будет поддерживаться на iOS, потому что управление цветом в iOS не активно, а целевое (читайте Рекомендации по управлению цветом).
Не видя ваших изображений и их фактических значений, трудно поставить диагноз, но я объясню свои выводы и эксперименты. Я предлагаю вам начать, как я, с отладки одного цвета.
Например, какая самая красная точка в цветовом пространстве P3? Его можно определить через UIColor
следующим образом:
UIColor(displayP3Red: 1, green: 0, blue: 0, alpha: 1)
Добавьте UIButton в свое представление с фоном, установленным на этот цвет, для целей отладки. Вы можете либо получить компоненты в коде, чтобы увидеть, какими будут эти значения в sRGB,
var fRed : CGFloat = 0
var fGreen : CGFloat = 0
var fBlue : CGFloat = 0
var fAlpha : CGFloat = 0
let c = UIColor(displayP3Red: 1, green: 0, blue: 0, alpha: 1)
c.getRed(&fRed, green: &fGreen, blue: &fBlue, alpha: &fAlpha)
или вы можете использовать калькулятор в macOS Color Sync Utility,
![Утилита синхронизации цвета](https://i.stack.imgur.com/Hsbti.png)
Убедитесь, что вы выбрали Расширенный диапазон, иначе значения будут ограничены 0 и 1.
Итак, как видите, ваш P3(1, 0, 0) соответствует (1,0930, -0,2267, -0,1501) в расширенном sRGB.
Теперь вернемся к вашему MTKView
,
Если вы установите для colorPixelFormat вашего MTKView значение .BGRA10_XR
, вы получите самый яркий красный цвет, если вывод вашего шейдера,
(1.0930, -0.2267, -0.1501)
Если вы установите colorPixelFormat
вашего MTKView на .bgra10_XR_sRGB
, вы получите самый яркий красный цвет, если вывод вашего шейдера,
(1.22486, -0.0420312, -0.0196301)
потому что вам нужно написать линейное значение RGB, так как этот формат текстуры применит для вас гамма-коррекцию. Будьте осторожны при применении инверсной гаммы, так как есть отрицательные значения. Я использую эту функцию,
let f = {(c: Float) -> Float in
if fabs(c) <= 0.04045 {
return c / 12.92
}
return sign(c) * powf((fabs(c) + 0.055) / 1.055, 2.4)
}
Последняя недостающая деталь — это создание широкой гаммы UIImage
. Установите цветовое пространство на CGColorSpace.displayP3
и скопируйте данные. Но какие данные, верно? Самый яркий красный цвет на этом изображении будет
(1, 0, 0)
или (65535, 0, 0) в 16-битных целых числах.
Что я делаю в своем коде, так это использую текстуры .rgba16Unorm
для управления изображениями в цветовом пространстве displayP3
, где (1, 0, 0) будет самым ярким красным цветом в P3. Таким образом, я могу напрямую скопировать его содержимое в файл UIImage
. Затем для отображения я передаю преобразование цвета в шейдер для преобразования из P3 в расширенный sRGB (то есть без насыщения цветов) перед отображением. Я использую линейный цвет, поэтому мое преобразование представляет собой просто матрицу 3x3. Я установил свой вид на .bgra10_XR_sRGB
, поэтому гамма будет применяться автоматически для меня.
Эта (столбцовая) матрица,
1.2249 -0.2247 0
-0.0420 1.0419 0
-0.0197 -0.0786 1.0979
Вы можете прочитать о том, как я его сгенерировал, здесь: Изучение цветового пространства display-P3
Вот пример, который я создал с помощью UIButtons и MTKView, сделанный на iPhoneX.
![Красный MTKView](https://i.stack.imgur.com/PMpuR.png)
Кнопка слева имеет самый яркий красный цвет в sRGB, а кнопка справа использует цвет displayP3. В центре я разместил MTKView, который выводит преобразованный линейный цвет, как описано выше.
Тот же эксперимент для зеленого, ![Зеленый MTKView](https://i.stack.imgur.com/BzgIe .png)
Теперь, если вы видите это на последнем iPhone или iPad, вы должны увидеть, что и квадрат в центре, и кнопка справа имеют одинаковые яркие цвета. Если вы видите это на Mac, который не может их отображать, левая кнопка будет иметь тот же цвет. Если вы видите это на компьютере с Windows или в браузере без надлежащего управления цветом, левая кнопка также может иметь другой цвет, но это только потому, что все изображение интерпретируется как sRGB, и, очевидно, эти пиксели имеют разные значения... Но внешний вид не будет правильным.
Если вам нужны дополнительные ссылки, проверьте модульный тест testP3UIColor
, который я добавил здесь: ColorTests.swift,
мои функции для инициализации UIImage
: Image.swift< / а>,
и пример приложения для опробования преобразований: SampleColorPalette.
Я не экспериментировал с CIImages
, но, думаю, применимы те же принципы.
Я надеюсь, что эта информация чем-то поможет. Мне также потребовалось много времени, чтобы понять, как правильно отображать цвета, потому что я не смог найти явную ссылку на поддержку displayP3 в документации Metal SDK.
person
endavid
schedule
30.03.2018