Skip to content

后处理

Bloom 原理是什么?

Bloom 原理是什么?

Bloom 是一种后处理效果。 它的作用是让画面中特别亮的地方向周围扩散出光晕,比如太阳、霓虹灯、魔法球、爆炸、能量武器。

rendering-bloom-principle

底层流程

Bloom 一般分成几步:

  1. 渲染原始画面。
  2. 从画面里提取特别亮的像素。
  3. 把这些高亮像素做模糊处理。
  4. 把模糊后的亮部重新叠加回原图。
  5. 最终画面看起来就有“发光溢出”的效果。

简单公式可以理解成:

最终颜色 = 原始画面 + 模糊后的高亮区域 * Bloom强度

为什么要先提取高亮?

因为不是所有东西都应该发光。

比如普通墙面、角色衣服、地面不应该产生 Bloom。 只有亮度超过阈值的部分才会被提取出来。

这个阈值通常叫:

Threshold

比如:

color brightness > threshold

超过阈值的像素保留,没超过的像素变黑。

为什么要模糊?

如果只把高亮区域直接叠回去,它只是更亮,不会有光晕。

所以要对高亮图做模糊:

  • 先降采样,降低分辨率。
  • 再做高斯模糊或类似模糊。
  • 然后上采样。
  • 最后叠回原图。

模糊越强,光晕越宽。 强度越高,画面越亮。

Bloom 和 HDR 的关系

Bloom 经常和 HDR 一起用。

原因是 HDR 允许颜色亮度超过 1.0。 比如普通白色可能是:

1.0

但太阳、能量球、强光可能是:

3.0、5.0、10.0

这些超过正常显示范围的亮度,就很适合作为 Bloom 的来源。

所以可以这样理解:

HDR 负责保留超亮信息,Bloom 负责把超亮信息扩散成光晕。

Bloom 是不是灯光?

不是。

Bloom 不是真正的光照计算。 它不会真的照亮旁边的物体,也不会产生真实阴影。

它只是一个屏幕空间后处理效果: 把已经渲染好的画面拿来加工。

所以 Bloom 更像是视觉增强,不是物理光照。

性能消耗在哪里?

Bloom 的性能主要花在:

  • 额外的 RenderTexture。
  • 亮部提取。
  • 多次降采样。
  • 多次模糊采样。
  • 多次上采样。
  • 最后的叠加合成。

移动端上 Bloom 不能乱开太重。 尤其是高分辨率、多次迭代、大范围 Bloom,会增加 GPU 带宽压力。

面试高分回答

NOTE

Bloom 是一种后处理效果,它先从 HDR 画面中根据阈值提取高亮区域,然后对高亮图做降采样和模糊,再把模糊后的亮部叠加回原图,从而形成亮光向外溢出的光晕效果。它本质上是屏幕空间的视觉增强,不是真正的光照,不会真实照亮周围物体。

一句话记忆:

Bloom = 提取高亮 + 模糊扩散 + 叠回原图。

SSAO 是什么?

SSAO 是什么?

SSAO 全称是 Screen Space Ambient Occlusion,中文叫屏幕空间环境光遮蔽

它的作用是: 让墙角、缝隙、物体接触处变暗,让画面更有体积感。

rendering-ssao-explained

为什么需要 SSAO?

真实世界里,角落和缝隙通常会更暗。 因为环境光很难照进去。

比如:

  • 墙和地面的交界处
  • 石头压在地上的底部
  • 角色脚底
  • 鼻子两侧
  • 盔甲缝隙
  • 桌子腿和地面接触处

如果没有 AO,这些地方可能会显得很平、很假,像模型“浮”在场景里。

SSAO 底层原理

SSAO 不是真实光照,它是一个屏幕空间后处理效果

大概流程是:

  1. 渲染场景后,得到屏幕上的深度图。
  2. 有些实现还会用法线图。
  3. 对当前像素,根据深度还原出它在空间中的位置。
  4. 在这个点附近,沿法线方向采样一圈点。
  5. 看这些采样点附近有没有几何体挡住。
  6. 如果周围遮挡很多,就让这个像素的环境光变暗。

简单理解:

附近越挤,越暗。
附近越空,越亮。

它为什么叫屏幕空间?

因为 SSAO 只依赖当前屏幕里已有的信息,比如:

  • 当前画面的深度
  • 当前画面的法线
  • 当前像素附近的采样结果

它不是去真正遍历整个 3D 世界。

