这个问题源自于我们的UI发现自己在FGUI下制作的东西,在Unity中显示的效果不对。例如90%透明度的黑底图片导出到Unity中的效果非常的透,可能只有70%左右的效果。

然后我们绞尽脑汁的找了半天不同,才发现是由于我们工程Color Space设置成为Linear的问题。而且相对的UGUI也存在这样的问题,我们做个简单的测试,在Gamma环境下,UGUI Image为黑色90%透明度的遮挡效果如下(为了方便后面要讲到的一些内容,我顺便取了下图中几个颜色显示出来的RGB的值):

然后我们打开Edit-Project Settings-Player-Other Settings,将Color Space由Gamma转为Linear,效果如下:

      

这就很神奇了。

于是就查了下有关Gamma和Linear的资料,看看如何能够解决这样的问题,由于网上相关资料很多,内容也很多,也防止自己以后忘记了要重新找,这里都先贴几个大佬发的文章。

问题源自于人眼对光照强度的敏感度是非线性的,对于这个问题,有个举例我觉得很好,就是在一个黑暗的房间中,若放上一根蜡烛,我们的眼睛能明显的感觉到变化。假如每个蜡烛的光照强度都一样,但是当在一个房间中有100个蜡烛的时候,再放上一根,我们是基本感觉不到变化的。所以人眼对亮部的识别特别差,对暗部的识别高一些。

聊聊Unity的Gamma校正以及线性工作流

Unite 2018 | 浅谈伽玛和线性颜色空间

在文章中有个公式可以很好的解决我们的疑惑,就是为什么变得更透明了。

在shader的混合模式为Blend SrcAlpha OneMinusSrcAlpha时,Gamma的计算公式为:

ret = srcColor * srcAlpha + dstColor * (1 - srcAlpha)

套用我们上面的例子srcColor为黑色的遮罩,即RGB=0,0,0,srcAlpha=0.9,dstColor为白色的底,即RBG=1,1,1,套入公式中:

0 * 0.9 + 1 * (1 - 0.9) = 0.1

但是在Linear下,计算公式为:

ret = (srcColor^2.2 * srcAlpha + dstColor^2.2 * (1 - srcAlpha) ) ^(1/2.2)

套入公式后,结果变为0.35,相比0.1要更白,所以看上去感觉更透明了。

(0 ^ 2.2 * 0.9 + 1 ^ 2.2 * (1 - 0.9)) ^ 0.45 = 0.35

紫色底,黑色透明遮罩的效果大家可自行计算一下,两个值也是近似最终效果的。

同时由于这个公式涉及到了srcColor和dstColor,所以在Shader中也是比较无解(文章中也提到了几个解决方案)。目前的做法就是加深srcColor的srcAlpha值来进行优化,例如

//hlsl语法
#if !defined(UNITY_COLORSPACE_GAMMA) && (UNITY_VERSION >= 550)if(v.color.r * v.color.g * v.color.b != 1)o.color.a = PositivePow(v.color.a, 0.4545454545);
#endif

注:在Shader中也有一些函数可以帮助我们在Gamma和Linear之间转换,例如

UnityCG.cginc

// Legacy for compatibility with existing shaders
inline bool IsGammaSpace()
{#ifdef UNITY_COLORSPACE_GAMMAreturn true;#elsereturn false;#endif
}inline float GammaToLinearSpaceExact (float value)
{if (value <= 0.04045F)return value / 12.92F;else if (value < 1.0F)return pow((value + 0.055F)/1.055F, 2.4F);elsereturn pow(value, 2.2F);
}inline half3 GammaToLinearSpace (half3 sRGB)
{// Approximate version from http://chilliant.blogspot.com.au/2012/08/srgb-approximations-for-hlsl.html?m=1return sRGB * (sRGB * (sRGB * 0.305306011h + 0.682171111h) + 0.012522878h);// Precise version, useful for debugging.//return half3(GammaToLinearSpaceExact(sRGB.r), GammaToLinearSpaceExact(sRGB.g), GammaToLinearSpaceExact(sRGB.b));
}inline float LinearToGammaSpaceExact (float value)
{if (value <= 0.0F)return 0.0F;else if (value <= 0.0031308F)return 12.92F * value;else if (value < 1.0F)return 1.055F * pow(value, 0.4166667F) - 0.055F;elsereturn pow(value, 0.45454545F);
}inline half3 LinearToGammaSpace (half3 linRGB)
{linRGB = max(linRGB, half3(0.h, 0.h, 0.h));// An almost-perfect approximation from http://chilliant.blogspot.com.au/2012/08/srgb-approximations-for-hlsl.html?m=1return max(1.055h * pow(linRGB, 0.416666667h) - 0.055h, 0.h);// Exact version, useful for debugging.//return half3(LinearToGammaSpaceExact(linRGB.r), LinearToGammaSpaceExact(linRGB.g), LinearToGammaSpaceExact(linRGB.b));
}

Color.hlsl

