Unity中的伽马(Gamma)空间和线性(Linear)空间

2024-06-12 08:36

本文主要是介绍Unity中的伽马(Gamma)空间和线性(Linear)空间,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

伽马空间定义:通常用于描述图像在存储和显示时的颜色空间。在伽马空间中,图像的保存通常经过伽马转换,使图片看起来更亮。

gamma并不是色彩空间,它其实只是如何对色彩进行采样的一种方式

为什么需要Gamma:

在游戏业界长期以来都忽视一个伽马矫正的问题,这就导致渲染出来的效果要么过曝,要么过暗,总是和真实世界不同。

尽管是使用了同一shader渲染,但选择颜色空间不同和处理gamma矫正时做法不同,就导致结果不同

CRT的亮度和施加电压不成线性

人眼和响应不成线性

unity中可以在此处选择不同的颜色空间,如图

 一、Gamma空间与线性空间

什么是线性颜色空间?

如图,横轴为输入给显卡进行渲染的的颜色,纵轴为显卡渲染后输出到显示器的颜色结果

所有线性空间就是输入等于输出的 ColorOut=ColorIn^{1} 

输入的颜色不进行任何处理 Gamma值为1

但现实世界要做到输入颜色等于输出颜色是很难的

因为显示器的颜色输出不是线性的,不同显示器输出的也是不同的

人眼对光强的感知能力并不是线性的——对暗部颜色变化更敏感,但很难识别亮部的颜色差异。

 RGB=0.5的灰色,但其物理亮度(光子数)却只有纯白(RGB=1)的22%。

这时为什么呢?为何不是线性的呢?

人们之所以不设定RGB值与亮度值线性相关,是因为人眼更善于发现暗部中亮度的细微差别。

人眼对光强的感知能力并不是线性的——对暗部颜色变化更敏感,但很难识别亮部的颜色差异。

 

在某些阴暗的环境下,点亮一盏灯,这时人眼就会觉得非常亮。如果同时点亮1000盏灯,反而觉得只是10倍的亮度,对亮度的认知相当于从0~1再从1~10.

 因为人眼不易识别亮部的颜色差异,这就导致了在亮部,我们不需要那么多的空间去存储亮度值,因为人眼根本就难以区别它们,如果按照线性存储,就会导致亮部空间的浪费。

所以在电子图象存储技术中,人们降低亮部的采样数来节约磁盘空间——或者说,在不增加数据量的前提下,分配更多的采样数给暗部以提高可辨识精度。

相机捕获到现实世界真实的光的信息,经过处理后显示到屏幕上,我们希望物理世界中的真实值能够于显示器中的呈现值相同,那么怎么做呢?

先来看一下这个做法的演变过程

从最简单的模型演变

(1)图片真实值0.2->(亮部浪费)图片存储值0.2->提交值0.2->(pow 2.2)呈现值0.029 (缺点:浪费存储空间、早期计算机无法直接让呈现值等同于提交值)

(这个2.2是历史问题,但后来对我们是有益的,所有就沿用下来并未修复)

改善以上问题:

(2)图片真实值0.2->(pow 0.45)图片存储值0.48->提交值0.48->(pow 2.2)呈现值0.2

游戏业界带来新的问题:

(3)图片真实值0.2->(pow 0.45)图片存储值0.48->光照计算0.48*2->提交值0.96->(pow 2.2)呈现值0.914(严重偏离真实值0.2*2=0.4)

二、伽马矫正

最后我们的具体做法是:相机捕获到现实世界真实的光的信息,然后对这些数据开n次方根(n即gamma值,一般取1.8~2.2),Output=Input^{\frac{1}{gamma}},然后通过采样存储图像。这样存储的图像就是经过Gamma校正的图像。

线性的光信号变成了非线性的电信号。

而在显示器上显示图片时,则需要做一次逆Gamma校正:Output=Input^{gamma}

将非线性的电信号转换成线性的光信号。