所以它有一个重要限制:

屏幕上看不到的信息,SSAO 通常也算不到。

比如一个物体在屏幕外,但理论上它应该遮挡环境光,SSAO 很可能不知道。

SSAO 和阴影有什么区别?

阴影通常和具体光源有关。 比如太阳光从左上角照下来,物体会往右下角投影。

SSAO 不是这种投影阴影。 它主要模拟的是环境光被附近几何体遮住

可以这样记:

  • Shadow Map:判断某个光源有没有被挡住。
  • SSAO:估算环境光有没有被周围物体挡住。
  • Contact Shadow:补光源方向上的近距离接触阴影。

SSAO 的优点

SSAO 的优点是:

  • 不需要提前烘焙。
  • 可以作用在动态物体上。
  • 能增强体积感。
  • 对墙角、缝隙、接触处效果明显。
  • 比真正的全局光照便宜很多。

所以很多游戏会用 SSAO 来让画面更“立体”。

SSAO 的缺点

因为它是屏幕空间算法,所以也会有一些问题:

  • 屏幕外物体无法参与。
  • 容易出现黑边。
  • 容易有噪点。
  • 采样半径太大会有脏污感。
  • 采样次数太多会影响性能。
  • 远处可能闪烁。
  • 移动端开启要谨慎。

面试高分回答

IMPORTANT

SSAO 是一种屏幕空间环境光遮蔽技术。它利用当前画面的深度和法线信息,在每个像素附近做采样,估算这个点周围有多少几何体会遮挡环境光。如果附近遮挡物多,就降低该像素的环境光贡献,让墙角、缝隙和物体接触处变暗,从而增强画面的体积感。

它的本质不是实时阴影,也不是全局光照,而是一种基于屏幕信息的近似后处理效果。

一句话记忆:

SSAO = 用深度和法线估算“环境光被挡住多少”。

Motion Blur 是什么?

Motion Blur 中文叫运动模糊。 它模拟的是现实相机拍摄快速运动物体时,因为曝光时间内物体位置发生变化,所以画面会沿运动方向出现拖影。

rendering-motion-blur-explained

它解决什么问题?

如果画面里物体移动很快,但每一帧都非常清晰,视觉上可能会觉得:

  • 动作很硬
  • 有跳帧感
  • 速度感不强
  • 镜头快速转动时不自然

Motion Blur 会把快速运动的像素沿运动方向拉开,让画面更像真实相机拍出来的效果。

底层原理

现代游戏里的 Motion Blur 通常是一个后处理效果

核心不是随便把画面糊掉,而是根据每个像素的运动向量来模糊。

运动向量可以简单理解成:

运动向量 = 当前帧位置 - 上一帧位置

也就是这个像素从上一帧到当前帧移动了多少、往哪个方向移动。

然后 Shader 会沿着这个方向多次采样颜色,再混合起来:

模糊颜色 = 沿运动方向采样多个颜色后求平均

所以 Motion Blur 的本质是:

根据像素运动方向,把颜色沿运动路径混合。

相机运动模糊

相机运动模糊来自摄像机本身的移动或旋转。

比如:

  • 快速转镜头
  • 冲刺
  • 镜头震动
  • 赛车高速前进
  • 第一人称快速甩视角

这种情况通常可以通过:

  • 当前帧相机矩阵
  • 上一帧相机矩阵
  • 深度图

来重建每个像素上一帧的位置,从而算出运动向量。

物体运动模糊

物体运动模糊来自物体自身移动。

比如:

  • 飞过去的子弹
  • 挥动的武器
  • 快速奔跑的角色
  • 旋转的轮胎
  • 高速移动的怪物

这种通常需要物体输出自己的 Motion Vector。 否则引擎可能只知道相机在动,不知道物体自己在动。

Motion Blur 和普通模糊的区别

普通模糊是把周围颜色平均一下。 它不管物体往哪动。

Motion Blur 是按运动方向模糊。 速度越快,拖影越明显;速度越慢,拖影越弱。

所以它不是简单的“画面变糊”,而是有方向、有速度依据的模糊

性能代价

Motion Blur 会有性能成本:

  • 需要运动向量 Buffer。
  • 需要读取深度或历史矩阵。
  • 需要屏幕空间多次采样。
  • 采样次数越多,GPU 压力越大。
  • 移动端开启要谨慎。

如果参数太重,还会导致画面糊、拖影脏、玩家头晕,尤其是动作游戏和射击游戏里要控制强度。

