如果 CAMetalLayerpixelFormat
设置为rgba8Unorm_srgb
. 正确的意思是我的 UIColor 和 UIImage 在 Metal 中应该和 UIKit 一样。我发现如果我的 CAMetalLayer pixelFormat 是rgba8Unorm
. 但我真的需要使用rgba8Unorm_srgb
.
我附上了这个项目的两个截图。它有一个平方的 CAMetalLayer。它的灰色背景颜色是它的MTLRenderPassDescriptor.colorAttachments[0].clearColor = MTLClearColorMake(0.5, 0.5, 0.5, 1)
. 它也有白色和黑色的四边形,还有一个上面有红色渐变的四边形,实际上使用了标准的 alpha 混合:
colorAttachments[0].rgbBlendOperation = .add
colorAttachments[0].alphaBlendOperation = .add
colorAttachments[0].sourceRGBBlendFactor = .sourceAlpha
colorAttachments[0].sourceAlphaBlendFactor = .sourceAlpha
colorAttachments[0].destinationRGBBlendFactor = .oneMinusSourceAlpha
colorAttachments[0].destinationAlphaBlendFactor = .oneMinusSourceAlpha
两个屏幕截图之间的唯一区别是它们的 CAMetalLayer 像素格式。但正如你所看到的,即使是透明的颜色也已经不同了。(它们实际上通过伽马校正完全不同)。白色和黑色是相同的,但所有其他颜色也不同。Alpha 混合也无法正常工作rgba8Unorm_srgb
:您可以看到,它在白色目标上的一半是不饱和的,而在黑色目标上的一半是过饱和的。
据我了解,我不需要担心伽玛校正,不需要修改我的着色器或颜色。无论pixelFormat如何,Metal都应该在线性空间中进行所有数学运算。那么为什么会这样呢?