相信大部分了解图形学的人,都听说过Gamma校正或者Gamma空间,线性空间这些词。这里不对Gamma Space形成的历史原因做过多描述。Gamma和Linear空间的一些原理,文章也很多,包括Unity官网的描述,都可以看看。

显示器显示的Gamma空间的颜色变化规律,对应了下图中的黄色曲线。当美术在Gamma空间中,RGB(255,255,255)的颜色单位上,增加了1的颜色亮度,最后输出显示的亮度,其实是低于1的。这个差距,在特别暗的地方更加明显,也就容易让场景因为太暗,而看不清细节。我们公司的美术也表示,线性空间的效果其实更加直观,而Gamma空间的颜色有可能会越叠越深。所以为了更好的美术效果,尤其是让贴图的阴暗处有更多的细节,将Gamma Space转换为Linear Space还是相当有必要的。

基本思路,一般来说就是通过pow(1/Gamma)将颜色强度提高。下图中的蓝色曲线是pow(1/2.2)的近似数,pow(0.45),这样就可以抵消掉黄色曲线的变化,使颜色变化可以趋于线性。

三种函数的曲线

Infinite 3D Head Scan by Lee Perry-Smith,licensed under a Creative Commons Attribution 3.0 Unported License(available from www.ir-ltd.net)

虽然Unity 5.5开始,已经提供转换工程为线性空间的功能,但是仅对OpenGLES 3.0及以上的设备进行支持。详细数据可以参考这篇Unity的Blog,可以看到,还有两成左右的设备是不具备这个条件的。所以如果项目组需要考虑低端机,尤其是考虑海外发行的话,就不能直接改变整个渲染空间。

因此替代的方法,是手动在Shader中,修改Colour Space。转换空间用到的相关函数,Unity其实已经在Unity CG.cgnic中提供了,可以直接使用。

函数如下:

  1. inline float GammaToLinearSpaceExact (float value)
  2. {
  3. if (value <= 0.04045F)
  4. return value / 12.92F;
  5. else if (value < 1.0F)
  6. return pow((value + 0.055F)/1.055F, 2.4F);
  7. else
  8. return pow(value, 2.2F);
  9. }
  10. inline half3 GammaToLinearSpace (half3 sRGB)
  11. {
  12. // Approximate version from http://chilliant.blogspot.com.au/2012/08/srgb-approximations-for-hlsl.html?m=1
  13. return sRGB * (sRGB * (sRGB * 0.305306011h + 0.682171111h) + 0.012522878h);
  14. // Precise version, useful for debugging.
  15. //return half3(GammaToLinearSpaceExact(sRGB.r), GammaToLinearSpaceExact(sRGB.g), GammaToLinearSpaceExact(sRGB.b));
  16. }

复制代码

  1. inline float LinearToGammaSpaceExact (float value)
  2. {
  3. if (value <= 0.0F)
  4. return 0.0F;
  5. else if (value <= 0.0031308F)
  6. return 12.92F * value;
  7. else if (value < 1.0F)
  8. return 1.055F * pow(value, 0.4166667F) - 0.055F;
  9. else
  10. return pow(value, 0.45454545F);
  11. }
  12. inline half3 LinearToGammaSpace (half3 linRGB)
  13. {
  14. linRGB = max(linRGB, half3(0.h, 0.h, 0.h));
  15. // An almost-perfect approximation from http://chilliant.blogspot.com.au/2012/08/srgb-approximations-for-hlsl.html?m=1
  16. return max(1.055h * pow(linRGB, 0.416666667h) - 0.055h, 0.h);
  17. // Exact version, useful for debugging.
  18. //return half3(LinearToGammaSpaceExact(linRGB.r), LinearToGammaSpaceExact(linRGB.g), LinearToGammaSpaceExact(linRGB.b))
  19. }

复制代码

其中主要用到的是GammaToLinearSpace()和LinearToGammaSpace()。下面将说一下,到底怎么用这两个函数。

主要的思路是,手机靓号买号把从贴图中读取进来的颜色,同时也是Gamma Space下的颜色,进行一次转换,转换到Linear Space。之后对这些颜色数据进行原本要进行的处理。处理结束后,在输出的时候,进行一次逆转换,将这些颜色数据,从Linear Space转换回Gamma Space。

以下是我实际使用的一段代码:

  1. <blockquote>half4 color = UNITY_SAMPLE_TEX2D(_MainTex, i.uv);

复制代码

补充一点,由于通道图,一般来说,其实已经是线性的了,所以是不需要参与到这个转换中的,直接用就好。但这段代码里特别注意的一点是,最后转换回Gamma Space的时候,我在Color上乘了一个Unity_ColorSpaceDouble。

最开始,我只进行了一个转换回Gamma Space的方法,然后发现,场景不仅没有变亮,反而变得更暗了。随后查阅到一篇文章提到了,需要在最后转回Gamma Space的时候,乘上一个值。

“与此相关的有,一个Unity提供的与色彩空间相关的值,Unity_ColorSpaceDouble。这个值在Gamma Color Space时为2,在Linear Color Space时为4.594(2的2.2次方)。对于这个值可以这样来理解。一般在Gamma Color Space中将两个Color值相乘后,为了避免颜色变得很暗,会在后面乘以2。”

也就是说,为了避免颜色变暗,应该扩大两倍,但同时因为是在线性空间下,所以这个2要变成Unity_ColorSpaceDouble。

