关于Gamma

这真是让人头疼的东西,困扰我好久,至今依旧没事就让我困惑一下.最开始以为Gamma只是简单的因为当初CRT显示器还有电视等输入电压和显示亮度之间非线性关系,将这个关系的幂次叫做显示设备的Gamma.

又学习到人眼对亮度的敏感度也是非线性的,对暗色更敏感.这又导致出现了针对人眼的矫正.

然后又发现操作系统还有个Gamma值,Windows是2.2,MacOS是1.8.还有录像机,照相机等图像摄入设备也有个Gamma值,再和颜色空间等概念撮合在一起,把脑子搞得一团乱麻.某个时段觉得自己好像理清楚了,没过多久就感觉被打脸.总之,我还是没搞清楚这些乱起八糟的Gamma值都干了些什么.

但是今天我要研究是Unity,只关注人眼对亮度的非线性感知以及如何矫正这个.

所以,在同一台电脑上,用同一显示器就能对照观察出Unity的颜色空间对人眼感受到的颜色的影响.也就用不管系统Gamma还有显示器Gamma他们究竟干了啥喽.

开始测试

Linear线性颜色空间

在Unity5.6.6,PC平台,Linear线性颜色空间下,我用如下代码将面片UV坐标的U值作为颜色输出.部分代码如下:

面片的RGB值随uv坐标的u值从0到1线性变化.即这个面片从右到左亮度是线性变化的.如下:

确实不符合人眼对亮度线性变化的认知.明亮的区域明显大于暗区,而且左边最亮的区域好长一段感觉都一样是白色.面片中间也不是人眼感知上的美术中灰,美术中灰应该在更靠右的地方.

这里我管这种颜色亮度值的线性变化叫数值线性好了,方便后面描述,免得搞混.接下来我想看让数值线性的颜色输入在显示器上看更符合人眼对亮度的线性变化感知,这里管它叫视觉线性好了.不搞混.就要用到矫正了.

为了区分之前提到的那么多乱七八糟的Gamma还有gamma矫正,这里我就为了方便描述管这个将数值线性的输入变得在显示器上符合视觉线性的矫正叫视觉矫正吧.

将最终颜色的亮度进行2.2次幂的运算后再输出到显示器上,代码如下:

最终我们在显示器上看到的颜色变化如下,更符合人眼的视觉线性了呢,暗部区域边宽了.

经过视觉矫正后,我们将数值线性的数字输入和视觉线性的颜色输出对应上了.对应关系就是2.2的幂次.

Gamma颜色空间

接下来把Unity切换到Gamma空间,我们再做一次上面的测试.继续用数值线性输入作为Shader的颜色输出,即把UV坐标的u值作为颜色输出:

这次显示的颜色直接就符合视觉线性了,我还没矫正呢,你怎么就对应上了?

哦,也就是说Gamma空间下,Shader最后写在颜色缓存的颜色值,在显示到显示器上前的某个阶段自动进行了视觉矫正.灰常好,这就是Gamma颜色空间呀.那是哪个阶段呢?我也不知道...

总结1(描述事实)

●Unity的Gamma颜色空间,Shader写入到颜色缓存的值会再后面某个阶段自动进行视觉矫正,即(2.2次幂运算),然后再以亮度显示在显示器上.

●Unity的Linear颜色空间,Shader写入到颜色缓存的值,会直接以亮度显示到显示器上.

好了,热身结束了,下面再进一步的测试吧

说到编辑色彩,那就不得不提Photoshop了,美术童鞋用得最多了.我们看看Photoshop的显示有哪些小秘密.

打开PS,新建一个文档,新建一个图层,用图层样式直接拉一个颜色渐变吧,如下

简单方便,我们就在PS里做了一个黑白渐变图:

嗯,直接就符合人眼的视觉线性了,不愧是PS啊,在背后默默干了好多事情不让我们去关注那些乱七八糟的矫正,专心画画就好了.

我用ps的取色器吸一下各个区域的颜色值看看

//---------下面都是我猜的,现在发现猜错了,图片里的信息就是数值线性的. =.= ------------//

图片中间的颜色,pS的取色器告诉我就是美术中灰的128,128,128.那这里我就有个疑问了,PS那到底做没做视觉矫正?就是说保存在图片里的颜色信息作为值输入,这个值最终显示到显示器的过程中间,PS有没有进行矫正来改变这个值呢?(这一段有点绕,要捋一捋)

为了验证我的疑惑,我将这张视觉线性的图片保存成png,导入到Unity中去.我可以直接用Shader用某个值作为输出颜色来和采样的信息进行对比,这样我就知道采样到的值是不是和我猜的一样.

