资讯详情

Unity URP Bloom后处理全解析:从原理到手写RenderFeature

📅 2026/10/17 23:29:11 | 华诺云谱 👁 阅读
Unity URP Bloom后处理全解析:从原理到手写RenderFeature
做渲染效果的时候Bloom泛光大概是最容易快速提升画面质感的一项。低强度模式下它能让霓虹灯、屏幕反光、金属高光边缘柔化出一圈渐变光晕高强度模式下又能把普通灯具变成那种梦幻的“发光体”。在 Unity URP 项目里真正把 Bloom 调好并不只是拉高 Intensity 那么简单从 HDR 输入、高亮阈值提取、降采样模糊到最终合成每个环节都会直接影响最终结果。这篇文章按我实际从零到落地的一遍过程来梳理目标是让你看完后既能用 URP Volume 快速把 Bloom 配出来也能在效果不理想时知道该去改哪里而不是在参数面板里乱拖。这篇内容适合正在用 URP 做渲染的开发者也适合刚开始接触后处理、想搞懂“为什么 Bloom 要这么多个 Pass”的新手。我会先聊原理再讲内置 Volume 的实操配置最后给一条手写 RenderFeature 的实现路线并附上我踩过的坑。如果你只是想快速出效果直接看第三部分如果你是想彻底搞明白流程建议从头读完。1. Bloom效果与URP实现认知1.1 Bloom在画面里到底承担什么Bloom 模拟的是真实摄影中高光区域向周围扩散的光学现象。镜头不是理想光学器件强光射入后会在感光元件和镜片之间发生散射、衍射于是亮的区域周围会出现一层不太锐利的光晕。把这种效果搬到游戏画面里作用不只是“好看”它还能起到两个很实际的作用一是给亮部提供一个过渡带避免纯黑旁边突然冒出纯白像素否则画面会显得“干硬”二是用亮度信息引导玩家视线大面积暗场景里一束带光晕的高光天然会成为视觉焦点。但要注意Bloom 不是简单地把所有亮的地方变亮。它处理的是“超过某个阈值的亮度成分”而不是把整张图都抹一层光。否则就是全局提亮画面会发灰亮部和暗部都会失去对比。理解这一点后面调 Threshold 参数时就不会糊涂。URP 里处理 Bloom 有两个层次一套是内置的 Volume Bloom直接在 Post-processing Volume 里加一个 Override 就行另一套是自己写后处理 Pass用 RenderFeature 把高亮提取、模糊、合成几步串起来。内置方案胜在省事手写方案胜在可控两者并不冲突。1.2 URP里实现Bloom的三条路线现在 URP 工程里想实现 Bloom基本上有下面三条路线内置 Volume Bloom 在 Global Volume 的 Override 列表里加一个 Bloom然后在相机上打开 Post Processing场景里把要做光晕的高光物体材质做成 HDR 自发光。这是最推荐的做法尤其是移动端项目。内置实现经过大量平台适配性能和质量都比较均衡日常需求足够了。自写 RenderFeature 把 Bloom 拆成“提取亮度 - 逐级降采样 - 多次模糊 - 逐级上采样 - 合成”几个 Pass通过ScriptableRendererFeature注册到 URP 管线里。这个路线适合想做风格化变形的团队比如自定义光晕拉伸、多尺度混合权重、阈值随时间变化等。工作量不小但能学到很多东西。用 ShaderGraph 手搓全屏后处理 理论上可以做一个 Custom Function 节点把 Bloom 的 Pass 串在Blit节点里。但 ShaderGraph 做全屏后处理有几个麻烦点颜色空间、平台宏、深度纹理采样都不太直观而且生成的代码涉及很多隐藏的中间纹理性能不好预估。不太建议作为主力方案最多用来做原型验证。如果你只是想快速交付我建议选择方案一。手写方案更适合当你需要“内置方案做不出来的效果”时再去动否则容易吃力不讨好。1.3 前置知识HDR与LDR的本质区别Bloom 能不能工作很大程度上取决于你的渲染目标是不是 HDR。URP 的相机输出默认是半浮点纹理也就是场景颜色以 HDR 形式存在中间 RT 上颜色值可以超过 1.0。而普通的屏幕显示是 LDR每个通道范围只能落在 0 到 1 之间。如果相机关掉了 HDR或者场景根本没有产生超过 1.0 的高光Bloom 的阈值提取就毫无意义。比如一个普通灰色物体它在 LDR 下的颜色是 0.8你再怎么提升自发光强度只要材质不是 HDR 输出它在 RT 里也最高是 1.0。你以为给了高光实际上只是把没超过阈值的亮灰色喂给了 Bloom最后光晕会很少甚至完全没有。所以在做 Bloom 前第一个要确认的事就是相机有没有开 HDR以及场景里的发光物体在材质上是否用了真正的 HDR 自发光颜色。很多“Bloom 不生效”的案子第一步排查就卡在这里。2. Bloom原理拆解从高亮提取到光晕合成2.1 高亮提取阈值与Soft KneeBloom 第一步是从原图里把需要发光的像素选出来。URP 内置 Bloom 会在内部生成一张“亮度贡献图”公式大致是先求当前像素的亮度再把亮度与阈值做比较只有超过阈值的部分才被保留。但这个保留方式不是硬生生一刀切而是带了一个 Soft Knee软膝过渡让阈值附近的像素按一定斜率平滑衰减。为什么需要软过渡因为如果硬切场景里高光边缘会出现一圈肉眼可见的“虚线”动态场景里稍微变化一点这条线还会闪烁。Soft Knee 相当于给提取曲线加了平滑台阶边缘看起来更自然。内置 Bloom 面板里的Threshold就是那个主阈值Soft Knee控制曲线过渡带的宽窄。提取亮度时还有一个容易踩的坑不能直接拿 RGB 三个通道分别和阈值比较。比如一个纯红色高光RGB 是 (3,0,0)逐通道比较后只有 R 通道超过阈值最终会得到一个奇怪的偏红光斑。正确做法是先算出一个亮度标量再按亮度比例缩放原色这样既保留了高光的色相又不会让低亮度通道变成黑洞。2.2 降采样与高斯模糊为什么不能全分辨率硬来拿到亮度贡献图之后下一步是模糊。Bloom 本质上是低频效果光晕的半径通常覆盖几十甚至上百个像素如果直接在全分辨率图上做二维高斯卷积计算量会非常夸张。即便是在桌面 GPU 上为了一个 Bloom 跑几十个 9-tap 采样也不划算。所以标准做法是降采样先把亮度图缩到一半分辨率再做高斯模糊然后再缩到四分之一继续模糊甚至会迭代到八分之一、十六分之一。URP 内置 Bloom 的思路类似它会以原始亮度图作为第一级后续逐级减半形成一个金字塔。每一级图上做少量高斯采样最终合起来就覆盖了很大的模糊半径但总计算量远小于全分辨率卷积。降采样也是有讲究的。普通点采样在缩小图像时容易丢高频信息导致亮斑区域出现“闪耀”或“蠕动”。很多实现会使用加权平均把附近的亮度贡献尽量保留下来这样上采样回去时比较稳定。这也是为什么有些引擎里能看到KarisAverage这个特殊采样函数它就是专门用来处理这个问题的。自己写 Bloom 时我建议不要直接偷懒用_MainTex的默认点过滤至少要开双线性过滤有条件就按亮度做加权。2.3 上采样与多层混合光晕层层扩展模糊做完后要把这些小尺寸图像拼回原分辨率。常见思路是自下往上从最小的那一级开始用双线性插值放大到下一级尺寸和当前这一级的亮度图混合得到一张更大的光晕图。这样反复几次最上层就覆盖到了原始分辨率。这个逐级混合的过程其实就是在模拟不同扩散半径的光晕。最底层的小图对应“紧贴高光的短距离光晕”最上层的大图对应“散射较远的弥漫光晕”。URP 里的Scatter参数控制的就是层与层混合时当前层内容向上一层扩散的程度。Scatter 越大远端光晕占比越高视觉上光晕会拖得很长Scatter 越小光晕就缩在高光附近。最后一步是合成。把上采样得到的 Bloom 纹理乘以Intensity加到原始场景颜色上。这里要特别注意执行顺序URP 的后处理流程里Bloom 通常在 ToneMapping 之前执行。也就是说Bloom 是作用在 HDR 场景颜色上的光晕贡献的亮度可以继续叠加再交给色调映射处理。如果你自己实现时把 Bloom 放在 ToneMapping 之后光晕会被 LDR 颜色空间限制住表现会不一样。2.4 内置参数逐一解读URP 内置 Bloom 的 Override 界面里核心参数并不复杂但每个参数背后的意义都不同。我整理成一张表参数作用参考起始值注意事项Threshold高亮像素的最低亮度阈值1.0值越高参与光晕的高光越少Intensity最终叠加强度0.8只放大光晕亮度不扩展半径Scatter光晕向远处扩散的程度0.7过高会让画面整体糊掉Clamp限制单像素光晕贡献的上限按需防止高光区域变成纯白硬块Tint给光晕叠加颜色倾向白色适合暖色灯、冷色月光High Quality Filter高质量采样开关false移动端开启后光晕更平滑但开销更高Dirt Texture镜头灰尘贴图None配合 Dirt Intensity 使用模拟镜头表面污渍举个实际例子你在一个夜晚街道场景里挂了一排霓虹灯牌。Threshold 设为 1.2只有灯牌本身的 HDR 自发光和反射高光超过阈值。Scatter 设为 0.6让光晕有一小段拖尾。Intensity 设为 1.1把这段拖尾略微加亮。这时如果发现灯牌中心发白就要把 Clamp 压低避免中心亮度无限堆叠。如果还是感觉光晕不够自然再考虑把 High Quality Filter 打开试试。3. 用URP内置Volume把Bloom跑起来3.1 工程与相机前置检查先用一个最常见的 URP 工程举例。你要做的第一件事不是急着建 Volume而是确认渲染管线设置。在 URP Asset 的 Renderer 里后处理是默认开启的但你还需要检查相机组件。URP Camera 上有一个Post Processing开关如果它是关的整个后处理栈都不生效。另外相机上一般会有HDR选项很多模板默认开着但如果你迁移过老项目有可能被关掉了。这个开关必须是开的原因前面说过Bloom 依赖 HDR 数据。接着检查渲染目标分辨率。做 Bloom 调试时Game 视图的分辨率最好和实际目标设备保持一致。如果你在电脑上开着 4K Game 窗口测试Bloom 的降采样层级和移动端的 1080P 完全不是一回事调出来的参数到真机上往往会差别明显。在场景准备上推荐先用一个纯黑环境加一个 HDR 自发光物体来做测试。黑色环境能让你一眼看清光晕的边界自发光物体则负责提供稳定的高光来源。你可以在 URP Lit 材质里找到Emission开关勾选后点击色块把 Color Picker 切到 HDR 模式手动填一个大于 1 的颜色值比如 (2.0, 1.5, 1.0)然后用这个材质做测试物体。3.2 创建Global Volume并添加BloomURP 的 Volume 系统负责所有后处理 Override 的管理Bloom 只是其中一个 Override。操作流程如下在 Hierarchy 里新建空物体添加Volume组件。把 Volume 组件的Is Global勾上表示这是一个全局 Volume作用于整个场景。如果不勾就要在 OnTrigger 范围内放置 Collider 才能生效。在 Volume Profile 字段处点击New创建一个新的 Profile。选中这个 Profile在 Inspector 下方找到Add Override按钮展开列表后选择Post-processing分类下的Bloom。点击 Bloom 前面的复选框让它参与混合默认情况下它会被 Enable。这时你会在 Bloom Override 里看到前面表格里的那些参数。如果你的场景里同时存在多个 Global Volume它们的权重会按照 Volume 混合规则叠加。最简单的方式是只保留一个全局 Volume避免调了半天发现另一个 Volume 把参数又覆盖了。我见过不少新手加了 Volume 却没在 Camera 上勾 Post Processing结果一切都“看起来正常”但画面没有任何变化。所以做完这一步我建议先看一眼相机组件确认Post Processing前面是勾选状态。3.3 一组可复用的基准参数和调参顺序不同的项目、不同的场景Bloom 参数不可能有一套万能方案。但我整理了一套可以当作起点的基准参数适合大多数“想让灯光看起来柔和一些”的场景Threshold: 1.0Soft Knee: 0.5如果界面里有Scatter: 0.7Intensity: 0.8Clamp: 1.0High Quality Filter: 关调参顺序很重要。我自己试下来最有效的顺序是先调 Threshold再调 Scatter最后调 Intensity。先调 Threshold 的目的是确定画面里哪些东西应该成为光晕源。你把 Threshold 从 1.0 慢慢往上加画面里光晕参与像素会越来越少。调到“只有你想要的灯光和镜面高光还亮着”为止。这个过程不需要 Intensity 参与因为 Intensity 只是把已经选出来的光晕放大。接着调 Scatter。Scatter 决定光晕从高光中心向外延伸多远。如果你想要紧凑的 LED 光晕Scatter 放在 0.4 到 0.6如果你想要很大的梦幻弥散光可以放到 0.8 到 1.0。Scatter 调好后光晕的“形状”基本定了。最后才是 Intensity。它更像音量旋钮把整体光晕加到合适的强度。如果在 Threshold 和 Scatter 没调好的情况下就去加 Intensity画面会变成一片大面积白色烟雾无法判断是半径问题还是亮度问题。3.4 曝光联动与画面层次控制Bloom 和曝光的关系非常紧密。同一场景即使材质 HDR 亮度不变自动曝光参数变化后Bloom 选出的高光区域也会跟着变化。URP 里如果开了Auto Exposure自动曝光相机会根据场景亮度做曝光补偿白天和晚上切换时 EV 值会变化。这时候 Bloom 的 Threshold 实质上是相对值你在白天调的 Threshold 到晚上不一定合适。稳妥做法是先固定曝光或者使用Tone Mapping和手动曝光模式等 Bloom 参数稳定后再打开自动曝光。另外要注意Bloom 会放大暗部噪点。如果场景里有大量亮度接近阈值的噪声像素它们会被选进光晕源导致画面出现“沙沙”的光雾。这时候可以把 Threshold 提高一点或者降低相机曝光让噪声远离阈值线。这个方法比后处理里去噪更省事也比在 Bloom 参数里硬拉作用更直接。4. 手写RenderFeature版Bloom原理落地4.1 什么时候值得手写内置 Bloom 再好用也有覆盖不到的场景。比如你想做 Anamorphic 拉伸光晕让水平方向的光晕长度明显大于垂直方向或者你想实现“高光颜色随时间扩散”的风格化效果又或者你不想被内置 Blo 的混合公式限制想自己控制每一层的权重。在这些需求面前手写一个 RenderFeature 是合理的。它能让你把整个算法握在手里后续加特性也容易。但要知道手写的性能不一定比内置好取决于你的 Pass 数量、纹理格式和采样次数。我建议把“手写”当作学习和定制工具而不是“节省性能”的手段。如果你只是想让 Bloom 更快优先检查内置 Bloom 的 High Quality Filter 是否关闭再考虑降分辨率而不是重写一套。4.2 RenderFeature骨架与Pass调度一个简单的手写 Bloom 至少需要 5 个 Pass亮度提取降采样水平高斯模糊垂直高斯模糊合成如果只做一层半分辨率模糊也可以合并成亮度提取 - 半分辨率采样 - 水平模糊 - 垂直模糊 - 合成。但这种流程光晕半径有限适合原型验证。在 URP 里注册后处理核心是继承ScriptableRendererFeature和ScriptableRenderPass。Feature 负责创建和调度 PassPass 负责在实际渲染时往 CommandBuffer 里写指令。下面这个骨架是很多 URP 后处理的基础结构我用 URP 14 的接口来写不同版本 API 名称可能有差异但思路一致。using UnityEngine; using UnityEngine.Rendering; using UnityEngine.Rendering.Universal; public class BloomFeature : ScriptableRendererFeature { [System.Serializable] public class Settings { public Material bloomMaterial; public float threshold 1.0f; public float intensity 1.0f; public int blurIterations 2; } public Settings settings new Settings(); private BloomPass bloomPass; public override void Create() { bloomPass new BloomPass(settings); } public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData) { if (settings.bloomMaterial null) { return; } renderer.EnqueuePass(bloomPass); } private class BloomPass : ScriptableRenderPass { private Settings settings; private RTHandle tempColor; private RTHandle bloomTex; public BloomPass(Settings settings) { this.settings settings; renderPassEvent RenderPassEvent.AfterRenderingTransparents; } public override void OnCameraSetup(CommandBuffer cmd, ref RenderingData renderingData) { // 这里根据相机描述符申请临时纹理 // RTHandleAllocator 或者 RenderTexture.GetTemporary 均可 } public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData) { CommandBuffer cmd CommandBufferPool.Get(CustomBloom); // 依次执行 // 1. 亮度提取 // 2. 降采样 // 3. 高斯模糊 // 4. 合成 context.ExecuteCommandBuffer(cmd); CommandBufferPool.Release(cmd); } public override void OnCameraCleanup(CommandBuffer cmd) { // 释放临时纹理 } } }这个骨架里我没有把 Blit 每一步都展开因为不同 URP 版本获取相机颜色目标的方式不同。你需要自己实现OnCameraSetup里的 RTHandle 创建以及在 Execute 里调用Blit命令把_MainTex按不同 Pass 处理到临时 RT。关键点是renderPassEvent不能乱设。Bloom 是后处理应该在场景不透明和透明物体都画完之后执行一般放在AfterRenderingTransparents或者更靠后的阶段。如果你把它放在BeforeRenderingOpaques那等于是给半成品场景做 Bloom得到的结果完全是错的。4.3 核心Shader片段亮度提取、高斯模糊、合成自己写 BloomShader 的核心是那几步处理函数。下面贴几个能直接放进 Shader Pass 里的核心片段。亮度提取的 Shader 函数重点是把高光颜色按亮度比例缩放。我用 HLSL 写一个示意float4 _BloomThreshold; float4 BrightPass(float2 uv) : SV_Target { float3 col SAMPLE_TEXTURE2D(_MainTex, sampler_LinearClamp, uv).rgb; float luma dot(col, float3(0.2126, 0.7152, 0.0722)); float contrib saturate(luma - _BloomThreshold.x) / max(luma, 1e-5); return float4(col * contrib, 1.0); }这里contrib计算的就是“超过阈值部分占整体亮度比例”。如果像素亮度为 2.0阈值为 1.0那么 contrib 是 0.5最终输出颜色是原来的一半。这样高光被保留但低于阈值的部分会被裁剪掉。用除法而不是简单减法是为了保留颜色比例避免红色高光变成不自然的品红。高斯模糊我建议用可分离的高斯方式。水平 Pass 只沿 u 方向采样垂直 Pass 只沿 v 方向采样两次结果组合成二维模糊。下面是一个简化的 9-tap 水平模糊片段float4_BlurOffset; float4 GaussianBlurH(float2 uv) : SV_Target { float3 sum 0.0; float weightSum 0.0; for (int i -4; i 4; i) { float2 offset float2(_BlurOffset.x * i, 0.0); float w GaussianWeight(i); sum SAMPLE_TEXTURE2D(_MainTex, sampler_LinearClamp, uv offset).rgb * w; weightSum w; } return float4(sum / weightSum, 1.0); }GaussianWeight可以用标准正态分布公式算也可以预计算成常量数组打进_BlurOffset之外另一个数组。实际项目里我建议预计算好 9 个权重放到 Shader 的CBUFFER里避免 GPU 每次跑循环重复算数学函数。合成 Pass 相对简单把 Bloom 纹理和场景颜色相加。如果你想让光晕更自然可以在相加时对 Bloom 颜色再做一个轻微的高光过滤但这部分属于风格化调整了。float3 finalColor sceneColor.rgb bloomColor.rgb * _BloomIntensity; return float4(finalColor, 1.0);4.4 手写版的性能取舍与兼容性手写 Bloom 最容易翻车的地方是中间纹理和 Pass 数量。每多一个 Pass就意味着多一次全屏或者半屏的渲染开销。移动端 GPU 对带宽更敏感中间 RT 用半浮点 R16G16B16A16 会比全浮点 R32G32B32A32 省很多带宽。另外一个非常影响性能的点是降采样级数。别一上来就降四层。对于手机端 1080P最高到四分之一分辨率就够用了也就是 540p 左右继续降到 270p 对视觉提升不大但采样数量还在往上加。兼容性上要注意URP 12 之后的 ScriptableRenderPass API 变化比较大从cameraColorTarget到后来的 RTHandle代码要跟着改。如果你在升级 URP 版本后发现自己手写的 Blit 流程不生效优先检查是不是 API 过期而不是怀疑算法本身。手写完后调试也有技巧。把 Bloom 中间结果直接输出到屏幕比如把亮度提取 Pass 的结果显示出来你能一眼看出哪些像素被选中了。这个调试方法比反复调整最终画面快得多。我一般会在 Shader 里加一个_DebugMode开关用来切换显示各 Pass 中间图。5. 常见问题与排查实录5.1 Bloom完全没反应先查这几项我修过很多 Bloom 不生效的案例几乎每次都是下面几个原因之一。按顺序排查基本能在五分钟内定位相机组件上的Post Processing没有打开。这是最常见的。场景里没有 Global Volume或者 Global Volume 的 Weight 为 0。Volume Profile 里没有真正添加 Bloom Override只是创建了空 Profile。发光物体的材质没有开 Emission或自发光颜色没有超过阈值。相机 HDR 被关闭。Bloom 的 Threshold 设置过高场景里没有任何像素能超过阈值。建议做一次“极简验证”把所有 Bloom 参数恢复默认Threshold 降到 0Intensity 调到 2.0再用一个 HDR 自发光球体放在镜头前。如果这时候还没有光晕说明是管线配置问题和参数无关。5.2 光晕发硬、过曝、颜色不对光晕发硬常常是 Soft Knee 太小或采样层数不够导致的。内置 Bloom 里打开High Quality Filter通常能改善边缘但如果开了还发硬就检查是不是 Threshold 太高把原高光的“中心核”选得太极端。过曝一般来自两个地方一是Intensity太高二是Clamp没有约束。高光原本是 4.0Bloom 又叠加了 2.0还没进 ToneMapping 就接近 6.0最终自然是一片白。把 Clamp 压到 1.0 左右让单像素光晕贡献封顶就不会无限堆亮了。颜色不对的情况我遇到最多的是“光晕发灰”。原因是亮度提取时直接用了float3(col - threshold)这种逐通道减阈值的写法导致本来有颜色的高光变成灰色。按前面代码里的contrib (luma - threshold) / luma方式提取颜色比例是正确的。5.3 移动端帧率崩掉的优化点如果 Bloom 在桌面没问题到移动端帧率骤降优先做这几件事把High Quality Filter关掉。把 Bloom 作用的分辨率降到原始屏幕分辨率的一半。减少模糊迭代次数两次足够。中间纹理使用半精度格式不要用 R32F。观察 Frame Debugger 里 Bloom 相关 Pass 数量和每个 Pass 的渲染目标大小。移动端很多 GPU 是 tile-based后处理链上的 RT 切换成本很高。你可以在 URP 的 Renderer 设置里为相机配一个独立的 Render Scale让 Bloom 在更低的分辨率上计算。实在不行就把 Bloom 从后处理链里去掉改用 Shader 在物体自发光材质里模拟一个简单的“假光晕”性能消耗几乎可以忽略。5.4 与抗锯齿、动态分辨率的关系Bloom 和 TAA 的关系通常是 Bloom 在 TAA 之后跑URP 内置顺序已经处理好了。如果你手写 Bloom一定要确保它排在抗锯齿后面否则 TAA 会把你模糊出来的光晕边缘再抖一遍产生重影。动态分辨率开启时后处理链的源分辨率会跟着变化。内置 Bloom 会自动适配当前 RT 大小但手写 Bloom 里如果硬编码了某个缩放系数比如固定做 2 层降采样到 960x540那么分辨率变化后层级比例就错了。建议手写时从cameraTargetDescriptor读取当前尺寸再根据尺寸决定降采样层级。多个 Volume 混合时也要注意如果场景里有多个 Global Volume并且它们的 Bloom Intensity 都设置了不同值最终结果会按权重混合。排查时可以先只保留一个 Volume把其他 Volume 临时禁用确认当前生效的是哪一个。我个人在实际操作中的体会是Bloom 是个“结果很热闹、过程很冷静”的效果。越急着堆参数越容易调成一团糊反而是先建立最简单的测试场景一步步确认每个 Pass 在干什么最后再回到真实场景里微调效率最高。最后再分享一个小技巧调 Bloom 之前先在材质上把要发光物体的 HDR 自发光亮度标定到一个稳定值比如纯白色 2.0。这样你之后改曝光、改色调映射时至少知道 Bloom 的输入没有漂移所有变化都来自后处理本身排查范围会小很多。如果你只是想让普通项目快速提升质感内置 Bloom 足够用如果你想做更风格化的光晕手写一遍这个流程绝对值得。
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