sRGB 贴图工作流
什么是sRGB贴图工作流
sRGB贴图工作流是实时渲染中颜色管理的关键部分。它涉及在图形管线中正确处理颜色空间,以确保最终显示的颜色准确。核心原则是:颜色贴图(如反照率、漫反射)通常以sRGB颜色空间存储,因为人眼对亮度的感知是非线性的,sRGB编码可以更有效地利用有限的位深。然而,光照计算必须在线性空间进行,否则结果会不正确。因此,需要在采样纹理后将颜色从sRGB转换到线性空间,渲染完成后再将输出转换回sRGB进行显示。
为什么需要sRGB工作流
- **物理正确性**:光照方程在线性空间中才成立。如果在sRGB空间直接计算,会导致光照过亮或色彩偏移。
- **避免颜色失真**:不正确的颜色空间处理会导致纹理颜色与设计不符,尤其在暗部和亮部。
- **一致性**:确保在不同平台和显示器上颜色一致。
sRGB与线性空间的区别
- **sRGB**:是一种非线性颜色空间,编码了伽马校正(约2.2),用于存储和显示,以匹配人眼感知。
- **线性空间**:光照计算和物理模拟应在该空间进行,像素值与光强度成正比。
实现sRGB工作流
在图形API和引擎中,通常通过以下方式实现:
- **纹理导入设置**:将颜色贴图标记为sRGB,这样GPU在采样时会自动将其转换到线性空间。例如,在Unity中,颜色贴图默认勾选“sRGB (Color Texture)”,而法线贴图、粗糙度等数据贴图则使用线性。
- **渲染目标格式**:使用支持sRGB的帧缓冲格式(如sRGB8_ALPHA8),GPU在写入时会自动进行线性到sRGB的转换。
- **着色器中的处理**:如果手动处理,需要在采样颜色贴图后执行`pow(color, 2.2)`或使用硬件sRGB纹理采样。
- **最终输出**:如果渲染到非sRGB目标,需要手动进行伽马校正。
- **不要对非颜色数据使用sRGB**:法线贴图、粗糙度、金属度、AO等数据应使用线性空间,否则数值会被错误解码。
- **混合顺序**:透明混合应在线性空间进行,然后转换为sRGB输出。
- **Mipmap生成**:sRGB纹理的mipmap应在sRGB空间生成,否则平均颜色会偏暗。
- **UI元素**:UI通常设计在sRGB空间,应避免被线性化处理。
- 将颜色贴图错误设置为线性,导致画面偏暗。
- 将数据贴图设置为sRGB,导致数值错误。
- 忘记在最终输出时转换回sRGB,画面过亮。
注意事项
常见错误
总结
sRGB贴图工作流是保证渲染质量的基础,正确配置纹理和渲染目标的颜色空间可以避免许多视觉问题。
常见问题
为什么颜色贴图要勾选sRGB?
因为颜色贴图以sRGB空间存储,勾选sRGB后GPU在采样时会自动将其转换为线性空间,保证光照计算正确。如果不勾选,颜色会偏暗。
法线贴图需要勾选sRGB吗?
不需要。法线贴图存储的是方向数据,不是颜色,应使用线性空间。如果勾选sRGB,法线方向会被错误解码,导致光照异常。
在Unity中如何设置sRGB贴图工作流?
在Player Settings中,Color Space选择Linear。然后在纹理导入设置中,颜色贴图默认勾选sRGB,数据贴图取消勾选。
线性空间渲染比伽马空间好吗?
是的,线性空间渲染提供物理正确的光照,色彩更真实,避免过曝或失真。现代引擎和移动设备都建议使用线性空间。
sRGB和伽马校正有什么关系?
sRGB编码包含了伽马校正(约2.2),用于补偿显示器的非线性响应。伽马校正是将线性值转换为sRGB值的过程,反伽马校正是将其转回线性。