面试高分回答

TIP

Motion Blur 是一种后处理效果,用来模拟相机曝光期间物体或相机发生运动导致的拖影。现代渲染中通常会为像素计算运动向量,也就是当前帧和上一帧在屏幕空间的位置差,然后沿着这个运动方向对颜色进行多次采样和混合,从而得到运动模糊效果。

它可以增强速度感和镜头真实感,但会带来额外的 Buffer、采样和带宽成本,移动端和操作反馈强的游戏里需要谨慎使用。

一句话记忆:

Motion Blur = 用运动向量决定方向,把颜色沿移动方向拖开。

Depth of Field 是什么?

Depth of Field,简称 DOF,中文叫景深。 它模拟的是相机镜头效果:焦点位置清晰,焦点前后变模糊。

rendering-depth-of-field-explained

它解决什么问题?

没有景深时,前景、中景、远景都很清楚。 这样信息很多,但画面可能缺少镜头感,玩家视线也不容易集中。

开启景深后:

  • 焦点处清楚。
  • 焦点前方模糊。
  • 焦点后方模糊。
  • 画面更像真实相机拍出来的效果。

比如剧情镜头对准角色的脸,背景就会虚化。

底层原理

实时渲染里的景深通常是一个后处理效果

大概流程是:

  1. 渲染出原始画面。
  2. 拿到屏幕深度图。
  3. 设置一个焦点距离 Focus Distance
  4. 判断每个像素的深度离焦点有多远。
  5. 离焦点越远,模糊半径越大。
  6. 按不同模糊半径采样周围颜色。
  7. 最后合成出景深效果。

简单理解:

离焦点越近,越清楚
离焦点越远,越模糊

CoC 是什么?

景深里常见一个概念叫 CoC,全称 Circle of Confusion,中文叫弥散圆

你可以这样理解:

一个点没有准确落在焦平面上时,它在屏幕上会扩散成一个圆。这个圆越大,画面越模糊。

所以:

  • CoC 小:接近焦点,比较清晰。
  • CoC 大:远离焦点,更模糊。

面试里说出 CoC,会显得你不是只知道效果名字,而是知道底层原理。

Focus Distance 是什么?

Focus Distance 是焦点距离。 它决定哪个距离上的物体最清楚。

比如:

  • 对焦主角脸部。
  • 对焦准星命中的敌人。
  • 对焦剧情里的关键物体。
  • 对焦菜单里的角色模型。

游戏里可以动态调整焦点距离,比如相机射线打到哪里,就把焦点设置到哪里。

Aperture / F-stop 是什么?

它们和光圈有关。

简单说:

光圈越大,景深越浅,焦外越模糊。

游戏里的参数不一定完全物理准确,但通常会影响:

  • 模糊强度
  • 模糊半径
  • 焦点前后清晰范围
  • 散景效果

它有什么代价?

景深会消耗性能,因为它需要:

  • 读取深度图。
  • 计算每个像素的离焦程度。
  • 对画面做多次采样模糊。
  • 大半径模糊会增加 GPU 带宽压力。
  • 高质量散景效果更贵。

移动端一般要谨慎使用,尤其是全屏高质量景深。

常见问题

景深容易出现这些问题:

  • 物体边缘漏色。
  • 前景和背景混合不自然。
  • 透明物体深度不准确。
  • UI 被误模糊。
  • 模糊太强导致玩家看不清。
  • 动态对焦变化太快会让人头晕。

所以游戏里常常只在剧情、拍照模式、菜单背景、瞄准镜里使用,而不是一直开很强。

面试高分回答

IMPORTANT

Depth of Field 是景深效果,用来模拟相机对焦。实时渲染中通常会根据屏幕深度图和焦点距离计算每个像素的离焦程度,也就是 CoC 弥散圆大小。像素离焦点越远,CoC 越大,模糊半径越大;离焦点越近,则保持清晰。最后通过后处理模糊和合成,得到焦点清晰、焦外虚化的效果。

一句话记忆:

景深 = 按深度判断离焦程度,焦点清晰,焦外模糊。

Color Grading 是什么?

Color Grading 中文叫调色。 它是后处理的一种,用来在画面渲染完成后,统一调整整张画面的颜色、明暗、对比和风格。

rendering-color-grading-explained

它解决什么问题?

游戏场景正常渲染出来后,可能会有这些问题:

  • 画面偏灰。
  • 色彩不统一。
  • 明暗不够有层次。
  • 场景缺少氛围。
  • 不同关卡的美术风格不一致。