// Gamma22
......real3 Gamma22ToLinear(real3 c)
{return PositivePow(c.rgb, real3(2.2, 2.2, 2.2));
}real4 Gamma22ToLinear(real4 c)
{return real4(Gamma22ToLinear(c.rgb), c.a);
}......real3 LinearToGamma22(real3 c)
{return PositivePow(c.rgb, real3(0.454545454545455, 0.454545454545455, 0.454545454545455));
}real4 LinearToGamma22(real4 c)
{return real4(LinearToGamma22(c.rgb), c.a);
}// sRGB
......real3 SRGBToLinear(real3 c)
{real3 linearRGBLo  = c / 12.92;real3 linearRGBHi  = PositivePow((c + 0.055) / 1.055, real3(2.4, 2.4, 2.4));real3 linearRGB    = (c <= 0.04045) ? linearRGBLo : linearRGBHi;return linearRGB;
}real4 SRGBToLinear(real4 c)
{return real4(SRGBToLinear(c.rgb), c.a);
}......real3 LinearToSRGB(real3 c)
{real3 sRGBLo = c * 12.92;real3 sRGBHi = (PositivePow(c, real3(1.0/2.4, 1.0/2.4, 1.0/2.4)) * 1.055) - 0.055;real3 sRGB   = (c <= 0.0031308) ? sRGBLo : sRGBHi;return sRGB;
}real4 LinearToSRGB(real4 c)
{return real4(LinearToSRGB(c.rgb), c.a);
}

后续了解的更多的时候继续补充。

关于Color Space是Gamma还是Linear的一些问题相关推荐

  1. Unity Gamma Linear Color Space

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

  2. Gamma、Linear、sRGB 和Unity Color Space,你真懂了吗?

    "为什么我渲染出来的场景,总是感觉和真实世界不像呢?" 游戏从业者或多或少都听过Linear.Gamma.sRGB和伽马校正这些术语,互联网上也有很多科普的资料,但是它们似乎又都没 ...

  3. Gamma Linear Color Space

    http://www.manew.com/forum.php?mod=viewthread&tid=105872 一.真实?感觉?    1.你相信你的眼睛吗 (蓝黑or白金?) (A和B的颜 ...

  4. 彩色空间(Color Space)

    背景 学习openCV-Python Tutorial,在Image Processing in OpenCV这一节里有提到彩色空间的转换,结合其他的一些资料对彩色空间(Color Space),彩色 ...

  5. java.lang.IllegalArgumentException: Numbers of source Raster bands and source color space components

    项目在文件压缩的时候报错如下: Exception in thread "main" java.lang.IllegalArgumentException: Numbers of ...

  6. Linear Color Space 渲染时几点注意

    https://chengkehan.github.io/LinearColorSpace.html 转载于:https://www.cnblogs.com/jim-game-dev/p/612436 ...

  7. sRGB Color Space

    转自:http://www.sjbrown.co.uk/2004/05/14/gamma-correct-rendering/ With consumer-level hardware now cap ...

  8. Unity下Gamma和Linear颜色空间的区别。

    伽马校正:pow(color, 1/2.2), 变得更亮了,例如:color值为0.5,校正后是0.5^(1/2.2) = 0.7297 移除伽马校正:pow(color, 2.2),变暗了,例如co ...

  9. Unity3D Gamma,Linear和sRGB

    关于CRT伽马值的由来不多赘述了,网上太多了,我们只要知道显示器会把图像进行一次gamma2.2就够了. 这里主要讲一下为什么说Linear空间是唯一正确空间,以及为什么图片在unity中需要勾选sR ...

最新文章

  1. 用户体验设计常犯10个逻辑谬误
  2. 应用Mongoose开发MongoDB(2)模型(models)
  3. 关于如如何运行tensorrt
  4. php设置东京时区,php设置时区方法介绍
  5. win10 dns异常上不了网如何解决
  6. influxdb mysql对比_influxdb基础入门
  7. 【机房收费系统】---导出Excel表
  8. 中央处理器(CPU)—— 控制器的功能和基本原理(微程序控制器(CU))
  9. G盘格式化了,要怎样恢复文件
  10. [附源码]java+ssm计算机毕业设计磐基建筑机械租赁有限公司机械租赁系统41c32(源码+程序+数据库+部署)
  11. 图片文件压缩并上传至阿里云OSS
  12. 【MM VS价】移动平均价V标准价格S(一)
  13. 外卖商家入驻选择类目(JS数组)
  14. 酷讯网半年内两换CEO 风投要业绩被指心太急
  15. ORB_SLAM2中特征提取之图像金字塔尺度不变性理解
  16. 期货反向跟单的路还能走多远?
  17. android kindleFire develop
  18. CVTE C/C++研发实习面试(凉)
  19. 人生的意义与价值——季羡林
  20. Strange Counter(maths)

热门文章

  1. 【Qt】QML快速入门7——输入元素
  2. 肝了一早上,终于把mybatis的一级缓存和二级缓存原理搞懂了~
  3. 5月份必火20条爆笑段子
  4. 没有没有联网鸿蒙的智能猫眼,智能猫眼的功能
  5. VSP存储配置SNMP
  6. 构建OpenStack私有云--第一步:配置Keystone服务
  7. 神经网络推理加速: 合并卷积和BN层运算原理及实验
  8. vue使用luckySheet前端excel的在线表格,导入显示以及导出excel文件
  9. 《程序员练习生》第2期 什么年龄开始编程最好
  10. 无线网络中PPK-MIC和CKIP-CMIC的学习资料