Shader特效——“Sephia等效果”的实现 【GLSL】

发表于2018-02-07
评论0 2.6k浏览
本篇文章给大家介绍下如果使用GLSL代码实现一个Sephia等效果的shader效果。

效果图1

GLSL 代码:
const float PI = 3.14159265;  
uniform sampler2D uImageUnit;  
uniform float uR;  
void main(void)  
{  
   ivec2 ires = textureSize(uImageUnit, 0);  
   float Res = float(ires.s);  
   vec2 st = gl_FragCoord.xy/ires;  
   float Radius = Res * uR;  
   // pixel coordinates from texture coords  
   vec2 xy = Res * st;  
   // twirl center is (Res/2, Res/2)  
   vec2 dxy = xy - vec2(Res/2., Res/2.);  
   float r = length(dxy);  
   vec4 color = vec4(0.);  
   if(r<=Radius)  
   {  
      float angle = atan(dxy.y, dxy.x);  
      int num = 40;  
      for(int i=0; i<num; i++)  
      {  
         // ❤  
         int tmpR = (r-i)>0 ?(r-i):0;  
         int newX = tmpR*cos(angle) + Res/2;    
         int newY = tmpR*sin(angle) + Res/2;    
         if(newX<0)  
            newX=0;    
         if(newX>Res-1)  
            newX=Res-1;    
         if(newY<0)  
            newY=0;    
         if(newY>Res-1)  
            newY=Res-1;    
         color += texture2D(uImageUnit, vec2(newX, newY)/ires);  
      }  
      color /= num;  
   }  
   else  
   {  
      color = texture2D(uImageUnit, st);  
   }  
   gl_FragColor = color;  
}  

效果图2

GLSL 代码:
const float PI = 3.14159265;  
uniform sampler2D uImageUnit;  
uniform float uR;  
void main(void)  
{  
   ivec2 ires = textureSize(uImageUnit, 0);  
   float Res = float(ires.s);  
   vec2 st = gl_FragCoord.xy/ires;  
   float Radius = Res * uR;  
   // pixel coordinates from texture coords  
   vec2 xy = Res * st;  
   // twirl center is (Res/2, Res/2)  
   vec2 dxy = xy - vec2(Res/2., Res/2.);  
   float r = length(dxy);  
   vec4 color = vec4(0.);  
   if(r<=Radius)  
   {  
      float angle = atan(dxy.y, dxy.x);  
      int num = 40;  
      for(int i=0; i<num; i++)  
      {  
         // ❤  
         angle += .01;  
         int newX = r*cos(angle) + Res/2;    
         int newY = r*sin(angle) + Res/2;    
         if(newX<0)  
            newX=0;    
         if(newX>Res-1)  
            newX=Res-1;    
         if(newY<0)  
            newY=0;    
         if(newY>Res-1)  
            newY=Res-1;    
         color += texture2D(uImageUnit, vec2(newX, newY)/ires);  
      }  
      color /= num;  
   }  
   else  
   {  
      color = texture2D(uImageUnit, st);  
   }  
   gl_FragColor = color;  
}  

效果图3

GLSL 代码:
const float PI = 3.14159265;  
uniform sampler2D uImageUnit;  
uniform float uD, uR;  
varying vec2 vST;  
void main(void)  
{  
   ivec2 ires = textureSize(uImageUnit, 0);  
   float Res = float(ires.s);  
   vec2 st = vST;  
   float Radius = Res * uR;  
   // pixel coordinates from texture coords  
   vec2 xy = Res * st;  
   // twirl center is (Res/2, Res/2)  
   vec2 dxy = xy - vec2(Res/2., Res/2.);  
   float r = length(dxy);  
   // add radian(distance dependent) offset  
   float beta = atan(dxy.y, dxy.x) + radians(uD) * 2. * (Radius - r)/Radius;  
   //float beta = atan(dxy.y, dxy.x) + radians(uD) * 20./ sqrt(r+1);  
   vec2 xy1 = xy;  
   if(r<=Radius)  
   {  
      xy1 = Res/2. + r*vec2(cos(beta), sin(beta));  
   }  
   // Restore coordinates  
   st = xy1/Res;  
   vec3 irgb = texture(uImageUnit, st).rgb;  
   gl_FragColor = vec4( irgb, 1.0 );  
}  

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

标签: