🌈 Gamma 知识总结笔记
✅ 一、Gamma 是什么?
Gamma 是一种非线性映射函数,通常指:
f(x) = x^γ
用于在图像处理、编码和显示中进行亮度值的非线性变换,其本质目的是:
- 🎯 更贴合人眼感知(人眼对暗部更敏感)
- 🎯 更节省存储空间(比如 8-bit 下更有效地分配灰阶)
- 🎯 兼容早期 CRT 显示器的物理响应曲线
🌍 二、人眼感知 & 显示器特性
项目 | 是否线性 | 说明 |
---|---|---|
真实世界中的光强 | ✅ 线性 | 两倍光强 = 两倍亮度 |
人眼的亮度感知 | ❌ 非线性 | 对暗部更敏感,对亮部不敏感 |
早期 CRT 显示器亮度响应 | ❌ 非线性 | 输出亮度 ≈ 电压^2.2 |
现代显示器(LCD/OLED) | ✅ 接近线性 | 不再需要硬件 Gamma 补偿,但标准仍使用 Gamma 映射 |
🔄 三、Gamma 在图像处理中的三阶段流程
【标准流程】:
真实光 → Gamma 编码(^0.454) → 存图
↓
De-Gamma(^2.2)
↓
线性空间处理(混色/光照)
↓
显示器(自动 Gamma 映射 ^0.454)
↓
人眼看到(自然亮度)
🛠 四、线性工作流(Linear Workflow)
为什么需要?
因为:
- 非线性空间中混色/光照计算不准确
- 会导致高光过曝、暗部死黑、颜色脏
怎么做?
步骤 | 操作 | 说明 |
---|---|---|
① 存储前 | Gamma 编码 | 用 ^0.4545(≈1/2.2),贴合人眼感知 |
② 渲染前 | Gamma 解码 | 用 ^2.2,还原真实亮度值 |
③ 渲染过程 | 在线性空间中运算 | 物理真实的混色、加光 |
④ 显示输出 | 再 Gamma 映射 | 显示器或软件执行,贴合人眼感知 |
🎨 五、贴图 & Gamma 的关系
贴图类型 | 是否 Gamma 编码? | 说明 |
---|---|---|
BaseColor / Albedo | ✅ 是 | 给人看的,需贴合感知 |
Metallic / Roughness / AO / Normal | ❌ 否 | 给引擎算的,要线性真实 |
✅ Unity/UE 中的
sRGB
开关就是控制是否做 Gamma 解码!
📺 六、FFmpeg 中的 Gamma 用法
FFmpeg 中涉及 Gamma 的部分一般在滤镜(如 zscale
、colorspace
)里,控制的是:
transfer
参数:指定图像使用的 Gamma 曲线类型(如bt709
,linear
)- 实际作用是进行 Gamma 编码 or 解码
- 用于控制图像数据的亮度分布,不是针对显示器行为
例子:
# 将图像从线性空间编码为 bt709 Gamma 曲线
ffmpeg -i input.png -vf zscale=transfer=bt709 output.png
# 将 bt709 图像解码回线性空间进行处理
ffmpeg -i input.png -vf zscale=transfer=linear,format=rgbf32 output.exr
🧠 总结一句话:
Gamma 是一套非线性亮度映射方法,贯穿图像的编码、处理、显示全过程,既要服务人眼感知,又要保证物理计算的真实。