• 资料
  • 为什么
    • 韦伯定理
      •  
        • 人眼对于暗部是更敏感的
          • 举例
      • 中灰
        • 说明
          • 如果均匀记录物理灰阶,画面的样本分布是下图这样的(绿线为0.5,样本明显往高光区集中)
          • 如果均匀美术灰阶,画面的样本分布是下图这样的(红线为0.5,亮暗部分格式128个灰阶)
          • 在下图中可以看到,如果线性记录像素的物理光强数据,在物理灰阶中,美术暗部只有56个灰阶,这样的结果就是暗部会有明显的色阶断层。
        • 如果做一次非线性映射(就是gamma校正),把美术灰阶中的中灰提到中间,这样亮部和暗部就都能分配到128个样本。这样下来保存的才是人眼看着舒服的/正常的结果。
        • 美术中灰50%=物理中灰21.8%
    • 美术与物理的转换
      • 把人感受到的均匀灰阶和自然界线性增长的亮度进行一个映射,就是gamma编码的曲线
    • CRT(阴极射线显像管)
      • 这种设备的亮度和电压不成线性关系,而是和gamma值约为2.2类似幂律的关系
      • 由于CRT的这个物理特性,刚好可以把亮度压暗,也就说,左图变亮的情况下,经过右图显示器的压低亮度校正,结果刚好可以显示正常。
      • 值得注意的是,上述所说的前提是,在条件相同的情况下(在明暗不同的环境下,看到的结果可能不同),我们取的中灰值,也不是指特定的一个值。
  • 是什么
    • 简单定义
      • Vout = Vingamma
        • 传递函数其实就是伽马校正所使用的函数,我们一般看到的是被简化的幂函数
      • Gamma是指对线性三色值和非线性视频信号之间进行编码和解码的操作。
        • 色彩值与视频信号
          • 知道了颜色的颜色值之后,想要在电子设备上显示,就需要把它转换为视频信号,传递函数就是用来做转换的。
        • 传递函数包括两部分:
          • 分类
            • 光转电传递函数(OETF),把场景线性光转到非线性视频信号值。
            • 电转光传递函数(EOTF),把非线性视频信号值转到显示光亮度。
          • 一个简单理解:拍照时,将照片存储在内存卡中,就是用视频信号存储的,如果要看这个照片,就把视频信号再转换成光信号。
          • 传递函数其实就是Gamma校正所使用的函数。
        • 编码和解码的理解:
          • 当保存为图片时,就用gamma小于1的函数处理,这样一来,物理上0.218的色值,就可以映射到美术上的中灰。
          • 如果这张图片要被打开查看时,如果直接用物理数据,是偏亮的,这个时候又要进行一次校正,也就是显示器要用到一条gamma大于1的下压曲线来校正,把亮度压低,达到符合人眼的美术灰阶。
          • 上述流程如图:
            • 用一张图来举例:

              • gamma编码:
                • 目的
                  • 储存更多的暗部信息
                • 左图为存在硬盘中,将捕获到的物理数据做一次gamma值约为0.4的映射,这个过程称为gamma编码
                • 由图中可以看到,此时图像要比实际物理像素更亮(图不一定是实际的情况,只是亮度提高了的直观表示)
              • gamma校正:
                • 目的
                  • 适应人眼的感光
                • 中间为显示图像时,需要为每一个像素做一次gamma值约为2.2的校正,来使的最终结果为正确的物理数据。
                • 可以看到经过gamma校正好,之前偏亮的图像亮度降低了。
        • 为什么不用线性的方式存储,而要来回转换呢?
          • 非线性转换为了优化存储空间和带宽
          • 我们用于显示图像数据都是8bit,要充分利用带宽,就需要使用更多位置去存储暗部值。也就是 暗部使用高精度保存,亮部使用相对较低精度保存。
  • 这么用
    • 不规范产生的问题
      • 亮度叠加
        •  
          • 可以看到非线性空间下亮度叠加出现了过曝(亮度>1的)的情况
          • 因为Gamma空间经过gamma编码后的亮度值相对之前会变大。
      • 颜色混合
        •  
          • 如果在混合前没有非线性的颜色进行转换,就会在纯色的边界出现一些硬边。
      • 光照计算
        •  
          • 在光照渲染结算时,如果我们把非线性空间下(视觉上的)的棕灰色0.5当做实际物理光强为0.5来计算时,就会出现左边这种情况
          • 在显示空间下是0.5,但在渲染空间下它的实际物理光强为0.18(如右图)
    • 确保线性工作流的规范
      • 在生产的各个环节,正确使用Gamma编码及解码,使最终的到的颜色数据与最开始输入的物理数据一致;如,若是使用Gamma空间的贴图,在传给着色器前需要从Gamma空间转到线性空间;
      • unity前
        • Substance Painter到unity过程
        • PS到Unity
          •  
            • PS会读取显示器的Color Profile 反向补偿回去,即不会经过显示器伽马变换;
            • PS有名为Document Color的第二个Color Profile,其默认值就是SRGB COLOR Profile,和显示器的一致,颜色因此被压暗,所以PS中看到结果和unity一样;
          • 关于PS和Unity中的混合:
            • Unity混合为线性混合;
            • PS图层间混合,则是每个上层图层经过伽马变换后,再做混合,故而会显得较暗。设置中更改,“用灰度系数混合RGB颜色”,参数为1,结果才为直接混合结果。
          • 绘制时
            • 在32位通道下完成操作(计算),最后再切换为8位通道保存
              • 目的
                • 确保trl+t缩小、柔边笔刷涂抹、高斯模糊等操作所得图片的准确性
      • unity中
        • 设置部分
        • 目前支持线性空间的平台
          • Unity硬件特性支持,主要由两个硬件特性支持:SRGB Frame Buffer,SRGB Sampler;
            • SRGB Frame Buffer:
              • 将shader计算结果输出到显示器前进行Gamma校正;
              • 作为纹理被读取时,自动把存储的颜色从sRGB空间转换到线性空间;
              • 调用ReadPixels(),ReadBackImage()时,直接返回sRGB空间下的颜色;
              • sRGB Frame Buffer仅支持每通道为8bit的格式,不支持浮点;
              • HDR开启后,会先把渲染结果绘制到浮点格式的FB中,最后绘制到sRGB FB上输出;
            • SRGB Sampler:将sRGB贴图进行线性采用转换;
              • 利用硬件特性进行sRGB贴图线性采样和shader计算结果Gamma校正,比起在shader中对贴图采样和计算结果校正要快;
        • 手动修改
          • 《Shader入门精要》
          • 利用Unity CG.cgnic中封装的函数
            • GammaToLinearSpace
              • 采样贴图时使用
            • LinearToGammaSpace
              • 最后输出
Logo

分享前沿Unity技术干货和开发经验,精彩的Unity活动和社区相关信息

更多推荐