HDR (automatic exposure control + Tonemapping + Bloom)

前段时间在VR项目里实现了PCF+VSM之后,为了让阳光照射的区域看起来亮一些,降低了阴影区域的亮度,明暗区域的对比度确实高了,但是室内就有些过于暗了,于是寻思着得把HDR模块加上了。

一般我们说的HDR其实是代指,automatic exposure control + Tonemapping + Bloom, 先根据场景的一帧计算出平均亮度,如果偏暗就加亮一些,反之亦然,调整好亮度之后再调整灰度,让明部跟暗部保持更多的细节,最后对高光部分做个Bloom,看起来更真实。

Bloom

在现实世界中 ,很亮的灯周围都会有一圈模糊的光晕,Bloom就是指这个光晕。我的HDR处理是在计算完光照跟阴影之后进行的,光照着色的输出为一张RGBA16F格式的纹理,注意这里不能再用RGBA8了,用这张纹理作为HDR的输入。

首先进行计算的是平均亮度,这里有两种计算方式,一是利用RTT的方式,渲染到一张一半长宽的纹理里去,循环这个操作,直到纹理只剩1x1像素,这个像素就是场景所有像素的平均了,这里要注意的一点是,RTT的时候,原纹理的过滤方式一定要设为Linear,这样渲染出来的半尺寸纹理才是原纹理的平均。方式二是利用ComputeShader,这个实现跟RTT类似,但是速度会快上一倍左右,因为VR程序非常非常考验性能,我选择的就是这种方式,这里重点说下这个。

第一个问题就是原纹理的尺寸不是2的N次幂,而且会根据用户设定变化,这种无规律的尺寸在ComputeShader里面处理起来比较麻烦,我们需要先把它规格化一下,一般的方案是RTT到一张长宽分别是 离原纹理的一半最近的2的N次幂的纹理上,比如1733*1733就应该规格化到 1024*1024的纹理上。尺寸规范化之后,就可以很方便的用ComputeShader计算平均亮度了,这里面有个技巧,就是可以利用GPU的并行操作进一步加快计算过程,具体参见这里:《AVERAGE LUMINANCE CALCULATION USING A COMPUTE SHADER》
使用sRGB计算亮度的公式是这个:

float lum = 0.2126 * color.r + 0.7152 * color.g + 0.0722 * 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值