在Linear颜色空间下,我用Unlit/Texture这个shader直接采样刚刚的视觉线性图,并把数值线性的Shader(UV坐标的u值作为颜色输出)放在上方作对比

1,默认在勾选sRGB(Color Texture)选项时,采样的颜色是视觉线性的,如下下图:

2,不勾选sRGB(Color Texture)选项时,采样颜色是数值线性的,如下:

仔细观察还会发现,不够选sRGB选项后,采样的颜色有色阶条纹,这是进行了什么操作然后精度丢失了的现象.放大看如下

我大胆猜测,去掉sRGB出现了精度丢失,说明这种情况下会进行某种矫正导致的.也就是说Unity在Linear颜色空间下,对为勾sRGB的图片会提前进行视觉反矫正(变亮)处理,即1/2.2次幂的运算,而勾了sRGB则直接采样,所以Linear空间下,sRGB的图片是直接采样到了图片信息.

上面都是我猜的哈,如果猜得没错,那么PS就没有进行视觉矫正,因为它就是直接以非线性变化的数值来表现视觉线性的颜色变化.而不是把数值线性的输入通过视觉矫正改为视觉线性.所以PS里看到的效果,和在看图软件,Unity内直接采样显示的效果一样.(本来就没矫正嘛)

继续在Gamma颜色空间测试

Unity切换到Gamma颜色空间,我们还是把数值线性的shader放在上面作对比

用Unlit/Texture直接显示png图片的颜色.如下:

勾不勾sRGB已经不影响颜色了

上下显示眼神一致,我们在前面的测试中已经知道,Gamma空间下,Shader写入到颜色缓存中的颜色在最终显示到显示器上前会自动进行一次视觉矫正(变暗),也就是说Unlit/Texture采样到的贴图颜色和上方我们作对比的shader一样,输出都是数值线性的.所有经过一次矫正后现在都是视觉线性的了.

咦?这次怎么采样图片得到的信息又是数值线性的?刚刚我还猜图片里保存的信息是数值非线性的...这不是打我脸嘛.

别急,仔细观察2个面片的颜色,发现相比于线性颜色空间,Gamma空间显示的都有微微的色阶条纹.而下方采样贴图的色阶条纹更宽更明显,如下:

下面的色剂条纹还是很明显的,仔细看

这里我再次大胆猜测,Gamma空间下,unity会提前对图片进行一次视觉反矫正(变亮),然后在Shader里采样写入到颜色缓存后,又经过一次自动的视觉矫正(变暗).最终两次操作相抵消,显示在我们眼前的还是和图片原始信息一样,是数值非线性的,用数值非线性的方式模拟视觉线性.

但是,这样的两次运算(先视觉反矫正进行1/2.2次幂运算,再进行视觉矫正的2.2次幂运算)会由于精度问题会丢失很多的信息.所以出现了图中所示的那些色阶条纹.

总结一下:

●Unity里,Linear颜色空间下,图片默认勾选sRGB选项时,采样的是图片原始信息.

●Unity里,Linear颜色空间下,图片不勾选sRGB选项,会对图片进行视觉反矫正(变亮).

●Unity里,Gamma颜色空间下,图片默认都会先进行一次视觉反矫正(变亮),最终输出后又会做一次视觉矫正(变暗),两次操作相抵消,但是损失了很多颜色信息.(所以PBR流程会推荐使用线性颜色空间,不单单是因为效果好,估计这个也是一个因素)

●PhotoShop里,颜色显示是视觉线性的图片,保存的颜色信息是以数值非线性来体现视觉线性,这样其他软件采样图片信息然后直接显示,人眼看上去就也是视觉线性的,与PS中保存一致,还不用做多余的操作.

虽然这都是我猜的,但是我觉得很有道理的样子,欢迎大佬们批评指正.

-------------------------------------------- 分割线 -------------------------------------------

果然涉及到Gamma的东西,打脸总是来得很快,看了大佬的文章,我要捋一下自己的思路

陈嘉栋:聊聊Unity的Gamma校正以及线性工作流​zhuanlan.zhihu.com

首先显示器的Gamma是最初CRT显示器的硬件特性,输入电压和输出亮度不成正比,而是一个指数的对应关系.相当于显示器自动对颜色做了一次2.2次幂运算(变暗)后再输出.

而系统为了矫正显示器Gamma的影响,就要提前对输入信息进行了Gamma矫正(提亮),对输入数据进行了指数1/2.2次幂的运算,然后和显示器Gamma相抵消,最终显示的亮度值还是线性的.