最后来看一下效果吧~

上图为Gamma Space时的效果,下图为做完一系列变换后的结果。可以看到,整体颜色变亮,尤其是暗部的亮度和细节都有明显的提升。

可以看到特别暗的地方,在进行Gamma校正之后的变化也相对较大。所以这里也需要注意一点,如果是项目已经进行了一段时期之后,想要进行Gamma校正,一定要同时修改光照等一系列参数,以避免一些地方的光照效果过曝。

Unity Gamma校正转为线性空间相关推荐

  1. Gamma校正与线性空间

    基础知识部分 为了方便理解,首先会对( Luminance )的相关概念做一个简单介绍.如果已经了解就跳到后面吧. 我们用Radiant energy(辐射能量)来描述光照的能量,单位是焦耳(J),因 ...

  2. 关于Unity gamma校正

    现实 => 捕捉设备 => 显示器 => 显示图像 encoding decoding 1/2.2 2.2 1.liner空间 图片本身亮度与显示的亮度成线性相关 y=x 2.sRG ...

  3. 浅谈unity中gamma空间和线性空间

    转载请标明出处:http://www.cnblogs.com/zblade/ 一.概述 很久没有写文章了,今天写一篇对gamma空间和线性空间的个人理解总结,在查阅和学习了各个资料后,算是一个个人笔记 ...

  4. Unity Gamma Linear Color Space

    转载文章,出自http://www.manew.com/thread-105872-1-1.html,作者 alphatt Gamma & Linear Color Space 一.真实?感觉 ...

  5. Gamma Correction/Gamma校正/灰度校正/亮度校正(已更正) - 部分 DCC 中的线性工作流配置

    文章目录 也可以简单参考 SIGGRAPH 2010 的 PBS 的 Gamma-Correct Unity 中的 gamma.linear 工作流 Unity BRP 管线中的 shaderlab ...

  6. OpenGL(十八)Gamma校正 色域 与 HDR

    通常来说,在不同设备上看到的颜色是不同的.其中最常提及的概念是高动态光照渲染(High-Dynamic Range,简称 HDR ).它可以使图像在亮度的表现上更丰富.这篇文章讨论设备颜色和校正的相关 ...

  7. 【图像处理】——图像的灰度化处理(Python实现三种方法——最大值法、平均值法、加权均值法、gamma校正)

    目录 一.什么是图像的灰度化? 二.灰度化的几种方法(最大值法.平均值法.加权均值法.gamma校正) 1.直接调用函数:cv2.cvtColor() 图像颜色空间转换 2.最大值法 (1)概念 (2 ...

  8. OpenGL基础45:光照矫正(下)之Gamma校正

    接上文:OpenGL基础44:光照矫正(上) 四.Gamma矫正 4.1.人的视觉特性 和很多错视图一样,对于下面这张灰阶图,如果1表示纯白,0表示纯黑,那么这张图片的哪个位置代表的是0.5,也就是自 ...

  9. OpenGL核心技术之Gamma校正

    笔者介绍:姜雪伟,IT公司技术合伙人,IT高级讲师,CSDN社区专家,特邀编辑,畅销书作者,国家专利发明人;已出版书籍:<手把手教你架构3D游戏引擎>电子工业出版社和<Unity3D ...

最新文章

  1. 打开.264后缀名格式的文件
  2. python3语法错误python_[大数据]Python 3.x中使用print函数出现语法错误(SyntaxError: invalid syntax)的原因 - 码姐姐找文...
  3. 计算机语言里的笑脸,设备类型显示笑脸
  4. 刷脸支付弊端举例_刷脸支付的优势和弊端,你都知道?
  5. java collections读书笔记(3) vector(2)
  6. 华为回应申请大量“鸿蒙”商标;5G第一个演进版本标准正式完成;SUSE 收购 Rancher Labs| 极客头条
  7. cpoint 两个点距离_Wasserstein距离学习笔记
  8. 容器技术Docker K8s 29 容器服务ACK基础与进阶-弹性伸缩
  9. C++中的万能头文件
  10. ong拼音汉字_拼音ong的正确发音
  11. WINDOWS 2008 R2 下安装usb转serial线缆驱动
  12. WeChat-JSAPI支付
  13. 美国金融危机产生的原因
  14. 直流屏电源模块GF22007-2高频充电模块R22007
  15. 字节跳动全链路压测(Rhino)的实践
  16. pg_repack bloat 处理测试初步
  17. JAVA代码托管平台_推荐几个常用的代码托管平台
  18. 凸优化基础知识笔记-凸集、凸函数、凸优化问题
  19. 网线连接olt配置计算机IP,OLT配置上行以太网端口属性
  20. faiss通用向量搜索服务玩转腾讯880万词向量

热门文章

  1. xampp打开mysql的admin访问被拒绝_U盘插入电脑提示无法访问?别怕,我找到解决办法了...
  2. java替换html特殊字符,HTML特殊字符替换问题 html escape相关
  3. [tomcat]-tomcat8启动时SessionIdGeneratorBase.createSecureRandom耗时
  4. Jmeter-逻辑控制器
  5. [TCP/IP] TCP如何实现流量控制和拥塞控制
  6. Javaweb编程中的乱码问题
  7. 3月6日 输入与输出 数据类型 运算符
  8. final/override控制
  9. [转载]另眼看待变量间多重共线性
  10. qq掉线咒语:aidusort.as