转自http://blog.csdn.NET/candycat1992/article/details/39255575
1.新建一个场景
2.将以下脚本添加到摄像机上
[csharp] view plain copy
using UnityEngine;
using System.Collections;
[ExecuteInEditMode]
public class TestRenderImage : MonoBehaviour {
#region Variables
public Shader curShader;
public float grayScaleAmount = 1.0f;
private Material curMaterial;
#endregion
#region Properties
public Material material
{
get
{
if (curMaterial == null)
{
curMaterial = new Material(curShader);
curMaterial.hideFlags = HideFlags.HideAndDontSave;
}
return curMaterial;
}
}
#endregion
// Use this for initialization
void Start()
{
if (SystemInfo.supportsImageEffects == false)
{
enabled = false;
return;
}
if (curShader != null && curShader.isSupported == false)
{
enabled = false;
}
}
void OnRenderImage(RenderTexture sourceTexture, RenderTexture destTexture)
{
if (curShader != null)
{
material.SetFloat("_LuminosityAmount", grayScaleAmount);
Graphics.Blit(sourceTexture, destTexture, material);
}
else
{
Graphics.Blit(sourceTexture, destTexture);
}
}
// Update is called once per frame
void Update()
{
grayScaleAmount = Mathf.Clamp(grayScaleAmount, 0.0f, 1.0f);
}
void OnDisable()
{
if (curMaterial != null)
{
DestroyImmediate(curMaterial);
}
}
}
3.新建一个shader,修改为以下代码,然后赋值给上面的脚本
[csharp] view plain copy
Shader "Custom/ImageEffect" {
Properties {
_MainTex ("Base (RGB)", 2D) = "white" {}
_LuminosityAmount ("GrayScale Amount", Range(0.0, 1.0)) = 1.0
}
SubShader {
Pass {
CGPROGRAM
#pragma vertex vert_img
#pragma fragment frag
#include "UnityCG.cginc"
uniform sampler2D _MainTex;
fixed _LuminosityAmount;
fixed4 frag(v2f_img i) : COLOR
{
//Get the colors from the RenderTexture and the uv's
//from the v2f_img struct
fixed4 renderTex = tex2D(_MainTex, i.uv);
//Apply the Luminosity values to our render texture
float luminosity = 0.299 * renderTex.r + 0.587 * renderTex.g + 0.114 * renderTex.b;
fixed4 finalColor = lerp(renderTex, luminosity, _LuminosityAmount);
return finalColor;
}
ENDCG
}
}
FallBack "Diffuse"
}
4.效果图
分析:这里的特效是针对整个画面的,通过修改shader可以整体地改变画面的效果。
解释:一旦通过上述的各种检查,我们就需要调用内置的OnRenderImage函数来实现画面特效。这个函数负责从Unity渲染器中抓取当前的render texture,然后使用Graphics.Blit()函数再传递给Shader(通过sourceTexture参数),然后再返回一个处理后的图像再次传递回给Unity渲染器(通过destTexture参数)。这两个行数互相搭配是处理画面特效的很常见的方法。你可以在下面的连接中找到这两个函数更详细的信息:OnRenderImage:该摄像机上的任何脚本都可以收到这个回调(意味着你必须把它附到一个Camera上)。允许你修改最后的Render Texture。Graphics.Blit:sourceTexture会成为material的_MainTex。
画面特效是顺序处理的,这就像Photoshop中的layers。如果你有多个屏幕特效,你可以按顺序添加给该Camera,那么它们就会按照这个顺序被处理。
上述的过程是被简化过的,但通过这些我们可以看出画面特效的核心是如何工作的。最后,我们总结上述使用Render Texture实现画面特效的核心过程:
在脚本中检查当前平台对特效的支持;
通过OnRenderImage()函数抓取render texture,再通过Graphics.Blit()函数传递给虚拟材质中的Shader进行后处理;
Shader的_MainTex即为接收到的render texture,在frag函数里对图像进行逐像素处理后再返回给OnRenderImage函数,得到最后的屏幕画面。