zoukankan      html  css  js  c++  java
  • (转)径向模糊效果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里的效果:

  • 相关阅读:
    关于两次指针(struct型)传参数的问题
    git学习基础教程
    程序员恶性循环- 有感
    基于Tomcat 的WEB Project存在的安全漏洞总结
    使用Maven自动部署Java Web项目到Tomcat问题小记
    MyEclipse中Maven的配置
    mybatis处理集合、循环、数组和in查询等语句的使用
    JBOSS的启动和停止
    myeclipse越来越卡了怎么回事啊?
    linux shell 模拟post请求
  • 原文地址:https://www.cnblogs.com/wonderKK/p/4378483.html
Copyright © 2011-2022 走看看