高动态范围光照(High Dynamic Range Imaging,简称HDRI或HDR)

1 HDR基本概念

  高动态范围光照(High Dynamic Range Imaging,简称HDRI或HDR),是一种表达超过了显示器所能表现的亮度范围的图像映射技术,已成为目前游戏应用不可或缺的一部分。通常,显示器能够显示R、G、B分量在[0, 255]之间的像素值。而256个不同的亮度级别显然不能表示自然界中光线的亮度情况。比如,太阳的亮度可能是一个白炽灯亮度的几千倍,是一个被白炽灯照亮的桌面的亮度的几十万倍,这远远超出了显示器的亮度表示能力。

想象在一个房间中,刺眼的阳光从窗外照进来,若使用常规方法渲染这个房间,房间中白色的墙壁的颜色是(255, 255, 255),阳光的颜色也是(255, 255, 255),墙壁将表现得和窗外的阳光颜色一样。很明显,这和我们现实看到的差异很大,现实场景中阳光要比墙壁刺眼很多,我们需要使用某种技术对阳光的亮度和墙壁的亮度进行处理,让其在显示器上的效果接近现实效果。

简单的将高范围的亮度按比例缩放后映射到[0, 255]是不可行的,比如将[0, 511]的范围按照2:1映射到[0, 255],虽然表示的亮度范围扩大了,但是将导致色带(Color Banding)问题,色带如图1所示。

image
image

图1 左图有色带问题,右图显示正常

在有限的亮度范围内显示自然界中相当宽广的亮度范围,正是HDR技术所要解决的问题。

2 HDR渲染步骤

1)将整个场景渲染到一张浮点纹理上(16bit或32bit都可以);

2)色调映射(Tone Mapping);

3)渲染泛光(Bloom)效果;

4)将泛光和色调映射的结果进行叠加。

第一步很简单,只需要硬件支持浮点纹理即可,比较重要的是本文重点介绍的2、3两步,最后将2、3两步的结果进行叠加,形成最终效果图。

【显示设备上[0, 255]的亮度范围在着色器程序中使用[0, 1]的浮点数表示,下文的亮度和颜色值表示均使用着色器程序的标准。在算法中都用到了亮度的计算,每个像素的亮度的计算方法是L=0.27R+0.62G+0.06B】

3 色调映射

色调映射是在有限动态范围媒介上近似显示高动态范围图像的技术。对于人眼来说也有类似的映射方式,因为人眼对亮度的感知范围远低于自然界的亮度范围,只能感知到某个范围内的光照。和显示设备不同的是,人眼对光的感知范围是动态变化的,例如从光亮的室外环境突然走入一个黑暗的室内环境,刚刚开始一片漆黑,过一会儿才可以看清周围环境,人眼的这个调节过程叫做光适应(Light Adaptation)。所以要模拟出真实的光照效果,除了表现出合适的光照,还需要模拟出人眼对光线的调节过程。

最简单的色调映射是将亮度超过1的值置为1,这种做法会出现文章开始提到的墙壁和阳光一样亮的问题;另一种简单的色调映射是将每个像素的除以最高亮度像素的亮度值,可以很好的将所有像素的亮度映射到[0, 1]之间,这种方法会导致场景中某些特别亮的像素会导致场景中的其他部分特别暗。比较好的方式是采用平均亮度值进行调节,由于平均亮度值反映了场景中的整体亮度,所以受到场景中少部分过亮或过暗的像素影响不大。

3.1 计算平均亮度

计算平均亮度的公式为:

image

该公式先对亮度取对数,平均后再进行幂运算。之所以不是直接对亮度平均,而是取了对数,是为了防止过亮的像素对整体造成的影响过大,该公式来源于参考文献1。

计算平均亮度的最简单的方法是遍历所有像素,用上述公式求平均值。该方法需要CPU完成,效率不高,DirectX的“HDRLighting”例子采用了一种基于GPU加速的方法,利用像素着色器多次DownSampling,最后求得平均值,具体流程如下:

1)首先将场景渲染到纹理中,在此基础上,对该纹理取样并计算相应像素亮度的ln()值并进行平均(相当于上述公式去掉exp),存入64*64的纹理中;

2)对上一步的纹理44 DownSampling,生成1616的纹理;

3)对上一步的纹理44 DownSampling,生成44的纹理;

4)对上一步的纹理44 DownSampling,生成11的纹理,并计算其exp()值。

最后生成的11的纹理中的像素为公式中要求的平均亮度Lavg。*

3.2 光适应

为了模拟人眼对于不同光强会自动调节适应范围的效果,只需要对这一帧求出的平均亮度Lavg与上一帧的平均亮度Lavg进行插值即可,当然这个插值不是线性插值,“HDRLighting”中的代码如下:

|

1

|

float fNewAdaptation = fAdaptedLum + (fCurrentLum - fAdaptedLum) * ( 1 - ``pow``( 0.98f, 30 * g_fElapsedTime ) );

|

其中,fAdaptedLum为上一帧的Lavg,fCurrentLum为当前帧的Lavg,g_fElapsedTime为当前帧和上一帧的时间间隔,fNewAdaptation为最终Lavg的计算结果。

3.3 计算缩放因子

场景的整体亮度可以通过缩放因子进行调节,公式如下:

image

