网易首页 > 网易号 > 正文 申请入驻

高质量泛光(Bloom)从理论到实战

0
分享至

这是侑虎科技第1258篇文章,感谢作者AKG4e3供稿。欢迎转发分享,未经作者授权请勿转载。如果您有任何独到的见解或者发现也欢迎联系我们,一起探讨。(QQ群:793972859)

作者主页:

https://www.zhihu.com/people/long-ruo-li-21

泛光(Bloom)是现代电子游戏中常见的后处理特效,通过图像处理算法将画面中高亮的像素向外“扩张”形成光晕以增加画面的真实感,能够生动地表达太阳、霓虹灯等光源的亮度。Bloom的好坏能够极大地改善游戏的表现力。

泛光特效的原理并不复杂,提取图像高亮的部分做模糊再叠加回原图。 在互联网上有很多关于泛光算法原理的介绍文章或者教程,我这里就不唠叨了。

为什么写这篇文章

尽管网上有非常多的资料,但是要想制作出高品质的泛光效果却没那么容易。使用最基础的方法做出的效果可能是下图这样的,显然这个结果距离在显示器上制造闪闪发光的小太阳还很遥远:

第一次写泛光特效的时候还是在高二,当时在玩Minecraft,磕磕绊绊地抄着代码却只是在游戏里实现了一个比上图还要不堪的效果。我想在游戏里面复现文章一开始那张图的效果,却没有进一步的资料可以参考,这令我十分沮丧。迫于做题家的压力也没有钻研下去,最后不了了之。

网上的教程大多数都在介绍完基础理论就戛然而止,鲜有更加深入的探讨与实践。为了弥补童年时的遗憾,萌生了写这篇文章的想法。

什么是高品质泛光

对于优秀的泛光特效来说,我认为需要满足以下几个特点:

1. 发光物边缘向外 “扩张” 的足够大

2. 发光物中心足够亮(甚至超过1.0而被Clamp成白色)

3. 该亮的地方(灯芯、火把)要亮,不该亮的地方(白色墙壁、皮肤)不亮

下面是一组比较有代表性的(我认为)高质量泛光效果截图:

与之对应的,放一组(我认为)效果比较一般的泛光。 如果该亮的地方不够亮,不该亮的地方亮了,那么很容易产生场景的 “模糊” 感:

下面这张图则是发光处的中心和向外扩散出的轮廓都很亮,此外下图中红色土地也在发光,画面显得很脏:

下图则是发光物泛光的扩散范围不够大,画面的表现力不够强:

高质量的泛光效果可以用一张图清晰地总结。 简单来说就是中间亮的批爆,但是越往外亮度下降越快。 这有点类似正态分布曲线。 下图是UE4给出的理想泛光亮度曲线:

为何要使用 HDR 纹理

HDR纹理允许像素的亮度超过255,这能够很好地表示现实世界的亮度。 尽管最终输出到屏幕上会被Clamp,但最重要的是在对HDR纹理做滤波的时候,超亮的像素可以被有效地扩散到周围区域。

滤波的本质是对Kernal覆盖的范围内所有像素按某种权重做加权平均。打个比方,我和马云的财富平均一下,我也是富哥了。不同的Filter有不同的Weight,但是只要高亮像素的值足够大,它总能够辐射到周边的像素。

下面是一组对比图,使用了大尺寸(radius=100,sigma=30)的高斯模糊进行处理。HDR源纹理输出像素为纯白,值缩放大小由Emissive intensity控制:

其中Emissive intensity = 1.0时对应普通的LDR纹理。 因为Kernal的尺寸足够大,1.0的像素值很快被分摊干净。 如果像素足够亮,那么即使处于Kernal边缘也能够积累可观的亮度。 像素越亮,它能扩散的距离就越远。 这意味着单个高亮像素也能扩散出很大的范围:

此外,HDR纹理能够帮助我们快速区分需要进行模糊的高亮像素。 这能够让美术更加灵活地根据真实世界的参数调整材质。

快速的大范围模糊

要想光晕扩的足够大,第一件事情就是扩大模糊的范围。一种非常简单的思路就是加大滤波盒的尺寸,使用一个巨大的Kernal对纹理进行模糊。但是性能上肯定是吃不消,单Pass的纹理采样次数是N^2而双Pass是N+N。

此外还有一个问题,在处理高分辨率纹理时你需要等比增加滤波盒的尺寸,才能形成同等大小的模糊。比如在1000x1000分辨率下用250像素的Kernal,模糊的结果占1/4屏幕,当分辨率增加到2000x2000的时候,要使用500像素的Kernal才能达到同样的效果。