默念三遍 :Gamma是变暗, Gamma矫正是变亮

Gamma是变暗, Gamma矫正是变亮

Gamma是变暗, Gamma矫正是变亮

但是Gamma矫正应该是分配给应用软件自己处理.比如在Gamma空间下,Unity就不会做Gamma矫正,数值线性的颜色最终会被显示器的Gamma特性处理得变暗一些,恰好就符合了人眼的视觉感知.真巧妙.不需要CPU做啥事,显示器去干了,还省了性能

(所以叫Gamma空间,意思是被显示器Gamma处理过,变暗了)

既然我猜错了,那么PS里我做的视觉线性的图,其RGB存储的二进制数据也是数值线性的喽.

这是为啥?难道是把亮度信息进行了视觉矫正(就是Gamma矫正变亮)后,再存储嘛?

这时候就要认真考虑下sRGB和AdobeRGB颜色空间了.

在我的认知里,图片如果是8位的,即RGB信息各用8位的2进制数据保存,最多就只能保存0到255的整数这些数据.一共256种灰阶.那么红绿蓝三个通道组合起来一共能表示16777216种颜色.俗话说的真彩色.

但是如过把黑色到白色的亮度均匀分成256份来存储,人眼对高亮度的好多灰阶是看不出区别的,等于这样分,254,255这两个灰人眼觉得是一样.

而在sRGB颜色空间中,各位业界大佬早就认识到人眼对亮度的非线性感知的影响.为了最大化利用存储空间,即让这256种灰阶人眼都能看出区别.对黑到白的亮度划分就不是均匀的分了.而是暗部灰阶分多一些,亮部的灰阶分少一些.即亮度和存储信息有个0.45次幂的映射.

所以sRGB颜色空间的图片里,将黑到白区间比作(0,1),我们会把0.218亮度的灰,做一个0.45次幂的计算,得到0.5.然后以以128保存在图片信息里.

AdobeRGB也是一样的,会有上面的映射.所以ps里我们做的视觉线性的图,实际亮度是非线性的,但是编码到图片里后,又变成了线性数值保存了.

那回到之前的测试,考虑显示器Gamma,还有sRGB的颜色编码的影响:

总结1:

●Unity的Gamma颜色空间,Shader写入到颜色缓存的颜色值,会被显示器Gamma影响(做了一次2.2次幂的运算,变暗).

●Unity的Linear颜色空间,Shader写入到颜色缓存的颜色值,会被unity进行一次Gamma矫正(做了一次1/2.2次幂的运算,变亮),然后与显示器Gamma抵消.最终以原始信息亮度显示.

●PS取色器吸到的颜色就是图片保存的颜色信息.

总结2:

●PS里直接显示图片的信息会被显示器Gamma影响变暗.比如图片保存的128,PS直接显示的0.5,然后被显示器Gamma影响变暗,最终得到0.218的亮度,符合美术中灰的人眼感知.

●Unity Gamma颜色空间下,图片采样得到存储的值.比如保存的128,就采样得到0.5,最终写入到颜色缓存,被显示器Gamma影响变暗,得到0.218的亮度,显示和PS一样.

●Unity Linear颜色空间下,勾选了sRGB的图片,会使用sRGB的编码采样.比如保存的128,采样得 到0.218(0.5的2.2次幂运算).写入到颜色缓存后,unity的Gamma矫正和显示器的Gamma抵消,最终还是以0.218的亮度显示(和Gamma颜色空间一样),显示和PS一样.

●Unity Linear颜色空间下,未勾选了sRGB的图片,就直接采样.比如保存的128,采样得到0.5.写入到颜色缓存后,unity的Gamma矫正和显示器的Gamma抵消,最终还是以0.5的亮度显示,比PS中的亮.

继续欢迎大佬们批评指正,非常感谢.我知道肯定又会有很多误区

