srgb的伽马值_srgb模式和标准模式

srgb的伽马值_srgb模式和标准模式sRGB标准人眼对亮度的感知不是线性的,其对较暗区域的变化更加敏感参见:ComputerColorisBroken基于人眼该特点,sRGB标准要求图像(各通道为8bits,最多存储256个亮度值)使用编码伽马,把更多地空间用来存储更多暗部区域,来最大化地利用表示亮度的数据位或带宽伽马校正(Gammacorrection)在早期,阴极射线管(CRT)显示器是唯一的电子显示设备,但它的输入电压和显示出来的亮度关系不是线性的,而是一个类似幂律(pow-law)曲线的关系,…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

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模式和标准模式

对渲染的意义

渲染中用到的光照都是在线性空间的。所以所有的计算都需要转换到线性空间计算

下面时参考文章:

sRGB标准与伽马校正

sRGB标准

人眼对亮度的感知不是线性的,其对较暗区域的变化更加敏感   参见:Computer Color is Broken

基于人眼该特点,sRGB标准要求图像(各通道为8bits,最多存储256个亮度值)使用编码伽马,把更多地空间用来存储更多暗部区域,来最大化地利用表示亮度的数据位或带宽

srgb的伽马值_srgb模式和标准模式

伽马校正Gamma correction

在早期,阴极射线管(CRT)显示器是唯一的电子显示设备,但它的输入电压和显示出来的亮度关系不是线性的,而是一个类似幂律(pow-law)曲线的关系,使得信号被压暗

巧合地是,sRGB标准的编码伽马是一个将图像变亮的幂率曲线,正好与其形成互补,使得不需要再做调整就可以让sRGB图像在CRT上显示出与现实场景一致的亮度

后来出现的LCD和等离子显示器,为了保证兼容,在硬件上也都选择了和当年CRT一样的非线性特性

类似于sRGB标准的编码伽马(encoding Gamma),由于能校正CRT的显示伽马(display Gamma,标准值 γ = 2.2),因此又被称为伽马校正(Gamma correction)

srgb的伽马值_srgb模式和标准模式

srgb的伽马值_srgb模式和标准模式

 

srgb的伽马值_srgb模式和标准模式

对渲染的意义

渲染中用到的光照都是在线性空间的。因为在设计光照的时候都是认为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空间中进行着色计算,会造成了渲染出来的游戏总是暗沉沉的(如下右图所示),和真实世界不像

srgb的伽马值_srgb模式和标准模式

srgb的伽马值_srgb模式和标准模式

参考

klayge:gamma的传说

candycat1992:【图形学】我理解的伽马校正(Gamma Correction)

Unity:LinearRendering-LinearOrGammaWorkflow 

Gamma Correction and Why It Matters

learnopengl:Gamma Correction

(1条消息) 【图形学】我理解的伽马校正(Gamma Correction)_candycat-CSDN博客_gamma校正

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/193178.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(1)


相关推荐

  • JAVA爬电信_基于JAVA的电信基站接口调用代码实例

    JAVA爬电信_基于JAVA的电信基站接口调用代码实例代码描述:基于JAVA的电信基站接口调用代码实例关联数据:电信基站接口地址:http://www.juhe.cn/docs/api/id/161.[代码][Java]代码importjava.io.BufferedReader;importjava.io.DataOutputStream;importjava.io.IOException;importjava.io.InputStream…

    2022年10月27日
  • mapminmax 用法

    mapminmax 用法mapminmax是MATLAB实现归一化的工具包,默认:(1)将矩阵的每行分别进行归一化;(2)每行的最大值最小值作为每行归一化的xmin和xmax;(3)将数据归一化到[-1,1].若要将数据归一化到0到1之间,即y∈[0,1],使用b=mapminmax(a,0,1);若给与确定的最大值和最小值作为每行的xmin和xmax,使用:b= mapminmax(a,0,1);PS.xmin…

  • DELPHI XE5开发WEB服务器及安卓手机客户端[通俗易懂]

    DELPHI XE5开发WEB服务器及安卓手机客户端[通俗易懂]Xe5开发web服务端和手机客户端时间:2013-9-1817:09:45点击: 6456Delphixe5作为最新开发利器,就类似如当年的DELPHI,功能强大,快发速度快,把VS2012远远甩在后面。下面以一个小例作为您开启新的历程: 建立一个webservices stand-alonevclapplication作为手机访问的服务端1、new-

  • 没有人不为真情所动,你若不流泪,我请你吃饭。[通俗易懂]

    没有人不为真情所动,你若不流泪,我请你吃饭。[通俗易懂]我是哭了好几场啊,难道我神经脆弱?告诉我你哭了几场,我脸都洗不过来啊。不是我不懂爱情,没有爱心,不相信真情,确是这世界忙碌得很,谁与我共行?科学探索:英国一位农夫在自家花园内发现了三只瑟瑟发抖的小狐狸,于是给了它们一个毛绒玩具。没想到小家伙们把它当做了自己的妈妈,不但和它形影不离,吃饭的时候还会留下部分食物,把盆子推到它跟前好友爱的一幕!给饿了的小北极熊食物。在蛮荒之地,气候恶劣。食物不足时,白熊…

  • 串口助手(简洁版)上位机软件零基础教程( C# + visual studio2017 )(二)

    串口助手(简洁版)上位机软件零基础教程( C# + visual studio2017 )(二)在上篇博客中,我们完成了串口助手(简洁版)可视化窗体的设计,并且单击启动后可以运行。但是光有外壳,没有灵魂。所以接下来我们将继续一步一步来编写上位机软件的程序部分。首先,我谈一下自己所理解的C#上位机软件程序编写的中心思想。以串口助手(简洁版)为例,所有程序都是以“事件”为核心来进行的,对应的“事件”发生了,那软件就去执行我们自己编写的对应…

  • mysql innodb的事业隔离级别_sqlserver事务隔离级别

    mysql innodb的事业隔离级别_sqlserver事务隔离级别在Mysql中,事务主要有四种隔离级别,今天我们主要是通过示例来比较下,四种隔离级别实际在应用中,会出现什么样的对应现象。Readuncommitted(未提交读)Readcommitted(已提交读)Repeatableread(可重复读)Serializable(可串行化)在理解四种隔离级别之前,我们需要先了解另外三个名词:脏读不可重复读幻读脏读A事务,会读取到B事务还未提交的数…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号