[OpenGL] HDR效果测试

引入

        在刚开始接触着色器语言时,我就考虑过这样的问题:

        (1) 场景中如果有多个光源,它们对物体颜色的贡献应该以怎样的方式叠加在一起?

        (2) 如果所有光源贡献的总和超过了1,颜色强弱细节将会丢失,呈现单一的白色。应用程序有没有办法避免这种现象?

        实际上,(1)的答案本身应该非常简单,那就是直接将所有光源的贡献(算上当前位置的衰减)直接相加。但是,考虑到问题(2),哪怕光非常昏暗,只要灯光数量足够多,就总会出现总和超过1的现象,使得画面效果失真,而在现实世界中,却好像并没有见过这样的情况——哪怕光线非常强烈,人眼也不至于完全看不见场景细节,也就是说,人眼具有在较强和较暗光照下看清物体细节的能力。

        这让我对(1)的结论产生了怀疑:会不会存在一种更好的加权方式,能够尽可能在总和超过1的情况下,保留更多的颜色细节,而不是呈现单一的白色?

       之后,接触到了一个叫HDR的东西。HDR这个词好像在很多地方都被广泛提及,但它们具体指代的东西,却不尽相同。HDR的全称是High Dynamic Range(高动态范围)。而我们所称的“HDR",更准确而言只是一种色调映射的图像算法,是软件级别的东西,将颜色映射到一个更加合理的区间范围,来保留更多的颜色细节。

HDR模拟

        此处,我使用了https://learnopengl-cn.github.io/05%20Advanced%20Lighting/06%20HDR/中给出的色调映射公式:

color = vec3(1.0) - exp(-color * hdrExp);

        其中,参数hdrExp控制了曝光度,它的值越大,曝光就越强。

        [OpenGL] HDR效果测试_第1张图片

        在hdrExp = 1时,它的函数图像大致如上,可看出颜色较暗时变化接近线性变化,随着颜色变亮,映射后的颜色增速逐渐变缓。      

[OpenGL] HDR效果测试_第2张图片 红色线条曝光度为1,蓝色线条曝光度为2

        随着hdrExp的增加,映射后的颜色会更加偏亮。

        如在下图中,我将多个点光源移动到了图中心部分最亮的那个位置,此时由于光源过多,它们的颜色贡献总和超过了1,中心呈现比较刺眼的白色。

        

[OpenGL] HDR效果测试_第3张图片 关闭HDR

        此时,我们在其它参数都保持不变的情况下,开启“HDR”,可在下图看到,刺眼的“白色”消失了,我们看到了多个点光源照亮同一区域地板的颜色细节,并依然能感受到,该区域依然比别的区域更亮:

        

[OpenGL] HDR效果测试_第4张图片 开启HDR

 

        曝光度变化的比较:

       [OpenGL] HDR效果测试_第5张图片[OpenGL] HDR效果测试_第6张图片

        [OpenGL] HDR效果测试_第7张图片[OpenGL] HDR效果测试_第8张图片

         上面四张图,从左到右,从上到下,曝光度分别为0.3,0.65,1.36,3.6。

        啊,本来还做了gamma矫正,但是目前我的点光源依然是用比较古老的光照方程来做的,使用gamma矫正完全没有什么好的效果,等哪天做好了PBR demo再来测试一下效果吧~

你可能感兴趣的:(OpenGL)