sRGB标准与伽马校正 理解

article/2025/7/27 18:31:32

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校正


http://chatgpt.dhexx.cn/article/OEP8GeIJ.shtml

相关文章

伽马校正和颜色空间

一、伽马校正 所谓gamma校正,实际上是一个颜色的非线性变换。下面来解释这个变换曲线存在的原因。 1.1 人眼的非线性视觉效应 为什么要有gamma校正了。一言以蔽之,人眼的生理效应。如下图所示, 第一行是人眼感受到的线性亮度变化&#xf…

伽马校正探究

关于伽马校正的前因后果,在网上有不同版本的说法,由于年代久远的因素,导致原本很简单的事情越说越复杂。今天我们的目标就是抓住伽马的头,而不是摸一下伽马的尾巴。 一,鱼龙混杂的论调 1,CRT 显示器的物理…

图像的伽马校正

图像的伽马校正 图像的伽马校正属于图像增强中幂次增强&#xff0c; γ>1时&#xff0c;使图像变暗&#xff0c;即图像变黑&#xff1b; γ<1时&#xff0c;使图像变亮&#xff0c;即图像变白。 下面是伽马校正的过程&#xff1a; 1&#xff09;将像素值为【0,255】如2…

伽马校正笔记(Gamma Correction)

在数字图像系统中&#xff0c;伽马&#xff08;Gamma&#xff09;是一个重要的但很少被正确理解的特性。它定义了一个像素的数值和对应的实际亮度之间的关系。 人眼感知的亮度和相机“看到”的亮度区别 对于数码相机来说&#xff0c;当检测的光子数增加一倍时&#xff0c;sens…

伽马校正-

伽马校正 问题描述&#xff1a;读取图像&#xff0c;然后对图像进行伽玛校正。 伽马校正 这里是一篇写伽马校正比较好的文章&#xff0c;我觉得可以作为背景知识补充。 伽马校正用来对照相机等电子设备传感器的非线性光电转换特性进行校正。如果图像原样显示在显示器等上&…

图形 2.6 伽马校正

一、Gamma校正 1、颜色空间 图中可以看到&#xff0c;sRGB和Rec.709的色域虚线一样&#xff0c;三原色的位置是相同的&#xff0c;那么它们之间的区别就是&#xff1a;传递函数不同 2.传递函数 定义 知道了颜色的颜色值之后&#xff0c;想要在电子设备上显示&#xff0c;就…

伽马校正(Gamma Correction)与sRGB

文章目录 CRT显示器与人眼视觉非线性显示与渲染伽马校正sRGB 纹理正确的点光衰减补充参考资料 CRT显示器与人眼视觉 过去, 大多数监视器是阴极射线管显示器(CRT). 这些监视器有一个物理特性就是两倍的输入电压产生的不是两倍的亮度. 输入电压产生约为输入电压的 2.2 次幂的亮度…

图形学基础——伽马校正

百人计划学习视频连接&#xff1a;【技术美术百人计划】图形 2.6 伽马校正 颜色空间 具体内容在之前的文章有讲&#xff1a;色彩空间介绍 sRGB&#xff1a;微软在1996年发布的通用颜色标准DCI-P3&#xff1a;数字电影播放的颜色标准Rec-709、PAL&#xff1a;电视行业的颜色标…

伽马校正

注&#xff1a;本文为博主参考书籍和他人文章并加上自己的理解所编&#xff0c;作为学习笔记使用并将其分享出去供大家学习。若涉及到引用您的文章内容请评论区告知&#xff01;如有错误欢迎指正&#xff01; 一、伽马校正简介 射伽马校正是图像预处理阶段经常使用的一个非…

可执行文件的装载,进程和线程,运行时库的入口函数(第六章)

目录 第1步.创建一个独立的虚拟内存空间 第2步.读取可执行文件头&#xff0c;建立虚拟空间和可执行文件之间的映射关系 第3步.将cpu的指令寄存器设置成可执行文件的入口地址&#xff0c;启动运行。 程序开始执行&#xff0c;发生页错误。 随着程序的执行&#xff0c;不停…