总结一下就是: 

想要游戏的效果接近真实世界,那么就需要保证在光照计算之前处于线性空间!

sRGB=Gamma^{\frac{1}{2.2}} = Gamma矫正=Gamma 0.45    提亮

Gamma 2.2 = Gamma 空间

Gamma 1 = 线性空间

Color * Gamma 1/2.2 * Gamma 2.2 = Color * Gamma 1 = Color

假如摄像机不做Gamma矫正,会是什么情况?

三、sRGB

unity在贴图的导入设置面板中有“sRGB(Color Texture)”选项,勾选它,告诉Unity这是一张sRGB贴图,需要对它做sRGB解码才可以获得用于光照计算的数据;不勾选,即表示这是一张线性贴图,这张贴图的RGB数据可直接用于光照计算。

sRGB是一种颜色空间,它的定义包括White Point、Primaries、OETF、EOTF

Color SpaceWhite PointPrimariesOETFEOTF
sRGBD65R(0.640,0.330),
G(0.300,0.600),
B(0.150,0.060)
δ=12.92,
β=0.0031308,
α=1.055,
γ=12/5
2.2
Rec.709同 sRGB同 sRGBδ=4.5,
β=0.004,
α=1.099,
γ=20/9
~2.4

sRGB标准和Rec.709标准所定义的白点、三元色相同,只是传递函数的定义不同;

下图的马蹄形区域表示人眼能够感知到的最大色域,三角形围起来的区域即 sRGB / Rec.709 的色域:

 

1.色域: sRGB首先设定了RGB三个基色的坐标

2.白点: sRGB也规定了白点位置

3.gamma: sRGB的gamma设定为≈2.2也就是说从外而向内切,先切的很细,然后逐渐变粗

sRGB的编码伽马值实际是12/5=1/2.4,但我们常听说的是1/2.2,这是因为完整版本的伽马函数【1.055*x ^(1/2.4)-0.055】在形状上更接近【x ^(1/2.2)】,如下图的黑线更接近红线,而不是绿线,红线【x ^(1/2.2)】就被大家当做是简化版本的伽马矫正啦:

渲染时的图片来源,不论是照片还是DCC软件,还是手绘和渲染,都是在sRGB颜色空间下工作的

Substance Painter导出贴图时,会对提供色彩信息的贴图(比如Albedo和Specular Color)做sRGB编码(目的是为了让贴图看起来更舒服,匹配人眼感知,同时优化数据存储),所以我们应把它们当作sRGB贴图来使用;而对法线贴图/金属度贴图这类用以存储数值信息的贴图,是不做sRGB编码的,所以我们应把它们当作线性贴图来使用。

对sRGB编码的图片是直接使用还是转换使用?

线性空间:直接用(系统替我们转换)

Gamma空间:手动转换

四、Unity线性空间流程图

 关于 Gamma 与线性的混淆

色彩空间为什么那么空?色度系统、色度图、色域、伽马、白点...  

这篇关于Unity中的伽马(Gamma)空间和线性(Linear)空间的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1053712

相关文章

线性因子模型 - 独立分量分析(ICA)篇

序言 线性因子模型是数据分析与机器学习中的一类重要模型,它们通过引入潜变量( latent variables \text{latent variables} latent variables)来更好地表征数据。其中,独立分量分析( ICA \text{ICA} ICA)作为线性因子模型的一种,以其独特的视角和广泛的应用领域而备受关注。 ICA \text{ICA} ICA旨在将观察到的复杂信号

理解分类器(linear)为什么可以做语义方向的指导?(解纠缠)

Attribute Manipulation(属性编辑)、disentanglement(解纠缠)常用的两种做法:线性探针和PCA_disentanglement和alignment-CSDN博客 在解纠缠的过程中,有一种非常简单的方法来引导G向某个方向进行生成,然后我们通过向不同的方向进行行走,那么就会得到这个属性上的图像。那么你利用多个方向进行生成,便得到了各种方向的图像,每个方向对应了很多

