sRGB标准与伽马校正 理解
srgb : 颜色值会以非线性的方式存储
如一个颜色值在线性空间中,rgb=(1,1,1),
在gamma空间中,rgb会变为(1的2.2幂次,1的2.2幂次,1的2.2幂次),颜色值会发生改变,这样方便在显示器中显示的时候,正确显示(因为在显示器中显示时,会使得图像变暗)
如果一个图片的颜色格式为srgb,则说明这张图片存储的颜色值是encode gamma之后的颜色值
在unity中设置为gamma空间时,图片颜色值会在导入时变成非线性的颜色值
srgb标准是图片颜色值固定按照2.2分之一(0.45)次幂的颜色变化
所有显示器硬件在进行颜色值的转换时固定按照2.2次幂来对颜色值进行转换
对渲染的意义
渲染中用到的光照都是在线性空间的。所以所有的计算都需要转换到线性空间计算
下面时参考文章:
sRGB标准与伽马校正
sRGB标准
人眼对亮度的感知不是线性的,其对较暗区域的变化更加敏感 参见:Computer Color is Broken
基于人眼该特点,sRGB标准要求图像(各通道为8bits,最多存储256个亮度值)使用编码伽马,把更多地空间用来存储更多暗部区域,来最大化地利用表示亮度的数据位或带宽
伽马校正(Gamma correction)
在早期,阴极射线管(CRT)显示器是唯一的电子显示设备,但它的输入电压和显示出来的亮度关系不是线性的,而是一个类似幂律(pow-law)曲线的关系,使得信号被压暗
巧合地是,sRGB标准的编码伽马是一个将图像变亮的幂率曲线,正好与其形成互补,使得不需要再做调整就可以让sRGB图像在CRT上显示出与现实场景一致的亮度
后来出现的LCD和等离子显示器,为了保证兼容,在硬件上也都选择了和当年CRT一样的非线性特性
类似于sRGB标准的编码伽马(encoding Gamma),由于能校正CRT的显示伽马(display Gamma,标准值 γ = 2.2),因此又被称为伽马校正(Gamma correction)
对渲染的意义
渲染中用到的光照都是在线性空间的。因为在设计光照的时候都是认为1的亮度是0.5的2倍
光照如此,texture又如何呢?渲染中用到的 texture一般有两个来源,一个是照片,一个是artist手工画的
前文提到了,照片是gamma = 1/2.2的。一般图象处理软件也都是在gamma空间工作的,所以artist画的图一般也可以认为是gamma = 1/2.2的
所以,我们在pixel shader常可以见到这样的代码:
float4 diff = tex2D(diffuse_texture, uv); return diff * max(0, dot(light_dir, normal));
这样的代码对吗?不对也对。
说其不对,是因为这里没显式地做gamma校正。做校正的话应该是这样的:
float4 diff = pow(tex2D(diffuse_texture, uv), 2.2f); // 对输入的纹理进行display gamma,转到线性空间 return pow(diff * max(0, dot(light_dir, normal)), 1 / 2.2f); // 对输出进行encoding gamma,再次转回gamma = 1/2.2空间
也就是说,gamma校正的过程就是把输入的texture都转换到线性空间,并把输出的调整到gamma = 1/2.2的空间
说其对,是因为如果diffuse texture如果是sRGB格式的,那么再读取的时候硬件会把它自动转到线性空间
glTexImage2D(GL_TEXTURE_2D, 0, GL_SRGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image);
如果render target的texture也是sRGB格式的,在输出的时候硬件也会把它自动转到gamma = 1/2.2空间
glEnable(GL_FRAMEBUFFER_SRGB);
所以,如果输入和输出纹理都是sRGB,那么原先那段shader就是正确的。对于不支持sRGB的老硬件,就必须自己做pow了
除了渲染,另一个需要注意gamma的地方就是mipmap。如果原texture是gamma = 1/2.2空间的,那么在建立mipmap chain的时候,需要将原texture先转到线性空间,来计算各级mipmap;完成计算后,再将各级mipmap转到gamma = 1/2.2空间
另外,gamma变换只作用于RGB通道,Alpha透明度则不受影响
对于normal texture、mask texture等存放的不是颜色信息,这类texture不应勾选为sRGB
总之,计算都要发生在线性空间,所以输入的纹理要先进行display gamma。如果输出的render target是sRGB格式,输出时要进行encoding gamma
输出时encoding gamma,会导致写入color buffer的颜色是非线性的,这样混合就发生在非线性空间中。解决方法是,在中间计算时不要对输出进行encoding gamma,在最后进行一个屏幕后处理操作对最后的输出进行encoding gamma
最佳选择是采用sRGB格式,这样pow是硬件内自动实现,速度更快,代码也简单。鉴于目前很多texture的数据是gamma = 1/2.2的,而纹理格式却被错误地标记成没有sRGB的,所以需要修改它们的格式标记,并重新建立mipmap
如果在gamma空间中进行着色计算,会造成了渲染出来的游戏总是暗沉沉的(如下右图所示),和真实世界不像
参考
klayge:gamma的传说
candycat1992:【图形学】我理解的伽马校正(Gamma Correction)
Unity:LinearRendering-LinearOrGammaWorkflow
Gamma Correction and Why It Matters
learnopengl:Gamma Correction
(1条消息) 【图形学】我理解的伽马校正(Gamma Correction)_candycat-CSDN博客_gamma校正
sRGB标准与伽马校正 理解相关推荐
- 我理解的伽马校正(Gamma Correction)
[图形学]我理解的伽马校正(Gamma Correction) 2015年05月30日 18:22:52 妈妈说女孩子要自立自强 阅读数:69844 版权声明:本文为博主原创文章,未经博主允许不得转载 ...
- 伽马校正笔记(Gamma Correction)
在数字图像系统中,伽马(Gamma)是一个重要的但很少被正确理解的特性.它定义了一个像素的数值和对应的实际亮度之间的关系. 人眼感知的亮度和相机"看到"的亮度区别 对于数码相机来说 ...
- 有生之年转ta系列 2.6 伽马校正
本文内容来自 [技术美术百人计划]图形 2.6 伽马校正 观后记录 美术岗位代码或者算法一类的问题可能不太懂 本文仅用来记录学习,如果有不对的请指出谢谢 图形部分 第二章 伽马校正 颜色空间 色度图 ...
- 伽马校正(gamma correction)学习笔记
学习HDR和Bloom特效的过程中,接触到了伽马矫正的问题.查阅了不少资料,这一篇讲的最清楚,下面的图片也是来自该文章. 这应该说是一个历史遗留问题,以前的CRT显示器是使用电子显像管,通过控制电流大 ...
- OpenGL学习脚印:伽马校正(Gamma Correction)
写在前面 由于CRT,LED等显示设备显示颜色时并非按照线性方式工作,因此我们在程序中输出的颜色,最终输出到显示器上时会产生亮度减弱的现象,这种现象在计算光照和实时渲染时对图形质量有一定影响,需要我们 ...
- OpenCV论道:为什么我的伽马校正函数只有一行?
最近在用 OpenCV 识别棋盘棋子,基本的思路是这样的:先转灰度,再做高斯模糊和二值化,此时棋盘格上有的有棋子,有的无棋子:通过迭代腐蚀,消去棋子,再迭代膨胀回来,就得到了一个纯净的棋盘:识别棋盘, ...
- (二十)unity shader之——————基于物理的渲染技术(PBS):下篇(PBS技术拓展:全局光照、伽马校正、HDR)
前面两篇文章我们介绍了PBS实现的数学和理论基础,和standard shader的原理和实现,还有一些其他的渲染相关的unity技术.其中有些概念和技术没有讲的很详细,现在对这些重要的概念进行更深入 ...
- 图像亮度、对比度调节(伽马校正)
[OpenCV学习]图像亮度.对比度调节(伽马校正) 作者:gnuhpc 出处:http://www.cnblogs.com/gnuhpc/ #include "cv.h" #i ...
- OpenGL Gamma Correction伽马校正的实例
OpenGL Gamma Correction伽马校正 先上图,再解答. 完整主要的源代码 源代码剖析 先上图,再解答. 完整主要的源代码 #include <glad/glad.h> # ...
- matlab批量读取图像图片并批量处理图像(以伽马校正为例)以及批量保存图像
文章目录 处理1张图片,获取4幅不同伽马校正图像 批量读取图片模板 批量处理多张图片,分别获取4幅伽马校正图像 参考 处理1张图片,获取4幅不同伽马校正图像 实验结果 实验代码 get_4_pictu ...
最新文章
- 3 ADO.NET跟踪日志
- 为什么 HTTPS 是安全的?
- python回归方程系数计算_线性回归中的正规方程将θ系数返回为“NaN”
- 06 矩阵计算【动手学深度学习v2】
- centos java 乱码_CentOS 7.4 java验证码乱码的问题
- 继承redis spring_Spring 极速集成注解 Redis 实践
- python画折线图虚线_python绘制简单折线图代码示例
- jQuery插件之ajaxFileUpload异步上传
- 数控加工中心编程和UG编程和什么区别
- C语言程序设计(第三版)何钦铭著 习题4-11
- 取消u盘写保护 u盘量产教程(无数尝试后的终极解决办法)
- 微信小程序 满意度调查问卷
- Excel多行转置为一列
- arcgis快速生成图框_arcgis图框的制作
- python软著申请_软著申请注意事项放心选择
- Linux系统日志管理
- Web中常用字体介绍
- 多箭齐发稳增长 地方两会圈定2022年经济重点
- android的spinner字体控制
- ARM外设 cortex-a8