Color Grading 就是在最后统一“修图”。

比如:

  • 沙漠关卡偏暖。
  • 科幻实验室偏冷。
  • 恐怖场景偏暗、偏绿。
  • 回忆场景低饱和。
  • 战斗爆发时提高对比度和亮度。

底层原理

Color Grading 通常是一个全屏后处理 Pass

流程大概是:

  1. 场景先正常渲染到一张 RenderTexture
  2. 后处理 Shader 读取每个像素的颜色。
  3. 根据调色参数修改颜色。
  4. 或者通过 LUT 把输入颜色映射成目标颜色。
  5. 输出最终画面。

简单公式可以理解成:

最终颜色 = 调色函数(原始颜色)

更具体一点:

finalColor = ApplyLUT(AdjustExposureContrastSaturation(sceneColor))

常见调色参数

常见参数有:

  • Exposure:曝光,控制整体亮暗。
  • Contrast:对比度,让亮处更亮、暗处更暗。
  • Saturation:饱和度,控制颜色鲜艳程度。
  • Temperature:色温,偏冷或偏暖。
  • Tint:色调偏移,比如偏绿或偏紫。
  • Gamma:中间调亮暗。
  • Lift:阴影区域调整。
  • Gain:高光区域调整。
  • Curves:曲线,更精细地控制明暗和颜色。
  • LUT:查找表,统一套一套颜色风格。

LUT 是什么?

LUT 全称是 Look Up Table,中文叫查找表

它的作用是:

把一个输入颜色,映射成另一个输出颜色。

比如原来一个像素是:

偏蓝的灰色

经过 LUT 后可能变成:

偏暖的橙灰色

这样美术可以在外部工具里调出一种风格,然后导入 Unity,让游戏画面统一套用。

Color Correction 和 Color Grading 区别

这两个词经常一起出现。

Color Correction 偏修正。 比如曝光不对、白平衡不对、画面偏色,需要先修准确。

Color Grading 偏风格化。 比如做电影感、冷暖氛围、梦境感、压抑感、赛博朋克感。

简单说:

  • Color Correction:让颜色变对。
  • Color Grading:让颜色变好看、变有风格。

性能代价

Color Grading 一般没有 Bloom、SSAO、景深那么重。 如果只是简单颜色调整或采样一张 LUT,成本通常不算高。

但它仍然是全屏后处理,所以会有:

  • 全屏像素处理成本。
  • RenderTexture 读写成本。
  • 移动端带宽成本。
  • 多个后处理叠加时的额外消耗。

移动端上一般建议把多个后处理合并,避免多次全屏 Pass。

面试高分回答

CAUTION

Color Grading 是一种后处理调色技术,它会在场景渲染完成后,对最终画面的每个像素进行颜色变换,例如调整曝光、对比度、饱和度、色温、曲线,或者通过 LUT 将输入颜色映射成目标颜色。它的目的不是改变模型、灯光或材质本身,而是统一最终画面的视觉风格和情绪氛围。

一句话记忆:

Color Grading = 对最终画面做统一颜色映射,让画面从“渲染结果”变成“美术风格”。

FXAA、TAA、MSAA 区别是什么?

它们都是抗锯齿方案,但核心区别是:

FXAA 改最终图,MSAA 改像素采样,TAA 利用多帧历史。

rendering-fxaa-taa-msaa-comparison

先说锯齿怎么来的

屏幕是一个个像素组成的。 但游戏里的模型边缘、斜线、细线是连续的。

当连续的边缘落到离散像素上时,就会出现一格一格的台阶状边缘,这就是锯齿。

抗锯齿的目标就是: 让边缘过渡更平滑,减少闪烁和台阶感。

FXAA 是什么?

FXAA 全称是 Fast Approximate Anti-Aliasing。 它是一种后处理抗锯齿

流程大概是:

  1. 场景已经渲染成一张最终图片。
  2. FXAA 在这张图里找高对比边缘。
  3. 判断哪里像锯齿。
  4. 沿着边缘方向做轻微模糊。
  5. 最终让锯齿看起来不那么明显。

它的优点是:

  • 很便宜。
  • 实现简单。
  • 兼容性好。
  • 不需要特殊几何采样。
  • 对移动端比较友好。

缺点是:

  • 本质是“抹边”。
  • 画面可能变糊。
  • 文字、UI、细节纹理可能被一起模糊。
  • 对远处闪烁问题帮助有限。

