后处理之径向模糊
游戏中为了突出画面震撼或者突出移动速度快时,可以用径向模糊来提升表现的效果。例图如下:
径向模糊的原理是取一个中心点,然后沿着中心点----像素点的方向选取几个点采样,然后该像素点输出这几个采样点的平均值。因此约靠近中心越清晰,越远则越模糊。画图工具里瞎比划一下。。。
代码里进行了一些优化,思路是将图像渲染到了低分辨率的RenderTexture上,然后再进行模糊处理,最后将模糊后的RenderTexture和原始图像进行插值。
public class TestEffect : PostEffectsBase { public Shader testShader; private Material testMaterial; public Material material { get { testMaterial = CheckShaderAndCreateMaterial(testShader, testMaterial); return testMaterial; } } [Range(0.0f, 0.05f)] public float blurFactor = 0.01f; public Vector2 blurCenter = new Vector2(0.5f, 0.5f); public int downSampleFactor = 2;//降低分辨率 [Range(0f, 2f)] public float lerpFactor = 1; void OnRenderImage(RenderTexture src, RenderTexture dest) { if (material != null) { //用于中间存放降低分辨率的RT RenderTexture rtS = RenderTexture.GetTemporary(src.width >> downSampleFactor, src.width >> downSampleFactor); RenderTexture rtD = RenderTexture.GetTemporary(src.width >> downSampleFactor, src.width >> downSampleFactor); Graphics.Blit(src, rtS); material.SetFloat("_BlurFactor", blurFactor); material.SetVector("_BlurCenter", blurCenter); material.SetTexture("_BlurTex", rtD); material.SetFloat("_LerpFactor", lerpFactor); Graphics.Blit(rtS, rtD, material,0); Graphics.Blit(src, dest,material, 1); RenderTexture.ReleaseTemporary(rtS); RenderTexture.ReleaseTemporary(rtD); } else { Graphics.Blit(src, dest); } } }
Shader "TestEffectShader" { Properties { _MainTex ("Base (RGB)", 2D) = "white" {} _BlurFactor ("BlurFactor", Float) = 0.01 _BlurCenter("BlurCenter",Color)=(0.5,0.5,0,0) _BlurTex("BlurTexture",2D)= "white" {} _LerpFactor("LerpFactor",Float)=1 } SubShader { Pass { ZTest Always Cull Off ZWrite Off CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" sampler2D _MainTex; fixed _BlurFactor; fixed2 _BlurCenter; struct v2f { float4 pos : SV_POSITION; fixed2 uv: TEXCOORD0; }; v2f vert(appdata_img v) { v2f o; o.pos = UnityObjectToClipPos(v.vertex); o.uv = v.texcoord.xy; return o; } fixed4 frag(v2f i) : SV_Target { fixed2 dir=i.uv -_BlurCenter.xy; fixed4 c=0; for(int j=0;j<5;j++){ c+=tex2D(_MainTex, i.uv +dir*j*_BlurFactor); } c/=5; return c; } ENDCG } Pass { ZTest Always Cull Off ZWrite Off CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" sampler2D _MainTex; sampler2D _BlurTex; fixed _LerpFactor; fixed2 _BlurCenter; struct v2f { float4 pos : SV_POSITION; fixed2 uv1: TEXCOORD0; fixed2 uv2: TEXCOORD1; }; v2f vert(appdata_img v) { v2f o; o.pos = UnityObjectToClipPos(v.vertex); o.uv1 = v.texcoord.xy; o.uv2 = v.texcoord.xy; return o; } fixed4 frag(v2f i) : SV_Target { fixed2 dir=i.uv2 -_BlurCenter.xy; fixed dis=length(dir); fixed4 normalColor=tex2D(_MainTex,i.uv1); fixed4 blurColor=tex2D(_BlurTex,i.uv2); return lerp(normalColor,blurColor,_LerpFactor*dis); } ENDCG } } Fallback Off }