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

相关文章

陀螺仪LSM6DSV16X与AI集成(8)----MotionFX库解析空间坐标

陀螺仪LSM6DSV16X与AI集成.8--MotionFX库解析空间坐标 概述视频教学样品申请源码下载开启CRC串口设置开启X-CUBE-MEMS1设置加速度和角速度量程速率选择设置FIFO速率设置FIFO时间戳批处理速率配置过滤链初始化定义MotionFX文件卡尔曼滤波算法主程序执行流程lsm6dsv16x_motion_fx_determin欧拉角简介演示 概述 本文将探讨

【Unity Shader】片段着色器(Fragment Shader)的概念及其使用方法

在Unity和图形编程中,片段着色器(Fragment Shader)是渲染管线中的一个阶段,负责计算屏幕上每个像素(片段)的颜色和特性。片段着色器通常在顶点着色器和任何几何处理之后运行,是决定最终像素颜色的关键步骤。 Fragment Shader的概念: 像素处理:片段着色器处理经过顶点着色器和几何着色器处理后,映射到屏幕空间的像素。颜色计算:它计算每个像素的颜色值,这可能包括纹理采样、光

【Unity Shader】Alpha Blend(Alpha混合)的概念及其使用示例

在Unity和图形编程中,Alpha Blend(也称为Alpha混合)是一种用于处理像素透明度的技术。它允许像素与背景像素融合,从而实现透明或半透明的效果。Alpha Blend在渲染具有透明度的物体(如窗户、玻璃、水、雾等)时非常重要。 Alpha Blend的概念: Alpha值:Alpha值是一个介于0(完全透明)和1(完全不透明)的数值,用于表示像素的透明度。混合模式:Alpha B

线性回归(Linear Regression)原理详解及Python代码示例

一、线性回归原理详解         线性回归是一种基本的统计方法,用于预测因变量(目标变量)与一个或多个自变量(特征变量)之间的线性关系。线性回归模型通过拟合一条直线(在多变量情况下是一条超平面)来最小化预测值与真实值之间的误差。 1. 线性回归模型         对于单变量线性回归,模型的表达式为:         其中: y是目标变量。x是特征变量。β0是截距项(偏置)。β1

java NIO 缓存区之内核空间、用户空间和虚拟地址

IO是基于缓存区来做的,所谓的输入和输出就是从缓存区中移入和移出数据。以IO输入为例,首先是用户空间进程向内核请求某个磁盘空间数据,然后内核将磁盘数据读取到内核空间的buffer中,然后用户空间的进程再将内核空间buffer中的数据读取到自身的buffer中,然后进程就可以访问使用这些数据。     内核空间是指操作系统内核运行的空间,是为了保证操作系统内核的能够安全稳定地运行而为内核专

内存填充越界 + malloc空间不够导致越界

【创建时间:2014-11-1 11:50】 [2014-10-31]:环境:系统:Linux版本:3.08    平台:Hisi3516c。 内存填充越界: 问题: 申请了一个2048字节局部静态的变量存储一个固定RGB值,方便后续画框、线时快速copy。但是在第一次赋固定值时,越界了,导致内核自动向应用程序 发送信号 SIGBUS(7)给应用程序,导致应用程序异常

DataWhale机器学习——第三章线性模型笔记

读书笔记: 《机器学习》第三章 线性模型 3.1 基本形式 3.1.1 线性模型的定义 3.1.2 线性模型的优点 简单易理解计算效率高容易实现和解释 3.1.3 线性模型的局限性 只能表达线性关系对于复杂的非线性关系,表现较差 3.2 线性回归 3.2.1 基本概念 3.2.2 最小二乘法 正规方程 3.2.3 正则化 为防止过拟合,可以在损失函数中加入正

让IE8支持CSS3属性(border-radius、box-shadow、linear-gradient)

下载 PIE-1.0.0.zip解压后,将文件夹重命名为PIE,放到项目目录下在CSS3文件中添加一行代码 behavior: url(PIE/PIE.htc); 例如: .form__input{border-radius: 0.3em;behavior: url(PIE/PIE.htc);} 参考: TYStudio-专注WEB前端开发 css3pie

Unity Meta Quest 开发:关闭 MR 应用的安全边界

社区链接: SpatialXR社区:完整课程、项目下载、项目孵化宣发、答疑、投融资、专属圈子 📕教程说明 这期教程我将介绍如何在应用中关闭 Quest 系统的安全边界。 视频讲解: https://www.bilibili.com/video/BV1Gm42157Zi 在 Unity 中导入 Meta XR SDK,进行环境配置后,打开 Assets > Plugins > An

新建帐套提示“无法创建数据库!请检查目录…是否存在,以及系统空间是否充足.

1、在K/3安装路径下K3ERP文件夹下,找到DBFILE文件夹;2、右击单击“DBFILE”文件夹,选择“属性”→【安全】→【添加】,选择【高级】→【立即查找】→找到everyone用户;3、把该用户添加到【用户和组】中,并赋予“完全控制权限”。