我有两个配置了以下选项的CIContexts:
let options1:[CIContextOption:Any] = [CIContextOption.cacheIntermediates: false, CIContextOption.outputColorSpace: NSNull(), CIContextOption.workingColorSpace: NSNull()];
let options2:[CIContextOption:Any] = [CIContextOption.cacheIntermediates: false];
字符串
和一个MTKView与CAMetalLayer配置HDR输出。
metalLayer = self.layer as? CAMetalLayer
metalLayer?.wantsExtendedDynamicRangeContent = true
metalLayer.colorspace = CGColorSpace(name: CGColorSpace.itur_2100_HLG)
colorPixelFormat = .bgr10a2Unorm
型
当输入在BT.2020像素缓冲区中时,这两个上下文选项会产生不同的输出。但我认为输出不应该有所不同。因为第一个选项只是禁用了颜色管理。第二个选项在sRGB扩展线性颜色空间中执行中间缓冲区计算,然后在输出中将这些缓冲区转换为BT.2020颜色空间。输出不同是因为中间步骤?
最后,在显示HDR采样缓冲区时,哪个选项是正确的?
1条答案
按热度按时间2w3rbyxf1#
让我先回答你的最后一个问题:是的,这是设置
MTKView
显示HDR内容的有效和好方法。但是,正如你指出的,你还需要告诉MTLView
通过设置metalLayer.edrMetadata = .hlg
将EDR值色调Map到显示器的亮度范围。另外,我发现以下设置也适用于显示EDR内容:
字符串
在这种情况下,视图似乎知道如何自动将扩展线性EDR值色调Map到其显示屏-无需设置
edrMetadata
。剩下的我想分成两个主题:
工作颜色空间
你是对的:当设置
CIContextOption.workingColorSpace: NSNull()
时,您可以有效地禁用Core Image的自动颜色管理。然而,我建议您只在以下情况下才这样做:所以在你的例子中,如果你不想在你的管道中应用滤镜,你可能可以通过设置工作空间为
NSNull()
来禁用颜色匹配。这甚至可以保存一点处理时间,尽管不是很多,因为颜色空间转换相当便宜。在大多数情况下,我建议不要触及
workingColorSpace
选项,让CI决定使用什么。输出颜色空间
不幸的是,
CIContextOption.outputColorSpace
是非常误导的。它似乎并没有在几乎所有的用例中使用-至少到目前为止我还没有看到任何效果。那是因为通常你要么
CIContext
的渲染API,就像在createCGImage(_ image:, from fromRect:, format:, colorSpace:)
中,第二点是这里的关键。我相信你正在使用
CIRenderDestination
API渲染到视图中,可能定义如下:型
这里的问题是
CIRenderDestination
不能完全推断目标的颜色空间(它通常默认为sRGB)。这就是为什么你必须显式设置它。在这里,你知道视图期望可绘制的纹理包含
itur_2100_HLG
中的像素数据。所以直接设置它,或者简单地将其设置为视图的颜色空间:型
然后Core Image将知道在渲染到目标时要转换到哪个颜色空间。
有了这个变化,现在应该没有更多的颜色管理关闭(
CIContextOption.workingColorSpace: NSNull()
)和打开之间的区别。