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 ); }