图像伽马校正_自适应伽马矫正matlab

图像伽马校正_自适应伽马矫正matlabGamma矫正颜色空间(具体内容在之前的文章有讲)sRGB

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

Jetbrains全系列IDE稳定放心使用

百人计划学习视频连接:【技术美术百人计划】图形 2.6 伽马校正


颜色空间

具体内容在之前的文章有讲:色彩空间介绍

  • sRGB:微软在1996年发布的通用颜色标准
  • DCI-P3:数字电影播放的颜色标准
  • Rec-709、PAL:电视行业的颜色标准
    在这里插入图片描述
    图中可以看出sRGB和Rec-709表示的颜色范围很接近,三原色的位置也是相同的

    那他们的区别在哪里呢?

    答案是 他们的传递函数的不同

什么是传递函数

当我们已经知道了颜色空间下三原色的值,但是我们需要将它显示到电子设备上,那就需要把它转换成一个视频信号。
这里就需要用到一个转换函数,也叫传递函数
在这里插入图片描述
一个传递函数包含2个部分:

  • OEFT 把光转换为电子信号(例如:拍摄视频的时候,将场景中的光保存成信号)
  • EOFT 把电子信号转换成光信号(例如:播放视频的时候,将视频中的信号转换成光强度)

而传递函数就是Gamma校正所使用的一个函数

Gamma校正

什么是Gamma校正?
就是指对线性三色值和非线性视频信号之间进行编码和解码的操作

也可以简单的定义为:在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
那为什么不直接用线性方式存储颜色信号呢?

首先我们知道了图像的来龙去脉:自然界捕获的图像 -> 图像存储和处理->显示器输出

而两头的颜色数量都是非常丰富的,但是中间的存储和处理出于存储容量和渲染时带宽的限制,24位色图片每个通道只有28个色阶,总共只能显示224种颜色。

如过是32位通道的图片,确实可以直接存储物理光强,因为存储空间足够;但是目前主流使用还是8位通道的图片

因此,我们得出结论

  • 主要是为了优化存储空间和带宽,传递函数能更好的帮我们利用编码空间
  • 人眼对暗部的变化更加敏感,为了充分的利用带宽,那么就需要使用更多位置存储暗部值。也就是说暗部使用更高精度保存,而亮部使用更低精度保存

韦伯定律

在这里插入图片描述
正常人会觉得是上面更均匀,但是实际下面才是均匀变化的。

将自然界线性增长的亮度和心理上感受到的亮度进行一个映射得到下面的曲线,就是Gamma编码的曲线
在这里插入图片描述
这种情况也符合一个定律,就是韦伯定律
在这里插入图片描述

小结

  1. 人眼对暗部的变化比亮部更加敏感
  2. 我们目前所使用的RGBA32,每个颜色通道只有8位用于记录信息,为了合理使用带宽和存储空间,需要进行非线性转换
  3. 目前我们所普遍使用的sRGB颜色空间标准,他的传递函数gamma值为2.2

CRT

早期的人们是如何修正人眼的视觉感受和物理亮度的差异
在这里插入图片描述
CRT与转换函数
在这里插入图片描述

中灰值

中灰值是什么?
在这里插入图片描述
在这里插入图片描述
中灰值并非是一个固定的具体数值,而是取决于视觉感受

线性工作流

在这里插入图片描述
为了保证我们在着色器中拿到的颜色值是线性空间下的颜色值

如果不在线性空间下进行渲染工作,会产生什么问题
在这里插入图片描述
在这里插入图片描述

Unity中的颜色空间

在这里插入图片描述

  • 选择Gamma Space时,Unity不会做任何处理
  • 当选择Linear Space时,引擎的渲染流程在线性空间计算,理想情况下项目使用线性空间的贴图颜色,不需要勾选sRGB,如果勾选了sRGB的贴图,会通过硬件特性采样时进行线性转换。

在这里插入图片描述
Unity目前主要通过以下两个硬件特性来支持
在这里插入图片描述

资源导出问题

在这里插入图片描述

当Substance的贴图导出时,线性的颜色值经过伽马变换,颜色被提亮了,所以需要在Unity中勾选sRGB选项,让它在采样时能还原回线性值。
在这里插入图片描述
如果使用线性空间,一般来说Photoshop可以什么都不改,导出的贴图只要勾上sRGB就可以了。如果调整PhotoShop的伽玛值为1,导出的贴图在Unity中也不需要勾选sRGB了。

关于Color profile

在这里插入图片描述

半透明效果不一致在这里插入图片描述

Unity中的混合是线性混合,Photoshop的图层和图层之间做混合的时候,每个上层图层都经过了伽马变换,然后才做了混合。在设置中更改,选择“用灰度系数混合RGB颜色”,参数设置为1,这样图层才是直接混合的结果。

作业

手动尝试几种伽马校正的方法

1. 直接修改Unity3d的设置为Linear空间进行gamma校正

写了一个简单的带纹理的blin-phong模型

