1 伽马相关概念

1.1 人眼对亮度变化的感知

​ 人眼对亮度变化的感知不是线性的,如下图,人眼对亮区的亮度变化不太敏感,对暗区的亮度变化较敏感。另外,我们可以想象一下,在一个黑暗的房间里,由 1 根蜡烛到 2 根蜡烛的变化,我们很容易感知到,但是由 100 根蜡烛到 101 根蜡烛的变化,我们就不容易感知到。因此,对于固定的存储空间,我们应该给暗区分配更多的存储空间,而给亮区少分配些空间,这样能让更多的细节在暗区呈现,而亮区不必呈现太多细节(因为人眼感知不到亮区的细微变化,呈现太多细节只会浪费空间)。

1.2 伽马编码和伽马解码

1)伽马函数

​ 伽马函数公式如下,因其指数部分 γ 读音为伽马(gamma)而来。

​ 当 0 < γ < 1 时,伽马函数的图像从左往右逐渐平缓,通常作为伽马编码处理;当 γ > 1 时,伽马函数的图像从左往右逐渐陡峭,通常作为伽马解码处理。如下是 γ 值为 0.45 和 2.2 的函数图像。

2)伽马函数在图像捕捉****和显示中的应用

​ 一般情况下,一个像素使用 8 位存储,可以表示 256 种颜色。为了尽可能线性化人眼感知的亮度变化(人眼对暗区的亮度变化更敏感,需要使用更多的存储空间,对亮区的亮度变化不太敏感,可以少分配些空间),对相机采集到的图像进行伽马编码处理后,再存入 jpeg 等格式图片文件中,在读取图片文件时,通过伽马解码处理后再显示,如下图所示。

​ 在早期,CRT(Cathode Ray Tube,阴极射线管)几乎是唯一的显示设备,它有一个特性,输入电压和显示亮度不是线性关系,而是伽马函数关系,并且其 γ 值刚好是伽马编码函数的 γ 值的倒数,这正好补偿了图像捕捉设备的伽马编码造成的亮度非线性问题。因此,显示设备只需要输入线性变化的电压,就可以还原线性变化的亮度,而不需要进行伽马解码处理。现在 CRT 设备很少见了,并且后来的显示设备有着不同的伽马曲线(γ 值不同),但人们仍在硬件上做了调整来提供兼容性。

​ 注意:透明通道不参与伽马编码和伽马解码。

3)sRGB 颜色标准

​ 微软联合爱普生、惠普制定了 sRGB 颜色空间标准,推荐相机的伽马编码函数的 γ 值为 0.45,显示器的伽马解码函数的 γ 值为 2.2(因为 2.2 × 0.45 ≈ 1)。绝大多数的摄像机、PC 和打印机都使用了 sRGB 标准。

1.3 颜色空间

​ Unity 中材质渲染的颜色空间分为伽马空间(默认)和线性空间,如下。

​ 伽马空间中,Unity 不会对 Shader 的输入和输出进行任何处理,因此,输入的像素可能是非线性的,输出的像素经过显示器的伽马解码处理后可能会得到非预期的亮度,通常表现为场景整体变暗。

​ 线性空间中,Unity 会把输入纹理设置为 sRGB 模式,在该模式下,硬件在对纹理进行采样时会自动进行伽马解码,在 Shader 写入颜色缓冲前自动进行伽马编码(HDR 除外)。

​ 用户可以在【Edit→Project Settings→Player→Other Settings→Rendering→Color Space】中设置颜色空间,如下。

2 伽马对亮度和混合的影响

​ 当颜色空间使用默认在伽马空间时,如果不进行伽马矫正,可能会出现场景整体偏暗、混合异常等问题。本节实验完整资源见→Unity3D伽马校正对比实验

2.1 伽马对亮度的影响

