後期效果對於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的係數,則造成了指數遞減的殘影