✨机器学习笔记(二)—— 线性回归、代价函数、梯度下降

1️⃣线性回归(linear regression) f w , b ( x ) = w x + b f_{w,b}(x) = wx + b fw,b​(x)=wx+b 🎈A linear regression model predicting house prices: 如图是机器学习通过监督学习运用线性回归模型来预测房价的例子,当房屋大小为1250 f e e t 2 feet^

【高等代数笔记】线性空间(一到四)

3. 线性空间 令 K n : = { ( a 1 , a 2 , . . . , a n ) ∣ a i ∈ K , i = 1 , 2 , . . . , n } \textbf{K}^{n}:=\{(a_{1},a_{2},...,a_{n})|a_{i}\in\textbf{K},i=1,2,...,n\} Kn:={(a1​,a2​,...,an​)∣ai​∈K,i=1,2,...,n

Unity Post Process Unity后处理学习日志

Unity Post Process Unity后处理学习日志 在现代游戏开发中,后处理(Post Processing)技术已经成为提升游戏画面质量的关键工具。Unity的后处理栈(Post Processing Stack)是一个强大的插件,它允许开发者为游戏场景添加各种视觉效果,如景深、色彩校正、辉光、模糊等。这些效果不仅能够增强游戏的视觉吸引力,还能帮助传达特定的情感和氛围。 文档

win7系统中C盘空间缩水的有效处理方法

一、深度剖析和完美解决   1、 休眠文件 hiberfil.sys :   该文件在C盘根目录为隐藏的系统文件,隐藏的这个hiberfil.sys文件大小正好和自己的物理内存是一致的,当你让电脑进入休眠状态时,Windows 7在关闭系统前将所有的内存内容写入Hiberfil.sys文件。   而后,当你重新打开电脑,操作系统使用Hiberfil.sys把所有信息放回内存,电脑

求空间直线与平面的交点

若直线不与平面平行,将存在交点。如下图所示,已知直线L过点m(m1,m2,m3),且方向向量为VL(v1,v2,v3),平面P过点n(n1,n2,n3),且法线方向向量为VP(vp1,vp2,vp3),求得直线与平面的交点O的坐标(x,y,z): 将直线方程写成参数方程形式,即有: x = m1+ v1 * t y = m2+ v2 * t

Unity协程搭配队列开发Tips弹窗模块

概述 在Unity游戏开发过程中,提示系统是提升用户体验的重要组成部分。一个设计良好的提示窗口不仅能及时传达信息给玩家,还应当做到不干扰游戏流程。本文将探讨如何使用Unity的协程(Coroutine)配合队列(Queue)数据结构来构建一个高效且可扩展的Tips弹窗模块。 技术模块介绍 1. Unity协程(Coroutines) 协程是Unity中的一种特殊函数类型,允许异步操作的实现

[Linux]:环境变量与进程地址空间

✨✨ 欢迎大家来到贝蒂大讲堂✨✨ 🎈🎈养成好习惯,先赞后看哦~🎈🎈 所属专栏:Linux学习 贝蒂的主页:Betty’s blog 1. 环境变量 1.1 概念 **环境变量(environment variables)**一般是指在操作系统中用来指定操作系统运行环境的一些参数,具有全局属性,可以被子继承继承下去。 如:我们在编写C/C++代码的时,在链接的时候,我们并不知

【编程底层原理】方法区、永久代和元空间之间的关系

Java虚拟机(JVM)中的内存布局经历了几个版本的变更,其中方法区、永久代和元空间是这些变更中的关键概念。以下是它们之间的关系: 一、方法区: 1、方法区是JVM规范中定义的一个概念,它用于存储类信息、常量、静态变量、即时编译器编译后的代码等数据。 3、它是JVM运行时数据区的一部分,与堆内存一样,是所有线程共享的内存区域。 二、永久代(PermGen): 1、在Java SE 7之前,