一句话:

FXAA 是在最终画面上找边缘,然后把锯齿抹平。

MSAA 是什么?

MSAA 全称是 Multi-Sample Anti-Aliasing。 它是在光栅化阶段做的抗锯齿。

普通渲染时,一个像素可能只判断一次这个像素是否被三角形覆盖。 MSAA 会在一个像素内部放多个采样点,比如 2x4x8x

如果一个像素只有一部分被三角形覆盖,MSAA 可以更准确算出覆盖比例。 所以几何边缘会更平滑。

它的优点是:

  • 几何边缘效果好。
  • 不会像 FXAA 那样明显糊整张图。
  • 对模型轮廓、三角形边缘很有效。

缺点是:

  • 显存更高。
  • 带宽更高。
  • 对贴图锯齿、Shader 锯齿、透明物体锯齿帮助有限。
  • 在 Deferred Rendering 里支持和成本会更麻烦。

一句话:

MSAA 是在一个像素里放多个采样点,让几何边缘覆盖更准确。

TAA 是什么?

TAA 全称是 Temporal Anti-Aliasing。 它是时间抗锯齿,核心是利用多帧信息。

流程大概是:

  1. 当前帧渲染时,让相机采样位置做很小的抖动。
  2. 每一帧拿到的采样信息略有不同。
  3. 通过 Motion Vector 找到像素上一帧的位置。
  4. 把当前帧和历史帧进行累积混合。
  5. 多帧叠加后,边缘和远处细节更稳定。

它的优点是:

  • 对远处细线闪烁很有效。
  • 对亚像素锯齿有效。
  • 对草、栏杆、远处模型抖动效果好。
  • 现代 PC 和主机项目很常见。

缺点是:

  • 可能产生拖影。
  • 可能让画面变糊。
  • 依赖 Motion Vector。
  • 动态物体、透明物体、粒子特效容易出问题。
  • 实现复杂度比 FXAA 高。

一句话:

TAA 是用当前帧加历史帧,把锯齿和闪烁在时间上平均掉。

三者怎么选?

如果是移动端,常见选择是:

  • 低端机:FXAA 或关闭抗锯齿。
  • 中高端机:2x 或 4x MSAA。
  • 特定管线和项目:谨慎使用 TAA。

如果是 PC 或主机,常见选择是:

  • TAA 很常见,因为远景稳定性好。
  • TAA 后面经常配锐化,缓解画面变糊。
  • MSAA 更适合 Forward 管线和几何边缘明显的场景。
  • FXAA 常作为低成本兜底方案。

面试高分回答

NOTE

FXAA、MSAA、TAA 都是抗锯齿方案,但工作阶段不同。FXAA 是后处理方法,在最终图像上检测高对比边缘并模糊,成本低但容易糊。MSAA 是光栅化阶段的多重采样,通过在一个像素内放多个覆盖采样点来平滑几何边缘,效果干净但显存和带宽成本高,并且对贴图和 Shader 锯齿帮助有限。TAA 是时间抗锯齿,通过相机抖动、运动向量和历史帧累积来减少锯齿和远处闪烁,稳定性好,但容易产生拖影和画面变糊。

一句话记忆:

FXAA 最便宜但会糊;MSAA 擅长几何边缘;TAA 擅长时间稳定和远景闪烁。

后处理为什么通常需要全屏 Pass?

后处理为什么通常需要全屏 Pass?

因为后处理处理的不是某一个模型,而是已经渲染好的整张屏幕图像。 所以它通常要让 Shader 覆盖整个屏幕,对每个像素都执行一次。

rendering-post-process-fullscreen-pass

先理解 Pass 是什么

一次 Pass 可以简单理解成:

GPU 执行一次绘制流程,跑一段 Shader,输出一批像素结果。

普通物体渲染时,Pass 可能是在画模型。 后处理 Pass 通常不是画模型,而是画一个覆盖全屏的三角形或四边形。

它的目的不是表现这个三角形本身,而是借它让片元着色器在整张屏幕上执行。

后处理的底层流程

大概流程是:

  1. 相机先正常渲染场景。
  2. 场景结果写入一张 RenderTexture
  3. 后处理阶段画一个全屏三角形或全屏四边形。
  4. Shader 对屏幕上每个像素执行。
  5. 每个像素根据自己的 uv 去读取原始画面。
  6. Shader 加工颜色后输出最终结果。

简单说:

