Unity屏幕后处理学习笔记

项目链接

后处理简介

  感觉写得挺差的,还是建议直接看《Unity Shader入门精要》吧。

  屏幕后处理,是指渲染出图像后,对整个图像进行二次处理得到更好的结果,场景的后处理如调节亮度、对比度、模糊、bloom等等。
  我们也可以在渲染一部分后中止,进行后处理操作,再渲染剩下的部分。例如我们要做一个后处理描边效果,但不想对透明物体进行描边,就可以先渲染不透明物体,直接进行描边,再去渲染透明物体。
  Unity提供了一个接口OnRenderImage(RenderTexture src,RenderTexture dest) 来方便我们制作各种效果。他的使用框架大概是这样的。

using UnityEngine;
using System.Collections;

//PostEffectsBase是我们自己写的一个基类,含有一些检测平台是否支持后处理的辅助函数
public class MyPostEffectsBase : PostEffectsBase {
	public Shader shader;
	private Material myMaterial;
	public Material material {  
		get {
			//如果material和shader对应则返回,否则创建一个新的
			myMaterial = CheckShaderAndCreateMaterial(shader, myMaterial);	
			return myMaterial;
		}  
	}
//一些参数

	void OnRenderImage(RenderTexture src, RenderTexture dest) {
		if (material != null) {
			//....传参
			//调用后处理的material
			Graphics.Blit(src, dest, material);
		} else {
			Graphics.Blit(src, dest);
		}
	}
}

  我们需要把这个脚本挂在摄像机上,这样就会自动调用我们的后处理shader了,可以看一个例子。

项目链接
  在Scene0中我们实现了一个可调节亮度、饱和度、对比度的后处理效果,这个效果还算比较好理解的,实在不懂就看看Unity Shader入门精要吧。

边缘检测

卷积

  先从卷积开始, 卷积操作就是用卷积核 kernel来对每个像素进行处理,一个常见的卷积核,均值卷积如下。通常是一个方形区域,每一个格子对应一个权值。以这个卷积核为例,计算时,我们要把像素放在中心,对周围其他像素与对应的卷积权值的乘积求和,得到的就是最终像素值。
                         均值模糊卷积核

  例如我们用上面的均值卷积对下面例子中值为的0的像素进行运算。
在这里插入图片描述
  结果为 5* 1 + 4* 1 + 3* 1 + 2* 1 + 0* 1 + 1* 1 + 5* 1 + 4* 1 + 3* 1 = 27
  最后我们还要用27除以所有权值的和来做归一化,即27/ (1+1+1 +1+1+1 +1+1+1) = 3,至此我们运用均值卷积把0平均到了3,这就是均值模糊的思想。

  理解了这个例子边缘检测就好理解多了,简单的算子如下。
在这里插入图片描述
  我们对下面例子中间四个进行处理,结果如下。
在这里插入图片描述  运算后结果在这里插入图片描述

  可以看出,第二列的两个数因为处于色块中间,结果为0。而第三列的两个则变成了较大的数值,我们可以定义,经卷积处理后大于10的点为边缘,把他的颜色设立为_OutlineColor 黑色,小于10的则不做处理,这样我们就得到了黑色的描边,当然最好的还是用Lerp函数。
  上面提到的只是简易的版本,实际上还要再进行横向算子运算。在这里插入图片描述,得到两个方向的结果后进行以下操作在这里插入图片描述,当然考虑到开根号的运算量过大,有时也会用这种方法来简化代替在这里插入图片描述
  该部分实际案例见Scene1

高斯模糊

  我们前面提到了均值模糊,高斯模糊是在这个的基础上进一步优化,做到越靠近中心点,影响越大,类似的例子如下。在这里插入图片描述
  我们这次将使用55的卷积核,如下。但我们对一个像素的周围进行这个卷积时,每个像素要进行55的采样,其中就有很多重复的运算,我们可以把这个55的卷积核拆分成一个15和51的卷积核,这样每个像素只用采样25次,得到了优化。(这部分的拆分我并没有查找到推导的资料,如果有找到的欢迎和我联系)。
在这里插入图片描述
  使用上面这种拆分,我们要使用双pass,第一个pass先对原图像进行一个方向进行卷积得到buffer1,第二个pass再对buffer1进行另一个方向进行卷积得到buffer2,最后把buffer2映射到结果。

  代码见Scene2,推荐阅读顺序,先看shader代码,再看cs代码。

Bloom效果

  Bloom的原理很简单,规定一个阈值LuminanceThreshold,提取出大于这个阈值的额外存储再一个纹理上,用高斯模糊让这部分高亮更加均匀,再和原纹理叠加就可以了。

  见Scene3

猜你喜欢

转载自blog.csdn.net/STGSRHU/article/details/127957828