颜色工作流程

线性和非线性伽马色彩空间

sRGB 色彩空间的目的是表示在计算机显示器上显示的颜色。目前,sRGB 是非线性伽马色彩空间的标准。之所以需要它,是因为人类对光的感知是非线性的,而计算机显示器对光强度的响应也是非线性的。

人眼对较暗色调的区分能力优于较亮色调。因此,在屏幕上存储和显示图像时,为深色强度保留更多的准确性是有意义的。非线性伽马色彩空间通过伽马校正实现这一点,它通过幂函数处理图像中每个像素的强度:

\[I^{\gamma}\]

图像通常以应用了编码伽马的方式存储,屏幕则应用解码伽马。此图像显示了 Kanzi 用于在线性和伽马色彩空间之间转换的伽马传递函数图。

../../_images/gamma.svg

此图像显示了一个渐变,其中屏幕发出的光的强度线性增加。

../../_images/linear_emitted_intensity.png

将解码伽马应用于上述渐变会产生此渐变,其中感知光强度线性增加。

../../_images/linear_perceptual_intensity.png

非线性伽马色彩空间的问题在于其不适合图形操作。在非线性空间中进行颜色计算会导致颜色和 alpha 混合结果不准确。线性色彩空间对于数学上正确的光照和颜色混合计算是必需的。

在线性色彩空间中,数值强度值对应于其实际强度,这使得可以正确地添加和乘以颜色值。线性色彩空间渲染提供了更准确的结果和更真实的表面阴影,特别是在使用基于物理的渲染技术时。

这些图像显示了在非线性伽马(左)和线性(右)色彩空间中混合的示例。在非线性伽马色彩空间中混合会导致过亮的混合和饱和的色带。

../../_images/legacy-blending.png ../../_images/linear-blending.png

默认情况下,Kanzi 使用线性色彩工作流程,其中 Kanzi 在线性色彩空间中对色值进行操作。请参阅 使用线性颜色工作流 和 将应用程序从传统色彩工作流程转换为线性色彩工作流程。。

Kanzi 还支持非线性伽马或传统颜色工作流程,其中 Kanzi 在伽马颜色空间中对颜色值进行操作。请参阅 使用 legacy color workflow。

使用线性颜色工作流

默认情况下,Kanzi 使用线性色彩工作流程。这使得光照计算更加真实,并且颜色混合更加准确。为了实现精确的颜色和光照渲染,Kanzi 在进行操作之前将所有颜色值转换为线性色彩空间。然后,Kanzi 将颜色值转换回伽马色彩空间以进行存储或显示。

图像 (Images)

要在您的 Kanzi Studio 项目中配置图像以进行线性色彩工作流程:

  • 在 Library > Resource Files > Images 中,对于每个使用 ASTC、ETC2、JPEG、PNG 或 PVRTC 格式的图像资源,设置 sRGB Content 属性的值:

    • 如果图像包含 sRGB 颜色信息,请将 sRGB Content 属性设置为启用。这是默认设置。

      如果您禁用包含 sRGB 颜色信息的图像的 sRGB Content 属性,Kanzi 渲染使用该图像的纹理时可能会比预期更亮。

    • 如果图像包含非颜色信息,例如法线、粗糙度或遮挡贴图,请将 sRGB Content 属性设置为禁用。

      包含非颜色信息的纹理以线性格式存储。通过禁用 sRGB Content 属性,您将 Kanzi 设置为直接将图像数据传递给着色器,而不执行颜色空间转换。

    ../../_images/srgb-content.png
  • 默认情况下,Kanzi 在线性色彩空间中预乘图像的 alpha 通道。要在图像的色彩空间中预乘 alpha 通道,请在 Library > Resource Files > Images 中选择一个图像,并在 Properties 中禁用 Linear Premultiply 属性。请参阅 在第三方工具中准备图像。

    ../../_images/linear-premultiply.png

颜色属性绑定

要在线性色彩工作流中的绑定表达式中设置颜色值:

  • 在 sRGB 色彩空间中指定 Color4 值。请参阅 color4。

    例如:

    Color4(0, 0.75, 0.25, 1)
    
    ../../_images/r0g192b64.png
  • 在线性色彩空间中指定各个 RGB 色彩通道的值。

    使用 sRGBToLinear 绑定函数将颜色通道值转换为线性色彩空间。

    例如:

    • 此绑定表达式等于 Color4(0, 0.75, 0.25, 1):

      color = Color4(0, 0, 0, 1)
      color.g = sRGBToLinear(0.75)
      color.b = sRGBToLinear(0.25)
      color
      
      ../../_images/r0g192b64.png
    • 此绑定表达式等于 Color4(0, 0.879, 0.535, 1):

      color = Color4(0, 0, 0, 1)
      color.g = 0.75
      color.b = 0.25
      color
      
      ../../_images/r0g225b137.png

着色器 (Shaders)

在线性色彩工作流程中,着色器期望颜色输入为线性色彩空间,并在输出时也是线性色彩空间。为了在以每通道8位的纹理格式中存储颜色值时保持准确性,Kanzi 在存储之前将颜色值转换回 sRGB 色彩空间。

Graphics API