其中Lscale(x,y)是当前像素的亮度值。Key是一个常数,Key 的大小决定了映射后场景的整体明暗程度,一般取0.18(在伽马校正理论中,0.18经过校正后大概是0.5,也就是我们感官上的中等灰度级)。Key值的选择可以看作摄像机的曝光程度,我们可以使用这个公式控制自由的摄像机的曝光程度,Key越大整个场景就显得越白。一般来说,高曝光的Key最高为0.72,低曝光的Key最低为0.045,一般程度的曝光Key选择0.18附近的值。

3.4 归一化处理

到此为止,色调映射已经基本完成,剩下的只需要将Lscale(x,y)映射到[0, 1]范围内即可,公式如下:

image

其中其中Color(x,y)是当前像素的颜色值。

4 渲染泛光效果

泛光是一种光学效应,它是指在来自于强光源的光线看起来像是影响到了周围物体。想象一间房间,窗户外面阳光明媚,若往窗外看去,感觉窗户光亮的边缘有一圈模糊,这就是泛光效果。在游戏中适当的增加泛光效果,能够增强画面的真实感。

渲染泛光效果的思路很简单,主要分为两个步骤,第一步是使用bright-pass filter提取出场景中高亮部分,第二步对高亮部分进行模糊处理。"HDRLighting"中bright-pass filter的代码如下:

[
复制代码

](javascript:void(0); "复制代码")

<pre style="margin: 0px 0px 0px 22px; white-space: pre-wrap; overflow-wrap: break-word; font-size: 12px !important; font-family: "Courier New" !important;"> 1 // Determine what the pixel's value will be after tone mapping occurs
2 vSample.rgb *= g_fMiddleGray/(fAdaptedLum + 0.001f);
3
4 // Subtract out dark pixels
5 vSample.rgb -= BRIGHT_PASS_THRESHOLD; 6
7 // Clamp to 0
8 vSample = max(vSample, 0.0f);
9
10 // Map the resulting value into the 0 to 1 range. Higher values for 11 // BRIGHT_PASS_OFFSET will isolate lights from illuminated scene 12 // objects.
13 vSample.rgb /= (BRIGHT_PASS_OFFSET+vSample); </pre>

[
复制代码

](javascript:void(0); "复制代码")

第二步则是对第一步的结果进行模糊,首先对第一步的结果进行22或44的downsampling,再使用2*2的高斯核心对其进行模糊。其中先对图像downsampling再模糊的做法是利用GPU进行图像模糊的一种提高性能的方法,因为downsampling后图像分辨率降低了,计算量自然就少了;而downsampling后的图片再放大,本身又是一种模糊,可以减少高斯模糊的采样数量。最终效果如图2所示

image
image
image

图2 图片来源于微软DirectX SDK中“HDRLighting”例子,左图为过度曝光的场景,中间图片为bright-pass filter处理后的结果,右图为模糊之后的效果

5 融合

现在需要将色调映射的图像与泛光的图像进行融合。在融合操作中除了常见的α融合外,还有一种叠加(Additive Blending)操作,它可以将两种颜色的值进行加法操作,通常会使得颜色越变越白,这正是我们所要的效果。将色调映射的图像与泛光的图像进行叠加操作,即可生成最终图像。

6、最终效果

“HDRLighting”中LDR和HDR的效果对比如图3所示。

image
image

图3 “HDRLighting”中LDR和HDR的效果对比,左图为LDR,右图为HDR

其他的一些HDR渲染效果如图4-7所示。图4中很明显的观察到汽车窗户的镜面光,图5中蓝色的灯光显得比较亮,但是暗的地方也很清晰;图6和图7来自游戏“孤岛危机”,效果相当不错,其中就有HDR的功劳(当然要做到这样的画质,HDR只是冰山一角)。图6场景明暗得当,透过树叶可以看到天空略微模糊;图7中可以看到爆炸产生的碎片以及车上的显示屏有泛光效果,充分体现了亮度的差别,而这些细节让游戏更加逼真。

image

图4 Unity3D文档中的HDR渲染效果图1

image

图5 Unity3D文档中的HDR渲染效果图2

image

图6 “孤岛危机”截图1

image

图7 “孤岛危机”截图2

参考文献:

[1]Reinhard, Erik, Mike Stark, Peter Shirley, and James Ferwerda. "Photographic Tone Reproduction for Digital Images". ACM Transactions on Graphics (TOG), Proceedings of the 29th Annual Conference on Computer Graphics and Interactive Techniques (SIGGRAPH), pp. 267-276. New York, NY: ACM Press, 2002.

[2]Akenine-Möller T, Haines E, Hoffman N. Real-time rendering 3 [M].

[3]DirectX 9.0c SDK

[4]http://www.cnblogs.com/cxrs/archive/2013/03/22/hdr%E9%AB%98%E5%8A%A8%E6%80%81%E8%8C%83%E5%9B%B4%E5%85%89%E7%85%A7%E6%B8%B2%E6%9F%93.html

[5]http://wenku.baidu.com/view/fe31607ea26925c52cc5bf97.html

[6]http://www.zwqxin.com/archives/shaderglsl/review-high-dynamic-range.html

[7]http://zh.wikipedia.org/wiki/%E9%AB%98%E5%8A%A8%E6%80%81%E8%8C%83%E5%9B%B4%E6%88%90%E5%83%8F

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342

推荐阅读更多精彩内容