Vulkan 交换链格式 UNORM 与 SRGB?

And*_*zos 10 vulkan

在 Vulkan 程序中,片段着色器通常向每个红/蓝/绿通道输出 0.0 到 1.0 范围内的单精度浮点颜色,然后将这些颜色写入(混合到)交换链图像中,然后呈现在屏幕上。根据交换链图像的格式(创建交换链时指定),浮点值被编码为位。

当我将交换链格式从 更改为 时,VK_FORMAT_B8G8R8A8_UNORMVK_FORMAT_B8G8R8A8_SRGB观察到帧的整体亮度大大增加,并且还存在一些轻微的颜色变化。

我对 SRGB 格式的理解是,它很像 UNORM 格式,只是浮点值到 8 位整数的映射不同,因此它在某些区域具有更高的颜色分辨率,而在其他区域具有较低的颜色分辨率,但实际含义“预编码”RGB 浮点值的数量保持不变。

所以我对亮度的增加有点惊讶。难道我对SRGB编码的理解有误?和/或与 UNORM 相比,这种亮度增加是预期的吗?

或者也许我有一个错误并且亮度不会增加?

更新:

我观察到,如果我使用 SRGB 交换链图像以 VK_FORMAT_B8G8R8A8_SRGB 格式而不是 VK_FORMAT_B8G8R8A8_UNORM 加载图像/纹理,那么额外的亮度就会消失。它看起来就像我使用 VK_FORMAT_B8G8R8A8_UNORM 交换链图像并以 VK_FORMAT_B8G8R8A8_UNORM 格式加载图像/纹理一样。

另外,如果我将交换链图像放入 VK_FORMAT_B8G8R8A8_UNORM 格式,然后使用 VK_FORMAT_B8G8R8A8_SRGB 加载图像/纹理,则帧看起来特别暗/几乎是黑色。

弄清楚正在发生的事情会很有帮助。

Nic*_*las 18

这是色彩空间和显示问题。

假定片段着色器在线性 RGB 色彩空间中写入值。因此,如果您要渲染具有线性 RGB 色彩空间 ( UNORM) 的图像,则直接解释 FS 生成的值。当渲染具有 sRGB 色彩空间的图像时,您正在将一个空间(线性)中的值写入另一个空间(sRGB)中。因此,这些值会自动转换为 sRGB 色彩空间。这与将位置从模型空间转换到世界空间或其他空间没有什么不同。

不同的是你一直错误地看待你的场景。VkSurfaceFormat::colorSpace看,你的交换链的价值很有可能是VK_COLOR_SPACE_SRGB_NONLINEAR_KHR

VkSurfaceFormat::colorspace告诉您显示引擎将如何解释您呈现的交换链图像中的像素数据。这不是您提供的设置;这是显示引擎告诉您它将如何解释您发送给它的值。

我说它是 sRGB“可能性非常大”,因为在扩展之外,这是唯一可能的值。无论您是否喜欢,您都会渲染到 sRGB 显示设备。

因此,如果您写入 UNORM 图像,显示设备将读取实际的数据位并解释它们,就好像它们位于 sRGB 色彩空间中一样。仅当片段着色器自己编写的数据位于 sRGB 色彩空间中时,此操作才有意义。

然而,FS 通常不是这样生成数据的。您计算的光照计算仅对线性 RGB 色彩空间中的颜色值有意义。因此,除非您编写 FS 在计算最终颜色值后故意进行 sRGB 转换,否则您的所有结果很可能都在线性 RGB 颜色空间中。这就是您一直在写入帧缓冲区的内容。

然后显示引擎会破坏它

通过使用 sRGB 图像作为目标,您可以强制进行从线性 RGB 到 sRGB 的色彩空间转换,然后显示引擎将其解释为 sRGB 值。这意味着您的照明方程最终产生了正确的结果

无法正确进行伽玛校正渲染(包括几乎肯定也在 sRGB 色彩空间中的源纹理图像,因为这是大多数图像编辑器的默认色彩空间。例外情况是光泽贴图、法线贴图或其他不存储“颜色”的图像。)导致线性光注意看起来比二次衰减更正确的情况,尽管二次衰减是现实的运作方式


J. *_*lly 5

这就是伽玛校正。

将交换链与 VK_FORMAT_B8G8R8A8_SRGB 结合使用,可以利用应用伽马校正作为渲染管道中最后一步的能力。这会在幕后自动为您发生。

这是您唯一希望进行伽玛校正的地方。确保您的着色器没有应用伽玛校正。您可能会将其视为:

color = pow(color, vec3(1.0/2.2));
Run Code Online (Sandbox Code Playgroud)

如果您的交换链执行伽玛校正,则无需在着色器中执行此操作。

大多数图像都是 SRGB(图片、颜色纹理等)。线性图像适用于特定数据,例如蓝色噪声纹理或高度图。

  • 使用 VK_FORMAT_R8G8B8A8_SRGB 加载 SRGB 图像
  • 使用 VK_FORMAT_R8G8B8A8_UNORM 加载线性图像

如果遵循上述规则,则不需要着色器转换。