读书笔记11《Unity Shader入门精要》

铁名_IronName Lv4

第 12 章 屏幕后处理效果

屏幕后处理效果(screen post-processing effects)是游戏中实现屏幕特效的常见方法。屏幕后处理指的是在渲染完整个常见得到屏幕图像后,再对这个图像进行一系列的操作,可以为游戏画面添加更多的艺术效果,例如景深(Depth of Field),运动模糊(Motion Blur)等。

基础脚本

1
MonoBehaviour.OnRenderImage (RenderTexture src, RenderTexture dest)

这个函数接口会把当前渲染得到的图像存储在第一个参数对应的源渲染纹理中,通过函数中的一系列操作后,再把目标渲染纹理,即第二个参数对应的渲染纹理显示到屏幕上。

1
2
3
public static void Blit(Texture src, RenderTexture dest);
public static void Blit(Texture src, RenderTexture dest, Material mat, int pass = -1);
public static void Blit(Texture src, Material mat, int pass = -1);

在 OnRenderImage 函数中,利用 Graphics.Blit 函数完成对渲染纹理的处理。

  • 在进行屏幕后处理之前,我们需要检查:当前平台是否支持渲染纹理和屏幕特效,是否支持当前使用的Unity Shader等。
  • 'SystemInfo.supportsImageEffects' is obsolete: 'supportsImageEffects always returns true, no need to call it'

调整亮度、饱和度和对比度

实践

在 Unity 中实现调整亮度、饱和度和对比度的屏幕后处理效果。

  • ZTest Always Cull Off ZWrite Off屏幕后处理 Shader 标配,防止挡住其他物体。

边缘检测

卷积(convolution)

使用一个卷积核(kernel)对一张图像的每个像素进行一系列操作。

边缘检测算子 / 卷积核

Roberts 左边 2×22\times2 是 x 方向的梯度,右边 2×22\times2 是 y 方向的梯度。

-100-1
0110

Prewitt 左边 3×33\times3 是 x 方向的梯度,右边 3×33\times3 是 y 方向的梯度。

-1-1-1-101
000-101
111-101

Sobel 左边 3×33\times3 是 x 方向的梯度,右边 3×33\times3 是 y 方向的梯度。

-1-2-1-101
000-202
121-101

得到两个方向上的梯度值 GxG_xGyG_y 后,计算整体梯度:

G=Gx2+Gy2G=\sqrt{G_x^2+G_y^2}

由于开根号消耗性能,可以用另一种方法计算:

G=Gx+GyG=|G_x|+|G_y|
实践

使用 Sobel 算子进行边缘检测,实现描边效果。

  • _MainTex_TexelSize_MainTex纹理对应的每个纹素的大小。

高斯模糊

G(x,y)=12πσ2ex2+y22σ2G(x,y)=\frac{1}{2\pi\sigma^2}e^{-\frac{x^2+y^2}{2\sigma^2}}

上面的是高斯方程,可以用于计算高斯核中每个位置的值。σ\sigma 是标准方差(一般取值为 1),x 和 y 分别对应了当前位置到卷积核中心的整数距离。
一个的二维高斯函数可以拆分成两个一维函数。在代码里就是用 2 个 Pass 来处理。

实践

在 Unity 中实现高斯滤波的模糊效果。

  • 为 Pass 定义名字,可以在其他 Shader 中直接通过它们的名字来使用它们。

水平方向模糊的顶点着色器写出了个低级错误,看来状态确实不行了。

Bloom 效果

模拟真实摄像机的一种图像效果,让画面中较亮的区域“扩散”到周围的区域中。

实践

在 Unity 中实现 Bloom 效果。

  • UsePass 使用路径错误时不会报错,但是会导致 shader.isSupported 为 false。然后 PostEffectBase 的 CheckShaderAndCreateMaterial 就会返回 null。

你猜我怎么知道的😅

运动模糊

两种方法:
一、累计缓存(accumulation buffer):当物体快速移动产生多张图像后,我们取它们的平均值最为最后的运动模糊图像。对性能消耗大。
二、速度缓存(velocity buffer):在缓存中存储各个像素当前的运动速度,然后利用该值来决定模糊的方向。

实践

在 Unity 中用类似累计缓存的方法实现运动模糊的效果。

  • Graphics.Blit 的默认行为:当不指定Pass索引时,它会按顺序调用Shader中的Pass。
  • 标题: 读书笔记11《Unity Shader入门精要》
  • 作者: 铁名_IronName
  • 创建于 : 2026-01-26 12:38:28
  • 更新于 : 2026-02-15 15:21:00
  • 链接: https://blog.ironname.top/2026/01/26/读书笔记11《Unity-Shader入门精要》/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
评论