资讯动态

Bloom后处理完全指南:从HDR原理到多级模糊参数调优实战

发布时间:2026/10/15 23:59:17 来源:尧图企业网站定制
1. 从“发光”这件事说起Bloom 后处理到底在做什么第一次在引擎里看到 Bloom 这个词很多人会把它和“泛光”“辉光”“光晕”混着叫。其实说白了它模拟的是一个非常朴素的物理现象当人眼或者相机镜头面对一个特别亮的光源时光线会因为散射而在亮区周围形成一圈柔和的溢出。你晚上看路灯灯本身是一个点但你看到的是一团带毛边的光球这就是 Bloom 在实时渲染里想还原的东西。我最早接触 Bloom 是在做一个小型夜景 Demo 的时候。场景里放了几盏自发光材质的路灯结果渲染出来就是几个死白的小方块完全没有“亮”的感觉。后来加了 Bloom整个画面的氛围立刻就不一样了——亮的地方会“呼吸”暗部被衬托得更沉视觉重心自然就被拉到了光源上。从那以后我就意识到Bloom 不是一个锦上添花的滤镜它是让 HDR 画面真正“活”过来的关键一环。这篇文章适合谁看如果你正在做游戏、做可视化、做影视预演或者只是想在引擎里把画面调得更有质感那 Bloom 是你绕不开的一个后处理环节。我会从原理讲到参数从参数讲到实操再从实操讲到踩过的坑。不管你是刚接触后处理的新手还是已经用过 Bloom 但总觉得效果“差点意思”的老手应该都能从里面找到能直接抄作业的东西。需要先明确一点Bloom 不是孤立存在的。它和 HDR、色调映射、曝光控制是绑在一起的。你单独把 Bloom 拉满画面只会糊成一团你把它关掉HDR 的高光又无处释放。所以下面我会把这些关联环节一起拆开讲而不是只盯着 Bloom 这一个节点。2. Bloom 的核心原理与方案选型2.1 从物理现象到屏幕像素Bloom 的基本链路要理解 Bloom先要理解一个前提屏幕能显示的亮度范围是有限的。标准 sRGB 屏幕的亮度大概在 0 到 1 之间严格说是 0 到 100 尼特左右但真实世界的光照动态范围远超这个区间。太阳直射可以到几万尼特而夜晚的暗部可能只有零点几尼特。HDR 渲染的意义就是先把这些超出屏幕范围的高亮值保留下来再通过色调映射压缩到可显示区间。Bloom 就发生在这个“保留”和“压缩”之间。它的基本链路是这样的场景以 HDR 格式渲染高亮区域的值可以远大于 1。提取出超过某个阈值的亮部区域作为 Bloom 的源。对这个源进行多次降采样和模糊形成不同尺度的光晕。把这些模糊结果叠加回原图再统一做色调映射。这个链路里阈值提取和多级模糊是两个最核心的环节。阈值决定了“多亮才算亮”模糊决定了“光晕铺多远”。很多人调 Bloom 只调强度结果要么没效果要么整个画面像蒙了一层雾问题就出在这两个环节没配合好。2.2 为什么用多级模糊而不是一次大模糊这是我在实际项目里被问得最多的一个问题。既然要模糊为什么不用一个大的高斯核一次性糊完非要搞什么多级降采样原因有两个。第一是性能。一个半径 64 的高斯模糊如果直接在原分辨率上做采样次数是平方级增长的开销非常吓人。而通过降采样每一级的分辨率减半模糊半径相对变大用很小的核就能覆盖很大的范围。第二是质量。单次大模糊会让光晕变得非常均匀、非常“塑料”而多级模糊叠加出来的光晕近处紧实、远处松散更接近真实镜头的光学散射。常见的实现是 5 到 6 级降采样每一级做一次横向和纵向的分离高斯模糊。分离模糊的意思是先横着糊一遍再竖着糊一遍效果等价于一次二维模糊但采样次数从 N² 降到 2N。这个优化在实时渲染里是标配几乎没有人会跳过。2.3 阈值、软阈值与膝盖参数阈值Threshold是 Bloom 的入口开关。只有亮度超过这个值的像素才会被提取出来参与 Bloom。但如果你用一个硬阈值亮部边缘会出现明显的“一刀切”痕迹——亮度刚好在阈值上下的两个像素一个发光一个不发光过渡非常生硬。所以实际实现里都会引入软阈值也就是所谓的“膝盖”Knee。它的作用是在阈值附近做一个平滑过渡亮度低于阈值的不参与高于阈值加膝盖值的完全参与中间的部分按比例参与。这样提取出来的亮部边缘是柔和的不会出现硬边。我一般会把阈值设在 1.0 到 1.5 之间膝盖设在 0.5 到 1.0 之间。阈值太低暗部也会被拉进来发光画面会脏阈值太高只有极亮的光源才会 Bloom效果会很克制。这个没有绝对标准要看场景的整体曝光水平。2.4 不同引擎和框架下的方案差异不同工具链对 Bloom 的实现细节有差异但核心思路是一致的。有的引擎把 Bloom 放在色调映射之前有的放在之后有的用能量守恒的叠加方式有的用简单的加法。这些差异会直接影响最终观感。方案类型处理位置特点适用场景色调映射前 BloomHDR 阶段高光保留完整光晕颜色准确写实风格、HDR 管线色调映射后 BloomLDR 阶段实现简单但高光容易溢出变白轻量项目、风格化渲染能量守恒叠加加权混合亮度不会无限累积画面稳定需要长时间观看的场景简单加法叠加直接相加效果强烈但容易过曝强调光效的演示我个人的习惯是优先用色调映射前的方案因为它的物理逻辑更顺调起来也更有依据。色调映射后的方案虽然省事但一旦场景里有多个亮源画面很容易糊成一片白后期很难救。3. 核心参数拆解与实操要点3.1 强度、半径与阈值的三方博弈Bloom 的参数看起来不多但每一个都会牵动整体效果。我习惯把它们分成三组来理解强度Intensity控制 Bloom 叠加回原图的比例。强度越高光晕越明显但过高会让画面发灰。半径Radius / Spread控制模糊的扩散范围。半径越大光晕铺得越开但细节会被吃掉。阈值Threshold控制哪些像素参与 Bloom。阈值越低参与的区域越多画面越“梦幻”。这三个参数是互相影响的。你把阈值调低参与发光的区域变多这时候如果强度不变画面就会过曝你把半径调大光晕覆盖范围变广这时候如果强度不变暗部会被抬起来对比度下降。所以调参的时候不能一个一个孤立地调要三个一起看。我通常的调参顺序是先定阈值确定哪些东西该发光再调半径确定光晕铺多大最后微调强度确定光晕有多明显。这个顺序能避免反复推翻前面的设置。3.2 降采样级数与分辨率的关系降采样级数决定了 Bloom 的“层次感”。级数太少光晕只有一层看起来单薄级数太多性能开销上去了而且最粗的那几级可能已经糊到看不出形状。一般来说5 级降采样能覆盖从几个像素到几百个像素的模糊范围对大多数场景够用了。如果画面分辨率是 1080p第一级降采样到 540p第二级 270p以此类推到第五级大概是 67p。这个尺度已经足够形成大范围的光晕。但这里有个坑如果分辨率本身很低比如 720p 甚至更低降采样级数太多会导致最粗的几级只有几个像素模糊出来是一团马赛克。这时候要么减少级数要么在降采样时用更好的滤波方式。我在一个低分辨率项目里就遇到过这个问题最后把级数从 6 降到 4画面反而干净了很多。3.3 亮度提取的常见误区亮度提取看起来简单——算一下像素亮度和阈值比一下——但实际做的时候有几个容易忽略的点。第一个是亮度公式。很多人直接用 RGB 的平均值但人眼对不同波长的敏感度是不一样的。绿色最敏感红色次之蓝色最弱。所以标准的亮度计算应该用加权公式比如 Rec.709 的 0.2126R 0.7152G 0.0722B。用平均值的话蓝色光源的 Bloom 会偏强绿色光源的 Bloom 会偏弱和真实观感对不上。第二个是提取后的颜色处理。有的实现会把提取出来的亮部直接转成灰度再做模糊这样 Bloom 就是白色的。但真实世界里红色光源的 Bloom 应该是偏红的蓝色光源的 Bloom 应该是偏蓝的。所以更好的做法是保留颜色信息只对亮度做阈值判断模糊时颜色一起参与。这样出来的光晕才有颜色倾向画面更丰富。第三个是提取区域的边界处理。如果提取时不做任何羽化亮部边缘会有锯齿。软阈值就是解决这个问题的但膝盖参数的设置需要根据场景亮度分布来调不能照搬默认值。3.4 与色调映射的配合顺序Bloom 和色调映射的先后顺序直接决定了高光的表现。如果 Bloom 在色调映射之前那么参与模糊的是 HDR 值高光可以远大于 1模糊出来的光晕能量是充足的。如果 Bloom 在色调映射之后那么参与模糊的已经是压缩到 0 到 1 的值高光被削平了Bloom 的强度就会打折扣。我做过一个对比测试同一个场景同一个 Bloom 参数只改顺序。色调映射前的 Bloom光晕有明显的层次中心亮、边缘柔色调映射后的 Bloom光晕整体偏平亮部容易直接顶到白色。差距非常明显。所以如果你的管线支持一定要把 Bloom 放在色调映射之前。如果因为某些原因必须放在之后那就要在提取亮部时做一次反向的亮度扩展把高光重新拉开否则 Bloom 会显得很“薄”。4. 完整实操流程与关键环节实现4.1 场景准备与 HDR 管线确认在动手调 Bloom 之前先确认你的渲染管线是不是 HDR 的。如果是 LDR 管线Bloom 的效果会大打折扣因为高光信息在渲染阶段就已经丢失了。确认的方法很简单在场景里放一个自发光材质把亮度值调到 5 或者 10看看渲染出来的像素值能不能超过 1。如果被截断在 1那就是 LDR 管线需要先改成 HDR。HDR 管线的关键设置包括渲染目标格式要用浮点或者半浮点比如 RGBA16F色调映射要放在后处理的最后一步曝光控制要启用让不同亮度场景能自动适配。这些设置在不同引擎里位置不一样但逻辑是相通的。我一般会先搭一个测试场景一个暗环境几盏不同颜色的自发光球体亮度从 1 到 20 不等。这个场景能直观地看出 Bloom 对高亮的响应也方便对比不同参数的效果。4.2 亮度提取与阈值配置亮度提取是 Bloom 的第一步。在着色器里大致逻辑是这样的vec3 color texture(sceneColor, uv).rgb; float brightness dot(color, vec3(0.2126, 0.7152, 0.0722)); float contribution smoothstep(threshold, threshold knee, brightness); vec3 bloomSource color * contribution;这段代码里smoothstep就是软阈值的实现。threshold是起始阈值threshold knee是完全参与的上限。中间的部分按平滑曲线过渡。配置的时候我会先把膝盖设为 0也就是硬阈值看看哪些区域被提取出来。然后慢慢加大膝盖观察边缘过渡是否自然。如果膝盖太大提取出来的亮部会变少Bloom 会变弱膝盖太小边缘又会有硬边。一般 0.5 到 1.0 之间是比较舒服的区间。注意阈值是相对于当前曝光水平的。如果你的场景曝光会自动变化阈值也要跟着调整否则白天和夜晚的 Bloom 表现会完全不一样。有的引擎会把阈值和曝光绑定这是更省心的做法。4.3 多级降采样与模糊实现降采样和模糊是 Bloom 里最耗性能的部分也是优化空间最大的部分。标准的流程是从提取出的亮部图开始降采样到一半分辨率。在降采样后的图上做横向高斯模糊。再做纵向高斯模糊。重复降采样和模糊直到达到预设的级数。从最粗的一级开始逐级向上叠加最终得到完整的 Bloom 图。模糊核的选择也有讲究。常见的是 9 抽头高斯核权重按高斯分布分配。抽头太少模糊会有块状感抽头太多性能开销大。9 抽头在质量和性能之间是一个比较好的平衡点。我在实现时习惯把横向和纵向模糊写成两个独立的 Pass这样中间结果可以复用也方便调试。如果引擎支持 Compute Shader用 Compute 来做模糊会比全屏 Pass 更高效因为可以更好地利用线程组共享内存。4.4 合成与最终输出合成阶段就是把 Bloom 图叠加回原图。叠加方式有两种加法叠加和加权混合。加法叠加是finalColor sceneColor bloomColor * intensity简单直接但亮度容易累积过头。加权混合是finalColor mix(sceneColor, sceneColor bloomColor, intensity)控制更精细。我一般用加法叠加但会在叠加前对 Bloom 图做一次能量归一化避免多级模糊叠加后能量过大。归一化的方法很简单把每一级的模糊结果乘以一个衰减系数越粗的级系数越小。这样叠加出来的光晕既有层次又不会过曝。合成之后才是色调映射。色调映射的曲线选择也会影响 Bloom 的观感。用 Reinhard 曲线高光压缩比较柔和Bloom 过渡自然用 ACES 曲线高光滚降更陡Bloom 会更集中。这个就看项目风格了没有绝对的好坏。4.5 性能优化与移动端适配Bloom 在桌面端通常不是性能瓶颈但在移动端就是另一回事了。移动端 GPU 的带宽和填充率都有限全分辨率的多次模糊很容易把帧率拉垮。我的优化策略是降低 Bloom 的处理分辨率。比如场景渲染是 1080pBloom 可以在 540p 甚至 360p 上做最后合成时再上采样。因为 Bloom 本身就是模糊的分辨率低一点肉眼几乎看不出来但性能能省一半以上。另一个策略是减少降采样级数。移动端用 3 到 4 级就够了再多的级数在手机屏幕上根本看不出区别。模糊核也可以简化从 9 抽头降到 5 抽头配合更好的降采样滤波质量损失很小。还有一个容易被忽略的点是 Bloom 的更新频率。如果场景光照变化不快Bloom 不需要每帧都重新计算可以隔帧更新甚至每三帧更新一次。这个技巧在移动端特别有效能省下大量 GPU 时间。5. 常见问题与排查技巧实录5.1 光晕发灰、画面发雾怎么办这是最常见的问题。表现是加了 Bloom 之后整个画面像蒙了一层灰纱对比度下降暗部不黑亮部不亮。原因通常是阈值太低导致大量中间亮度的像素也参与了 Bloom。这些像素本身不够亮模糊之后变成一层低强度的灰雾铺满整个画面。解决办法是提高阈值让只有真正的高光参与。如果提高阈值后 Bloom 太弱可以适当加大强度而不是降低阈值。另一个可能的原因是叠加方式不对。如果用加法叠加且没有做能量归一化多级模糊的结果累加起来会形成一个很大的基底这个基底就是灰雾的来源。检查每一级的衰减系数确保粗级别的贡献被压下去。5.2 光晕出现方块或条纹光晕出现方块状或者条纹状的伪影一般是降采样或模糊的滤波方式有问题。最常见的情况是降采样时用了最近邻采样导致像素块被直接放大模糊后就是一个个方块。解决办法是降采样时用双线性或者更好的滤波。如果引擎支持可以用盒式滤波或者高斯滤波来做降采样质量会好很多。另外模糊核的权重如果分配不均匀也会出现条纹。检查高斯核的权重是否按标准公式计算别用简单的平均。还有一种可能是分辨率不匹配。比如提取亮部时用的是全分辨率降采样时却用了非整数倍的缩放导致采样点错位。确保每一级降采样都是严格的 2 倍关系能避免大部分这类问题。5.3 Bloom 在暗部也出现光晕暗部出现光晕说明亮度提取环节有问题。可能是亮度计算用了错误的公式把暗部像素的亮度算高了也可能是阈值设置得太低暗部像素刚好越过了阈值。先检查亮度公式确认用的是加权公式而不是平均值。然后检查阈值把阈值临时调高到 2 或者 3看看暗部光晕是否消失。如果消失了说明就是阈值问题如果还在那可能是提取时的颜色空间不对比如在 sRGB 空间做了线性空间的运算。还有一个隐蔽的原因是自发光材质的亮度设置。有的材质在暗部也有微弱的自发光虽然肉眼看不出来但数值上可能刚好超过阈值。检查场景里所有自发光材质的亮度值确保暗部材质不会误触发 Bloom。5.4 性能突然下降的排查思路Bloom 导致性能下降通常有几个方向可以查排查方向可能原因解决方法分辨率Bloom 处理分辨率过高降低 Bloom 分辨率级数降采样级数过多减少到 4-5 级模糊核抽头数过多降到 9 抽头或 5 抽头更新频率每帧都重新计算改为隔帧更新带宽中间渲染目标过多合并 Pass减少 RT 切换我遇到过一次性能骤降最后发现是 Bloom 的中间渲染目标用了全分辨率而且每级都新建了一个 RT。改成半分辨率并复用 RT 之后帧率直接回来了。所以排查的时候先看分辨率和 RT 数量这两个是最容易出问题的地方。5.5 不同场景下的参数速查调 Bloom 最怕的就是换一个场景就要重新调一遍。我整理了一个速查表按场景类型给出大致的参数范围可以作为起点再根据实际情况微调。场景类型阈值膝盖强度半径级数夜景写实1.2-1.50.6-0.80.6-0.80.8-1.25-6日间写实1.5-2.00.5-0.80.4-0.60.6-1.04-5风格化0.8-1.20.8-1.20.8-1.21.0-1.54-5移动端1.2-1.80.6-1.00.5-0.80.8-1.23-4UI 展示1.0-1.50.5-1.00.3-0.50.5-0.83-4这个表里的数值不是绝对的因为不同引擎的亮度单位和曝光设置不一样。但相对关系是通用的夜景阈值低、强度高日间阈值高、强度低风格化可以放开一点移动端要克制。6. 进阶技巧与效果打磨6.1 用镜头脏污贴图增加真实感真实的镜头不是完美的。镜头表面有灰尘、有指纹、有微小的划痕这些瑕疵会让高光在散射时产生不规则的纹理。在 Bloom 里叠加一张镜头脏污贴图Lens Dirt能让光晕看起来更有“镜头感”而不是纯数学的模糊。做法很简单在 Bloom 合成阶段把 Bloom 图和一张脏污贴图相乘再叠加回原图。脏污贴图一般是一张灰度图亮的地方表示脏污严重Bloom 会被放大暗的地方表示干净Bloom 被抑制。贴图可以找现成的也可以自己用噪声生成。我试过几种不同的脏污贴图发现对比度高、纹理细碎的贴图效果最好。太均匀的贴图会让光晕变得很脏反而不好看。另外脏污贴图的强度要控制好一般 0.2 到 0.4 就够了太高会喧宾夺主。6.2 色差与 Bloom 的配合色差Chromatic Aberration是另一个能提升真实感的镜头效果。它模拟的是镜头对不同波长光线的折射率不同导致红绿蓝三个通道在画面边缘产生微小偏移。当色差和 Bloom 一起用时光晕的边缘会带上一圈淡淡的彩色非常像真实镜头拍出来的效果。实现上色差一般是在后处理的最后阶段做对屏幕 UV 做轻微的径向偏移三个通道分别采样。偏移量很小通常只有几个像素。和 Bloom 配合时色差会让 Bloom 的边缘不那么“干净”但正是这种不干净让它更真实。需要注意的是色差不能太强否则画面会像老式电视一样模糊。我一般把偏移量控制在屏幕宽度的 0.1% 到 0.3% 之间超过这个范围就太夸张了。6.3 动态 Bloom 与曝光联动在自动曝光的场景里Bloom 的阈值如果固定不变就会出现白天 Bloom 太强、夜晚 Bloom 太弱的问题。解决办法是让阈值和当前曝光值联动曝光高的时候阈值也高曝光低的时候阈值也低。具体做法是在计算阈值时乘以一个和曝光相关的系数。比如effectiveThreshold baseThreshold * (1.0 / exposure)。这样当场景变亮、曝光降低时阈值会自动提高避免白天过曝当场景变暗、曝光提高时阈值会自动降低让夜晚的灯光更容易 Bloom。这个联动逻辑在不同引擎里的实现方式不一样但思路是通用的。我建议在项目早期就把这个机制搭好不然后期场景一多手动调阈值会非常痛苦。6.4 用 Bloom 引导视觉焦点Bloom 不只是氛围效果它还可以用来引导玩家的注意力。人眼天生会被亮的东西吸引所以你可以通过控制哪些物体发光、发光多强来暗示玩家“往这边看”。比如在一个解谜场景里关键道具可以设置较高的自发光亮度配合 Bloom 让它微微发光玩家自然就会注意到。而背景里的装饰性光源亮度可以压低Bloom 弱一点不抢焦点。这种用法在关卡设计里非常实用比放一个箭头或者高亮描边要自然得多。我做过一个测试同一个场景一个版本用 Bloom 引导一个版本用 UI 箭头引导。结果大部分测试者都表示 Bloom 版本更“舒服”不会打断沉浸感。当然这也看场景类型竞技类游戏可能还是箭头更直接。7. 我踩过的坑与实操心得7.1 别在 LDR 管线里硬调 Bloom这是我早期犯的最大错误。当时项目用的是默认的 LDR 管线我硬是加了 Bloom结果怎么调都不对——要么没效果要么整个画面发白。后来才明白LDR 管线里高光已经被截断在 1 了Bloom 提取出来的亮部全是 1模糊之后就是一片均匀的白没有任何层次。改成 HDR 管线之后同样参数下 Bloom 立刻就有了层次感。所以如果你发现 Bloom 怎么调都不对先检查管线是不是 HDR 的。这个坑我踩了整整两天希望你别再踩。7.2 阈值不是越低越好新手调 Bloom 容易陷入一个误区觉得阈值越低发光的东西越多效果越明显。但实际上阈值太低会让大量中间亮度的像素参与进来这些像素模糊之后形成一层灰雾把画面的对比度全吃掉了。我现在的习惯是先把阈值调到一个比较高的值确保只有最亮的光源在发光然后慢慢往下调直到画面开始出现灰雾感再往回退一点。这个“退一点”的位置就是比较合适的阈值。宁可 Bloom 克制一点也不要让画面发灰。7.3 多级模糊的衰减系数要手动调很多引擎的 Bloom 实现里每一级模糊的衰减系数是固定的但固定值不一定适合你的场景。如果场景里光源很多固定衰减会导致粗级别的贡献过大画面过曝如果光源很少固定衰减又会让 Bloom 太弱。我的做法是把衰减系数暴露成可调参数在场景里实时预览。一般来说第一级的衰减在 0.8 到 1.0 之间之后每一级乘以 0.7 到 0.9。具体值要看场景亮度分布没有万能公式。但这个参数一旦调好整个 Bloom 的层次感会提升一个档次。7.4 移动端要敢于降质量在移动端做 Bloom最忌讳的就是照搬桌面端的参数。桌面端可以全分辨率、6 级降采样、9 抽头模糊移动端这么搞帧率直接崩。我的经验是移动端 Bloom 的分辨率不要超过屏幕的 1/4级数不要超过 4模糊核用 5 抽头就够。如果还不够快就改成隔帧更新。这些降质量的手段在手机屏幕上几乎看不出来但性能能省下 60% 以上。玩家不会因为 Bloom 少了一级而降体验评分但一定会因为帧率不稳而骂人。7.5 用参考图校准别凭感觉调调 Bloom 最容易出现的问题就是“调着调着就偏了”。因为人眼会适应你盯着看久了会觉得过曝的画面也“挺好看”。所以一定要找参考图来校准。我的做法是找几张电影截图或者摄影作品观察它们的高光是怎么处理的——光晕有多大、颜色是什么倾向、暗部有没有被影响。然后把自己的画面和参考图放在一起对比差距一目了然。这个方法比反复微调参数有效得多也能帮你建立对 Bloom 的“手感”。8. 后续可以继续深挖的方向Bloom 本身是一个相对成熟的技术但围绕它还有很多可以探索的空间。比如和体积光的结合——当光源穿过雾气或者烟尘时Bloom 和体积光的叠加能产生非常漂亮的光柱效果。再比如和景深的配合——失焦区域的高光 Bloom 会比清晰区域更弥散这个细节能让画面的空间感更强。还有一个方向是时域稳定性。在相机快速移动或者场景光照剧烈变化时Bloom 容易出现闪烁或者拖影。用时域抗锯齿的思路来做 Bloom 的时域滤波能显著提升稳定性但实现复杂度也会上去。这个我在一个项目里尝试过效果不错但调参花了不少时间。如果你已经把基础 Bloom 调明白了建议往这几个方向试试。每一个都能让你的画面再上一个台阶而且这些技巧在实际项目里的区分度很高不是那种“加了看不出区别”的优化。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