什么是HDR

作者:追风剑情 发布于:2017-8-13 12:27 分类:Shader

      在使用基于物理的渲染时,我们经常会听到一个名词就是HDR。HDR是High Dynamic Range的缩写,即高动态范围,与之相对的是低动态范围(Low Dynamic Range, LDR)。那么这个动态范围是指什么呢?通俗来讲,动态范围指的就是最高的和最低的亮度值之间的比值。在真实世界中,一个场景中最亮和最暗区域的范围可以非常大,例如,太阳发出的光可能要比场景中某个影子上的点的亮度要高出几万倍,这些范围远远超过图像或显示器能够显示的范围。通常在显示设备使用的颜色缓冲中每个通道的精度为8位,意味着我们只能用这256种不同的亮度来表示真实世界中所有的亮度,因此,在这个过程中一定会存在一定的精度损失。早期的拍摄设备利用人眼的特点,使用了伽马曲线来对捕捉到的图像进行编码,尽可能充分地利用这些有限的存储空间。然而,HDR的出现给我们带来了新的希望,HDR使用远远高于8位的精度(如32位)来记录亮度信息,使得我们可以表示超过0~1内的亮度值,从而可以更加精确地反映真实的光照环境。尽管我们最后还是需要把信息转换到显示设备使用的LDR内,但中间的计算却可以让我们得到更加真实可信的效果。Nvidia曾总结过使用HDR进行渲染的动机:让亮的物体可以真的非常亮,暗的物体可以真的非常暗,同时又可以看到两者之间的细节。

      使用HDR来存储的图像被称为高动态范围图像(HDRI),使用一张HDRI图像来作为场景的Skybox。这样的Skybox可以更加真实地反映物体周围的环境,从而得到更加真实的反射效果。不仅如此,HDR对与光照叠加也有非常重要的作用。如果我们的场景中有很多光源或是光源强度很大,那么一个物体在经过多次光照渲染叠加后最终得到的光照亮度很可能会超过1。如果没有使用HDR,这些超过1的部分全部会截取到1,使得场景丢失了很多亮部区域的细节。但如果开启了HDR,我们就可以使用色调映射(tonemapping)技术来控制这个转换的过程,从而允许我们最大限度地保留需要的亮度细节。

      HDR的使用可以允许我们在屏幕后处理中拥有更多的控制权。例如,我们常常同时使用HDR和Bloom效果。Bloom效果需要检测屏幕中亮度大于某个阈值的像素,把它们提取出来后进行模糊,再叠加到原图像中。但是,如果不使用HDR的话,我们只能使用小于1的阈值来提取需要的像素,但很多时候我实际上是需要提取那些非常亮的区域,例如车窗上对太阳的强烈反光。由于没有使用HDR,这些值实际上很可能和街上一些颜色偏白的区域几乎一样,造成不希望的区域也会出现泛光的效果。如果我们使用HDR,这些就可以解决了,我们只需要使用超过1的阈值来只提取那些非常亮的区域即可。

      总体来说,使用HDR可以让我们不会丢失高亮度区域的颜色值,提供了更真实的光照效果,并为一些屏幕后处理提供了更多的控制能力。但HDR也有自身的缺点,首先由于使用了浮点缓冲来存储高精度图像,不仅需要更大的显存空间,渲染速度会变慢,除此之外,一些硬件并不支持HDR。而且一旦使用了HDR,我们无法再利用硬件的抗锯齿功能。事实上,在Unity中如果我们同时打开了硬件的抗锯齿(在Edit->Project Settings->Quality->Anti Aliasing中打开)和摄像机的HDR,Unity会发出警告来提示我们由于开启了抗锯齿,因此,无法使用HDR缓冲。尽管如此,我们可以使用基于屏幕后处理的抗锯齿操作来弥补这一点。

      在Unity中使用HDR也非常简单,我们可以在Camera组件面板中打开HDR选项即可。此时,场景就会被渲染到一个HDR的图像缓冲中,这个缓冲的精度范围可以远远超过0~1。最后,我们可以使用一个色调映射的屏幕后处理脚本来把HDR图像转换到LDR图像进行显示。

更多内容https://docs.unity3d.com/Manual/HDR.html

标签: Shader

Powered by emlog  蜀ICP备18021003号-1   sitemap

川公网安备 51019002001593号