在iOS上的Metal中,默认的colorPixelFormat是bgra8Unorm
。当我将格式更改为rgba16Float
时,所有图像都会变亮。为什么?为什么?
一个例子:
艺术品
的数据MTKView
,格式为bgra8Unorm
。纹理贴图四边形。使用SRGB=false
创建的纹理。
的MTKView
,格式为rgba16Float
。纹理贴图四边形。使用SRGB=false
创建的纹理。
的
为什么rgba16Float
的一切都更亮。我的理解是,SRGB=false
意味着导入图稿时不进行gamma校正。假设艺术品未应用伽马。
这是怎么回事
2条答案
按热度按时间pjngdqdw1#
如果您的图稿具有Gamma(它是根据您上传的第一张图像),如果您想在线性空间中使用它,则必须将其转换为线性Gamma。
这里发生的是,您在线性工作空间中显示图像的伽马编码值,而不使用颜色管理或变换来转换这些 * 值 *。
但是:阅读你的一些评论,纹理不是一个图像,而是一个.svg??您是否将颜色值转换为线性空间?
**事情是这样的:RGB值是无意义的数字,除非您定义这些RGB值与给定空间的关系。
例如,sRGB中的#00FF00与Adobe 98中的#00FF00颜色不同。在你的情况下,你是线性的,但什么是初级呢?还在使用sRGB原色?P3初级?我没有看到真实的的色调偏移,所以我假设你在第二个例子中使用了sRGB原色和线性转移曲线。
也就是说,中间最高的孩子绿色衬衫的RGB值是#8DB54F,归一化为0-1,即0.553 0.710 0.310。这些数字 * 本身 * 不知道它们是否是伽马编码的。
sRGB、Y和Light之间的关系:
在sRGB中,#8DB54F,当在sRGB监视器上显示时,亮度(Y)为39
这可以通过以下方式找到
第一个月
或
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的绿色衬衫在解释和显示为sRGB时是L* 69,Y 65大约是L* 84(这些数字是基于数学,这里是我MacBook上每个颜色选择器的值):100d 1xx 1c 1d 1x的字符串
sRGB是伽马编码信号,用于最好地利用每通道8位的有限位深度。有效伽马曲线类似于人类感知,使得更多的位用于定义较暗区域,因为人类感知对暗区域中的亮度变化更敏感。如上所述,它是以下的简化曲线:
sRGB_Video = Linear_Video^0.455
(需要注意的是,MONITOR增加了大约1.1的指数)因此,如果0%是黑色,100%是白色,那么中间灰色,大多数人会说在0%和100%之间的点是:
Y 18.4%. = L* 50% = sRGB 46.7%
个也就是说,sRGB十六进制值#777777将显示18.4Y的亮度,并且相当于50 L* 的感知亮度。中灰。
但等等,还有更多
那么,发生了什么,你正在告诉
MTKView
,你正在向它发送引用 * 线性 * 值的图像数据。但你实际上是发送 sRGB 值,由于应用了伽马校正,这些值更亮。然后颜色管理是取它认为是线性值,并将它们转换为输出显示所需的值。色彩管理需要知道值 * 意味着什么,它们与什么颜色空间相关。当你设置
SRGB=false
时,你告诉它你发送的是线性值,而不是伽玛编码值。但是,您显然是在将伽马编码的值发送到线性空间中,而没有将值转换/解码为线性。除非隐式地这样做,否则线性化不会发生。
解决方案
线性化图像数据或设置标志
SRGB=true
如果您还有其他问题,请告诉我。但是,您可能希望看到Poynton Gamma FAQ或颜色常见问题解答以澄清。
**此外,对于灰色:**线性值0.216相当于sRGB(0-1)值0.500
niknxzdl2#
我最近不得不与这个问题作斗争,我终于弄明白了为什么将像素格式从
bgra8Unorm
更改为rgba16Float
会改变视觉外观,即使它应该只是我们如何存储像素数据的实现细节。缺少的部分是当未指定
colorspace
时核心动画如何合成CAMetalLayer。如果像素格式为bgra8Unorm
,则Core Animation假定像素数据位于非线性sRGB空间中。如果像素格式为rgba16Float
,则Core Animation假定像素数据在线性空间中。这就是为什么你所有的颜色看起来更明亮。颜色看起来太亮和褪色是sRGB颜色被解释为线性空间中的颜色的典型症状。解决办法其实很简单。只需将
CAMetalLayer
的colorspace
设置为与内容的色彩空间(通常为sRGB)相匹配:字符串
并且无论像素格式如何,您的内容看起来都应该相同。