(转)径向模糊效果shader

转自:http://blog.csdn.net/xoyojank/article/details/5146297

最先在这里看到:http://www.gamerendering.com/2008/12/20/radial-blur-filter/

这效果在鬼泣4中切换场景时见过, 极品飞车12的运动模糊也有这种感觉.

原理:

    确定一个中心点(如0.5, 0.5), 跟当前像素连一条线. 以当前像素为中心, 在线上的附近像素进行采样, 最后取一下平均值.

代码翻译成HLSL:

// This texture should hold the image to blur.
sampler2D Texture0;

// some const, tweak for best look
const float fSampleDist;
const float fSampleStrength; 


// some sample positions
float samples[10] = 
{
   -0.08,
   -0.05,
   -0.03,
   -0.02,
   -0.01,
   0.01,
   0.02,
   0.03,
   0.05,
   0.08
};


float4 ps_main( float2 texCoord  : TEXCOORD0 ) : COLOR
{
   // 0.5,0.5 is the center of the screen
   // so substracting uv from it will result in
   // a vector pointing to the middle of the screen
   float2 dir = 0.5 - texCoord;
   // calculate the distance to the center of the screen
   float dist = length(dir);
   // normalize the direction (reuse the distance)
   dir /= dist;
   
   // this is the original colour of this pixel
   // using only this would result in a nonblurred version
   float4 color = tex2D(Texture0, texCoord);
   
   float4 sum = color;
   // take 10 additional blur samples in the direction towards
   // the center of the screen
   for (int i = 0; i < 10; ++i)
   {
      sum += tex2D(Texture0, texCoord + dir * samples[i] * fSampleDist);
   }

   // we have taken eleven samples
   sum /= 11.0;
   
   // weighten the blur effect with the distance to the
   // center of the screen ( further out is blurred more)
   float t = saturate(dist * fSampleStrength);
   
   //Blend the original color with the averaged pixels
   return lerp(color, sum, t);
}

 

 Unity shaderLab:

//径向模糊后处理
Shader "RadialBlur" {
         Properties {
                 _MainTex ("Base (RGB)", 2D) = "white" {}
                 _fSampleDist("SampleDist", Float) = 1 //采样距离
                 _fSampleStrength("SampleStrength", Float) = 2.2 //采样力度
         }
         SubShader {
                 Pass {               
                         ZTest Always Cull Off ZWrite Off
                         Fog { Mode off }  
                         CGPROGRAM
                         #pragma vertex vert
                         #pragma fragment frag
         
                         #include "UnityCG.cginc"
         
                         struct appdata_t {
                                 float4 vertex : POSITION;
                                 float2 texcoord : TEXCOORD;
                         };
         
                         struct v2f {
                                 float4 vertex : POSITION;
                                 float2 texcoord : TEXCOORD;
                         };
                         
                         float4 _MainTex_ST;
                         
                         v2f vert (appdata_t v)
                         {
                                 v2f o;
                                 o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
                                 o.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex);
                                 return o;
                         }
         
                         sampler2D _MainTex;
                         float _fSampleDist;
                         float _fSampleStrength;

                         // some sample positions  
                         static const float samples[6] =   
                         {   
                            -0.05,  
                            -0.03,    
                            -0.01,  
                            0.01,    
                            0.03,  
                            0.05,  
                         }; 
                         
                         half4 frag (v2f i) : SV_Target
                         {
                                
                            //0.5,0.5屏幕中心
                            float2 dir = float2(0.5, 0.5) - i.texcoord;//从采样中心到uv的方向向量
                            float2 texcoord = i.texcoord;
                               float dist = length(dir);  
                            dir = normalize(dir); 
                            float4 color = tex2D(_MainTex, texcoord);  

                            float4 sum = color;
                               //    6次采样
                            for (int i = 0; i < 6; ++i)  
                            {  
                                                            
                                   sum += tex2D(_MainTex, texcoord + dir * samples[i] * _fSampleDist);    
                            }  

                            //求均值
                            sum /= 7.0f;  

                           
                            //越离采样中心近的地方,越不模糊
                            float t = saturate(dist * _fSampleStrength);  

                            //插值
                            return lerp(color, sum, t);
                            
                         }
                         ENDCG 
                 }
         } 
         Fallback off
 }

 

 

两个参数, 动态调整的话可以产生极品飞车12那种速度感(也算是第一人称运动模糊的简单实现吧).

这是RM里的效果:

posted @ 2015-03-30 16:44  ☆A希亿  阅读(7994)  评论(0编辑  收藏  举报