首页 > 代码库 > Motion Blur

Motion Blur

Motion Blur

  此篇介绍最简单的全局Motion Blur。算法是将当前帧与前一帧按某一比例混合。这是一个过程,例如有10帧,在第1帧中,只有第1帧原图,第2帧中有1、2帧原图,第3帧中会有1、2、3帧原图,依次类推。

  技术分享

  假设混合比较为a,即原图为1-a,累积图为a,那么1帧新进入的图,在下一帧中,所占的比例就只有a,再下一帧就只有a^2,再下一帧就只有a^3,依次类推,第N帧后,比例会接近于0。a越小,消失的会越快,也就意味着MotionBlur效果越弱。相反,a越大,MotionBlur效果越强。通过将此混合参数叫做BlurAmount。为了防止完全抛弃新进帧的情况,通常会限制BlurAmount不大于0.92。

  技术分享

  最后,MotionBlur的Shader需要特殊处理一下。首先需要将原始帧与累积帧混合在一起。但普通的混合会连带alpha一起混合,而我们想做做的只是混合RGB,希望alpha保留。所以需要2个Pass,第一个Pass根据BlurAmount混合RGB,第二个Pass直接写入新的alpha。完整Shader如下:

技术分享
  1 Shader "Hidden/MotionBlur" {  2 Properties {  3     _MainTex ("Base (RGB)", 2D) = "white" {}  4     _AccumOrig("AccumOrig", Float) = 0.65  5 }  6   7     SubShader {   8         ZTest Always Cull Off ZWrite Off  9         Fog { Mode off } 10         Pass { 11             Blend SrcAlpha OneMinusSrcAlpha 12             ColorMask RGB 13             BindChannels {  14                 Bind "vertex", vertex  15                 Bind "texcoord", texcoord 16             }  17          18             CGPROGRAM 19             #pragma vertex vert 20             #pragma fragment frag 21             #pragma fragmentoption ARB_precision_hint_fastest 22      23             #include "UnityCG.cginc" 24      25             struct appdata_t { 26                 float4 vertex : POSITION; 27                 float2 texcoord : TEXCOORD; 28             }; 29      30             struct v2f { 31                 float4 vertex : POSITION; 32                 float2 texcoord : TEXCOORD; 33             }; 34              35             float4 _MainTex_ST; 36             float _AccumOrig; 37              38             v2f vert (appdata_t v) 39             { 40                 v2f o; 41                 o.vertex = mul(UNITY_MATRIX_MVP, v.vertex); 42                 o.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex); 43                 return o; 44             } 45      46             sampler2D _MainTex; 47              48             half4 frag (v2f i) : COLOR 49             { 50                 return half4(tex2D(_MainTex, i.texcoord).rgb, _AccumOrig ); 51             } 52             ENDCG  53         }  54  55         Pass { 56             Blend One Zero 57             ColorMask A 58              59             BindChannels {  60                 Bind "vertex", vertex  61                 Bind "texcoord", texcoord 62             }  63          64             CGPROGRAM 65             #pragma vertex vert 66             #pragma fragment frag 67             #pragma fragmentoption ARB_precision_hint_fastest 68      69             #include "UnityCG.cginc" 70      71             struct appdata_t { 72                 float4 vertex : POSITION; 73                 float2 texcoord : TEXCOORD; 74             }; 75      76             struct v2f { 77                 float4 vertex : POSITION; 78                 float2 texcoord : TEXCOORD; 79             }; 80              81             float4 _MainTex_ST; 82              83             v2f vert (appdata_t v) 84             { 85                 v2f o; 86                 o.vertex = mul(UNITY_MATRIX_MVP, v.vertex); 87                 o.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex); 88                 return o; 89             } 90      91             sampler2D _MainTex; 92              93             half4 frag (v2f i) : COLOR 94             { 95                 return tex2D(_MainTex, i.texcoord); 96             } 97             ENDCG  98         } 99         100     }101 102 SubShader {103     ZTest Always Cull Off ZWrite Off104     Fog { Mode off }105     Pass {106         Blend SrcAlpha OneMinusSrcAlpha107         ColorMask RGB108         SetTexture [_MainTex] {109             ConstantColor (0,0,0,[_AccumOrig])110             Combine texture, constant111         }112     }113     Pass {114         Blend One Zero115         ColorMask A116         SetTexture [_MainTex] {117             Combine texture118         }119     }120 }121 122 Fallback off123 124 }
View Code

 

  

  

Motion Blur