Back to shaders
Shader test bench
Shockwave Pulse.fs
runnable fragment
Complete GLSL fragment shader. Stronghold runs it directly when the browser can compile it.
Code
uniform sampler2D inputImage;
uniform int pulse;
uniform float rate;
uniform float magnitude;
uniform float distortion;
uniform vec2 center;
precision mediump float;
/*
{
"CATEGORIES" : [
"Distortion Effect"
],
"DESCRIPTION" : "",
"ISFVSN" : "2",
"INPUTS" : [
{
"NAME" : "inputImage",
"TYPE" : "image"
},
{
"NAME" : "pulse",
"TYPE" : "event"
},
{
"NAME" : "rate",
"TYPE" : "float",
"MAX" : 4,
"DEFAULT" : 1,
"LABEL" : "rate",
"MIN" : 0
},
{
"NAME" : "magnitude",
"TYPE" : "float",
"MAX" : 0.20000000000000001,
"DEFAULT" : 0.080000000000000002,
"LABEL" : "magnitude",
"MIN" : 0
},
{
"NAME" : "distortion",
"TYPE" : "float",
"MAX" : 20,
"DEFAULT" : 10,
"LABEL" : "distortion",
"MIN" : 0
},
{
"NAME" : "center",
"TYPE" : "point2D",
"MAX" : [
1,
1
],
"DEFAULT" : [
0.5,
0.5
],
"MIN" : [
0,
0
]
}
],
"PASSES" : [
{
"PERSISTENT" : true,
"WIDTH" : "1",
"DESCRIPTION" : "this buffer stores the last frame's time offset in the first component of its only pixel- note that it's requesting a FLOAT target buffer...",
"HEIGHT" : "1",
"TARGET" : "lastTime",
"FLOAT" : true
},
{
}
],
"CREDIT" : "by VIDVOX"
}
*/
void main()
{
// if this is the first pass, i'm going to read the position from the "lastPosition" image, and write a new position based on this and the hold variables
if (PASSINDEX == 0) {
vec4 srcPixel = texture2D(lastTime, (vec2(0.5) / u_resolution.xy));
// i'm only using the X, which is the last render time we reset
srcPixel.r = (pulse && FRAMEINDEX>10) ? 0.0 : clamp(srcPixel.r + rate * 0.01,0.0,1.0);
gl_FragColor = srcPixel;
}
// else this isn't the first pass- read the position value from the buffer which stores it
else {
vec2 uv = (gl_FragCoord.xy / u_resolution.xy).xy;
vec2 texCoord = uv;
vec2 mod_center = center;
float distance = distance(uv, mod_center);
vec4 lastPosVector = texture2D(lastTime, (vec2(0.5) / u_resolution.xy));
float adustedTime = lastPosVector.r * (1.0+length(distance));
if ( (distance <= (adustedTime + magnitude)) && (distance >= (adustedTime - magnitude)) ) {
float diff = (distance - adustedTime);
float powDiff = 1.0 - pow(abs(diff*distortion),
0.8);
float diffTime = diff * powDiff;
vec2 diffUV = normalize(uv - mod_center);
texCoord = uv + (diffUV * diffTime);
}
gl_FragColor = texture2D(inputImage, texCoord);
}
}