回到模糊的问题,模糊滤波的本质是查询Kernal范围内的所有像素并加权平均,即范围查询问题。在计算机图形学中实现快速范围查询,通常会请到老朋友Mipmap出场。Mipmap将图像大小依次折半形成金字塔,Mip[i]中的单个像素代表了Mip[i-1]中的2x2像素块均值,也代表Mip[i-2]中的4x4像素块均值:

通过查询高Level的Mipmap可以在常数时间内查询大范围的源纹理。 在(w/4,h/4)的贴图上做3x3滤波,近似于在(w,h)的贴图上做12x12的滤波。 为此需要创建size逐级递减的纹理,并使用downSampler着色器将Mip[i-1]下采样到Mip [i],以Unity为例,在OnRenderImage中一个最简单的下采样Mip串实现:

在downSample着色器中直接输出源纹理的颜色。 注意源纹理需要启用双线性滤波,这样硬件会帮助我们计算上一级Mip中2x2像素块的均值:

在足够高的Mip等级下,模糊的范围确实增大了。但是模糊的结果不够好,这是因为双线性滤波本质上是个2x2的Box Filter,方形的Pattern很严重:

为了获得更加圆滑的模糊我们需要选用更高级的Blur Kernel,高斯模糊是一个不错的选择。一个5x5,标准差为1的高斯模糊就足够好了。这里我选择手动计算高斯滤波盒的权重,通常来说使用预计算的2D数组会加快计算速度:

自此我们通过多次下采样形成Mip链以实现大范围的圆形模糊效果:

描绘中心高亮区域

使用下采样生成大范围的模糊仅仅是第一步,直接将最高层级Mip叠加到图像上虽然能够产生足够大的光晕扩散,但是发光物的中心区域不够明亮。 此外,发光物和泛光之间没有过度而是直接跳变,从高亮区域跳到低亮度区域显得非常不自然:

不管使用何种滤波器,本质上都是在做加权平均。只要一平均,就有人拖后腿!每次模糊都会降低源图像的亮度,并将这些亮度分摊到周围的纹理。边缘的跳变来自于高层级Mip和原图之间亮度差距过大:

为了实现发光物和最高层Mip之间的过渡,我们需要叠加所有的Mip层级到原图上。因为 Mip[i]是基于Mip[i-1]进行计算的,相邻层级之间相对连续则不会产生跳变:

较低的Mip层级模糊范围小且亮度高,主要负责发光物中心的高亮,较高的Mip层级模糊范围大且亮度低,主要负责发光物边缘的泛光。叠加所有的Mipmap就能同时达到高质量泛光的两个要求,即够亮与够大:

是不是有感觉了?

处理方块图样

因为我们直接从Mipmap链中采样到全分辨率,很难免会出现方块状的Pattern,因为最高级别的Mip分辨率小到个位数:

可以通过模糊滤波来解决方块图样。值得注意的是不能直接对小分辨率的高阶Mip进行滤波,因为分辨率太小,不管怎么滤波,上采样到Full Resolution的时候都会有方块。除非滤波发生在高分辨率纹理。

但是高分辨率纹理上一大块区域都对应低分辨率Mip上的同一个Texel,如果Kernal不够大那么做Filter的时候查询的值都是同一个Texel,这意味着在高分辨率纹理上要使用超大的滤波盒才能消除这些方块。下图很好的说明了这一点:

