Gamma传说
来源:互联网 发布:四国集团知乎 编辑:程序博客网 时间:2024/04/27 14:22
Gamma校正对于图形和图像来说是个常提的概念,但对于gamma的缘由和使用方法,却存在着很多传说。本文将尽可能解析gamma校正来源,破解各种迷思。
Gamma校正从何而来
有一种常见的说法,gamma来源于眼睛对光感受。我也曾经错误地采用了这种说法。在wikipedia上查到了gamma的真正来源:
所以,gamma校正和人眼特性无关,仅仅和CRT有关。更新的显示方法,比如LCD和等离子之类,为了保证兼容,也都选择了和当年CRT一样的非线性特性。(其实和系统有关,Mac OS X 10.6就用的1.8,其他系统,包括电视,都用的2.2)
Gamma计算很简单,只是个power而已,也就是:
其中的γ就是用来校正的gamma值。
输入和输出
现在让我们来看看一个输入输出的例子。假设相机是线性的,显示器也是线性的,那么输入和输出的关系就是:
也就是通过相机拍照后,在显示器上看到的和真实场景的色彩一样。
可惜,现实是残酷的,显示器的gamma为2.2,所以如果相机仍然是线性的,那么结果就会变成:
这样在显示器上看到的就会有明显的色彩失真。解决方法是把相机的gamma设成1/2.2,这样两次调整之后又能得到真实场景的色彩了:
其实从这个过程也可以看出,gamma校正是为了在输入和输出的环节中保证能和真实场景一致,而眼睛不在这个环节中,所以和眼睛对亮度的感受没有直接关系了。
对渲染的意义
前面讲的输入是对相机拍的照片而言。而对渲染来说,情况又如何呢?渲染中用到的光照都是在线性空间的。因为在设计光照的时候都是认为1的亮度是0.5的2倍。光照如此,texture又如何呢?渲染中用到的 texture一般有两个来源,一个是照片,一个是artist手工画的。前文提到了,照片是gamma = 1/2.2的。一般图象处理软件也都是在gamma空间工作的,所以artist画的图一般也可以认为是gamma = 1/2.2的。所以,我们在pixel shader常可以见到这样的代码:
2
return diff * max(0, dot(light_dir, normal));
这样的代码对吗?不对也对。
说其不对,是因为这里没显式地做gamma校正。做校正的话应该是这样的:
2
return pow(diff * max(0, dot(light_dir, normal)), 1 / 2.2f);
也就是说,gamma校正的过程就是把输入的texture都转换到线性空间,并把输出的调整到gamma = 1/2.2的空间。
说其对,是因为如果diffuse texture如果是sRGB格式的,那么再读取的时候硬件会把它自动转到线性空间。如果render target的texture也是sRGB格式的,在输出的时候硬件也会把它自动转到线性空间。所以,如果输入和输出纹理都是sRGB,那么原先那段shader就是正确的。对于不支持sRGB的老硬件,就必须自己做pow了。
除了渲染,另一个需要注意gamma的地方就是mipmap。如果原texture是gamma =1/2.2的,那么在建立mipmap chain的时候,每一层都必须和渲染一样,先转到线性空间,计算之后再转到gamma = 1/2.2的。否则,255和0混合得到的是51,而不是128。
总结
总之,计算都要发生在线性空间,所以输入和输出需要进行gamma校正。最佳选择是采用sRGB格式,这样pow是硬件内自动实现,速度更快,代码也简单。鉴于目前很多texture的数据是gamma = 1/2.2的,而纹理格式却被错误地标记成没有sRGB的,所以需要修改它们的格式标记,并重新建立mipmap。
- Gamma传说
- gamma的传说(转自KlayGE Engine)
- gamma
- gamma
- Gamma
- gamma
- 传说
- 传说
- 传说
- 传说
- 传说
- 理解 Gamma
- gamma校正
- Gamma校正
- Gamma 校正
- Gamma曲线
- Gamma 介绍
- 理解 Gamma
- 几种TCP连接中出现RST的情况
- Leetcode---Remove Duplicates from Sorted List
- HDU 5475 An easy problem 2015ICPC 上海网络赛
- C语言中的printf和scanf函数说明
- 精选30道Java笔试题
- Gamma传说
- Android——DDMS简单介绍
- 初窥VIsual Studio2015的跨移动平台开发
- JAVA基础学习(十八)--常用 工具类
- 如何在windows7上的dos界面登录mysql(1)
- 写测试用例的经验总结
- Ubuntu 安装mysql和简单操作
- 数组和指针的长度
- 安装spark on yarn error