【笔记】【百人计划】图形2.7 LDR与HDR

一、基本概念

HDR = High Dynamic Range(高动态范围)

LDR = Low Dynamic Range(低动态范围)

动态范围 = 最高亮度/最低亮度

  • 对于显示器来说,实际的物理亮度是不同意的。因此需要匹配LDR0-1的范围

  • 自然界中的亮度是HDR的

    • 在显示时需要转换到LDR的范围(Tone mapping色调映射)
  • LDR

    • 8位精度
    • 单通道0-1(0-255)
    • 常用LDR图片储存格式
      • jpg、png等
    • 拾色器、一般图片、电脑屏幕
  • HDR

    • 远高于8位精度
    • 单通道可以超过1
    • 常用HDR图片储存格式
      • hdr/tif/exr/raw
    • HDRI、真实世界

为什么需要HDR

  • 更好地色彩,更高的动态范围和更丰富的细节,并有效地防止画面国宝,超过亮度值1的色彩也能很好地表现,像素光亮度变得正常,视觉传达更真实。
  • HDR有超过1的数值,范围更大,能让bloom的表现更好。

一些HDR图网站

http://www.hdrlabs.com/sibl/archive.html

https://www.openfootage.net/hdri-panorama/

二、Unity中的HDR

Camera-HDR设置

  • 场景将渲染为HDR图像缓冲区
  • 后处理:Bloom&Tone mapping
  • 完成转换HDR->LDR
  • LDR图像发送给显示器
image-20220730183404967

Lightmap HDR设置

  • 选择High Quality 将启用HDR光照贴图支持,而Normal Quality将切换为使用RGBM编码
  • RGBM编码:将颜色存储在RGB通道中,将乘数M储存在Alpha通道中

(项目设置-Player-Other settings-Lightmap Encoding)

image-20220730183556522

拾色器HDR设置

1
[HDR] _BackColor("BackColor", Color) = (1,1,1,1)
  • 使用Intensity滑动条可调整颜色强度
  • 每增加1,提供的光亮增加一倍

image-20220730183703721

HDR的优缺点

  • 优点
    • 画面中亮度超过1的部分不会被截为1,增加亮部细节并减少曝光
    • 减少画面较暗部分的色阶感
    • 更好地支持Bloom
  • 缺点
    • 渲染速度较慢,需要更多显存
    • 不支持硬件AA
    • 部分手机不支持

三、HDR与Bloom

Bloom用于表现高光的晕光效果

为实现泛光,我们像平时那样渲染一个有光场景,提取出场景的HDR颜色缓冲以及只有这个场景明亮区域可见的图片。被提取的带有亮度的图片接着被模糊,结果被添加到HDR场景上面。(learnopengl)

unity中的BLoom

Untiy会首先进行下采样(down sample)来计算高光像素,并存在RT中,完成次数由一个参数控制,再up回去,并将下采样的RT加入进去。

image-20220730184829163

我对这个操作目前的理解是,和learnopengl中为了完成高斯模糊是一样的

img

在毛星云大佬的 《高品质后处理:十种图像模糊算法的总结与实现》中也可以看到对各种模糊算法的解释,如果说是以多次的Box filtering来近似高斯模糊或者其他模糊效果的话,就很好理解了。

四、HDR与Tone mapping

色调映射就是为了把HDR转化为LDR

  • 线性映射效果不好
image-20220730185314765
  • 把高光区域和阴影区域像中等亮度方向压缩->S曲线

ACES

ACES(Academy Color Encoding System学院颜色编码系统)

效果:对比度提高,很好地保留暗处和亮出的细节

image-20220730185423773
1
2
3
4
5
6
7
8
9
10
11
12
13
// ACES
//https://knarkowicz.wordpress.com/2016/01/06/aces-filmic-tone-mapping-curve/
float3 ACESToneMapping(float3 color, float adapted_lum)
{
const float A = 2.51f;
const float B = 0.03f;
const float C = 2.43f;
const float D = 0.59f;
const float E = 0.14f;

color *= adapted_lum;
return (color * (A * color + B)) / (color * (C * color + D) + E);
}

其他Tone mapping曲线

image-20220730185538359
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// Reinhard
float3 ReinhardToneMapping(float3 color, float adapted_lum)
{
const float MIDDLE_GREY = 1;
color *= MIDDLE_GREY / adapted_lum;
return color / (1.0f + color);
}
// CE
float3 CEToneMapping(float3 color, float adapted_lum)
{
return 1 - exp(-adapted_lum * color);
}
// Filmic
float3 F(float3 x)
{
const float A = 0.22f;
const float B = 0.30f;
const float C = 0.10f;
const float D = 0.20f;
const float E = 0.01f;
const float F = 0.30f;

return ((x * (A * x + C * B) + D * E) / (x * (A * x + B) + D * F)) - E / F;
}

float3 Uncharted2ToneMapping(float3 color, float adapted_lum)
{
const float WHITE = 11.2f;
return F(1.6f * adapted_lum * color) / F(WHITE);
}

LUT

在Color Grading的All None 模式中有一个Lookup Texture(滤镜)

  • LUT在LDR之间做变换,Tone mapping是映射HDR到LDR

  • 调整rgb三个通道的LUT被称为3D LUT

img

img

作业

结合先行版基础渲染光照介绍(一)试试IBL在HDR和LDR的区别

相机设置HDR

左侧探针设置LDR,右侧探针设置HDR,都是1024的分辨率

在生成的贴图上可以看到,一张是exr后缀的HDR贴图,一张是png后缀的LDR贴图。

把它放在我们的材质上,说实话我没看出来有啥区别……

image-20220731223034086

但是随着Lod层级的增加,就可以看出来区别了

image-20220731223343672 image-20220731223409296 image-20220731223432177

非常地合情合理,在HDR中储存的辐射度范围是大于0-1的,在mipmap中也会储存更高动态范围的光照,在ibl里的细节也就更丰富。

参考资料

[1] https://www.bilibili.com/video/BV1VA41137Wp ,【技术美术百人计划】图形 2.7 LDR与HDR

[2] https://learnopengl-cn.github.io/05%20Advanced%20Lighting/07%20Bloom/

[3] https://zhuanlan.zhihu.com/p/125744132 ,高品质后处理:十种图像模糊算法的总结与实现

[4] Unity Shader入门精要 p361,362

[5] https://zhuanlan.zhihu.com/p/21983679 ,Tone mapping进化论