线性颜色工作流程需要:

  • OpenGL 扩展 GL_EXT_sRGB 以启用在 sRGB 模式下创建帧缓冲区。

  • EGL 版本 1.5 或更高版本,或带有 EGL_KHR_gl_colorspace 扩展的 EGL 版本 1.4。

要使用线性色彩工作流程,确保在 Project > Properties 中将 Target Graphics API 设置为 OpenGL ES 2.0 Extension Pack 或更高。默认值为 OpenGL ES 2.0 Extension Pack。

使用 legacy color workflow

在传统颜色工作流中,Kanzi 在非线性伽马色彩空间中对颜色值进行操作。这比线性色彩工作流提供的渲染结果精度较低。

当您使用传统颜色工作流程时:

  • 将您的应用程序部署到不支持线性色彩空间的设备。

    要支持线性色彩空间,您的目标平台必须实现 EGL 1.5 版或更高版本,或带有 EGL_KHR_gl_colorspace 扩展的 EGL 1.4 版。

    然后 Kanzi 会使用 Legacy 颜色空间重新尝试创建 EGL 窗口表面。如果回退成功,应用程序将继续使用旧版颜色空间。

    如果 Kanzi 无法使用 Legacy 颜色空间创建 EGL 窗口表面,它会报告一个错误,其中包含所请求的颜色空间和 EGL 错误代码。在这种情况下,请将应用程序配置为使用旧版颜色工作流。

  • 将项目从较早版本的 Kanzi 迁移。

在传统颜色工作流程中,Kanzi 不会转换颜色输入。如果您使用 Kanzi Engine API 创建 ColorRGBA 对象,请在 sRGB 色彩空间中提供颜色值。

要使用传统颜色工作流程:

  1. 通过设置以下任一项,将您的应用程序配置为使用未指定的颜色空间:

    • 在 application.cfg:

      SurfaceColorSpace = "legacy"
      
    • 在 C++ 应用程序中的 Application::onConfigure 函数中:

      configuration.defaultSurfaceProperties.colorSpace = "legacy";
      

    请参阅 SurfaceColorSpace。

  2. 在 Kanzi Studio 中,在 Project > Properties 中将 Color Workflow 属性设置为 Legacy。

    ../../_images/project-properties.png ../../_images/color-workflow-legacy.png
  3. 编写着色器以在目标显示器的伽马空间中输出颜色,这很可能是 sRGB。请参阅 着色器 (Shaders)。

将应用程序从传统色彩工作流程转换为线性色彩工作流程。

要将您的应用程序从传统颜色工作流转换为线性色彩工作流:

  1. 通过移除以下内容,将您的应用程序配置为使用 sRGB 色彩空间:

    • 在 application.cfg:

      SurfaceColorSpace = "legacy"
      
    • 在 C++ 应用程序中的 Application::onConfigure 函数中:

      configuration.defaultSurfaceProperties.colorSpace = "legacy";
      

    当您移除该配置时,Kanzi 对 SurfaceColorSpace 使用默认值 srgb。请参阅 SurfaceColorSpace。

  2. 在 Project > Properties 集中的 Kanzi Studio 中:

    • Color Workflow 到 Linear

    • Target Graphics API 到 OpenGL ES 2.0 Extension Pack 或更高版本。

    ../../_images/project-properties.png ../../_images/color-workflow-linear.png ../../_images/target-graphics-opengl-es-2.0-extension-pack.png
  3. 在 Library > Materials and Textures > Material Types 中,对于每种材料类型,确保将:

    • 绑定不包含不必要的手动添加的 sRGB 转换。

      例如,您不需要使用 linearTosRGB 绑定函数将颜色值从线性色彩空间转换为 sRGB 色彩空间。在线性色彩工作流中,着色器期望颜色输入为线性色彩空间。

    • 着色器在输入或输出时不应用伽马校正。

      在线性色彩工作流程中,着色器期望颜色输入为线性色彩空间,并且它们输出的颜色也在线性色彩空间中。

  4. 在 Library > Resource Files > Images 中,对于每个使用 ASTC、ETC2、JPEG、PNG 或 PVRTC 格式的图像资源,检查 sRGB Content 属性是否设置正确:

    • 如果图像包含 sRGB 颜色信息,请将 sRGB Content 属性设置为启用。这是默认设置。

      如果您禁用包含 sRGB 颜色信息的图像的 sRGB Content 属性,Kanzi 渲染使用该图像的纹理时可能会比预期更亮。

    • 如果图像包含非颜色信息,例如法线、粗糙度或遮挡贴图,请将 sRGB Content 属性设置为禁用。

      包含非颜色信息的纹理以线性格式存储。通过禁用 sRGB Content 属性,您将 Kanzi 设置为直接将图像数据传递给着色器,而不执行颜色空间转换。

    ../../_images/srgb-content.png
  5. 要获得所需的颜色混合效果,请在项目中根据需要调整部分透明的颜色。

    例如:使用这些颜色画笔填充的节点在传统和线性色彩工作流模式下看起来不同:

    ../../_images/red-green-blue-brushes.png

    Legacy 颜色工作流程

    Linear 颜色工作流程

    ../../_images/color-brush-blending-legacy.png ../../_images/color-brush-blending-linear.png

另请参阅

应用程序开发

材质类型和材质

着色器 (Shaders)

图像 (Images)

纹理 (Textures)

Bindings expressions 参考