游戏实时渲染中HDR入门介绍

游戏实时渲染中HDR入门介绍

虽然HDR这个概念绝大多数做游戏的人都知道了,不过可能有的人会像我一样一直对这个概念一知半解,这里做下学习笔记,省的以后又忘了= =

1. 到底什么是HDR?
这个概念大概很多人早就听说了,比如买电视的时候,看游戏宣传的的时候,都声称自己是HDR啥啥啥的,那么到底啥是HDR呢?咱能不能把这玩意用到自己的游戏之中呢?如果查百度的话大概会得到这个答案:High Dynamic Range,再仔细看看的话意思大概是高动态光啥啥啥的,然后我就一脸懵逼,还是没懂。那么这个高动态指的是什么呢:原来的(或者说传统的)颜色范围是0~1,8位的,255阶,而现实中的颜色/光强范围肯定没这么少,HDR也就是让这个范围超过1,一般是用16位float来储存(用32位也行,不过内存太大精度过高一般用不到),这样就可以储存更多的东东,精度更高,效果自然更好。然而到这里自然就会产生一个问题,那个好像现在显卡输出,显示器接受的格式好像还是0~1的8位格式吧(目前有新的显示器&电视啦,支持真HDR,即你可以超出8位输出啦,这个暂且不提),你超过1有啥用,最后还不是得弄回来(弄回来的方式叫做Tone mapping,这个下面再说),这样岂不是效果差不多?看下面分析。

2. HDR对于游戏起什么作用,和不用HDR比的话。
既然说到最后还是0~1,那么HDR还有什么作用呢?其中有一种原因是超过1的值会给做Bloom,Bloom是用来模仿人眼看超亮的东西产生的一种光向外溢出的效果,这个超亮并不是指大于1就一定是超亮,但是和HDR结合的话,用1作为阈值效果还不错,所以就这么用了,当然也可以设为其它值,比如设成0,那么就是全屏高斯模糊(一般Bloom的实现方式)了。为了只让超亮的东西Bloom,HDR是有必要的,不然没有大于1的值,你只能设个0.8什么的,那样其实Bloom的地方有很多,这样会显得图像很模糊。下面车的窗户就是Bloom效果。
游戏实时渲染中HDR入门介绍_第1张图片

有的同学可能会说我不用Bloom,或者说我就自己调一个阈值,效果其实还不错,那HDR我就不用了行不行。HDR的作用并不只是配合Bloom使用,它更基本的作用是让渲染更加正确,更加真实(尤其是配合特别物理的PBR^_^人家PBR好不容易计算这么真实,你没HDR,结果全错了。。。)。这么说太虚了,具体解释一下:在LDR(即非高动态范围)中,因为范围是0~1,那么最后计算结果如果超过1的话(光照方程可没限制结果必须小于1)那么就会被clamp成1,啥细节都没了,也就是说超亮的光照不能有。下图就是被clamp的东东,细节啥都看不清。
游戏实时渲染中HDR入门介绍_第2张图片

美术同学在打光的时候如果出现这种事情,那么本能的做法是降低光照强度,让最后计算的结果处于0~1的范围中,但这种做法会造成不好也不真实的渲染结果,毕竟你不能说阳光的强度和小手电的光照强度差不多吧?白天和夜晚的各种光源强度差不多?美术同学当然可以根据经验(以前都是这么做的)来调一个可以接受的光照,但是这种结果并不是正确的,也会严重影响PBR的效果。材质已经是按照实际的物理来制作了,但是光源是经验值,这样出来的结果肯定不好看。正确的方式当然是可以大于1才行,这样的话亮的东西能够特别亮,暗的也能特别暗,然后细节还都能看得到。
游戏实时渲染中HDR入门介绍_第3张图片
上图左边是用了HDR的,右边是没用的,可以看出人脸上面红色和绿色已经超过1了,clamp后过爆并且发黄。如果不想过爆,就得降低光照强度,这样别的地方有可能会过暗,然后又可能得补光,最后就是整体画面变“平”,各种错误叠加。

3. HDR环境贴图是啥?
大概上网搜什么环境Cubemap,全景图天空盒的时候经常会看见这个词:HDR贴图。这是啥?这个意思就是贴图存储的颜色是超过1的,不是用传统的8位存储。这个有啥作用呢?因为Cubemap经常用于Image Based Lighting,也就是间接光的光源用,这个光源不能说是只有0~1吧,超过1是很正常的,所以如果不是HDR的话效果其实不好也不对。尤其是渲染绝缘体的时候,因为PBR的理论,绝缘体的反射(即间接高光)很弱,也就是5%光强不到的样子,这样如果光强如果不到1的话,一乘,结果就是特别暗,就像下图,所以HDR贴图还是很有必要的。
游戏实时渲染中HDR入门介绍_第4张图片

4. 一直和HDR息息相关的Tone mapping又是做什么的。
上面HDR其实说了一半,非常重要的另一半,就是如何将算出来的颜色重新映射会0~1怎么做呢?这个过程叫做Tone mapping,是在场景渲染完成之后,后处理中进行的。做法也都是将0~n区间的数值通过函数映射到0~1区间,具体的Tone mapping算法有好多种,其中Reinhard tone mapping是最开始用的,也是最简单的,具体算法很简单:
texColor = texColor/(1+texColor);
然后又有数种更好的Tone mapping算法,具体可以见 https://zhuanlan.zhihu.com/p/21983679?refer=highwaytographics里面总结了Tone mapping算法历史进程。

5. Automatic exposure是什么?或者说更基础的Exposure是什么,在HDR中起什么作用?
看HDR资料的时候,经常会出现Exposure,或者说曝光这个摄影用词。为啥会有摄影用词呢?可以说HDR本身,包括相关的各种色调调整等处理其实都是从电影行业传过来的,算法也都是和电影行业息息相关,随着即时渲染越来越真实,其算法也越来越贴近真实世界,或者说向电影业(作为先驱者已经对于图像处理有一套成熟理论了)借鉴学习。具体到曝光这个东西,在摄影中指的是进光量,也就是由光圈,快门速度决定多少光打到感光原件上。
而到游戏中,曝光可以很简单的认为(具体算法没那么简单,更多是模拟了摄像机的参数,以方便美术同学调整)就是一个系数,用来乘以计算出来的颜色,让整体画面变亮或变暗。作用是模仿眼睛,比如在夜景的时候使用高曝光值,使得暗部细节能够看到,而很亮的地方使用低曝光值,让亮的细节能够看到。这样使得整体场景打光可以统一且按照真实情况打光,不需要为了看清细节错误的调整光照。这个过程是在Tonemapping之前做。
一般由美术同学调整这个值,而Automatic exposure则是自动完成这一过程,原理是检测前几帧的画面平均亮度(这个需要Compute Shader),然后根据亮度来自动调整曝光度,让整个画面处于一个适度的亮度中,比如从一个暗房走出到阳光下的时候,开始会很刺眼啥都看不清,几秒后就能看清了,这个就是自动曝光在调整,这个过程也是模拟了人眼在现实中的效果。

参考:
1. https://learnopengl.com/#!Advanced-Lighting/HDR
2. https://knarkowicz.wordpress.com/2016/01/09/automatic-exposure/



你可能感兴趣的:(游戏实时渲染中HDR入门介绍)