原始画面 -> 全屏 Pass -> 后处理 Shader -> 最终画面

为什么必须全屏?

因为很多后处理效果都是基于最终画面的。

比如:

  • Color Grading:每个像素都要调色。
  • Bloom:每个像素都可能参与高亮提取和叠加。
  • FXAA:每个像素都要检查周围边缘。
  • SSAO:每个像素都要根据深度估算遮蔽。
  • Depth of Field:每个像素都要根据深度决定模糊程度。
  • Motion Blur:每个像素都要根据运动向量采样混合。

这些效果不是只改某个物体,而是改整张屏幕。 所以就需要全屏覆盖。

全屏 Pass 不是重新画所有物体

这个点面试里很重要。

全屏 Pass 并不是把场景里的 Mesh、材质、灯光重新渲染一遍。 它通常只是画一个覆盖屏幕的三角形,然后在 Fragment Shader 里读取屏幕纹理。

也就是说:

场景物体已经画完了,后处理是在加工这张最终图。

为什么会有性能消耗?

因为全屏 Pass 会让每个屏幕像素都执行 Shader。

假设分辨率是 1920 x 1080,那一帧就有大约 207 万个像素。 一个全屏 Pass 就意味着这些像素基本都要跑一遍。

如果一个效果还要多次采样,比如 Bloom、SSAO、景深,那成本就更高。

可以粗略理解成:

后处理成本 ≈ 屏幕像素数 × 采样次数 × Pass 数量

所以后处理很吃:

  • 分辨率
  • 采样次数
  • RenderTexture 读写
  • GPU 带宽
  • Pass 数量

怎么优化?

常见优化方式:

  • 合并多个后处理 Pass。
  • 降低某些后处理的分辨率。
  • 减少模糊迭代次数。
  • 减少采样次数。
  • 移动端关闭重型效果。
  • Bloom、SSAO、景深这类效果做分档。
  • 尽量避免频繁创建临时 RenderTexture。
  • 用全屏三角形代替全屏四边形,减少一些边界和插值问题。

面试高分回答

IMPORTANT

后处理通常需要全屏 Pass,是因为它处理的是相机已经渲染好的屏幕图像,而不是单个物体。引擎会先把场景渲染到 RenderTexture,然后画一个覆盖全屏的三角形或四边形,让后处理 Shader 对每个屏幕像素执行,通过 UV 读取原始颜色、深度、法线或运动向量,再输出处理后的颜色。

它的成本主要来自全屏像素处理、纹理采样、RenderTexture 读写和多 Pass 带宽消耗。

一句话记忆:

后处理全屏 Pass = 拿整张屏幕图像当输入,让 Shader 对每个像素重新加工一次。

RenderTexture 分辨率如何影响性能?

核心一句话: RenderTexture 分辨率越高,需要处理的像素越多,显存、带宽、采样和后处理成本都会上升。

rendering-rendertexture-resolution-performance

最关键的点

分辨率成本不是线性看宽或高,而是看面积:

像素数量 = 宽度 * 高度

所以宽高各变成 2 倍,像素数会变成 4 倍。

比如:

960 * 540      = 约 52 万像素
1920 * 1080    = 约 207 万像素
3840 * 2160    = 约 829 万像素

也就是说,4K 不是 1080p 的 2 倍成本,而大约是 4 倍像素成本

影响哪些性能?

第一,影响显存。

RenderTexture 本质是一张 GPU 纹理。 分辨率越大,像素越多,占用越高。

简单估算:

显存 = 宽 * 高 * 每像素字节数

比如 RGBA32 是每像素 4 字节。 1920 * 1080 * 4 大约就是 8MB。

如果是 HDR 格式,比如 R16G16B16A16,每像素可能是 8 字节,显存就会翻倍。

第二,影响 GPU 带宽。

后处理不是只存一下 RT,它经常要反复读写。

比如 Bloom:

原图 RT -> 提取高亮 RT -> 模糊 RT -> 上采样 RT -> 合成 RT

每一步都可能读一张图、写一张图。 分辨率越高,读写的数据量越大,移动端尤其容易被带宽卡住。

第三,影响采样成本。

很多后处理会对 RenderTexture 多次采样。

比如:

  • Bloom 要多次模糊采样。
  • SSAO 要采样周围深度。
  • 景深要根据模糊半径采样周围颜色。
  • FXAA 要读取周围像素。
  • Motion Blur 要沿运动方向采样多次。

所以成本可以粗略理解成:

