Shader特效——“Sephia等效果”的实现 【GLSL】
发表于2018-02-07
本篇文章给大家介绍下如果使用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 );
}