fixed4 frag (v2f i) : SV_Target
{ 
   

	fixed3 MainTex = tex2D(_MainTex, i.uv) * _DiffuseColor.rgb;
	float3 normalDir = normalize(i.worldNormal);
	float3 lightDir = normalize(UnityWorldSpaceLightDir(_WorldSpaceLightPos0.xyz)) ;
	float3 Diffuse =  _LightColor0.rgb * MainTex.rgb *  saturate(dot(lightDir, normalDir));
	float3 viewDir = normalize(_WorldSpaceCameraPos.xyz - i.worldPos.xyz);
    float3 halfDir = normalize(lightDir + viewDir);
	float3 Specular = _LightColor0.rgb * pow(saturate(dot(halfDir, normalDir)), _Gloss);

	float3 Ambient = UNITY_LIGHTMODEL_AMBIENT.xyz * MainTex.rgb;
	float4 col = fixed4(Diffuse + Specular, 1);
	return col;
}

Gamma空间:
在这里插入图片描述

Linear空间:
在这里插入图片描述

2. 在shader中手动进行gamma校正

fixed4 frag (v2f i) : SV_Target
{ 
   

		fixed3 MainTex = tex2D(_MainTex, i.uv) * _DiffuseColor.rgb;//先将Gamma空间的颜色值进行一次转换,转换到Linear空间。
		MainTex.rgb = GammaToLinearSpace(MainTex.rgb);
		float3 normalDir = normalize(i.worldNormal);
		float3 lightDir = normalize(UnityWorldSpaceLightDir(_WorldSpaceLightPos0.xyz)) ;
		float3 Diffuse =  _LightColor0.rgb * MainTex.rgb *  saturate(dot(lightDir, normalDir));
		float3 viewDir = normalize(_WorldSpaceCameraPos.xyz - i.worldPos.xyz);
       	float3 halfDir = normalize(lightDir + viewDir);
		float3 Specular = _LightColor0.rgb * pow(saturate(dot(halfDir, normalDir)), _Gloss);

		float3 Ambient = UNITY_LIGHTMODEL_AMBIENT.xyz * MainTex.rgb;
		float4 col = fixed4(Diffuse + Specular, 1);
		//输出的时候,再进行一次逆转换,从Linear空间转换回Gamma空间。
		col.rgb = LinearToGammaSpace(col.rgb * unity_ColorSpaceDouble);
		return col;
}

注:最后转换回Gamma Space的时候,我在Color上乘了一个Unity_ColorSpaceDouble。Unity_ColorSpaceDouble是一个Unity提供的与色彩空间相关的值,这个值在Gamma颜色空间时为2,在Linear Color Space时为4.594(2的2.2次方)。
对于这个值可以这样来理解。一般在Gamma颜色空间中将两个Color值相乘后,为了避免颜色变得很暗,会在后面乘以2。
也就是说,为了避免颜色变暗,应该扩大两倍,但是这个值在不同空间下不一样,所以要使用Unity_ColorSpaceDouble。

原效果:
在这里插入图片描述
加上gamma校正后的效果
在这里插入图片描述


参考学习:
《Unity+Shader入门精要》——冯乐乐著
https://blog.csdn.net/candycat1992/article/details/46228771

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

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

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

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

(0)


相关推荐

  • 免备案空间推荐(超低价免备案空间)

    “空间”对于搭建网站来说是比较重要的,然而国内空间访问有备案这个限制。最近试用一些不错的免费免备案空间,今天整理分享出来

  • 静态变量存储在那个区? – 转[通俗易懂]

    静态变量存储在那个区? – 转[通俗易懂]一时间忘咯然后就去转载..静态变量存储在__区A全局区B堆C栈D常量区参考答案:A知识点内存到底分几个区?1、栈区(stack)—由编译器自动分配释放,存放函数的参数值,局部变量的值等。2、堆区(heap)—一般由程序员分配释放,若程序员不释放,程序结束时可能由os回收。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表。3、全局区(静态区)(static)—全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域…

  • HTTP 405 错误 – 方法不被允许 (Method not allowed)【转载】

    HTTP 405 错误 – 方法不被允许 (Method not allowed)【转载】

    2021年10月12日
  • 张正友相机标定Opencv实现以及标定流程&&标定结果评价&&图像矫正流程解析(附标定程序和棋盘图)

    张正友相机标定Opencv实现以及标定流程&&标定结果评价&&图像矫正流程解析(附标定程序和棋盘图)使用Opencv实现张正友法相机标定之前,有几个问题事先要确认一下,那就是相机为什么需要标定,标定需要的输入和输出分别是哪些?相机标定的目的:获取摄像机的内参和外参矩阵(同时也会得到每一幅标定图像的选择和平移矩阵),内参和外参系数可以对之后相机拍摄的图像就进行矫正,得到畸变相对很小的图像。相机标定的输入:标定图像上所有内角点的图像坐标,标定板图像上所有内角点的空间三维坐标(一般情况下…

  • linux下解压rar文件的方法

    linux下解压rar文件的方法
      wgetlinux-3.8.0.tar.gz”>http://www.rarlab.com/rar_CN/rarlinux-3.8.0.tar.gz
      tarxzvfrarlinux-3.8.0.tar.gz
      cdrar
      makeinstall
      rarxfile.rar
      注意:rar目录中的rar文件就是可执行文件,如果没有makeinstall的权限,可以将rar放到PATH环境变量指定的目录中,直接运行r

  • 一步步学习SPD2010–第十章节–SP网站品牌化(12)–关键点

    一步步学习SPD2010–第十章节–SP网站品牌化(12)–关键点1.      SPD提供了许多工具帮助你管理CSS样式和文件2.      SPD使用一系列配置选项来决定它如何添加CSS标签到你的页面。3.      SPFoundation和SPServer主要的CSS是corev4.css。

发表回复

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

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