LDR与HDR
B站视频:图形 2.7 LDR与HDR
文章目录
- LDR与HDR
- 基本概念
- LDR
- HDR
- 为什么需要HDR
- 不同显示屏的差异
- Unity中的HDR
- Camera HDR 设置
- Lightmap HDR设置
- 拾色器 HDR设置
- 优缺点
- HDR与Bloom
- 通常Bloom渲染步骤
- 渲染出原图
- 获取图像中较亮部分
- 高斯模糊
- 叠加
- Unity中Bloom渲染步骤
- HDR与Tonemapping
- ACES
- LUT
- 其他参考资料
基本概念
HDR: High Dynamic Range,高动态范围
LDR: Low Dynamic Range,低动态范围
动态范围(Dynamic Range) = 最高亮度 / 最低亮度
LDR
- 8位精度(256精度);
- 单通道 0-1;
- 常用LDR图片储存格式:jpg、png、tga等;
- 拾色器、一般的图片、电脑屏幕。
HDR
- 远高于8位精度;
- 单通道可超过1;
- 常用HDR图片储存格式:hdr、tif、exr、raw等;
- HDRI、真实世界。
为什么需要HDR
-
**更好的色彩,更高的动态范围和更丰富的细节。**并且有效的防止画面过曝,超过亮度值1的色彩也能很好的表现,像素光亮度变得正常,视觉传达更加真实;
-
HDR才有超过1的数值,才有光晕(bloom)的效果,高质量的bloom能体现画面的渲染品质;
不同显示屏的差异
市场上的不同显示屏,它们由于不同的厂家以及不同的实现工艺手法,它们的实际亮度(物理亮度)是不统一的。以LDR来说,LDR范围为[0, 1],对应到不同屏幕上时,由于显示屏的亮度、强度不一致,就需要进行对应的匹配,也就是说匹配当前屏幕最低亮度0到最高亮度1的范围,这一步骤由各自厂家完成。
Unity中的HDR
Camera HDR 设置
- 场景将渲染为HDR图像缓冲区;
- 屏幕后处理:Bloom & Tonemapping;
- Tonemapping中完成转化:HDR -> LDR;
- LDR图像发送给显示器。
Lightmap HDR设置
- 选择High Quality将启用HDR光照贴图支持,而Normal Quality将切换为使用RGBM编码;
- RGBM编码:将颜色存储在RGB通道中,将乘数(M)存在Alpha通道中。
拾色器 HDR设置
- 使用Intensity滑动条可以调整颜色的强度;
- 滑动条每增加1,提供的光亮增加一倍;
- 在Shader中的属性栏内,目标颜色添加[HDR]标签。
Properties
{
[HDR]_Color ("Color", Color) = (1,1,1,1)
}
优缺点
优点
- 画面中亮度超过1的部分不会被截为1,增加亮部的细节并且减少曝光;
- 减少画面较暗部分的色阶;
- 更好地支持Bloom效果。
缺点
- 渲染速度较慢(增加了Tonemapping步骤),需要更多的显存;
- 不支持硬件抗锯齿;
- 部分手机不支持。
HDR与Bloom
通常Bloom渲染步骤
渲染出原图
获取图像中较亮部分
从原图提取出超出阈值的高亮部分。
高斯模糊
对提取出的高亮部分进行高斯模糊。
叠加
将高斯模糊后的高亮部分和原图进行叠加,得出最终效果。
Unity中Bloom渲染步骤
Unity实现Bloom效果和通常步骤不太一样。会在第一步先进行down sample(降采样,将原图分辨率减半)计算高光像素,然后根据down sample次数不断地进行降采样,并存到一张Render Texture中。次数到底后,再一步步up sample(升采样)回去。在up sample过程中,叠加之前相同次数的Render Texture。最终,回到原来的分辨率。
HDR与Tonemapping
在自然界中存在不同光源,不同光源的动态范围也不一样。例如蜡烛光的动态范围[10, 15](非真实值)、太阳光的动态范围[100000, 150000](非真实值),将这些动态范围转换到屏幕上可以看到的低动态范围,这个过程就叫做Tonemapping。
- 色调映射;
- Tonemapping:把HDR转化为LDR;
- 线性映射效果极差;
- 把高亮区域和阴影区域中等亮度方向压缩 -> S曲线;
ACES
- Academy Color Encoding System 学院颜色编码系统;
- 最流行、最被广泛使用的Tonemapping 映射曲线;
- 效果:对比度提高,很好地保留暗处和亮处的细节。
LUT
完整的ACES Tonemapping算法需要对每个像素做两次矩阵乘法以及两次多项式运算,如果在全屏后处理中使用,性能浪费较大。目前通行的优化方案是使用颜色查找表(Look Up Table, LUT),将每个像素颜色的计算过程转化为一次贴图采样。Unity中使用的Color LUT长这样:
Color LUT的具体使用步骤如下:
- 确定LUT使用的坐标空间,Unity使用的是Log C空间,该空间可以将[0, 59) 范围内的颜色值压缩到[0, 1];
- 选择LUT尺寸size,创建一张 size * (size * size) 大小的2D贴图;
- 逐个遍历像素,以uv坐标和尺寸换算到LUT空间坐标,再转换回线性空间颜色;
- 对线性空间颜色应用Tonemapping,结果写入像素对应uv处;
- 实际需要Tonemapping时,将输入线性空间颜色转换到LUT空间,再转换为uv坐标,采样LUT贴图,采样值作为最终结果;
- 也可以使用3D贴图,这样可以省去uv坐标转换的步骤;
使用Color LUT可以将对颜色的所有后处理全部整合到一起,因为不管多么复杂的计算,在实际应用时都转化成了一次采样。那么除了Tonemapping之外,其他诸如色相色温白平衡饱和度这样的调整统统都可以塞到一起去,这也就是为什么我们看Unity中生成LUT那个Shader里有一大堆参数了。
其他参考资料
Tone mapping进化论 - 知乎
【图形学基础拾遗】系统性理解颜色空间、HDR与Tonemapping - 知乎