基本概念
LDR
- 全称:Low Dynamic Range
- 8位精度(0-255)
- 单通道0-1
- 常用LDR图片存储的格式有jpg/png等
- 常用DCC工具中的拾色器、一般的图片、电脑屏幕都是LDR
HDR
- 全称:High Dynamic Range
- 远高于8位精度
- 单通道可以超过1
- 常用HDR图片存储的格式有hdr/tif/exr/raw等(其中很多是相机常用格式)
- HDRI、真实世界
补充
-
Dynamic Range(动态范围)= 最高亮度/最低亮度
-
ToneMapping:将超高的动态范围(HDR)转换到我们日常显示的屏幕上的低动态范围(LDR)的过程
-
生活中的动态范围:
- 因为不同的厂家生产的屏幕亮度(物理)实际上是不统一的,那么我们在说LDR时,它是一个0到1范围的值,对应到不同的屏幕上就是匹配当前屏幕的最低亮度 0 和最高亮度 1
- 自然界中的亮度差异是非常大的。例如,蜡烛的光强度大约为15,而太阳光的强度大约为10w。这中间的差异是非常大的,有着超级高的动态范围。
- 我们日常使用的屏幕,其最高亮度是经过一系列经验积累的,所以使用、用起来不会对眼睛有伤害;但自然界中的,比如我们直视太阳时,实际上是会对眼睛产生伤害的。
-
相机是如何将HDR映射到LDR的
- 首先将曝光值进行计算,映射到相机可以感应的范围
- 受光圈、快门、传感器的灵敏度等影响
- 然后把这个值输入为线性的值,存储到图片中(一般为raw格式)
- 之后会经过一个变化(LUT),通过白平衡、色彩校正、色调映射、伽马校正这个过程,最后的结果烘焙成LUT(pbr中LUT的图,就是这个过程的结果)
- 每个相机厂商的LUT格式不太一样。
为什么需要HDR
更好的色彩,更高的动态范围和更丰富的细节, 并且有效的防止画面过曝
超过亮度值1的色彩也能很好的表现,像素光亮度变得正常,视觉传达更加真实
HDR才有超过1的数值,才有光晕(bloom)的效果,高质量的bloom能体现画面的渲染品质
HDR图资源站
Unity中的HDR
Camera-HDR设置
- 将场景渲染为 HDR 图像缓冲区
- 屏幕后处理:Bloom & Tonemapping
- 在ToneMapping过程中,会把HDR转换为LDR
- LDR图像发送给显示器
Lightmap的HDR设置
- 选择High Quality将启用HDR光照贴图的支持,选择Normal Quality将切换为使用RGBM编码
- RGBM编码:将颜色存储在RGB通道中,将乘数(M)存储在Alpha通道中
拾色器的HDR设置
- 如果将Property的颜色参数的前边加上[HDR]就会将其标识为HDR
- 颜色设置为HDR,那么拾色器中就会出现一个Intensity的滑条用来调整强度
- 滑条每增加1,提供的光强度增加一倍
HDR优缺点
-
优点
- 画面中亮度超过1的部分不会被截掉,增加了亮部的细节,减少了曝光
- 减少画面暗部的色阶感
- 更好的支持bloom效果
-
缺点
- 渲染速度慢,需要更多显存
- 不支持硬件抗锯齿
- 部分低端手机不支持
HDR与Bloom
-
Bloom用来表现光晕的效果,提高画面的表现力
-
实现过程:
- 渲染出原图
- 计算超过某个阈值的高光像素
- 对高光的像素进行高斯模糊
- 然后叠加光晕、成图
-
Unity中的Bloom过程
HDR与ToneMapping
ToneMapping概念
在显示器上表现更高动态范围的颜色,将HDR转换为LDR的过程(映射关系为色调映射)
下图为直接用线性的亮度映射效果不佳,不符合真实世界规律,一般所有的映射最后都是通过一个s曲线来实现
ACES曲线
- Academy Color Encording System学院颜色编码系统
- 是最流行、最被广泛使用的ToneMapping映射曲线
- 效果:对比度提高,能很好的保留暗部和亮部的细节
- 之后在这个基础上再进行调色
其他类型的ToneMapping曲线
LUT(Lookup Table)
- 感觉像素映射,也可以说是滤镜,通过LUT,你可以将一组RGB值输出为另一组RGB值,从而改变画面的曝光与色彩(傅老师的课用过,以及做卡渲的时候)
- 和ToneMapping不同,LUT是在LDR之间做变化。 而ToneMapping是对HDR做变换的。
- 可以在PS中调整LUT,导出的LUT作为滤镜调整画面
参考资料来源
- 《Unity Shader入门精要》
- https://docs.unity.cn/cn/current/Manual/HDR.html
- https://zhuanlan.zhihu.com/p/91390940
- https://zhuanlan.zhihu.com/p/80253409
- https://zhuanlan.zhihu.com/p/21983679
- http://www.openexr.org/
- http://www.hdrlabs.com/sibl/archive.html
- https://zhuanlan.zhihu.com/p/66518450
- https://learnopengl.com/PBR/IBL/Diffuse-irradiance
- https://learnopengl-cn.github.io/05 Advanced Lighting/06 HDR
- https://zhuanlan.zhihu.com/p/21983679
- https://zhuanlan.zhihu.com/p/421398402
- 大佬笔记
作业
结合先行版基础渲染光照介绍(一)试试IBL在HDR和LDR的区别
使用了Unity的IBL技术试了下HDR、LDR贴图的不同(后续用split sum试试)
左侧HDR,右侧LDR
可以明显看出星体和行星带部分HDR会比LDR效果更亮一些,符合我们现实观察天体的效果,也增强了画面表现力、宽容度。
使用不同的mipmap层级,HDR保留的细节会多一点,毕竟精度更高。目前用的是和先行版_Gloss计算层级,下面是PBR中用粗糙度控制
1 | float3 reflectDirWS = reflect(-viewWS,normalWS); |
补充下各个ToneMapping实现
-
Reinhard tone mapping
1
2
3
4
5
6float3 ReinhardToneMapping(float3 color, float adapted_lum)
{
const float MIDDLE_GREY = 1;
color *= MIDDLE_GREY / adapted_lum;
return color / (1.0f + color);
} -
CryEngine2的做法
1
2
3
4float3 CEToneMapping(float3 color, float adapted_lum)
{
return 1 - exp(-adapted_lum * color);
} -
Filmic tone mapping
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17float3 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);
} -
ACES
1
2
3
4
5
6
7
8
9
10
11float3 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);
}