🎨 Linear 与 Gamma 渲染空间深度解析
📚 1. 理论基础 (Theoretical Basis)
1.1 核心定义
Gamma 空间与Linear 空间的区别在于计算机如何存储颜色以及如何进行光照计算。- Linear Space (线性空间): 物理世界是线性的。如果光的强度增加一倍,光子的数量也增加一倍 ()。在渲染中,这是光照计算必须发生的空间,以保证物理准确性。
- Gamma Space (伽马空间): 传统的显示器(CRT 时代遗留)并非线性输出亮度,而是遵循指数曲线(通常 )。为了适应这种非线性并在 8 位图像中保存更多暗部细节,我们在存储图片时会进行Gamma Encoding(提亮)。
1.2 数学模型
人眼对暗部变化比亮部更敏感。- Gamma Encoding (编码): 在保存图片时,将线性颜色 转换为 : (约为 0.45 次方,图像变亮)
- Gamma Decoding (解码/显示): 显示器将信号转换为物理光线: (约为 2.2 次方,压暗,最终还原为线性物理亮度)
1.3 设计心理学
- 真实感 (Realism): PBR (Physically Based Rendering) 极其依赖 Linear Space。因为能量守恒公式只有在线性空间下才成立。
- 美术直觉: 在 Gamma 空间工作的美术人员习惯了”手动补光”来对抗错误的暗部堆积,切换到 Linear 后,场景通常会变亮并显得更自然,需要重新调整打光习惯。
🛠️ 2. 实践应用 (Practical Implementation)
2.1 Vampirefall 适配指南
对于我们的项目(塔防 + 3D 视角),切换到 Linear 空间对视觉提升巨大,尤其是特效叠加和光照衰减。📋 切换清单 (Checklist)
-
Unity 设置:
Project Settings->Player->Other Settings->Color Space: 切换为 Linear。- 注意: 这要求最低图形 API 为 OpenGLES 3.0 (Android) / Metal (iOS)。
-
纹理设置 (Texture Importer):
这是最容易出错的地方。Unity 需要知道哪些图是”颜色”,哪些是”数据”。
纹理类型 sRGB (Color Texture) 说明 Albedo / Diffuse / BaseColor ✅ 勾选 这类贴图是在 sRGB 空间绘制的,Unity 采样时需自动转为 Linear。 UI Sprites ✅ 勾选 同上。 Normal Map ❌ 不勾选 法线是方向数据,必须保持线性值。 Mask Map / Metallic / Roughness ❌ 不勾选 非颜色数据参与计算,不可进行 Gamma 转换。 Noise / LUT ❌ 不勾选 数学查找表必须精确。 -
UI 系统 (Canvas):
- 旧版 Unity UI 在 Linear 空间下可能显得”发白”或”混合不正确”。
- 确保 UI Shader 支持 Linear (通常 Unity 内置 UI Shader 已处理)。
- 对于半透明 UI,Blend Mode 的数学计算在线性空间下结果不同,可能需要美术调整透明度。
2.2 Shader 修正
如果你在 Shader 中手动处理了颜色,需要注意:🌟 3. 业界优秀案例 (Industry Best Practices)
3.1 案例分析
-
《Genshin Impact (原神)》:
- 全流程 Linear Space。
- 特点: 卡通渲染 (NPR) 同样受益于 Linear Space,主要体现在阴影梯度的柔和过渡上。Gamma 空间下的阴影过渡通常非常生硬直接。
-
《Kingdom Rush Vengeance》 (参考):
- 虽然是 2D 风格,但现代 2D 引擎常开启 Linear 空间以获得更好的粒子混合效果(Additive Blending 在 Linear 下更柔和,不易过曝)。
3.2 优缺点对比
| 维度 | Linear Space | Gamma Space |
|---|---|---|
| PBR 表现 | ✅ 物理准确 | ❌ 能量不守恒,金属看起来像塑料 |
| 光照衰减 | ✅ 自然衰减 | ❌ 衰减过快,暗部死黑 |
| 混合 (Blending) | ✅ 线性叠加,自然 | ❌ 容易过曝,产生黑边 |
| 移动端性能 | ⚠️ 在极老旧机型有轻微 sRGB 读写消耗 (通常可忽略) | ✅ 最廉价,兼容 OpenGLES 2.0 |
| 工作流复杂度 | ⚠️ 需严格管理纹理 sRGB 选项 | ✅ 简单粗暴,所见即所得 (但错误) |
3.3 总结与建议
对于 Vampirefall:- 必须使用 Linear 空间。我们的 3D 塔防和 Roguelike 技能特效涉及大量透明混合,Linear 空间能解决”光效光污染”严重的问题。
- Lint 工具: 编写一个简单的编辑器脚本,扫描所有名为
*Normal*,*Mask*,*Data*的纹理,确保它们的 sRGB 选项被关闭。
3.4 常见疑问 (FAQ)
!!! question “Q: Gamma 工作流下 (Color Space = Gamma),贴图还需要勾选 sRGB 吗?” A: 勾不勾选在视觉上通常没有区别,但建议保持勾选。- 机制: 在 Gamma Space 模式下,Unity 的采样器不仅不会进行 Linear 转换,通常也会直接忽略贴图的 sRGB 标记。Shader 拿到的永远是贴图里的原始像素值 (Raw Value)。
- 为什么建议勾选:
- 语义正确: 标记这是”颜色”而不是”数据”。
- 无痛切换: 如果未来项目决定升级到 Linear Space,你不需要重新去勾选几千张贴图。
- UI 兼容: 部分旧版 GUI 系统依赖此标记识别 Alpha 通道行为。
- 贴图资源: 是兼容的。只要你的纹理 Import Setting 设置正确(Albedo 勾选 sRGB,Normal 不勾选),Unity 会根据当前的 Color Space 自动决定如何采样。Gamma 模式下读取原始值,Linear 模式下硬件去除 Gamma 曲线。同一份资源可以用于两种空间。
- 需要注意的副作用:
- 光照贴图 (Lightmaps): 必须重新烘焙。旧的光照贴图是基于错误的衰减计算的。
- 材质效果: 画面会突然变亮或变暗(通常暗部会变亮,高光会更柔和)。美术需要调整材质球参数(Intensity, Smoothness)来适配新的光照反应。
- 自定义 Shader: 如果你的 Shader 里为了在 Gamma 空间下好看写死了一些 Magic Number 或者
pow(x, 2.2),切换后需要把这些 Hack 去掉。
- URP 的设计初衷: Universal Render Pipeline (URP) 的核心光照模型和后处理栈 (Post-processing Stack) 都是基于 Linear Space 设计的。如果你强制用 Gamma,你会发现 HDR、Bloom、Tonemapping (色调映射) 的效果都会变得很奇怪。
- PBR 材质: 现在 Asset Store 买的素材基本都是 PBR 标准。PBR 的能量守恒公式只有在 Linear 空间下才是数学正确的。
- 唯一例外: 极少数纯 2D 像素风游戏 (Pixel Art),且完全不使用光照和半透明特效,美术希望”屏幕上显示的颜色 = 我在 PS 里画的颜色 (RGB 值完全一致)“,这时候有人会选择 Gamma 以获得绝对的色彩控制权。但即使是 2D 游戏,为了特效好看,现代项目也倾向于用 Linear 配合 Tonemapping。