Shader特效——“Median Filter效果”的实现 【GLSL】

发表于2018-02-07
评论0 6k浏览
效果图:

GLSL代码与算法注释:
#define SORT_SIZE  8  
float sort[SORT_SIZE];  
float medians[SORT_SIZE];  
// [0., 1.] -> [0, 255]  
float quant(float x)  
{  
   x = clamp(x, 0., 1.);  
   return floor(x * 255.);  
}  
float pack(vec3 c)  
{  
   float lum = (c.x + c.y + c.z) * (1. / 3.);  
   return lum;  
}  
vec3 unpack(float x)  
{  
   return vec3(x);  
}  
#define SWAP(a,b) { float t = sort[a]; sort[a] = sort[b]; sort[b] = t; }  
void bubble_sort(int num)// 简单的冒泡排序  
{  
        // 把最小值移到最左边  
        for(int j = 0; j < num; ++j)  
        {  
               for(int i= num-1; i >j; --i)  
               {  
                   if(sort[i] < sort[i-1])  
                   {  
                        SWAP(i, i-1);  
                   }  
               }  
        }  
}  
uniform sampler2D iChannel0;  
const vec2 iResolution = vec2(512., 512.);  
void main()  
{  
   vec2 ooRes = vec2(1.) / iResolution.xy;  
   //SORT_SIZE个列  
   for (int j=0; j<SORT_SIZE; j++)  
   {  
      //SORT_SIZE个行  
      for (int i=0; i<SORT_SIZE; i++)  
      {  
         vec2 uv = (gl_FragCoord.xy + vec2(i,j)-vec2(SORT_SIZE/2)) * ooRes;  
         float c = pack( texture2D(iChannel0,uv).rgb );  
         sort[i] = c;  
      }  
      // 针对某列进行纵向排序  
      bubble_sort( SORT_SIZE);  
      //保存该列的中值  
      float m = sort[(SORT_SIZE/2)];  
      medians[j] = m;  
   }  
   for (int i=0; i<SORT_SIZE; i++)  
   {  
      sort[i] = medians[i];  
   }  
   //对上一步 SORT_SIZE个列中值 进行横向排序  
   bubble_sort( SORT_SIZE);  
   // 提取中值  
   gl_FragColor = vec4(unpack(sort[SORT_SIZE/2]),1.0);  
}  

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引