unity透明通道加颜色_Unity的Gamma颜色空间和Linear颜色空间的小研究相关推荐

  1. unity透明通道加颜色_Unity SRP 6.透明

    翻译汇总文章: HipHopBoy:Unity SRP 系列翻译汇总​zhuanlan.zhihu.com 原文链接: https://catlikecoding.com/unity/tutorial ...

  2. unity透明通道加颜色_树叶透明贴图的制作原理及渲染!

    对于很多刚开始接触渲染模块的同学来说,不知道透明贴图的制作原理,以及如何渲染出好的效果,今天结合案例给大家讲解一下,先打开我们需要的素材,如下图: 在制作之前我们先给树叶一个普通的blinn材质,然后 ...

  3. unity透明通道加颜色_半透明物体的描边和投影

    起因是有人谈到HDRP更新了半透明阴影,然后想了想透明物体在NPR中还是比较常见的,至少我上次就看到有人发了个模型,就因为衣服上的丝绸部分没有加描边,导致看上去完成度很低. 透明物体有丝绸,雨衣(透明 ...

  4. unity透明通道加颜色_Unity-雪地效果的实现

    最终效果https://www.zhihu.com/video/1217959676639330304 本文使用unity实现雪地效果,主要参考了github上两个已有的demo,将其结合并并增加了一 ...

  5. 关于PNG导入Unity透明通道不显示为黑色的曲线救国方法

    有很多PS导出的PNG图片导入Unity中时,透明通道显示总是会有一些不可预知的问题,大体原因是由于编码的问题. 今日我做的图片导入Unity 中时,透明区域为白色,导致不能用于Shader,在上网查 ...

  6. unity ab包加载_Unity资源管理和打包

    Unity资源读取: RM: Resources.Load Addressables: Addressables.LoadAssetAsync AssetBundle:AssetBundle.Load ...

  7. Unity内置管线升级URP之色彩空间(伽马、sRGB、Gamma Space和Linear Space)

    目录 本文内容 伽马(Gamma) sRGB 色彩空间(Color Space) 总结 转色彩空间后出现问题的缘由 1.相同场景材质和光照为什么变暗了? 2.个人定制化的PBR显示不正确了?(讨论的是 ...

  8. unity 手机端和编辑器下播放带有透明通道的视频详解

    unity 手机端和编辑器下播放带有透明通道的视频详解 在项目开发中,可能会涉及到视频的播放,普通的视频播放如果大家不会的请自行百度,今天主要讲解带有透明通道的视频的播放问题,尤其是在手机端的处理,下 ...

  9. c语言给bmp图片加滤镜,关于BMP位图透明通道的详解制作教程, 教你输出透明的BMP位图...

    我是sjmhiex啊月谢谢大家的支持  百度贴吧:sjmhiex吧 QQ群:243153684 BMP支持透明比较常见的方法有两种: 一种是32位图,直接就可以是透明的,还可以是半透明效果,一般都是用 ...

  10. unity中RenderTexture显示图片中如何带透明通道

    这里准备了两个相机,一个用于显示ui界面,一个用于显示需要使用rt的相机,如下: 我们将Canvas模式改为camera给到UICamera,设置culling mask为ui: 接下来,在model ...

最新文章

  1. Python入门系列之字符编码
  2. vs2005格式化代码
  3. java图书凭租_如何通过java一步实现租书系统
  4. 最全的jquery datatables api 使用详解
  5. 如何在一个html页面中提交两个post,如何在同一个页面上从Django和Ajax获得多个post请求?...
  6. 20190913:(leetcode习题)罗马数字转整数
  7. CATIA怎么约束快捷键_3ds Max 常用快捷键大全,你学会了吗
  8. 【Tensorflow】相关面试题整理(转)
  9. Exchange 2013 OU大于500新建用户无法查询OU
  10. redis之数据操作详解
  11. eclipse中文语言包 离线安装
  12. 高等数学张宇18讲 第九讲 积分等式与积分不等式
  13. Linux文件其他操作
  14. 一场跨越时空的协奏:编钟、古琴与5G的“弦外之音”
  15. 33 - Guarded Suspension模式 等待唤醒机制的规范
  16. (寒假开黑gym)2018 ACM-ICPC, Syrian Collegiate Programming Contest(爽题)
  17. Android自定义按钮样式
  18. 微信中打开外部浏览器下载安装包
  19. 【软件工程1916|W(福州大学)_助教博客】团队第四次作业(第7次)成绩公示...
  20. ESP8266-Arduino编程实例-MAG3110磁力计驱动

热门文章

  1. STM32学习记录0003——STM32芯片解读
  2. burpsuite工具抓取Https数据包
  3. 计算机一级常用计算公式,全国计算机一级考试题库
  4. 数字全息实验-实例演示
  5. 一个喜爱电影的人能利用什么工具?
  6. 手把手教你使用人人开源
  7. java实现PNG图片任意角度旋转
  8. 51单片机循迹小车c语言程序,51单片机循迹小车源程序
  9. 高等数学习题全解指南下册同济第七版课后习题答案
  10. python约瑟夫环单向循环链表_约瑟夫环_约瑟夫环单向循环链表_约瑟夫环c语言循环链式...