问题又回到了如何使用廉价的小尺寸滤波盒实现大范围模糊的问题。和下采样时类似,采样逐级递进的方式对低分辨率的Mip链进行上采样。将Mip[i]上采样到Mip[i-1],再和Mip[i-1]本身叠加得到新的Mip[i-1],这种策略在《使命召唤 11的GDC分享》( http://www.iryoku.com/next-generation-post-processing-in-call-of-duty-advanced-warfare )中被提出:

进行这个操作需要额外创建一组RenderTexture,下面是下采样Mip链(RT_BloomDown)和上采样Mip链(RT_BloomUp)之间的数据倒腾关系,以964x460分辨率和N=7次为例:

对应的C#代码也比较简单,只是需要注意纹理之间尺寸、下标的关系。这里RT_BloomUp仅有N-1个纹理,记得在Frame Debugger中确保尺寸关系的正确:

upSample的着色器也比较简单,同样用的5x5的高斯模糊处理curr_mip,对于prev_mip 可以小滤一下也可以直接采样。经过测试最好对两者都进行滤波,能够得到更加平滑的效果。最后叠加两者作为本级Mip的处理结果:

现在方块图样有了明显的改善:

和闪烁抗衡

如果熟悉PBR流程的话,不难想到Specular的BRDF在Roughness非常小、NdotL接近1.0的时候,会输出极大的数值,尤其是当光源的强度足够高时。即高光部分非常亮,如果使用了法线贴图等高频法线信息,会导致画面闪烁的很厉害:

对此COD的方案是在Mip0到Mip1,即第一次下采样时,加入额外的权重来试图抹平因法线贴图碰巧NdotL很接近1.0而引起单个超高亮像素。这个做法叫做Karis Average:

需要一个单独的firstDownSample着色器来进行第一次下采样。高斯模糊版本对应的代码如下,如果使用的是自定义的Kernal可能需要做一些调整:

这个方法因为对亮度做了约束,会损失一定的Bloom范围和亮度,但是得到更加稳定的高光:

更好的滤波盒

在上下采样都使用5x5的高斯滤波盒显得有些奢侈。采样纹理是非常昂贵的操作,GPU需要经过数百个时钟周期才能完成。直接使用2x2的Box虽然足够快速,但会有很明显的Pattern。

在COD的分享中使用了更为小巧的滤波盒,下采样时按照2x2一组进行采样。采样共5组,并按照一定的权重加权。这个滤波盒在高斯模糊和2x2的Box之间进行了均衡,既保证了效率又保证了质量:

而在 上采样的Filter中,他们更是使用了更为简单的3x3 Tent Filter,值得注意的是他们使用了一个Radius来控制滤波的范围,这有点类似于深度学习中的 “带洞卷积” 滤波器。 这也是为何游戏有些地方会有明显的格子感的原因:

像素筛选

一种常见的表现手法是让角色身上的某个部件进行高亮,比如装甲能量槽:

要做到这一点需要在下采样之前,筛选出需要计算Bloom的像素。只有足够高亮度的像素才有资格被计算泛光,这和现实世界的规律相符,比如白炽灯、篝火或者是太阳。这要在HDR环境下进行渲染。

通常情况下使用的是1.0作为亮度筛选的阈值,也可以不设置阈值但通过Bloom Intensity控制最终Bloom的强度,比如乘以0.01,这样只要发光物(lum=1000)和正常场景物件(lum=1.0)亮度相差足够大就能产生泛光。

如果使用的是PBR工作流,那么问题变得非常简单。PBR材质通常都带有自发光贴图(或者是任何自定义的Mask贴图),这是美术事先标注的模型高亮处。只需要调整其强度,在Base Pass中输出超高的亮度值即可:

此外可以为发光物件使用单独的材质,比如角色的光剑、项链等道具。

代码仓库

https://github.com/AKGWSB/CasualBloom

参考与引用

[1] NEXT GENERATION POST PROCESSING IN CALL OF DUTY: ADVANCED WARFARE

http://www.iryoku.com/next-generation-post-processing-in-call-of-duty-advanced-warfare

[2] Custom Bloom Post-Process in Unreal Engine

https://www.froyok.fr/blog/2021-12-ue4-custom-bloom/

[3] 实时渲染学习笔记—光晕效果(bloom)

https://v.gd/XtZrcP

[4] 后处理-泛光效果

https://xiaoiver.github.io/coding/2019/02/07/Bloom.html

[5] Catlike Coding's Unity tutorial

https://catlikecoding.com/unity/tutorials/advanced-rendering/bloom/

文末,再次感谢AKG4e3的分享,作者主页:https://www.zhihu.com/people/long-ruo-li-21,如果您有任何独到的见解或者发现也欢迎联系我们,一起探讨。(QQ群:793972859)

近期精彩回顾

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
经济学家:税务倒查30年强烈冲击市场信心,不能见小利而忘大义,惊扰企业

经济学家:税务倒查30年强烈冲击市场信心,不能见小利而忘大义,惊扰企业

可达鸭面面观
2024-06-21 11:17:49
梅西老了!策动2个进球,却踢飞2个单刀,阿根廷球王自己都苦笑

梅西老了!策动2个进球,却踢飞2个单刀,阿根廷球王自己都苦笑

足球慢镜头
2024-06-21 10:07:59
中联部部长在海参崴出席“抵制新殖民主义”论坛,让人如鲠在喉

中联部部长在海参崴出席“抵制新殖民主义”论坛,让人如鲠在喉

顾礼先生
2024-06-20 14:53:15
北京今天迎雷雨天气最高温29℃ 周末两天北风增强

北京今天迎雷雨天气最高温29℃ 周末两天北风增强

北青网-北京青年报
2024-06-21 07:45:03
超值!Woj:蒙克4年7800万美元续约国王

超值!Woj:蒙克4年7800万美元续约国王

直播吧
2024-06-21 11:22:07
姜萍中专同学被找到,确认其月考数学成绩只有83分,有准考证可以证明

姜萍中专同学被找到,确认其月考数学成绩只有83分,有准考证可以证明

小萝卜丝
2024-06-20 21:06:54
美海军司令访澳时撺掇:利用对华矿产出口“威慑中国”

美海军司令访澳时撺掇:利用对华矿产出口“威慑中国”

观察者网
2024-06-20 21:41:45
连警方都说了,南海没有斧头帮,只有自拍杆

连警方都说了,南海没有斧头帮,只有自拍杆

三叔的装备空间
2024-06-20 17:55:31
普京:俄罗斯军队永远不会撤军

普京:俄罗斯军队永远不会撤军

亡海中的彼岸花
2024-06-21 08:47:10
澳大利亚:月壤属于全人类,不属于中国,中国人必须把月壤交出来

澳大利亚:月壤属于全人类,不属于中国,中国人必须把月壤交出来

功标青史
2024-06-20 11:30:19
后续!泼咖啡粉的女店员被辞退,现场完整对话曝光,果然有情况

后续!泼咖啡粉的女店员被辞退,现场完整对话曝光,果然有情况

皖声微言
2024-06-20 16:01:24
呼和浩特一家五口被杀害,仅剩下一个儿媳妇,村干部曝更多细节

呼和浩特一家五口被杀害,仅剩下一个儿媳妇,村干部曝更多细节

180°视角
2024-06-20 15:16:22
刚刚,许昌交警暴击太原城管!

刚刚,许昌交警暴击太原城管!

顾礼先生
2024-06-20 15:54:26
中国香港海关查获596颗高端CPU:走私中国内地,价值1120万!Intel至强处理器,可支持AI加速计算、云服务

中国香港海关查获596颗高端CPU:走私中国内地,价值1120万!Intel至强处理器,可支持AI加速计算、云服务

和讯网
2024-06-20 16:09:32
英格兰1-1害人害己!坑惨德国,法国比利时偷乐,西班牙6分很难受

英格兰1-1害人害己!坑惨德国,法国比利时偷乐,西班牙6分很难受

嘴炮体坛
2024-06-21 05:28:59
普京:乌克兰幻想俄罗斯撤军,不可能

普京:乌克兰幻想俄罗斯撤军,不可能

观察者网
2024-06-21 08:08:06
治安管理处罚法拟修改:被拘留人升学考、子女出生可申请出所

治安管理处罚法拟修改:被拘留人升学考、子女出生可申请出所

南方都市报
2024-06-21 10:56:18
印度少女被迫裸露乳房:想要遮挡自己的乳房,就必须得缴纳乳房税

印度少女被迫裸露乳房:想要遮挡自己的乳房,就必须得缴纳乳房税

忠于法纪
2024-06-20 15:16:49
离开越南前,普京警告了这一国

离开越南前,普京警告了这一国

直新闻
2024-06-21 11:50:35
对于中国外交部的这个批评,五角大楼送来了“神助攻”

对于中国外交部的这个批评,五角大楼送来了“神助攻”

枢密院十号
2024-06-20 21:20:39
2024-06-21 12:56:49
侑虎科技UWA
侑虎科技UWA
游戏/VR性能优化平台
1255文章数 864关注度
往期回顾 全部

科技要闻

已经全球第一了,为什么还要“奋斗100天”

头条要闻

普京离开越南前警告韩国:若向乌提供武器将犯下大错

头条要闻

普京离开越南前警告韩国:若向乌提供武器将犯下大错

体育要闻

1-0"吊打"意大利 西班牙这就叫冠军相?

娱乐要闻

陈晓惹争议!被曝婚变离家出走冷暴力

财经要闻

普华永道,引火烧身

汽车要闻

领克纯电,来得不晚

态度原创

房产
家居
健康
艺术
教育

房产要闻

海棠湾!一所重量级国际学校真的来了!

家居要闻

木质家具 充溢古典之风

晚餐不吃or吃七分饱,哪种更减肥?

艺术要闻

穿越时空的艺术:《马可·波罗》AI沉浸影片探索人类文明

教育要闻

悟空也要政治正确呀

无障碍浏览 进入关怀版