后期效果对于unity来说还是挺耗性能的,因为是对整屏幕逐像素计算,c#代码:
using UnityEngine;
public class _MotionBlur_1 : MonoBehaviour
{
public float blurAmount = 0.8f;
public Shader shader;
private Material mat;
public RenderTexture accumTexture;
void Start()
{
mat = new Material(shader); //创建一个材质
mat.hideFlags = HideFlags.HideAndDontSave;
}
void OnRenderImage (RenderTexture src, RenderTexture dst)
{
if (accumTexture == null)
{
accumTexture = new RenderTexture(src.width, src.height, 0);
accumTexture.hideFlags = HideFlags.HideAndDontSave;
Graphics.Blit( src, accumTexture ); //将最初的屏幕画面复制到accumTexture里面
}
blurAmount = Mathf.Clamp( blurAmount, 0.0f, 1f );
mat.SetTexture("_AccumTex", accumTexture); //指定着色器中参数_AccumTex为accumTexture
mat.SetFloat("_AccumAmt", blurAmount); //设置着色器中参数_AccumAmt为blurAmount
Graphics.Blit (src, accumTexture, mat); //将屏幕当前画面与accumTexture合并
Graphics.Blit(accumTexture, dst); //将合并后的最终画面输出到dst
}
}
接下来着色器会对mat.SetTexture("_AccumTex", accumTexture); //指定着色器中参数_AccumTex为accumTexture
mat.SetFloat("_AccumAmt", blurAmount); //设置着色器中参数_AccumAmt为blurAmount
</pre><pre name="code" class="csharp">这两个参数进行计算,主要是造成了残影效果,我们看看shader具体实现:
</pre><pre name="code" class="cpp">Shader "Tut/Effects/MotionBlur_1" {
Properties {
_MainTex ("Base (RGB)", 2D) = "white" {}
_AccumTex("Accum Tex",2D)=""{} //c#中传进来的纹理
_AccumAmt("AccumOrig", Float) = 0.65 //c#中传进来的纹理
}
SubShader {
ZTest Always Cull Off ZWrite Off
Fog { Mode off }
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct v2f {
float4 vertex : POSITION;
float2 uv : TEXCOORD;
};
v2f vert (appdata_base v)
{
v2f o;
o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
o.uv =v.texcoord;
return o;
}
sampler2D _MainTex;
sampler2D _AccumTex;
float _AccumAmt;
half4 frag (v2f i) : COLOR
{
half4 acc=tex2D(_AccumTex,i.uv);
half4 current=tex2D(_MainTex, i.uv); //屏幕当前纹理
acc=acc*_AccumAmt+current*(1-_AccumAmt); //将屏幕当前纹理与保存的纹理按照_AccumAmt与(1-_AccumAmt)的比例合并
return acc;
}
ENDCG
}
}
Fallback off
}
acc=acc*_AccumAmt+current*(1-_AccumAmt);这句是关键代码,acc乘上一个小于1的系数,则造成了指数递减的残影