• Gamma矫正的原理和实现


    计算机目前由R、G、B三个维度来表示颜色,每个颜色可以由8个比特共256个灰度来描述,那么一共可以描述256256256=16777216种颜色。
    过去大多数显示器都是阴极射线管显示器(CRT),这些显示器输出的亮度和存储的颜色值并不是线性的关系,因此在最终由显示器输出颜色的时候,其实会对颜色做一个gamma值的转换:
    brightness = pow(color, gamma)
    这个gamma值一般是2.2。
    巧的是,这个转换刚好和人眼对光强的感知是一致的,如下图所示:

    可以看到,当颜色值从0.1到0.2的时候,人眼感知到的亮度增加会更暗一些,这是因为人类的眼睛对比较暗的颜色变化更敏感。
    如果是日常的显示图片,显示器的这种处理其实是没有问题的(因为它和人眼的感知是一致的)。但是在渲染的时候,我们一般假设所显示的亮度是和颜色值是线性关系(Gamma为1),因此我们在屏幕中看到的图像实际上并不是理想的图像。需要在最终输出像素颜色的时候处理一下:
    brightness = pow(color, 1/gamma)
    我们可以参照下图来理解:

    假设我们想表达暗红色,那么如果我们直接输出颜色值0.5,那么最终所看到的亮度值其实只是0.5^2.2 = 0.218。想真正地让用户在屏幕中看到0.5的红色,需要(0.5(1/2.2))2.2=0.5。这样才能真正输出我们想要表达的亮度。这就是所谓的Gamma矫正。
    我们将显示器Gamma处理过后的颜色空间称为sRGB空间。
    另外需要注意的是,在程序中载入贴图的时候,因为艺术家在创作贴图的时候其实是在sRGB空间中创作的,因此在使用图片时,需要将采样出的颜色做一遍反gamma矫正(也就是pow(color, gamma)),才可以用于计算和显示。
    举个例子,在艺术家创作图片的时候,他想表达0.5的红色,因为是在sRGB空间中创作的,因此实际存到图片中的颜色值为0.5^(1/gamma)。 所以在采样该图片时,我们必须重新做一遍(0.5^(1/gamma * gamma)), 才能得到真正艺术家想要表达的0.5的值,用于线性的颜色计算。这样才能真正保证计算的颜色不出偏差。

    最后我用做了一下gamma矫正的试验,下图是不做gamma矫正和做gamma矫正的对比图,可以看到明显右图更亮了一些:

  • 相关阅读:
    【NodeJS】---express配置ejs mongoose route等
    【CSS3】---层模型position之fixed固定定位、absolute绝对定位和relative相对定位
    【CSS3】---:before :after生成内容
    px转rem的填坑之路
    markdown编写文件目录结构
    js reduce数组转对象
    处理Promise.reject()
    js事件循环
    为什么[] == false 为true
    为什么不建议用var
  • 原文地址:https://www.cnblogs.com/wickedpriest/p/12389127.html
Copyright © 2020-2023  润新知