​ 新建一个场景,调整相机位置和旋转角度分别为 (0, 0, -1.5)、(0, 0, 0),调整直射光旋转角度为 (45, -90, 0),使得直射光从右上角 45° 射向左下角;新建一个 Sphere,调整其位置为 (0, 0, 0),新建一个材质,重命名为 DiffuseMat,设置其 Shader 为【Legacy Shaders / Diffuse】,将该材质拖拽给 Sphere;设置环境光为全黑(在【Window→Rendering→Lighting→Environment→Ambient Color】中设置),使得渲染只受漫反射影响。伽马空间和线性空间中 Sphere 渲染如下。

​ 由于球体的渲染只受漫反射影响,并且直射光从右上角 45° 射向左下角,因此右边的渲染才更符合要求。另外,左侧图像相比右侧图像,整体偏暗一些。

2.2 伽马对混合的影响

​ 新建一个场景,创建 3 个 Quad 和 3 个材质,将这些材质分别拖拽到 3 个 Quad 中,将以下 Shader 绑定到这些材质中,将边缘渐变的圆形图片拖拽到 3 个材质中,调整 3 个材质的颜色分别为红、绿、蓝。

​ SimpleBlend.shader

Shader "MyShader/SimpleBlend" {
Properties {
_MainTex ("Main Tex", 2D) = "white" {}
_Color ("Color Tint", Color) = (1, 1, 1, 1)
} SubShader {
Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"} Pass {
ZWrite Off
Blend SrcAlpha OneMinusSrcAlpha CGPROGRAM #include "UnityCG.cginc" #pragma vertex vert_img
#pragma fragment frag sampler2D _MainTex;
fixed4 _Color; fixed4 frag(v2f_img i) : SV_Target {
return fixed4(_Color.rgb, tex2D(_MainTex, i.uv).a);
} ENDCG
}
} FallBack "Transparent/VertexLit"
}

​ 伽马空间和线性空间中 3 个 Quad 的渲染如下。

​ 左侧图片边缘较硬,右侧图片边缘较柔和,更符合实际情况。

3 伽马校正策略

​ 在线性空间下,系统自动进行了伽马校正;在伽马空间下,需要用户手动校正。另外,Unity 的线性空间并不是所有平台都支持,如:移动平台就无法使用线性空间。

​ 对非线性的输入纹理,进行伽马解码校正如下:

float3 tex = pow(tex2D(_Tex, i.uv).rgb, 2.2);

​ 在片元着色器输出前,进行伽马编码校正如下:

fragColor.rgb = pow(fragColor.rgb, 0.45);
return fragColor;

​ 注意:当场景中存在半透明物体时,上述校正会导致混合在非线性空间中进行,影响混合效果,一种有效的解决方法是:将伽马编码校正放在屏幕后处理中进行。

​ 声明:本文转自【Unity3D】伽马校正

