【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 Off 104 Fog { Mode off } 105 Pass { 106 Blend SrcAlpha OneMinusSrcAlpha 107 ColorMask RGB 108 SetTexture [_MainTex] { 109 ConstantColor (0,0,0,[_AccumOrig]) 110 Combine texture, constant 111 } 112 } 113 Pass { 114 Blend One Zero 115 ColorMask A 116 SetTexture [_MainTex] { 117 Combine texture 118 } 119 } 120 } 121 122 Fallback off 123 124 }
时间: 2024-10-13 23:52:54