一、建立一个基本的屏幕后处理脚本系统
屏幕后处理,通常指的是在渲染完整个场景得到屏幕图像后,再对这个图像进行一系列的操作,实现各种屏幕特效。可以为游戏画面添加更多的艺术效果,例如景深、运动模糊等。
因此想要实现屏幕后处理的基础在于得到渲染后的屏幕图像,即抓取屏幕,而unity为我们提供了这样一个方便的接口——OnRenderImage函数。它的函数声明如下:
MonoBehaviour.OnRenderImage(RenderTexture src,RenderTexture dest)
当我们在脚本中声明此函数后,会把当前渲染得到的图像存储在第一个参数对应的源渲染纹理中,通过函数中的一系列操作后,再把目标渲染纹理,即第二个参数对应的渲染纹理显示到屏幕上。在OnRenderImage函数中,我们通常是利用Graphics.Blit函数来完成对渲染纹理的处理。它有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);
其中,参数src对应了源纹理,在屏幕后处理技术中,这个参数通常就是当前屏幕的渲染纹理或上一步处理后得到的渲染纹理。参数dest是目标渲染纹理,如果它的值为null就会直接将结果显示在屏幕上。参数mat是我们使用的材质,这个材质使用的unity Shader将会进行各种屏幕后处理操作,而src纹理将会被传递给Shader中名为_MainTex的纹理属性。参数pass的默认值为-1,表示将会依次调用shader内的所有pass,否则只会调用给定索引的pass。
在默认情况下,OnRenderImage函数会在所有的不透明和透明的pass执行完毕后被调用,以便对场景中所有游戏对象都产生影响。但有时希望在不透明的pass执行完毕后立即调用OnRenderImage函数,从而不对透明物体产生任何影响。此时我们可以在OnRenderImage函数前添加ImageEffectOpaque属性来实现这样的目的。
总的来说,要在unity中实现屏幕后处理效果,过程通常如下:首先需要在摄像机中添加一个用于屏幕后处理的脚本,在这个脚本中,我们会实现OnRenderImage函数来获取当前屏幕的渲染纹理。然后再调用Graphics.Blit函数使用特定的Unity Shader来对当前图像进行处理,再把返回的渲染纹理显示到屏幕上。对于一些复杂的屏幕特效,我们可能需要多次调用Graphics.Blit函数来对上一步的输出结果进行下一步处理。
但是在进行屏幕后处理之前,我们需要检查一系列条件是否满足,例如当前平台是否支持渲染纹理和屏幕特效