成本 = 宽 * 高 * 采样次数 * Pass 数量

第四,影响填充率。

全屏后处理会让每个像素都跑 Fragment Shader。 RT 分辨率越高,需要跑的片元越多。

这对移动端非常敏感。

为什么很多后处理用半分辨率?

因为宽高减半后,像素数量只剩 1/4。

比如:

1920 * 1080 -> 960 * 540

像素量从约 207 万变成约 52 万。

Bloom、模糊、景深这类效果,本来就会被模糊,所以不一定需要全分辨率。 用半分辨率 RenderTexture 往往画质损失不明显,但性能收益很大。

MSAA 会进一步放大成本

如果 RenderTexture 开了 MSAA 4x,它可能需要保存更多采样数据。

这会影响:

  • 显存
  • 带宽
  • Resolve 成本
  • 深度和颜色缓冲成本

所以移动端 RenderTexture 不要随便开高 MSAA。

Unity 项目里怎么优化?

常见做法:

  • Bloom 用半分辨率或更低分辨率。
  • SSAO 降低采样数和分辨率。
  • 景深、模糊类效果用低分辨率 RT。
  • 避免频繁创建和销毁 RenderTexture。
  • 复用临时 RenderTexture。
  • 合并多个后处理 Pass。
  • 不需要 HDR 就别用高精度格式。
  • 不需要透明度就别用 Alpha 通道。
  • 移动端开启动态分辨率。
  • UI 小预览、角色头像、镜面反射不要盲目用全屏大小 RT。

面试高分回答

TIP

RenderTexture 分辨率会直接影响像素数量,而像素数量等于宽乘高。分辨率越高,RenderTexture 的显存占用越大,GPU 读写带宽越高,全屏 Pass 需要处理的片元越多。如果后处理还包含多次采样,比如 Bloom、SSAO、景深或 Motion Blur,成本会进一步乘上采样次数和 Pass 数量。移动端通常会对 Bloom、模糊、景深等效果使用半分辨率 RT,因为宽高减半后像素量只有四分之一,性能收益明显。

一句话记忆:

RT 分辨率影响的不是一张图大小这么简单,而是像素总量、显存、带宽、采样和 Pass 成本一起变大。

深度图如何用于后处理?

深度图 Depth Texture 记录的是: 屏幕上每个像素离相机有多远。

后处理拿到这个距离后,就可以判断远近、边缘、遮挡、离焦程度,然后做各种屏幕空间效果。

rendering-depth-texture-postprocess

底层流程

一般流程是:

  1. 相机正常渲染场景。
  2. GPU 生成颜色图 Color Buffer
  3. 同时生成深度图 Depth Buffer / Depth Texture
  4. 后处理全屏 Pass 读取当前像素的颜色和深度。
  5. 根据深度判断这个像素要怎么处理。
  6. 输出最终画面。

简单理解:

后处理 = 读取颜色 + 读取深度 + 根据远近加工画面

为什么要线性化深度?

深度图里的值很多时候不是线性的。 也就是说,深度值从 01,不一定均匀对应真实距离。

近处精度高,远处精度低。

所以很多后处理会先做:

linearDepth = Linearize(depth)

把深度转换成更接近真实距离的值,再用于计算。

能做哪些后处理?

Depth of Field 景深: 比较当前像素深度和焦点距离。离焦点越远,模糊越强。

Fog 雾效: 根据像素距离相机的远近混合雾颜色。越远越接近雾色。

SSAO: 采样当前像素周围的深度,估算附近有没有几何体遮挡环境光。

边缘描边: 比较当前像素和周围像素的深度差。深度突然变化的地方,通常就是物体轮廓。

软粒子: 比较粒子深度和场景深度,避免粒子和地面、墙面相交处出现硬边。

水面交界: 用水面深度和场景深度做差,生成岸边泡沫、浅水过渡。

Contact Shadow: 基于屏幕深度沿光照方向做短距离检查,补接触阴影。

常见坑

透明物体通常不写深度。 所以很多依赖深度的后处理,对透明物体可能不准确。

比如:

  • 透明玻璃不参与深度。
  • 粒子可能深度排序不稳定。
  • 半透明水面可能导致景深错误。
  • 描边可能描不到透明物体。

还有一个问题是精度。 远处深度精度较低,可能导致闪烁、条纹、边缘不稳定。

面试高分回答

NOTE

