Back to shaders

Shader test bench

Shockwave Pulse.fs

vidvox-isf-files pattern glsl runnable fragment MIT
Source
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);
	}
}