疯狂python讲义学习笔记——前十章完结

#第一章&#xff1a;绪论 #单行注释多行注释""" 多行注释 """#dir列出指定类或模块的属性与方法&#xff0c;help查看某个函数或方法的帮助文档 print(dir(str)) print(help(str.title))#第二章&#xff1a;数据类型 a5 print(type(a))#<clas…

嵌入式代码学习心得记录

一、C语言学习心得记录 函数递归 编写顺序 终结条件输入下一级递归参数,调用下一级递归函数.当前递归函数的操作代码,在下一级递归函数执行完成后执行的操作代码. #include <stdio.h> #include <string.h>void revert(char *s, int len) {// 终结条件if(len <…

python 字节流分段_一文掌握CTF中Python全部考点

声明&#xff1a;Tide安全团队原创文章&#xff0c;转载请声明出处&#xff01;文中所涉及的技术、思路和工具仅供以安全为目的的学习交流使用&#xff0c;任何人不得将其用于非法用途以及盈利等目的&#xff0c;否则后果自行承担&#xff01; 前 言 一次偶然的机会&#xff0c…

Python课程学习笔记 下

笔记目录 Python 学习笔记 上面向对象和异常面向对象基本理论定义类根据类实例化对象属性相关方法相关类的补充属性补充方法相关补充描述器python对象的生命周期内存管理机制面向对象的三大特性面向对象应当遵循的原则 错误和异常错误和异常的概念常见的系统异常和系统异常类继…

从点击APP图标到首页展示的加载过程

转载链接在这里 iOS 系统架构 Mac系统是基于Unix内核的图形化操作系统&#xff0c;Mac OS 和 iOS 系统架构的对比分析发现&#xff0c;Mac OS和iOS的系统架构层次只有最上面一层不同&#xff0c;Mac是Cocoa框架&#xff0c;而iOS是Cocoa Touch框架&#xff0c;其余的架构层次都…

python os模块

10.3 os模块 os就是“operating system”的缩写&#xff0c;顾名思义&#xff0c;os模块提供的就是各种 Python 程序与操作系统进行交互的接口。通过使用os模块&#xff0c;一方面可以方便地与操作系统进行交互&#xff0c;另一方面页可以极大增强代码的可移植性。如果该模块中…

Python:异常处理,模块和包,正则表达式

1&#xff0c;异常处理机制 Python的异常处理机制可以让程序具有极好的容错性&#xff0c;让程序更加健壮。当程序运行出现意外情况时&#xff0c;系统会自动生成一个Error对象来通知程序&#xff0c;从而实现将“业务实现代码”和“错误处理代码”分离&#xff0c;提供更好的可…

操作系统面试题总结

进程的常见状态&#xff1f;以及各种状态之间的转换条件? 创建状态&#xff1a;进程在创建时需要申请一个空白PCB&#xff0c;向其中填写控制和管理进程的信息&#xff0c;完成资源分配。如果创建工作无法完成&#xff0c;比如资源无法满足&#xff0c;就无法被调度运行&#…

Python--多线程与并行

一、线程和进程介绍 1.1、进程基本概念 进程&#xff08;Process&#xff09;&#xff0c;是计算机中已运行程序的实体&#xff0c;曾经是分时系统的基本运作单位。在面向进程设计的系统&#xff08;如早期的Unix、Linux2.4及更早的版本&#xff09;中&#xff0c;进程是程序…

【Python学习】--pythonf笔记

系列文章目录 文章目录 系列文章目录前言一、Python代码规范&#xff08;编码、代码格式&#xff09;1. 编码2. 代码格式3. import 语句4. 空格 二、Python代码注释&#xff08;块注释、行注释、文档注释&#xff09;1. 块注释2. 行注释3. 建议4. 文档注释 三、Python命名规范&…