【Unity3D】伽马校正的更多相关文章

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

    http://blog.csdn.net/candycat1992/article/details/46228771/ 写在前面 我相信几乎所有做图像处理方面的人都听过伽马校正(Gamma Corre ...

  2. 【视频开发】伽马校正(gamma correction)学习笔记

    我相信几乎所有做图像处理方面的人都听过伽马校正(Gamma Correction)这一个名词,但真正明白它是什么.为什么要有它.以及怎么用它的人其实不多.我也不例外.  最初我查过一些资料,但很多文章 ...

  3. 图像处理gamma修正(伽马γ校正)的原理和实现算法

    ☞ ░ 前往老猿Python博文目录 ░ 本文转自博客园:淇淇宝贝的文章<图像处理之gamma校正>,原文链接:https://www.cnblogs.com/qiqibaby/p/532 ...

  4. 伽马变换(一些基本的灰度变换函数)基本原理及Python实现

    1. 基本原理 变换形式 $$s=cr^{\gamma}$$ c与$\gamma$均为常数 可通过调整$\gamma$来调整该变换,最常用于伽马校正与对比度增强 2. 测试结果 图源自skimage ...

  5. 图像增强算法(直方图均衡化、拉普拉斯、Log、伽马变换)

    一.图像增强算法原理 图像增强算法常见于对图像的亮度.对比度.饱和度.色调等进行调节,增加其清晰度,减少噪点等.图像增强往往经过多个算法的组合,完成上述功能,比如图像去燥等同于低通滤波器,增加清晰度则 ...

  6. 基础图像处理之混合空间增强——(Java:拉普拉斯锐化、Sobel边缘检测、均值滤波、伽马变换)

    相信看过冈萨雷斯第三版数字图像处理的童鞋都知道,里面涉及到了很多的基础图像处理的算法,今天,就专门借用其中一个混合空间增强的案例,来将常见的几种图像处理算法集合起来,看能发生什么样的化学反应 首先,通 ...

  7. C++数字图像处理(1)-伽马变换

    https://blog.csdn.net/huqiang_823/article/details/80767019 1.算法原理    伽马变换(幂律变换)是常用的灰度变换,是一种简单的图像增强算法 ...

  8. 对比度增强(二):直方图正规划与伽马变换 cv.normal()函数使用及原理

    直方图正规化: 图像为I,宽为W,高为H,I(r,c)代表I的第r行第c列的灰度值:输出图像记为O,为使得输出图像的灰度值在[Omin,Omax]范围里,可用如下公式:                 ...

  9. OpenCV计算机视觉学习(3)——图像灰度线性变换与非线性变换(对数变换,伽马变换)

    如果需要处理的原图及代码,请移步小编的GitHub地址 传送门:请点击我 如果点击有误:https://github.com/LeBron-Jian/ComputerVisionPractice 下面 ...

  10. Gamma correction 伽马校准及 matlab 实现

    matlab 内置实现:imadjust Gamma Correction gamma correction formula : .^(gamma) or .^(1/gamma)? 用以调整图像光照强 ...

随机推荐

  1. 【MicroPython】要是找不到某个函数的定义,可能是做了宏转换

    转换宏 map查找接口

  2. 02-MySQL基本操作

    SQL 的一些简单语法规则 结束符 SQL 指令需要语句结束符,默认是英文分号;. 当然,还有另外两个结束符: \g 与英文分号;等效. \G:将查到的结构旋转90度变成纵向. 反引号`` SQL语句 ...

  3. http-长连接

    1. 短链接 http1.0 -- 1个请求-响应过程会创建且1个新的连接 2. 长连接 http1.1 -- 同域下可以创建1个tcp连接,多个请求在同一个tcp上串行处理请求 http2.0 -- ...

  4. Linux-网络-子网-子网掩码-网关-DNS解析

  5. [转帖]ck的离线安装

    下载 下载地址: https://repo.clickhouse.tech/tgz/stable/ 下载的包: clickhouse-common-static clickhouse-server c ...

  6. [转帖]Nginx反向代理中使用proxy_redirect重定向url

    https://www.cnblogs.com/kevingrace/p/8073646.html 在使用Nginx做反向代理功能时,有时会出现重定向的url不是我们想要的url,这时候就可以使用pr ...

  7. [转帖]JMeter 5.5 使用详解(持续更新中......)

    https://blog.csdn.net/qq_45138120/article/details/124056704?ops_request_misc=%257B%2522request%255Fi ...

  8. [转帖]nginx 反向代理中proxy_set_header的含义

    https://www.jianshu.com/p/cd813d68ed25 0.1212020.10.23 09:29:53字数 284阅读 9,939 1.proxy_set_header设置的请 ...

  9. [转帖]VMware vCenter证书过期解决方法

    https://www.yii666.com/blog/395521.html vCenter证书过期解决方法 目录 1 概述 2 详细操作步骤 2.1 检查关键的STS证书是否过期并修复 2.2 检 ...

  10. [转帖]Full GC (Ergonomics) 产生的原因

    发生Full GC,有很多种原因,不仅仅是只有Allocation Failure. 还有以下这么多: #include "precompiled.hpp" #include &q ...