深度图在后处理中主要用来提供屏幕像素的空间距离信息。相机渲染场景时会生成 Depth Buffer,后处理全屏 Pass 可以根据 UV 采样深度图,必要时把非线性深度转换成线性深度,再用于判断像素离相机的距离、与邻近像素的深度差或空间遮挡关系。景深、雾效、SSAO、描边、软粒子、水面交界和 Contact Shadow 都会用到深度图。

一句话记忆:

深度图让后处理知道“这个像素在空间里有多远”,所以才能做雾、景深、遮挡、描边和软交界。

移动端后处理如何取舍?

移动端后处理取舍的核心是:

帧率稳定优先,画面风格其次;能少 Pass 就少 Pass,能半分辨率就半分辨率。

rendering-mobile-postprocess-tradeoffs

为什么移动端要谨慎?

后处理通常是全屏 Pass。 也就是说,它不是处理一个物体,而是处理整张屏幕。

成本大概可以理解成:

成本 = 分辨率 * Pass 数量 * 采样次数 * 带宽压力

移动端 GPU 很容易被这些东西卡住:

  • 全屏像素处理
  • RenderTexture 读写
  • 多次纹理采样
  • 高分辨率后处理
  • 多个后处理叠加
  • 发热后降频

优先保留什么?

优先保留成本低、画面收益高的效果。

比如:

  • Color Grading
  • 简单 LUT
  • 曝光调整
  • 轻量色彩修正

这些通常是一次颜色映射,成本相对低,但能明显统一画面风格。

Bloom 怎么取舍?

Bloom 画面收益很高,但不能乱开。

推荐:

  • 用半分辨率或更低分辨率。
  • 减少模糊迭代次数。
  • 限制 Bloom 强度。
  • 只让真正高亮的物体产生 Bloom。
  • 避免整屏发白。
  • 低端机降低质量或关闭。

Bloom 很适合保留,但要降级做。

SSAO 怎么取舍?

SSAO 会增强体积感,但它要采样深度图,成本不低。

移动端建议:

  • 低端机关闭。
  • 中端机低分辨率、低采样。
  • 高端机再开较高质量。
  • 不要半径太大。
  • 不要强度太黑。
  • 室外大场景谨慎开,室内小场景收益更明显。

景深和运动模糊怎么取舍?

Depth of FieldMotion Blur 都要谨慎。

因为它们不仅有性能成本,还会影响清晰度。

适合用在:

  • 剧情镜头
  • 拍照模式
  • 菜单背景
  • 角色特写
  • 冲刺瞬间
  • 技能爆发瞬间

不太适合长期开很重,尤其是动作游戏、射击游戏、MOBA 这类需要清晰操作反馈的游戏。

抗锯齿怎么取舍?

移动端常见选择:

  • FXAA:便宜,但会糊。
  • MSAA:几何边缘好,但显存和带宽更高。
  • TAA:稳定性好,但可能拖影、变糊,还需要 Motion Vector。

如果是 Forward 管线,2x/4x MSAA 常见。 如果低端机压力大,可以用 FXAA 或直接关闭抗锯齿。

项目里推荐分档

低端机:

  • 关闭 SSAO。
  • 关闭景深。
  • 关闭运动模糊。
  • Bloom 低质量或关闭。
  • FXAA 或无抗锯齿。
  • 低分辨率 RenderTexture。

中端机:

  • 开 Color Grading。
  • Bloom 半分辨率。
  • FXAA 或 2x MSAA。
  • SSAO 低采样可选。
  • 特殊镜头开景深。

高端机:

  • Bloom 更高质量。
  • SSAO 可开启。
  • 更好的抗锯齿。
  • 特写镜头开景深。
  • 特定场景开 Motion Blur。

面试高分回答

TIP

移动端后处理要根据画面收益和性能成本做取舍。Color Grading、LUT 这类效果成本低、收益高,可以优先保留;Bloom 画面收益明显,但要用半分辨率、减少迭代和控制强度;SSAO、景深、Motion Blur 这类需要多次采样或影响清晰度的效果要谨慎,通常按机型分档或只在剧情、菜单、特写场景中使用。整体优化思路是减少全屏 Pass,降低 RenderTexture 分辨率,合并后处理,减少采样次数,并保证帧率和发热稳定。

一句话记忆:

移动端后处理不是能开就开,而是低成本常驻,高成本分档,强表现只在关键镜头用。

文章评价

读完这篇,留下你的看法

暂无审核通过的评价。

登录账号后才能评价。

本站访客数0总站访问量0本页访问量0