diff --git a/ISF/3d Rotate.fs b/ISF/3d Rotate.fs new file mode 100644 index 0000000..b04ec64 --- /dev/null +++ b/ISF/3d Rotate.fs @@ -0,0 +1,52 @@ +/*{ + "DESCRIPTION": "performs a 3d rotation", + "CREDIT": "by zoidberg", + "ISFVSN": "2", + "CATEGORIES": [ + "Geometry Adjustment" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "xrot", + "LABEL": "X rotate", + "TYPE": "float", + "MIN": 0.0, + "MAX": 2.0, + "DEFAULT": 1.0 + }, + { + "NAME": "yrot", + "LABEL": "Y rotate", + "TYPE": "float", + "MIN": 0.0, + "MAX": 2.0, + "DEFAULT": 1.0 + }, + { + "NAME": "zrot", + "LABEL": "Z rotate", + "TYPE": "float", + "MIN": 0.0, + "MAX": 2.0, + "DEFAULT": 1.0 + }, + { + "NAME": "zoom", + "LABEL": "Zoom Level", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 1.0 + } + ] +}*/ + + +void main() +{ + gl_FragColor = IMG_THIS_PIXEL(inputImage); +} diff --git a/ISF/3d Rotate.vs b/ISF/3d Rotate.vs new file mode 100644 index 0000000..e05b13b --- /dev/null +++ b/ISF/3d Rotate.vs @@ -0,0 +1,86 @@ +float PI_CONST = 3.14159265359; + + +// with help from http://duriansoftware.com/joe/An-intro-to-modern-OpenGL.-Chapter-3:-3D-transformation-and-projection.html +// and http://en.wikipedia.org/wiki/Rotation_matrix + + +mat4 view_frustum( + float angle_of_view, + float aspect_ratio, + float z_near, + float z_far +) { + return mat4( + vec4(1.0/tan(angle_of_view), 0.0, 0.0, 0.0), + vec4(0.0, aspect_ratio/tan(angle_of_view), 0.0, 0.0), + vec4(0.0, 0.0, (z_far+z_near)/(z_far-z_near), 1.0), + vec4(0.0, 0.0, -2.0*z_far*z_near/(z_far-z_near), 0.0) + ); +} + +mat4 scale(float x, float y, float z) +{ + return mat4( + vec4(x, 0.0, 0.0, 0.0), + vec4(0.0, y, 0.0, 0.0), + vec4(0.0, 0.0, z, 0.0), + vec4(0.0, 0.0, 0.0, 1.0) + ); +} + +mat4 translate(float x, float y, float z) +{ + return mat4( + vec4(1.0, 0.0, 0.0, 0.0), + vec4(0.0, 1.0, 0.0, 0.0), + vec4(0.0, 0.0, 1.0, 0.0), + vec4(x, y, z, 1.0) + ); +} + +mat4 rotate_x(float theta) +{ + return mat4( + vec4(1.0, 0.0, 0.0, 0.0), + vec4(0.0, cos(theta*PI_CONST), sin(theta*PI_CONST), 0.0), + vec4(0.0, -sin(theta*PI_CONST), cos(theta*PI_CONST), 0.0), + vec4(0.0, 0.0, 0.0, 1.0) + ); +} + +mat4 rotate_y(float theta) +{ + return mat4( + vec4(cos(theta*PI_CONST), 0.0, sin(theta*PI_CONST), 0.0), + vec4(0.0, 1.0, 0.0, 0.0), + vec4(-sin(theta*PI_CONST), 0, cos(theta*PI_CONST), 0.0), + vec4(0.0, 0.0, 0.0, 1.0) + ); +} + +mat4 rotate_z(float theta) +{ + return mat4( + vec4(cos(theta*PI_CONST), -sin(theta*PI_CONST), 0.0, 0.0), + vec4(sin(theta*PI_CONST), cos(theta*PI_CONST), 0.0, 0.0), + vec4(0.0, 0.0, 1.0, 0.0), + vec4(0.0, 0.0, 0.0, 1.0) + ); +} + +void main() +{ + isf_vertShaderInit(); + + vec4 position = gl_Position; + + gl_Position = view_frustum(radians(45.0), RENDERSIZE.x/RENDERSIZE.y, 0.0, 2.0) + * translate(0.0, 0.0, RENDERSIZE.x/RENDERSIZE.y) + * rotate_x(-xrot) + * rotate_y(yrot) + * rotate_z(-zrot) + * scale(zoom*RENDERSIZE.x/RENDERSIZE.y, zoom, zoom) + * position; + +} diff --git a/ISF/ASCII Art.fs b/ISF/ASCII Art.fs new file mode 100644 index 0000000..6683278 --- /dev/null +++ b/ISF/ASCII Art.fs @@ -0,0 +1,95 @@ +/*{ + "DESCRIPTION": "ASCII Art", + "CREDIT": "by VIDVOX (Ported from https://www.shadertoy.com/view/lssGDj)", + "ISFVSN": "2", + "CATEGORIES": [ + "Stylize", "Retro" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "size", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.1 + }, + { + "NAME": "gamma", + "TYPE": "float", + "DEFAULT": 1.0, + "MIN": 0.5, + "MAX": 2.0 + }, + { + "NAME": "tint", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 1.0 + }, + { + "NAME": "tintColor", + "TYPE": "color", + "DEFAULT": [ + 0.0, + 1.0, + 0.0, + 1.0 + ] + }, + { + "NAME": "alphaMode", + "TYPE": "bool", + "DEFAULT": 0.0 + } + ] + +}*/ + + + +float character(float n, vec2 p) // some compilers have the word "char" reserved +{ + p = floor(p*vec2(4.0, -4.0) + 2.5); + if (clamp(p.x, 0.0, 4.0) == p.x && clamp(p.y, 0.0, 4.0) == p.y) + { + if (int(mod(n/exp2(p.x + 5.0*p.y), 2.0)) == 1) return 1.0; + } + return 0.0; +} + + + +void main() { + float _size = size*36.0+8.0; + vec2 uv = gl_FragCoord.xy; + vec4 inputColor = IMG_NORM_PIXEL(inputImage, (floor(uv/_size)*_size/RENDERSIZE.xy)); + vec3 col = inputColor.rgb; + float gray = (col.r + col.g + col.b)/3.0; + gray = pow(gray, gamma); + col = mix(tintColor.rgb, col.rgb, 1.0-tint); + + float n = 65536.0; // . + if (gray > 0.2) n = 65600.0; // : + if (gray > 0.3) n = 332772.0; // * + if (gray > 0.4) n = 15255086.0; // o + if (gray > 0.5) n = 23385164.0; // & + if (gray > 0.6) n = 15252014.0; // 8 + if (gray > 0.7) n = 13199452.0; // @ + if (gray > 0.8) n = 11512810.0; // # + + vec2 p = mod(uv/(_size/2.0), 2.0) - vec2(1.0); + col = col*character(n, p); + float alpha = mix(tintColor.a * inputColor.a, inputColor.a, 1.0-tint); + if (alphaMode) { + alpha = (col.r + col.g + col.b)/3.0; + alpha = (alpha > 0.01) ? tintColor.a : alpha; + } + + gl_FragColor = vec4(col,alpha); + +} diff --git a/ISF/Apply Alpha.fs b/ISF/Apply Alpha.fs new file mode 100644 index 0000000..0b3eac5 --- /dev/null +++ b/ISF/Apply Alpha.fs @@ -0,0 +1,20 @@ +/*{ + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Color Adjustment" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + } + ] +}*/ + +void main() { + vec4 srcPixel = IMG_THIS_PIXEL(inputImage); + srcPixel.rgb = srcPixel.rgb * srcPixel.a; + srcPixel.a = 1.0; + gl_FragColor = srcPixel; +} \ No newline at end of file diff --git a/ISF/Auto Color Tone.fs b/ISF/Auto Color Tone.fs new file mode 100644 index 0000000..1494ae7 --- /dev/null +++ b/ISF/Auto Color Tone.fs @@ -0,0 +1,340 @@ +/*{ + "DESCRIPTION": "Creates variations on a base color using a given algorithm.", + "CREDIT": "by VIDVOX", + "CATEGORIES": [ + "Color Effect" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "LABEL": "Sample Mode", + "NAME": "sampleMode", + "TYPE": "long", + "VALUES": [ + 0, + 1, + 2 + ], + "LABELS": [ + "Base Color", + "Pixel Follow", + "Color Average" + ], + "DEFAULT": 0 + }, + { + "LABEL": "Color Mode", + "NAME": "colorModeOverride", + "TYPE": "long", + "VALUES": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6 + ], + "LABELS": [ + "Basic Complementary", + "Split Complementary", + "Compound Complementary", + "Spectrum", + "Shades", + "Analogous", + "Compound Analogous" + ], + "DEFAULT": 1 + }, + { + "LABEL": "Color Count", + "NAME": "colorCount", + "TYPE": "long", + "VALUES": [ + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16 + ], + "LABELS": [ + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9", + "10", + "11", + "12", + "13", + "14", + "15", + "16" + ], + "DEFAULT": 7 + }, + { + "LABEL": "Base Color", + "NAME": "baseColor", + "TYPE": "color", + "DEFAULT": [ + 0.25, + 0.59, + 0.9, + 1.0 + ] + }, + { + "LABEL": "Pixel Point", + "NAME": "pixelFollowLocation", + "TYPE": "point2D", + "DEFAULT": [ + 0.5, + 0.5 + ] + } + ], + "PERSISTENT_BUFFERS": [ + "autoColorBuffer" + ], + "PASSES": [ + { + "TARGET": "bufferPassA", + "WIDTH": "$WIDTH / 100.0", + "HEIGHT": "$HEIGHT / 100.0" + }, + { + "TARGET":"autoColorBuffer", + "WIDTH": "1.0", + "HEIGHT": "1.0" + }, + { + + } + ] +}*/ + + + + +vec3 rgb2hsv(vec3 c) { + vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); + //vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g)); + //vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r)); + vec4 p = c.g < c.b ? vec4(c.bg, K.wz) : vec4(c.gb, K.xy); + vec4 q = c.r < p.x ? vec4(p.xyw, c.r) : vec4(c.r, p.yzx); + + float d = q.x - min(q.w, q.y); + float e = 1.0e-10; + return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x); +} + +vec3 hsv2rgb(vec3 c) { + vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); + vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www); + return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y); +} + +float gray(vec4 c) { + return (c.r + c.g + c.b) * c.a / 3.0; +} + +void main() +{ + if (PASSINDEX == 0) { + vec4 inputColor = IMG_NORM_PIXEL(inputImage, vv_FragNormCoord); + gl_FragColor = inputColor; + } + else if (PASSINDEX == 1) { + vec4 inputColor = IMG_NORM_PIXEL(bufferPassA, vv_FragNormCoord); + vec4 oldColor = IMG_NORM_PIXEL(autoColorBuffer, vec2(0.5,0.5)); + gl_FragColor = mix(inputColor, oldColor, 0.8); + } + else if (PASSINDEX == 2) { + vec4 inputColor = IMG_THIS_PIXEL(inputImage); + vec4 inColor = baseColor; + float index = floor(gray(inputColor) * float(colorCount)); + //float index = floor(vv_FragNormCoord.x * float(colorCount)); + float variation = 0.3236; // 1/5 the golden ratio + int colorMode = colorModeOverride; + + if (sampleMode == 0) { + inColor = baseColor; + inColor.rgb = rgb2hsv(inColor.rgb); + } + else if (sampleMode == 1) { + inColor = IMG_PIXEL(inputImage, pixelFollowLocation); + inColor.rgb = rgb2hsv(inColor.rgb); + } + else if (sampleMode == 2) { + inColor = IMG_NORM_PIXEL(autoColorBuffer, vec2(0.5,0.5)); + inColor.rgb = rgb2hsv(inColor.rgb); + if (inColor.b < 0.1) { + inColor = inColor * 1.5; + } + } + + vec4 outColor = inColor; + + // Basic complimentary – saturation and brightness variations on two fixed 180 degree opposite hues + if (colorMode == 0) { + if (mod(index, 2.0) >= 1.0) { + outColor.r = outColor.r + 0.5; + outColor.r = outColor.r - floor(outColor.r); + } + + outColor.g = outColor.g - variation * floor(index / 2.0); + + if (outColor.g < 0.1) { + outColor.g = outColor.g + variation * floor(index / 2.0); + outColor.g = outColor.g - floor(outColor.g); + } + + outColor.b = outColor.b - variation * floor(index / 4.0); + if (outColor.b < 0.2) { + outColor.b = outColor.b + variation * floor(index / 4.0); + outColor.b = outColor.b - floor(outColor.b); + } + } + // Split complimentary – saturation and brightness variations on a 3 fixed 120 degree hues + else if (colorMode == 1) { + float divisor = 3.0; + float ratio = 0.45; + if (mod(index, 3.0) >= 2.0) { + outColor.r = outColor.r - ratio; + } + else if (mod(index, 3.0) >= 1.0) { + outColor.r = outColor.r + ratio; + } + + //outColor.g = outColor.g + variation * floor(index / divisor); + + if (mod(index, 5.0) >= 3.0) { + outColor.g = outColor.g - variation; + outColor.g = outColor.g - floor(outColor.g); + } + outColor.b = outColor.b - variation * floor(index / (divisor)); + if (outColor.b < 0.1) { + outColor.b = outColor.b + variation * floor(index / (divisor)); + outColor.b = outColor.b - floor(outColor.b); + } + } + // Compound complimentary – a combination of shades, complimentary and analogous colors with slight shifts + else if (colorMode == 2) { + if (mod(index, 3.0) >= 2.0) { + outColor.r = outColor.r + 0.5; + outColor.r = outColor.r + variation * index * 1.0 / float(colorCount - 1) / 4.0; + } + else { + outColor.r = outColor.r + variation * index * 1.0 / float(colorCount - 1); + } + outColor.r = outColor.r - floor(outColor.r); + + + if (mod(index, 2.0) >= 1.0) { + outColor.g = outColor.g + index * variation / 2.0; + } + else if (mod(index, 3.0) >= 2.0) { + outColor.g = outColor.g - variation / 2.0; + } + else { + outColor.g = outColor.g - index * variation / float(colorCount - 1); + } + if (outColor.g > 1.0) { + outColor.g = outColor.g - floor(outColor.g); + } + } + // Spectrum – hue shifts based on number of colors with minor saturation shifts + else if (colorMode == 3) { + outColor.r = outColor.r + index * 1.0 / float(colorCount); + if (mod(index, 3.0) >= 2.0) { + outColor.g = outColor.g - variation / 2.0; + outColor.g = outColor.g - floor(outColor.g); + } + else if (mod(index, 4.0) >= 3.0) { + outColor.g = outColor.g + variation / 2.0; + //outColor.g = outColor.g - floor(outColor.g); + } + } + // Shades – saturation and brightness variations on a single fixed hue + else if (colorMode == 4) { + if (mod(index, 2.0) >= 1.0) { + outColor.b = outColor.b - (index * variation) / float(colorCount-1); + } + else { + outColor.b = outColor.b + (index * variation) / float(colorCount-1); + outColor.b = outColor.b - floor(outColor.b); + } + if (outColor.b < 0.075) { + outColor.b = 1.0 - outColor.b * variation; + } + + if (mod(index, 3.0) >= 2.0) { + outColor.g = outColor.g - (index * variation) / 2.0; + } + else if (mod(index, 4.0) >= 3.0) { + outColor.g = outColor.g + (index * variation) / 2.0; + } + + if ((outColor.g > 1.0) || (outColor.g < 0.05)) { + outColor.g = outColor.g - floor(outColor.g); + } + } + // Analogous – small hue and saturation shifts + else if (colorMode == 5) { + + outColor.r = outColor.r + variation * index * 1.0 / float(colorCount - 1); + + if (mod(index, 3.0) >= 1.0) { + outColor.g = outColor.g - variation / 2.0; + if (outColor.g < 0.0) { + outColor.g = outColor.g + variation / 2.0; + } + if (outColor.g > 1.0) { + outColor.g = outColor.g - floor(outColor.g); + } + } + } + // Compound Analogous – similar to analogous but with negative hue shifts + else if (colorMode == 6) { + if (mod(index, 3.0) >= 1.0) { + outColor.r = outColor.r + variation * index * 1.0 / float(colorCount - 1); + } + else { + outColor.r = outColor.r - variation * index * 0.5 / float(colorCount - 1); + } + if (mod(index, 3.0) >= 1.0) { + outColor.g = outColor.g - variation / 2.0; + if (outColor.g < 0.0) { + outColor.g = outColor.g + variation; + } + if (outColor.g > 1.0) { + outColor.g = outColor.g - floor(outColor.g); + } + } + if (mod(index, 4.0) >= 2.0) { + if (outColor.b < variation) { + outColor.b = outColor.b + variation; + } + } + } + + gl_FragColor = vec4(hsv2rgb(outColor.rgb), inColor.a); + } +} diff --git a/ISF/Auto Colors Histogram.fs b/ISF/Auto Colors Histogram.fs new file mode 100644 index 0000000..1c1c144 --- /dev/null +++ b/ISF/Auto Colors Histogram.fs @@ -0,0 +1,108 @@ +/* +{ + "CATEGORIES" : [ + "Color Adjustment" + ], + "DESCRIPTION" : "", + "ISFVSN" : "2", + "INPUTS" : [ + { + "NAME" : "inputImage", + "TYPE" : "image" + }, + { + "NAME" : "sourceHistogram", + "TYPE" : "image" + }, + { + "NAME" : "maxGain", + "TYPE" : "float", + "MAX" : 8, + "DEFAULT" : 2, + "MIN" : 1 + } + ], + "PASSES" : [ + { + "WIDTH" : "2", + "TARGET" : "minmax", + "HEIGHT" : "1" + }, + { + + } + ], + "CREDIT" : "VIDVOX" +} +*/ + +void main() { + vec4 returnMe = vec4(0.0); + if (PASSINDEX==0) { + float minOrMax = (isf_FragNormCoord.x < 0.5) ? 0.0 : 1.0; + // go through each pixel of sourceHistogram + // find the darkest and brightest for each color channel + if (isf_FragNormCoord.x < 0.5) { + returnMe.a = 1.0; + for(int i=0;i<256;++i) { + vec4 histo = IMG_PIXEL(sourceHistogram,vec2(float(i),0.5)); + if (returnMe.r == 0.0) { + if (histo.r > 0.01) { + returnMe.r = float(i)/255.0; + } + } + if (returnMe.g == 0.0) { + if (histo.g > 0.01) { + returnMe.g = float(i)/255.0; + } + } + if (returnMe.b == 0.0) { + if (histo.b > 0.01) { + returnMe.b = float(i)/255.0; + } + } + } + } + else { + returnMe = vec4(1.0); + for(int i=255;i>=0;--i) { + vec4 histo = IMG_PIXEL(sourceHistogram,vec2(float(i),0.5)); + if (returnMe.r == 1.0) { + if (histo.r > 0.01) { + returnMe.r = float(i)/255.0; + } + } + if (returnMe.g == 1.0) { + if (histo.g > 0.01) { + returnMe.g = float(i)/255.0; + } + } + if (returnMe.b == 1.0) { + if (histo.b > 0.01) { + returnMe.b = float(i)/255.0; + } + } + } + } + } + else if (PASSINDEX==1) { + returnMe = IMG_THIS_PIXEL(inputImage); + vec4 minVal = IMG_PIXEL(minmax,vec2(0.5,0.5)); + vec4 maxVal = IMG_PIXEL(minmax,vec2(1.5,0.5)); + vec4 contrastVal = 1.0 / (maxVal - minVal); + if (contrastVal.r > maxGain) + contrastVal.r = maxGain; + + if (contrastVal.g > maxGain) + contrastVal.g = maxGain; + + if (contrastVal.b > maxGain) + contrastVal.b = maxGain; + + returnMe.r = (returnMe.r - minVal.r) * contrastVal.r; + returnMe.g = (returnMe.g - minVal.g) * contrastVal.g; + returnMe.b = (returnMe.b - minVal.b) * contrastVal.b; + } + + gl_FragColor = returnMe; +} diff --git a/ISF/Auto Levels.fs b/ISF/Auto Levels.fs new file mode 100644 index 0000000..9284c11 --- /dev/null +++ b/ISF/Auto Levels.fs @@ -0,0 +1,312 @@ +/*{ + "DESCRIPTION": "Auto Levels", + "CREDIT": "by Carter Rosenberg", + "ISFVSN": "2", + "CATEGORIES": [ + "Color Adjustment" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "min_threshold", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.0 + }, + { + "NAME": "mid_point", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.5 + }, + { + "NAME": "max_threshold", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 1.0 + }, + { + "NAME": "adapt_rate", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.5 + } + ], + "PASSES": [ + { + "TARGET": "bufferPassA", + "WIDTH": "$WIDTH / 2.0", + "HEIGHT": "$HEIGHT / 2.0" + }, + { + "TARGET": "bufferPassB", + "WIDTH": "max($WIDTH / 27.0, 1.0)", + "HEIGHT": "max($HEIGHT / 27.0, 1.0)" + }, + { + "TARGET": "bufferPassC", + "WIDTH": "max($WIDTH / 3.0, 1.0)", + "HEIGHT": "max($HEIGHT / 3.0, 1.0)" + }, + { + "TARGET": "bufferPassD", + "WIDTH": "max($WIDTH / 243.0, 1.0)", + "HEIGHT": "max($HEIGHT / 243.0, 1.0)" + }, + { + "TARGET": "bufferVariableNameA", + "PERSISTENT": true, + "WIDTH": "max($WIDTH/486.0,1.0)", + "HEIGHT": "max($HEIGHT/486.0,1.0)" + }, + { + + } + ] + +}*/ + + +varying vec2 left_coord; +varying vec2 right_coord; +varying vec2 above_coord; +varying vec2 below_coord; + +varying vec2 lefta_coord; +varying vec2 righta_coord; +varying vec2 leftb_coord; +varying vec2 rightb_coord; + +float gray(vec4 n) +{ + return (n.r + n.g + n.b)/3.0; +} + +// packed as min, mid, max +vec3 minmaxmean(vec4 n, vec3 old) +{ + float val = gray(n); + vec3 returnMe = old; + if (val < returnMe.x) { + returnMe.x = val; + } + if (val > returnMe.z) { + returnMe.z = val; + } + returnMe.y = returnMe.y + val / 9.0; + return returnMe; +} + +vec3 minmaxcompare(vec4 n, vec3 old) { + vec3 returnMe = old; + if (n.r < returnMe.x) { + returnMe.x = n.r; + } + if (n.g > returnMe.z) { + returnMe.z = n.g; + } + returnMe.y = returnMe.y + n.b / 9.0; + return returnMe; +} + + +void main() +{ + vec3 vals = vec3(1.0,0.0,0.0); + + // on this first pass we find the local mins, mid, and max for each pixel + if (PASSINDEX == 0) { + vec4 min_color = IMG_THIS_PIXEL(inputImage); + vec4 min_colorL = IMG_NORM_PIXEL(inputImage, left_coord); + vec4 min_colorR = IMG_NORM_PIXEL(inputImage, right_coord); + vec4 min_colorA = IMG_NORM_PIXEL(inputImage, above_coord); + vec4 min_colorB = IMG_NORM_PIXEL(inputImage, below_coord); + + vec4 min_colorLA = IMG_NORM_PIXEL(inputImage, lefta_coord); + vec4 min_colorRA = IMG_NORM_PIXEL(inputImage, righta_coord); + vec4 min_colorLB = IMG_NORM_PIXEL(inputImage, leftb_coord); + vec4 min_colorRB = IMG_NORM_PIXEL(inputImage, rightb_coord); + + vals = minmaxmean(min_color,vals); + + vals = minmaxmean(min_colorL,vals); + vals = minmaxmean(min_colorR,vals); + vals = minmaxmean(min_colorA,vals); + vals = minmaxmean(min_colorB,vals); + + vals = minmaxmean(min_colorLA,vals); + vals = minmaxmean(min_colorRA,vals); + vals = minmaxmean(min_colorLB,vals); + vals = minmaxmean(min_colorRB,vals); + gl_FragColor = vec4(vals.x,vals.y,vals.z,min_color.a); + } + // second pass: read from "bufferPassA", write to "bufferPassB" + else if (PASSINDEX == 1) { + vec4 min_color = IMG_THIS_PIXEL(bufferPassA); + vec4 min_colorL = IMG_NORM_PIXEL(bufferPassA, left_coord); + vec4 min_colorR = IMG_NORM_PIXEL(bufferPassA, right_coord); + vec4 min_colorA = IMG_NORM_PIXEL(bufferPassA, above_coord); + vec4 min_colorB = IMG_NORM_PIXEL(bufferPassA, below_coord); + + vec4 min_colorLA = IMG_NORM_PIXEL(bufferPassA, lefta_coord); + vec4 min_colorRA = IMG_NORM_PIXEL(bufferPassA, righta_coord); + vec4 min_colorLB = IMG_NORM_PIXEL(bufferPassA, leftb_coord); + vec4 min_colorRB = IMG_NORM_PIXEL(bufferPassA, rightb_coord); + + vals = minmaxcompare(min_color,vals); + + vals = minmaxcompare(min_colorL,vals); + vals = minmaxcompare(min_colorR,vals); + vals = minmaxcompare(min_colorA,vals); + vals = minmaxcompare(min_colorB,vals); + + vals = minmaxcompare(min_colorLA,vals); + vals = minmaxcompare(min_colorRA,vals); + vals = minmaxcompare(min_colorLB,vals); + vals = minmaxcompare(min_colorRB,vals); + gl_FragColor = vec4(vals.x,vals.y,vals.z,min_color.a); + } + // read from "bufferPassB", write to "bufferPassC" + else if (PASSINDEX == 2) { + vec4 min_color = IMG_THIS_PIXEL(bufferPassB); + vec4 min_colorL = IMG_NORM_PIXEL(bufferPassB, left_coord); + vec4 min_colorR = IMG_NORM_PIXEL(bufferPassB, right_coord); + vec4 min_colorA = IMG_NORM_PIXEL(bufferPassB, above_coord); + vec4 min_colorB = IMG_NORM_PIXEL(bufferPassB, below_coord); + + vec4 min_colorLA = IMG_NORM_PIXEL(bufferPassB, lefta_coord); + vec4 min_colorRA = IMG_NORM_PIXEL(bufferPassB, righta_coord); + vec4 min_colorLB = IMG_NORM_PIXEL(bufferPassB, leftb_coord); + vec4 min_colorRB = IMG_NORM_PIXEL(bufferPassB, rightb_coord); + + vals = minmaxcompare(min_color,vals); + + vals = minmaxcompare(min_colorL,vals); + vals = minmaxcompare(min_colorR,vals); + vals = minmaxcompare(min_colorA,vals); + vals = minmaxcompare(min_colorB,vals); + + vals = minmaxcompare(min_colorLA,vals); + vals = minmaxcompare(min_colorRA,vals); + vals = minmaxcompare(min_colorLB,vals); + vals = minmaxcompare(min_colorRB,vals); + gl_FragColor = vec4(vals.x,vals.y,vals.z,min_color.a); + } + // read from "bufferPassC", write to "bufferPassD" + else if (PASSINDEX == 3) { + vec4 min_color = IMG_THIS_PIXEL(bufferPassC); + vec4 min_colorL = IMG_NORM_PIXEL(bufferPassC, left_coord); + vec4 min_colorR = IMG_NORM_PIXEL(bufferPassC, right_coord); + vec4 min_colorA = IMG_NORM_PIXEL(bufferPassC, above_coord); + vec4 min_colorB = IMG_NORM_PIXEL(bufferPassC, below_coord); + + vec4 min_colorLA = IMG_NORM_PIXEL(bufferPassC, lefta_coord); + vec4 min_colorRA = IMG_NORM_PIXEL(bufferPassC, righta_coord); + vec4 min_colorLB = IMG_NORM_PIXEL(bufferPassC, leftb_coord); + vec4 min_colorRB = IMG_NORM_PIXEL(bufferPassC, rightb_coord); + + vals = minmaxcompare(min_color,vals); + + vals = minmaxcompare(min_colorL,vals); + vals = minmaxcompare(min_colorR,vals); + vals = minmaxcompare(min_colorA,vals); + vals = minmaxcompare(min_colorB,vals); + + vals = minmaxcompare(min_colorLA,vals); + vals = minmaxcompare(min_colorRA,vals); + vals = minmaxcompare(min_colorLB,vals); + vals = minmaxcompare(min_colorRB,vals); + gl_FragColor = vec4(vals.x,vals.y,vals.z,min_color.a); + } + // read from "bufferPassD", write to "bufferVariableNameA" + else if (PASSINDEX == 4) { + vec4 min_color = IMG_THIS_PIXEL(bufferPassD); + vec4 stalePixel = IMG_THIS_PIXEL(bufferVariableNameA); + vec4 min_colorL = IMG_NORM_PIXEL(bufferPassD, left_coord); + vec4 min_colorR = IMG_NORM_PIXEL(bufferPassD, right_coord); + vec4 min_colorA = IMG_NORM_PIXEL(bufferPassD, above_coord); + vec4 min_colorB = IMG_NORM_PIXEL(bufferPassD, below_coord); + + vec4 min_colorLA = IMG_NORM_PIXEL(bufferPassD, lefta_coord); + vec4 min_colorRA = IMG_NORM_PIXEL(bufferPassD, righta_coord); + vec4 min_colorLB = IMG_NORM_PIXEL(bufferPassD, leftb_coord); + vec4 min_colorRB = IMG_NORM_PIXEL(bufferPassD, rightb_coord); + + vals = minmaxcompare(min_color,vals); + + vals = minmaxcompare(min_colorL,vals); + vals = minmaxcompare(min_colorR,vals); + vals = minmaxcompare(min_colorA,vals); + vals = minmaxcompare(min_colorB,vals); + + vals = minmaxcompare(min_colorLA,vals); + vals = minmaxcompare(min_colorRA,vals); + vals = minmaxcompare(min_colorLB,vals); + vals = minmaxcompare(min_colorRB,vals); + gl_FragColor = mix(vec4(vals.x,vals.y,vals.z,min_color.a),stalePixel,adapt_rate);; + } + // read from "bufferVariableNameA", write to output + else if (PASSINDEX == 5) { + vec4 min_color = IMG_THIS_PIXEL(bufferVariableNameA); + vec4 min_colorL = IMG_NORM_PIXEL(bufferVariableNameA, left_coord); + vec4 min_colorR = IMG_NORM_PIXEL(bufferVariableNameA, right_coord); + vec4 min_colorA = IMG_NORM_PIXEL(bufferVariableNameA, above_coord); + vec4 min_colorB = IMG_NORM_PIXEL(bufferVariableNameA, below_coord); + + vec4 min_colorLA = IMG_NORM_PIXEL(bufferVariableNameA, lefta_coord); + vec4 min_colorRA = IMG_NORM_PIXEL(bufferVariableNameA, righta_coord); + vec4 min_colorLB = IMG_NORM_PIXEL(bufferVariableNameA, leftb_coord); + vec4 min_colorRB = IMG_NORM_PIXEL(bufferVariableNameA, rightb_coord); + + vals = minmaxcompare(min_color,vals); + + vals = minmaxcompare(min_colorL,vals); + vals = minmaxcompare(min_colorR,vals); + vals = minmaxcompare(min_colorA,vals); + vals = minmaxcompare(min_colorB,vals); + + vals = minmaxcompare(min_colorLA,vals); + vals = minmaxcompare(min_colorRA,vals); + vals = minmaxcompare(min_colorLB,vals); + vals = minmaxcompare(min_colorRB,vals); + + vec4 final_pixel = IMG_THIS_PIXEL(inputImage); + + + float val = gray (final_pixel); + if (vals.x < min_threshold) { + vals.x = min_threshold; + } + if (val < min_threshold) { + val = min_threshold; + } + if (vals.z > max_threshold) { + vals.z = max_threshold; + } + if (val > max_threshold) { + val = max_threshold; + } + //final_pixel.rgb = (final_pixel.rgb - vals.x) / (vals.z - vals.x); + // shift by the absdiff of the midpoint + //final_pixel.rgb = final_pixel.rgb + (mid_point - vals.y); + final_pixel.rgb = final_pixel.rgb - (0.5 - mid_point); + // by contrast adjustments + float diff = vals.z-vals.x; + if (diff < 0.01) { + diff = 0.01; + } + final_pixel.rgb = (final_pixel.rgb - vals.x) / diff; + //float contrast = 1.0/diff; + //final_pixel.rgb = ((vec3(2.0) * (final_pixel.rgb - vec3(vals.x))) * vec3(contrast) / vec3(2.0)) + vec3(0.5); + + gl_FragColor = final_pixel; + //gl_FragColor = vec4(vec3(vals.z),1.0); + } +} diff --git a/ISF/Auto Levels.vs b/ISF/Auto Levels.vs new file mode 100644 index 0000000..b6243fc --- /dev/null +++ b/ISF/Auto Levels.vs @@ -0,0 +1,27 @@ +varying vec2 left_coord; +varying vec2 right_coord; +varying vec2 above_coord; +varying vec2 below_coord; + +varying vec2 lefta_coord; +varying vec2 righta_coord; +varying vec2 leftb_coord; +varying vec2 rightb_coord; + +void main() +{ + isf_vertShaderInit(); + vec2 texc = vec2(isf_FragNormCoord[0],isf_FragNormCoord[1]); + vec2 d = 1.0/RENDERSIZE; + + left_coord = clamp(vec2(texc.xy + vec2(-d.x , 0)),0.0,1.0); + right_coord = clamp(vec2(texc.xy + vec2(d.x , 0)),0.0,1.0); + above_coord = clamp(vec2(texc.xy + vec2(0,d.y)),0.0,1.0); + below_coord = clamp(vec2(texc.xy + vec2(0,-d.y)),0.0,1.0); + + d = 1.0/RENDERSIZE; + lefta_coord = clamp(vec2(texc.xy + vec2(-d.x , d.x)),0.0,1.0); + righta_coord = clamp(vec2(texc.xy + vec2(d.x , d.x)),0.0,1.0); + leftb_coord = clamp(vec2(texc.xy + vec2(-d.x , -d.x)),0.0,1.0); + rightb_coord = clamp(vec2(texc.xy + vec2(d.x , -d.x)),0.0,1.0); +} \ No newline at end of file diff --git a/ISF/Bad TV.fs b/ISF/Bad TV.fs new file mode 100644 index 0000000..2e2ba31 --- /dev/null +++ b/ISF/Bad TV.fs @@ -0,0 +1,185 @@ + +/*{ + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Glitch" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "noiseLevel", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.5 + }, + { + "NAME": "distortion1", + "TYPE": "float", + "MIN": 0.0, + "MAX": 5.0, + "DEFAULT": 1.0 + }, + { + "NAME": "distortion2", + "TYPE": "float", + "MIN": 0.0, + "MAX": 5.0, + "DEFAULT": 5.0 + }, + { + "NAME": "speed", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.3 + }, + { + "NAME": "scroll", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.0 + }, + { + "NAME": "scanLineThickness", + "TYPE": "float", + "MIN": 1.0, + "MAX": 50.0, + "DEFAULT": 25.0 + }, + { + "NAME": "scanLineIntensity", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.5 + }, + { + "NAME": "scanLineOffset", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.0 + } + ] +}*/ + +// Adapted from http://www.airtightinteractive.com/demos/js/badtvshader/js/BadTVShader.js +// Also uses adopted Ashima WebGl Noise: https://github.com/ashima/webgl-noise + +/* + * The MIT License + * + * Copyright (c) 2014 Felix Turner + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * +*/ + + +// Start Ashima 2D Simplex Noise + +const vec4 C = vec4(0.211324865405187,0.366025403784439,-0.577350269189626,0.024390243902439); + +vec3 mod289(vec3 x) { + return x - floor(x * (1.0 / 289.0)) * 289.0; +} + +vec2 mod289(vec2 x) { + return x - floor(x * (1.0 / 289.0)) * 289.0; +} + +vec3 permute(vec3 x) { + return mod289(((x*34.0)+1.0)*x); +} + +float snoise(vec2 v) { + vec2 i = floor(v + dot(v, C.yy) ); + vec2 x0 = v - i + dot(i, C.xx); + + vec2 i1; + i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0); + vec4 x12 = x0.xyxy + C.xxzz; + x12.xy -= i1; + + i = mod289(i); // Avoid truncation effects in permutation + vec3 p = permute( permute( i.y + vec3(0.0, i1.y, 1.0 ))+ i.x + vec3(0.0, i1.x, 1.0 )); + + vec3 m = max(0.5 - vec3(dot(x0,x0), dot(x12.xy,x12.xy), dot(x12.zw,x12.zw)), 0.0); + m = m*m ; + m = m*m ; + + vec3 x = 2.0 * fract(p * C.www) - 1.0; + vec3 h = abs(x) - 0.5; + vec3 ox = floor(x + 0.5); + vec3 a0 = x - ox; + + m *= 1.79284291400159 - 0.85373472095314 * ( a0*a0 + h*h ); + + vec3 g; + g.x = a0.x * x0.x + h.x * x0.y; + g.yz = a0.yz * x12.xz + h.yz * x12.yw; + return 130.0 * dot(m, g); +} + +// End Ashima 2D Simplex Noise + +const float tau = 6.28318530718; + +// use this pattern for scan lines + +vec2 pattern(vec2 pt) { + float s = 0.0; + float c = 1.0; + vec2 tex = pt * RENDERSIZE; + vec2 point = vec2( c * tex.x - s * tex.y, s * tex.x + c * tex.y ) * (1.0/scanLineThickness); + float d = point.y; + + return vec2(sin(d + scanLineOffset * tau + cos(pt.x * tau)), cos(d + scanLineOffset * tau + sin(pt.y * tau))); +} + +float rand(vec2 co){ + return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453); +} + +void main() { + vec2 p = isf_FragNormCoord; + float ty = TIME*speed; + float yt = p.y - ty; + + //smooth distortion + float offset = snoise(vec2(yt*3.0,0.0))*0.2; + // boost distortion + offset = pow( offset*distortion1,3.0)/max(distortion1,0.001); + //add fine grain distortion + offset += snoise(vec2(yt*50.0,0.0))*distortion2*0.001; + //combine distortion on X with roll on Y + vec2 adjusted = vec2(fract(p.x + offset),fract(p.y-scroll) ); + vec4 result = IMG_NORM_PIXEL(inputImage, adjusted); + vec2 pat = pattern(adjusted); + vec3 shift = scanLineIntensity * vec3(0.3 * pat.x, 0.59 * pat.y, 0.11) / 2.0; + result.rgb = (1.0 + scanLineIntensity / 2.0) * result.rgb + shift + (rand(adjusted * TIME) - 0.5) * noiseLevel; + gl_FragColor = result; + +} \ No newline at end of file diff --git a/ISF/Basic Shape.fs b/ISF/Basic Shape.fs new file mode 100644 index 0000000..538725f --- /dev/null +++ b/ISF/Basic Shape.fs @@ -0,0 +1,287 @@ +/* +{ + "CATEGORIES" : [ + "Generator" + ], + "ISFVSN" : "2", + "INPUTS" : [ + { + "NAME" : "color", + "TYPE" : "color", + "DEFAULT" : [ + 1, + 1, + 1, + 1 + ] + }, + { + "VALUES" : [ + 0, + 1, + 2, + 3 + ], + "NAME" : "maskShapeMode", + "TYPE" : "long", + "DEFAULT" : 1, + "LABEL" : "Mask Shape Mode", + "LABELS" : [ + "Rectangle", + "Triangle", + "Circle", + "Diamond" + ] + }, + { + "NAME" : "shapeWidth", + "TYPE" : "float", + "MAX" : 2, + "DEFAULT" : 0.5, + "LABEL" : "Shape Width", + "MIN" : 0 + }, + { + "NAME" : "shapeHeight", + "TYPE" : "float", + "MAX" : 2, + "DEFAULT" : 0.5, + "LABEL" : "Shape Height", + "MIN" : 0 + }, + { + "NAME" : "center", + "TYPE" : "point2D", + "MAX" : [ + 1, + 1 + ], + "DEFAULT" : [ + 0.5, + 0.5 + ], + "MIN" : [ + 0, + 0 + ] + }, + { + "NAME" : "invertMask", + "TYPE" : "bool", + "DEFAULT" : false, + "LABEL" : "Invert Mask" + }, + { + "VALUES" : [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9 + ], + "NAME" : "horizontalRepeat", + "TYPE" : "long", + "DEFAULT" : 1, + "LABEL" : "Horizontal Repeat", + "LABELS" : [ + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9" + ] + }, + { + "VALUES" : [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9 + ], + "NAME" : "verticalRepeat", + "TYPE" : "long", + "DEFAULT" : 1, + "LABEL" : "Vertical Repeat", + "LABELS" : [ + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9" + ] + } + ], + "CREDIT" : "by VIDVOX" +} +*/ + + + +const float pi = 3.14159265359; + + +vec2 rotatePoint(vec2 pt, float angle, vec2 center) +{ + vec2 returnMe; + float s = sin(angle * pi); + float c = cos(angle * pi); + + returnMe = pt; + + // translate point back to origin: + returnMe.x -= center.x; + returnMe.y -= center.y; + + // rotate point + float xnew = returnMe.x * c - returnMe.y * s; + float ynew = returnMe.x * s + returnMe.y * c; + + // translate point back: + returnMe.x = xnew + center.x; + returnMe.y = ynew + center.y; + return returnMe; +} + +float sign(vec2 p1, vec2 p2, vec2 p3) +{ + return (p1.x - p3.x) * (p2.y - p3.y) - (p2.x - p3.x) * (p1.y - p3.y); +} + +bool PointInTriangle(vec2 pt, vec2 v1, vec2 v2, vec2 v3) +{ + bool b1, b2, b3; + + b1 = sign(pt, v1, v2) < 0.0; + b2 = sign(pt, v2, v3) < 0.0; + b3 = sign(pt, v3, v1) < 0.0; + + return ((b1 == b2) && (b2 == b3)); +} + +bool RotatedPointInTriangle(vec2 pt, vec2 v1, vec2 v2, vec2 v3, vec2 center) +{ + bool b1, b2, b3; + + vec2 v1r = v1; + vec2 v2r = v2; + vec2 v3r = v3; + + b1 = sign(pt, v1r, v2r) < 0.0; + b2 = sign(pt, v2r, v3r) < 0.0; + b3 = sign(pt, v3r, v1r) < 0.0; + + return ((b1 == b2) && (b2 == b3)); +} + + +float isPointInShape(vec2 pt, int shape, vec4 shapeCoordinates) { + float returnMe = 0.0; + + // rectangle + if (shape == 0) { + if (RotatedPointInTriangle(pt, shapeCoordinates.xy, shapeCoordinates.xy + vec2(0.0, shapeCoordinates.w), shapeCoordinates.xy + vec2(shapeCoordinates.z, 0.0), shapeCoordinates.xy + shapeCoordinates.zw / 2.0)) { + returnMe = 1.0; + // soft edge if needed + if ((pt.x > shapeCoordinates.x) && (pt.x < shapeCoordinates.x)) { + returnMe = clamp(((pt.x - shapeCoordinates.x) / RENDERSIZE.x), 0.0, 1.0); + returnMe = pow(returnMe, 0.5); + } + else if ((pt.x > shapeCoordinates.x + shapeCoordinates.z) && (pt.x < shapeCoordinates.x + shapeCoordinates.z)) { + returnMe = clamp(((shapeCoordinates.x + shapeCoordinates.z - pt.x) / RENDERSIZE.x), 0.0, 1.0); + returnMe = pow(returnMe, 0.5); + } + } + else if (RotatedPointInTriangle(pt, shapeCoordinates.xy + shapeCoordinates.zw, shapeCoordinates.xy + vec2(0.0, shapeCoordinates.w), shapeCoordinates.xy + vec2(shapeCoordinates.z, 0.0), shapeCoordinates.xy + shapeCoordinates.zw / 2.0)) { + returnMe = 1.0; + // soft edge if needed + if ((pt.x > shapeCoordinates.x) && (pt.x < shapeCoordinates.x)) { + returnMe = clamp(((pt.x - shapeCoordinates.x) / RENDERSIZE.x), 0.0, 1.0); + returnMe = pow(returnMe, 0.5); + } + else if ((pt.x > shapeCoordinates.x + shapeCoordinates.z) && (pt.x < shapeCoordinates.x + shapeCoordinates.z)) { + returnMe = clamp(((shapeCoordinates.x + shapeCoordinates.z - pt.x) / RENDERSIZE.x), 0.0, 1.0); + returnMe = pow(returnMe, 0.5); + } + } + } + // triangle + else if (shape == 1) { + if (RotatedPointInTriangle(pt, shapeCoordinates.xy, shapeCoordinates.xy + vec2(shapeCoordinates.z / 2.0, shapeCoordinates.w), shapeCoordinates.xy + vec2(shapeCoordinates.z, 0.0), shapeCoordinates.xy + shapeCoordinates.zw / 2.0)) { + returnMe = 1.0; + } + } + // oval + else if (shape == 2) { + returnMe = distance(pt, vec2(shapeCoordinates.xy + shapeCoordinates.zw / 2.0)); + if (returnMe < min(shapeCoordinates.z,shapeCoordinates.w) / 2.0) { + returnMe = 1.0; + } + else { + returnMe = 0.0; + } + } + // diamond + else if (shape == 3) { + if (RotatedPointInTriangle(pt, shapeCoordinates.xy + vec2(0.0, shapeCoordinates.w / 2.0), shapeCoordinates.xy + vec2(shapeCoordinates.z / 2.0, shapeCoordinates.w), shapeCoordinates.xy + vec2(shapeCoordinates.z, shapeCoordinates.w / 2.0), shapeCoordinates.xy + shapeCoordinates.zw / 2.0)) { + returnMe = 1.0; + } + else if (RotatedPointInTriangle(pt, shapeCoordinates.xy + vec2(0.0, shapeCoordinates.w / 2.0), shapeCoordinates.xy + vec2(shapeCoordinates.z / 2.0, 0.0), shapeCoordinates.xy + vec2(shapeCoordinates.z, shapeCoordinates.w / 2.0), shapeCoordinates.xy + shapeCoordinates.zw / 2.0)) { + returnMe = 1.0; + } + } + + return returnMe; +} + + + +void main() { + vec4 srcPixel = color; + vec2 centerPt = center * RENDERSIZE; + vec2 tmpVec = RENDERSIZE * vec2(shapeWidth,shapeHeight) / 2.0; + vec4 patternRect = vec4(vec2(centerPt - tmpVec),tmpVec * 2.0); + vec2 thisPoint = RENDERSIZE * isf_FragNormCoord; + + if ((thisPoint.x >= patternRect.x) && (thisPoint.x <= patternRect.x + abs(patternRect.z))) { + patternRect.z = patternRect.z / float(horizontalRepeat); + patternRect.x = patternRect.x + abs(patternRect.z) * floor((thisPoint.x - patternRect.x) / abs(patternRect.z)); + } + else { + patternRect.z = patternRect.z / float(horizontalRepeat); + } + + if ((thisPoint.y >= patternRect.y) && (thisPoint.y <= patternRect.y + abs(patternRect.w))) { + patternRect.w = patternRect.w / float(verticalRepeat); + patternRect.y = patternRect.y + abs(patternRect.w) * floor((thisPoint.y - patternRect.y) / abs(patternRect.w)); + } + else { + patternRect.w = patternRect.w / float(verticalRepeat); + } + + float luminance = isPointInShape(thisPoint.xy, maskShapeMode, patternRect); + + if (invertMask) + luminance = 1.0 - luminance; + + srcPixel = color * luminance; + + gl_FragColor = srcPixel; +} + diff --git a/ISF/Bloom.fs b/ISF/Bloom.fs new file mode 100644 index 0000000..d8c61b3 --- /dev/null +++ b/ISF/Bloom.fs @@ -0,0 +1,130 @@ +/*{ + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Stylize", + "Blur" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "blurAmount", + "TYPE": "float", + "MIN": 0.0, + "MAX": 12.0, + "DEFAULT": 12.0 + }, + { + "NAME": "intensity", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.0 + } + ], + "PASSES": [ + { + "TARGET": "halfSizeBaseRender", + "WIDTH": "floor($WIDTH/2.0)", + "HEIGHT": "floor($HEIGHT/2.0)", + "DESCRIPTION": "Pass 0" + }, + { + "TARGET": "quarterSizeBaseRender", + "WIDTH": "floor($WIDTH/4.0)", + "HEIGHT": "floor($HEIGHT/4.0)", + "DESCRIPTION": "Pass 1" + }, + { + "TARGET": "eighthSizeBaseRender", + "WIDTH": "floor($WIDTH/8.0)", + "HEIGHT": "floor($HEIGHT/8.0)", + "DESCRIPTION": "Pass 2" + }, + { + "TARGET": "quarterGaussA", + "WIDTH": "floor($WIDTH/4.0)", + "HEIGHT": "floor($HEIGHT/4.0)", + "DESCRIPTION": "Pass 3" + }, + { + "TARGET": "quarterGaussB", + "WIDTH": "floor($WIDTH/4.0)", + "HEIGHT": "floor($HEIGHT/4.0)", + "DESCRIPTION": "Pass 4" + }, + { + "TARGET": "fullGaussA", + "DESCRIPTION": "Pass 5" + }, + { + "TARGET": "fullGaussB", + "DESCRIPTION": "Pass 6" + } + ] +}*/ + + +varying vec2 texOffsets[5]; + + +void main() { + int blurLevel = int(floor(blurAmount/6.0)); + float blurLevelModulus = mod(blurAmount, 6.0); + // first three passes are just copying the input image into the buffer at varying sizes + if (PASSINDEX==0) { + gl_FragColor = IMG_NORM_PIXEL(inputImage, isf_FragNormCoord); + } + else if (PASSINDEX==1) { + gl_FragColor = IMG_NORM_PIXEL(halfSizeBaseRender, isf_FragNormCoord); + } + else if (PASSINDEX==2) { + gl_FragColor = IMG_NORM_PIXEL(quarterSizeBaseRender, isf_FragNormCoord); + } + // start reading from the previous stage- each two passes completes a gaussian blur, then + // we increase the resolution & blur (the lower-res blurred image from the previous pass) again... + else if (PASSINDEX == 3) { + vec4 sample0 = IMG_NORM_PIXEL(eighthSizeBaseRender,texOffsets[0]); + vec4 sample1 = IMG_NORM_PIXEL(eighthSizeBaseRender,texOffsets[1]); + vec4 sample2 = IMG_NORM_PIXEL(eighthSizeBaseRender,texOffsets[2]); + vec4 sample3 = IMG_NORM_PIXEL(eighthSizeBaseRender,texOffsets[3]); + vec4 sample4 = IMG_NORM_PIXEL(eighthSizeBaseRender,texOffsets[4]); + //gl_FragColor = vec4((sample0 + sample1 + sample2).rgb / (3.0), 1.0); + //gl_FragColor = vec4((sample0 + sample1 + sample2 + sample3 + sample4).rgb / (5.0), 1.0); + gl_FragColor = vec4((sample0 + sample1 + sample2 + sample3 + sample4).rgba / (5.0)); + } + else if (PASSINDEX == 4) { + vec4 sample0 = IMG_NORM_PIXEL(quarterGaussA,texOffsets[0]); + vec4 sample1 = IMG_NORM_PIXEL(quarterGaussA,texOffsets[1]); + vec4 sample2 = IMG_NORM_PIXEL(quarterGaussA,texOffsets[2]); + vec4 sample3 = IMG_NORM_PIXEL(quarterGaussA,texOffsets[3]); + vec4 sample4 = IMG_NORM_PIXEL(quarterGaussA,texOffsets[4]); + //gl_FragColor = vec4((sample0 + sample1 + sample2).rgb / (3.0), 1.0); + //gl_FragColor = vec4((sample0 + sample1 + sample2 + sample3 + sample4).rgb / (5.0), 1.0); + gl_FragColor = vec4((sample0 + sample1 + sample2 + sample3 + sample4).rgba / (5.0)); + } + // ...writes into the full-size + else if (PASSINDEX == 5) { + vec4 sample0 = IMG_NORM_PIXEL(quarterGaussB,texOffsets[0]); + vec4 sample1 = IMG_NORM_PIXEL(quarterGaussB,texOffsets[1]); + vec4 sample2 = IMG_NORM_PIXEL(quarterGaussB,texOffsets[2]); + //gl_FragColor = vec4((sample0 + sample1 + sample2).rgb / (3.0), 1.0); + gl_FragColor = vec4((sample0 + sample1 + sample2).rgba / (3.0)); + } + else if (PASSINDEX == 6) { + // this is the last pass- calculate the blurred image as i have in previous passes, then mix it in with the full-size input image using the blur amount so i get a smooth transition into the blur at low blur levels + vec4 sample0 = IMG_NORM_PIXEL(fullGaussA,texOffsets[0]); + vec4 sample1 = IMG_NORM_PIXEL(fullGaussA,texOffsets[1]); + vec4 sample2 = IMG_NORM_PIXEL(fullGaussA,texOffsets[2]); + //vec4 blurredImg = vec4((sample0 + sample1 + sample2).rgb / (3.0), 1.0); + vec4 blurredImg = vec4((sample0 + sample1 + sample2).rgba / (4.0)); + vec4 originalImg = IMG_NORM_PIXEL(inputImage,isf_FragNormCoord); + if (blurLevel == 0) + blurredImg = mix(originalImg, blurredImg, (blurLevelModulus/6.0)); + + gl_FragColor = max(mix(originalImg,blurredImg*1.2,intensity), originalImg); + } +} \ No newline at end of file diff --git a/ISF/Bloom.vs b/ISF/Bloom.vs new file mode 100644 index 0000000..b775ebf --- /dev/null +++ b/ISF/Bloom.vs @@ -0,0 +1,66 @@ +varying vec2 texOffsets[5]; + +void main(void) { + // load the main shader stuff + isf_vertShaderInit(); + + + int blurLevel = int(floor(blurAmount/6.0)); + float blurLevelModulus = mod(blurAmount, 6.0); + float blurRadius = 0.0; + float blurRadiusInPixels = 0.0; + // first three passes are just drawing the texture- do nothing + + // the next four passes do gaussion blurs on the various levels + if (PASSINDEX==3 || PASSINDEX==5) { + float pixelWidth = 1.0/RENDERSIZE.x; + // pass 3 is sampling 1/12, but writing to 1/4 + if (PASSINDEX==3) { + if (blurLevel==1) + blurRadius = blurLevelModulus/1.5; + else if (blurLevel>1) + blurRadius = 4.0; + } + // pass 5 is sampling 1/4 and writing to full-size + else if (PASSINDEX==5) { + if (blurLevel==0) + blurRadius = blurLevelModulus; + else if (blurLevel>0) + blurRadius = 6.0; + } + blurRadiusInPixels = pixelWidth * blurRadius; + texOffsets[0] = isf_FragNormCoord; + texOffsets[1] = (blurRadius==0.0) ? isf_FragNormCoord : clamp(vec2(isf_FragNormCoord[0]-blurRadiusInPixels, isf_FragNormCoord[1]),0.0,1.0); + texOffsets[2] = (blurRadius==0.0) ? isf_FragNormCoord : clamp(vec2(isf_FragNormCoord[0]+blurRadiusInPixels, isf_FragNormCoord[1]),0.0,1.0); + if (PASSINDEX==3) { + texOffsets[3] = (blurRadius==0.0) ? isf_FragNormCoord : clamp(vec2(isf_FragNormCoord[0]-(2.0*blurRadiusInPixels), isf_FragNormCoord[1]),0.0,1.0); + texOffsets[4] = (blurRadius==0.0) ? isf_FragNormCoord : clamp(vec2(isf_FragNormCoord[0]+(2.0*blurRadiusInPixels), isf_FragNormCoord[1]),0.0,1.0); + } + } + else if (PASSINDEX==4 || PASSINDEX==6) { + float pixelHeight = 1.0/RENDERSIZE.y; + // pass 4 is sampling 1/12, but writing to 1/4 + if (PASSINDEX==4) { + if (blurLevel==1) + blurRadius = blurLevelModulus/1.5; + else if (blurLevel>1) + blurRadius = 4.0; + } + // pass 6 is sampling 1/4 and writing to full-size + else if (PASSINDEX==6) { + if (blurLevel==0) + blurRadius = blurLevelModulus; + else if (blurLevel>0) + blurRadius = 6.0; + } + blurRadiusInPixels = pixelHeight * blurRadius; + texOffsets[0] = isf_FragNormCoord; + texOffsets[1] = (blurRadius==0.0) ? isf_FragNormCoord : clamp(vec2(isf_FragNormCoord[0], isf_FragNormCoord[1]-blurRadiusInPixels),0.0,1.0); + texOffsets[2] = (blurRadius==0.0) ? isf_FragNormCoord : clamp(vec2(isf_FragNormCoord[0], isf_FragNormCoord[1]+blurRadiusInPixels),0.0,1.0); + if (PASSINDEX==4) { + texOffsets[3] = (blurRadius==0.0) ? isf_FragNormCoord : clamp(vec2(isf_FragNormCoord[0], isf_FragNormCoord[1]-(2.0*blurRadiusInPixels)),0.0,1.0); + texOffsets[4] = (blurRadius==0.0) ? isf_FragNormCoord : clamp(vec2(isf_FragNormCoord[0], isf_FragNormCoord[1]+(2.0*blurRadiusInPixels)),0.0,1.0); + } + } + +} diff --git a/ISF/Boxinator.fs b/ISF/Boxinator.fs new file mode 100644 index 0000000..32f9d0c --- /dev/null +++ b/ISF/Boxinator.fs @@ -0,0 +1,146 @@ +/*{ + "CREDIT": "by mojovideotech", + "ISFVSN": "2", + "CATEGORIES": [ + "Stylize" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "rate", + "TYPE": "float", + "DEFAULT": 2.5, + "MIN": 0.0, + "MAX": 10.0 + }, + { + "NAME": "edge", + "TYPE": "float", + "DEFAULT": 0.001, + "MIN": 0.0, + "MAX": 0.01 + }, + { + "NAME": "blend", + "TYPE": "float", + "DEFAULT": 0.95, + "MIN": -1.0, + "MAX": 1.0 + }, + { + "NAME": "randomize", + "TYPE": "float", + "DEFAULT": 0.5, + "MIN": 0.0, + "MAX": 1.0 + }, + { + "NAME": "gamma", + "TYPE": "float", + "DEFAULT": -0.3, + "MIN": -0.5, + "MAX": 0.2 + }, + { + "NAME": "grid", + "TYPE": "point2D", + "DEFAULT": [ 64.0, 36.0 ], + "MIN": [ 1.5, 1.5 ], + "MAX": [ 900.0, 600.0 ] + } + ] +}*/ + +//////////////////////////////////////////////////////////////////// +// Boxinator by mojovideotech +// +// License Creative Commons Attribution-NonCommercial-ShareAlike 3.0 +//////////////////////////////////////////////////////////////////// + + +#ifdef GL_ES +precision mediump float; +#endif + + +//------------------------------------------------------------------ +// simplex noise function +// by : Ian McEwan, Ashima Arts +// © 2011 Ashima Arts, MIT License + +vec4 permute(vec4 x) { return mod(((x*34.0)+1.0)*x, 289.0); } + +vec4 taylorInvSqrt(vec4 r) { return 1.79284291400159 - 0.85373472095314 * r; } + +float snoise(vec3 v) { + const vec2 C = vec2(1.0/6.0, 1.0/3.0) ; + const vec4 D = vec4(0.0, 0.5, 1.0, 2.0); + vec3 i = floor(v + dot(v, C.yyy) ); + vec3 x0 = v - i + dot(i, C.xxx) ; + vec3 g = step(x0.yzx, x0.xyz); + vec3 l = 1.0 - g; + vec3 i1 = min( g.xyz, l.zxy ); + vec3 i2 = max( g.xyz, l.zxy ); + vec3 x1 = x0 - i1 + 1.0 * C.xxx; + vec3 x2 = x0 - i2 + 2.0 * C.xxx; + vec3 x3 = x0 - 1. + 3.0 * C.xxx; + i = mod(i, 289.0 ); + vec4 p = permute( permute( permute( + i.z + vec4(0.0, i1.z, i2.z, 1.0 )) + + i.y + vec4(0.0, i1.y, i2.y, 1.0 )) + + i.x + vec4(0.0, i1.x, i2.x, 1.0 )); + float n_ = 1.0/7.0; // N=7 + vec3 ns = n_ * D.wyz - D.xzx; + vec4 j = p - 49.0 * floor(p * ns.z *ns.z); // mod(p,N*N) + vec4 x_ = floor(j * ns.z); + vec4 y_ = floor(j - 7.0 * x_ ); // mod(j,N) + vec4 x = x_ *ns.x + ns.yyyy; + vec4 y = y_ *ns.x + ns.yyyy; + vec4 h = 1.0 - abs(x) - abs(y); + vec4 b0 = vec4( x.xy, y.xy ); + vec4 b1 = vec4( x.zw, y.zw ); + vec4 s0 = floor(b0)*2.0 + 1.0; + vec4 s1 = floor(b1)*2.0 + 1.0; + vec4 sh = -step(h, vec4(0.0)); + vec4 a0 = b0.xzyw + s0.xzyw*sh.xxyy ; + vec4 a1 = b1.xzyw + s1.xzyw*sh.zzww ; + vec3 p0 = vec3(a0.xy,h.x); + vec3 p1 = vec3(a0.zw,h.y); + vec3 p2 = vec3(a1.xy,h.z); + vec3 p3 = vec3(a1.zw,h.w); + vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3))); + p0 *= norm.x; + p1 *= norm.y; + p2 *= norm.z; + p3 *= norm.w; + vec4 m = max(0.6 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0); + m = m * m; + return 42.0 * dot( m*m, vec4( dot(p0,x0), dot(p1,x1), + dot(p2,x2), dot(p3,x3) ) ); +} +//------------------------------------------------------------------ + +float hash(float h) { return fract(sin(h) * 43758.5453123); } + +vec2 tile(vec2 cell, vec2 size) { return fract(cell*size); } + +float box(vec2 a, vec2 b){ vec2 o = step(b,a); return o.x*o.y; } + +void main(void){ + float T = TIME*rate; + vec2 uv = gl_FragCoord.xy/RENDERSIZE.xy; + vec2 g = floor(grid.xy); + float C = g.x*g.y ; + float I = 1.0 + floor(uv.x * g.x) + g.y * floor(uv.y * g.y) + g.x; + vec2 st = tile(uv, g); + float S = I / C * box(st, vec2(edge*g.xy)); + S = mix(S,hash(S),randomize); + vec3 color = vec3(S*T); + float n = snoise(color+IMG_NORM_PIXEL(inputImage, uv.xy).xyz*blend); + + gl_FragColor = sqrt(max(vec4(vec3(n, n, n ),1.0)+IMG_NORM_PIXEL(inputImage, uv.xy),0.0)+gamma); +} + diff --git a/ISF/Brick Pattern.fs b/ISF/Brick Pattern.fs new file mode 100644 index 0000000..b14575c --- /dev/null +++ b/ISF/Brick Pattern.fs @@ -0,0 +1,103 @@ +/* +{ + "CATEGORIES" : [ + "Generator", + "Duotone" + ], + "DESCRIPTION" : "Generates a basic brick pattern", + "ISFVSN" : "2", + "INPUTS" : [ + { + "NAME" : "brickSize", + "TYPE" : "float", + "MAX" : 1, + "DEFAULT" : 0.2, + "MIN" : 0 + }, + { + "NAME" : "fillSize", + "TYPE" : "float", + "MAX" : 1, + "DEFAULT" : 0.9, + "MIN" : 0 + }, + { + "NAME" : "brickOffset", + "TYPE" : "point2D", + "MAX" : [ + 1, + 1 + ], + "DEFAULT" : [ + 0, + 0 + ], + "MIN" : [ + 0, + 0 + ] + }, + { + "NAME" : "fillColor", + "TYPE" : "color", + "DEFAULT" : [ + 0, + 0, + 0, + 0 + ] + }, + { + "NAME" : "brickColor", + "TYPE" : "color", + "DEFAULT" : [ + 1, + 1, + 1, + 1 + ] + } + ], + "CREDIT" : "patriciogv" +} +*/ + +// Based on Brick example from https://thebookofshaders.com/09/ +// Author @patriciogv ( patriciogonzalezvivo.com ) - 2015 + + + +vec2 brickTile(vec2 _st, float _zoom){ + _st *= _zoom; + + // Here is where the offset is happening + _st.x += step(1., mod(_st.y,2.0)) * 0.5; + + return fract(_st); +} + +float box(vec2 _st, vec2 _size){ + _size = vec2(0.5)-_size*0.5; + vec2 uv = smoothstep(_size,_size+vec2(1e-4),_st); + uv *= smoothstep(_size,_size+vec2(1e-4),vec2(1.0)-_st); + return uv.x*uv.y; +} + +void main(void){ + vec2 st = isf_FragNormCoord; + vec4 color = fillColor; + float brickCount = (brickSize == 0.0) ? max(RENDERSIZE.x,RENDERSIZE.y) : 1.0 / brickSize; + // Apply the offset + st += brickOffset; + // Apply the brick tiling + st = brickTile(st,brickCount); + + float val = box(st,vec2(fillSize)); + color = mix(fillColor,brickColor,val); + + // Uncomment to see the space coordinates + //color.rgb = vec3(st,0.0); + + gl_FragColor = color; +} + diff --git a/ISF/Bright.fs b/ISF/Bright.fs new file mode 100644 index 0000000..c9d3e03 --- /dev/null +++ b/ISF/Bright.fs @@ -0,0 +1,24 @@ +/*{ + "CREDIT": "by zoidberg", + "ISFVSN": "2", + "CATEGORIES": [ + "Color Adjustment" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "bright", + "TYPE": "float", + "MIN": -1.0, + "MAX": 1.0, + "DEFAULT": 0.0 + } + ] +}*/ + +void main() { + gl_FragColor = clamp(IMG_THIS_PIXEL(inputImage) + vec4(bright,bright,bright,0.0), 0.0, 1.0); +} \ No newline at end of file diff --git a/ISF/Bump Distortion.fs b/ISF/Bump Distortion.fs new file mode 100644 index 0000000..60bf07a --- /dev/null +++ b/ISF/Bump Distortion.fs @@ -0,0 +1,80 @@ +/*{ + "CREDIT": "by carter rosenberg", + "ISFVSN": "2", + "CATEGORIES": [ + "Distortion Effect" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "level", + "TYPE": "float", + "MIN": -1.0, + "MAX": 1.0, + "DEFAULT": 0.5 + }, + { + "NAME": "radius", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.25 + }, + { + "NAME": "center", + "TYPE": "point2D", + "DEFAULT": [ + 0.5, + 0.5 + ] + } + ] +}*/ + +const float pi = 3.14159265359; + +#ifndef GL_ES +float distance (vec2 center, vec2 pt) +{ + float tmp = pow(center.x-pt.x,2.0)+pow(center.y-pt.y,2.0); + return pow(tmp,0.5); +} +#endif + +void main() { + vec2 uv = vec2(isf_FragNormCoord[0],isf_FragNormCoord[1]); + vec2 texSize = RENDERSIZE; + vec2 tc = uv * texSize; + vec2 modifiedCenter = center; + float r = distance(modifiedCenter, tc); + float a = atan ((tc.y-modifiedCenter.y),(tc.x-modifiedCenter.x)); + float radius_sized = radius * length(RENDERSIZE); + + tc -= modifiedCenter; + + if (r < radius_sized) { + float percent = 1.0-(radius_sized - r) / radius_sized; + if (level>=0.0) { + percent = percent * percent; + tc.x = r*pow(percent,level) * cos(a); + tc.y = r*pow(percent,level) * sin(a); + } + else { + float adjustedLevel = level/2.0; + tc.x = r*pow(percent,adjustedLevel) * cos(a); + tc.y = r*pow(percent,adjustedLevel) * sin(a); + } + } + tc += modifiedCenter; + vec2 loc = tc / texSize; + + if ((loc.x < 0.0)||(loc.y < 0.0)||(loc.x > 1.0)||(loc.y > 1.0)) { + gl_FragColor = vec4(0.0); + } + else { + gl_FragColor = IMG_NORM_PIXEL(inputImage, loc); + } +} diff --git a/ISF/CMYK Halftone-Lookaround.fs b/ISF/CMYK Halftone-Lookaround.fs new file mode 100644 index 0000000..c59c158 --- /dev/null +++ b/ISF/CMYK Halftone-Lookaround.fs @@ -0,0 +1,136 @@ +/*{ + "CREDIT": "by zoidberg", + "ISFVSN": "2", + "CATEGORIES": [ + "Halftone Effect" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "gridSize", + "TYPE": "float", + "MIN": 1.0, + "MAX": 256.0, + "DEFAULT": 45.0 + }, + { + "NAME": "smoothing", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.15 + } + ] +}*/ + +vec4 gridRot = vec4(15.0, 45.0, 0.0, 75.0); +//vec4 gridRot = vec4(15.0, 75.0, 0.0, 45.0); +//vec4 gridRot = vec4(0.0, 0.0, 0.0, 0.0); + + + +// during calculation we find the closest dot to a frag, determine its size, and then determine the size of the four dots above/below/right/left of it. this array of offsets move "one left", "one up", "one right", and "one down"... +vec2 originOffsets[4]; + + + +vec4 RGBAtoCMYK(vec4 inColor) +{ + /* + vec4 cmyk; + cmyk.xyz = 1.0 - inColor.xyz; + cmyk.w = min(cmyk.x, min(cmyk.y, cmyk.z)); // Create K + cmyk.xyz -= cmyk.w; // Subtract K equivalent from CMY + return cmyk; + */ + vec4 ret; + ret.w = 1.0 - max(max(inColor.x, inColor.y), inColor.z); + ret.x = (1.0-inColor.x-ret.w)/(1.0-ret.w); + ret.y = (1.0-inColor.y-ret.w)/(1.0-ret.w); + ret.z = (1.0-inColor.z-ret.w)/(1.0-ret.w); + //ret.w = min(min(ret.x, ret.y), min(ret.z, ret.w)); + return ret; + +} +vec4 CMYKtoRGBA(vec4 inColor) +{ + vec4 ret; + ret.xyz = (1.0-inColor.xyz)*(1.0-inColor.w); + ret.w = 1.0; + return ret; +} + +void main() { + // a halftone is an overlapping series of grids of dots + // each grid of dots is rotated by a different amount + // the size of the dots determines the colors. the shape of the dot should never change (always be a dot with regular edges) + originOffsets[0] = vec2(-1.0, 0.0); + originOffsets[1] = vec2(0.0, 1.0); + originOffsets[2] = vec2(1.0, 0.0); + originOffsets[3] = vec2(0.0, -1.0); + + vec4 cmykAmounts = vec4(0.0); + int i; + int j; + // for each of the channels (i) of CMYK... + for (i=0; i<4; ++i) { + // figure out the rotation of the grid in radians + float rotRad = radians(gridRot[i]); + // the grids are rotated counter-clockwise- to find the nearest dot, take the fragment pixel loc, + // rotate it clockwise, and split by the grid to find the center of the dot. then rotate this + // coord counter-clockwise to yield the location of the center of the dot in pixel coords local to the render space + mat2 ccTrans = mat2(vec2(cos(rotRad), sin(rotRad)), vec2(-1.0*sin(rotRad), cos(rotRad))); + mat2 cTrans = mat2(vec2(cos(rotRad), -1.0*sin(rotRad)), vec2(sin(rotRad), cos(rotRad))); + + // find the location of the frag in the grid (prior to rotating it) + vec2 gridFragLoc = cTrans * gl_FragCoord.xy; + // find the center of the dot closest to the frag- there's no "round" in GLSL 1.2, so do a "floor" to find the dot to the bottom-left of the frag, then figure out if the frag would be in the top and right halves of that square to find the closest dot to the frag + vec2 gridOriginLoc = vec2(floor(gridFragLoc.x/gridSize), floor(gridFragLoc.y/gridSize)); + + vec2 tmpGridCoords = gridFragLoc/vec2(gridSize); + bool fragAtTopOfGrid = ((tmpGridCoords.y-floor(tmpGridCoords.y)) > (gridSize/2.0)) ? true : false; + bool fragAtRightOfGrid = ((tmpGridCoords.x-floor(tmpGridCoords.x)) > (gridSize/2.0)) ? true : false; + if (fragAtTopOfGrid) + gridOriginLoc.y = gridOriginLoc.y + 1.0; + if (fragAtRightOfGrid) + gridOriginLoc.x = gridOriginLoc.x + 1.0; + // ...at this point, "gridOriginLoc" contains the grid coords of the nearest dot to the fragment being rendered + // convert the location of the center of the dot from grid coords to pixel coords + vec2 gridDotLoc = vec2(gridOriginLoc.x*gridSize, gridOriginLoc.y*gridSize) + vec2(gridSize/2.0); + // rotate the pixel coords of the center of the dot so they become relative to the rendering space + vec2 renderDotLoc = ccTrans * gridDotLoc; + // get the color of the pixel of the input image under this dot (the color will ultimately determine the size of the dot) + vec4 renderDotImageColorRGB = IMG_PIXEL(inputImage, renderDotLoc); + // convert the color from RGB to CMYK + vec4 renderDotImageColorCMYK = RGBAtoCMYK(renderDotImageColorRGB); + + // the amount of this channel is taken from the same channel of the color of the pixel of the input image under this halftone dot + float imageChannelAmount = renderDotImageColorCMYK[i]; + // the size of the dot is determined by the value of the channel + float dotRadius = imageChannelAmount * (gridSize*1.50/2.0); + float fragDistanceToDotCenter = distance(gl_FragCoord.xy, renderDotLoc); + if (fragDistanceToDotCenter < dotRadius) { + cmykAmounts[i] += smoothstep(dotRadius, dotRadius-(dotRadius*smoothing), fragDistanceToDotCenter); + } + + // calcluate the size of the dots abov/below/to the left/right to see if they're overlapping + for (j=0; j<4; ++j) { + gridDotLoc = vec2((gridOriginLoc.x+originOffsets[j].x)*gridSize, (gridOriginLoc.y+originOffsets[j].y)*gridSize) + vec2(gridSize/2.0); + renderDotLoc = ccTrans * gridDotLoc; + renderDotImageColorRGB = IMG_PIXEL(inputImage, renderDotLoc); + renderDotImageColorCMYK = RGBAtoCMYK(renderDotImageColorRGB); + + imageChannelAmount = renderDotImageColorCMYK[i]; + dotRadius = imageChannelAmount * (gridSize*1.50/2.0); + fragDistanceToDotCenter = distance(gl_FragCoord.xy, renderDotLoc); + if (fragDistanceToDotCenter < dotRadius) { + cmykAmounts[i] += smoothstep(dotRadius, dotRadius-(dotRadius*smoothing), fragDistanceToDotCenter); + } + } + } + + gl_FragColor = CMYKtoRGBA(cmykAmounts); +} \ No newline at end of file diff --git a/ISF/CMYK Halftone.fs b/ISF/CMYK Halftone.fs new file mode 100644 index 0000000..c65faf0 --- /dev/null +++ b/ISF/CMYK Halftone.fs @@ -0,0 +1,85 @@ +/*{ + "CREDIT": "by zoidberg", + "ISFVSN": "2", + "CATEGORIES": [ + "Halftone Effect" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "gridSize", + "TYPE": "float", + "MIN": 1.0, + "MAX": 256.0, + "DEFAULT": 45.0 + }, + { + "NAME": "smoothing", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.15 + } + ] +}*/ + +const vec4 gridRot = vec4(15.0, 45.0, 0.0, 75.0); + + + + +vec4 RGBAtoCMYK(vec4 inColor) +{ + vec4 ret; + ret.w = 1.0 - max(max(inColor.x, inColor.y), inColor.z); + ret.x = (1.0-inColor.x-ret.w)/(1.0-ret.w); + ret.y = (1.0-inColor.y-ret.w)/(1.0-ret.w); + ret.z = (1.0-inColor.z-ret.w)/(1.0-ret.w); + return ret; +} +vec4 CMYKtoRGBA(vec4 inColor) +{ + vec4 ret; + ret.xyz = (1.0-inColor.xyz)*(1.0-inColor.w); + ret.w = 1.0; + return ret; +} + +void main() { + // a halftone is an overlapping series of grids of dots + // each grid of dots is rotated by a different amount + // the size of the dots determines the colors. the shape of the dot should never change (always be a dot with regular edges) + + vec4 cmykAmounts = vec4(0.0); + + // for each of the channels (i) of CMYK... + for (int i=0; i<4; ++i) { + // figure out the rotation of the grid in radians + float rotRad = radians(gridRot[i]); + // the grids are rotated counter-clockwise- to find the nearest dot, take the fragment pixel loc, + // rotate it clockwise, and split by the grid to find the center of the dot. then rotate this + // coord counter-clockwise to yield the location of the center of the dot in pixel coords local to the render space + mat2 ccTrans = mat2(vec2(cos(rotRad), sin(rotRad)), vec2(-1.0*sin(rotRad), cos(rotRad))); + mat2 cTrans = mat2(vec2(cos(rotRad), -1.0*sin(rotRad)), vec2(sin(rotRad), cos(rotRad))); + + // render loc -> grid loc -> grid dot loc -> grid dot loc in render coords -> pixel color under grid dot loc + vec2 gridFragLoc = cTrans * gl_FragCoord.xy; + vec2 gridDotLoc = vec2(floor(gridFragLoc.x/gridSize)*gridSize, floor(gridFragLoc.y/gridSize)*gridSize); + gridDotLoc = gridDotLoc + vec2(gridSize/2.0); + vec2 renderDotLoc = ccTrans * gridDotLoc; + vec4 renderDotImageColorRGB = IMG_PIXEL(inputImage, renderDotLoc); + vec4 renderDotImageColorCMYK = RGBAtoCMYK(renderDotImageColorRGB); + + float channelAmount = renderDotImageColorCMYK[i]; + float dotRadius = channelAmount * (gridSize/2.0); + float fragDistanceToGridCenter = distance(gl_FragCoord.xy, renderDotLoc); + // the amount of the channel depends on the distance to the center of the grid, the size of the dot, and smoothing + float smoothDist = smoothing * (gridSize/6.0); + cmykAmounts[i] += smoothstep(dotRadius, dotRadius-(dotRadius*smoothing), fragDistanceToGridCenter); + } + + gl_FragColor = CMYKtoRGBA(cmykAmounts); +} \ No newline at end of file diff --git a/ISF/Channel Slide.fs b/ISF/Channel Slide.fs new file mode 100644 index 0000000..a26fac7 --- /dev/null +++ b/ISF/Channel Slide.fs @@ -0,0 +1,50 @@ +/*{ + "CREDIT": "by zoidberg", + "ISFVSN": "2", + "CATEGORIES": [ + "Color Effect" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "slideAmt", + "LABEL": "slide amount", + "TYPE": "color", + "DEFAULT": [ + 0.0, + 0.0, + 0.0, + 0.0 + ] + }, + { + "NAME": "reflection", + "TYPE": "bool", + "DEFAULT": 0.0 + } + ] +}*/ + +void main() { + vec4 srcPixel = IMG_THIS_PIXEL(inputImage); + if (reflection == true) { + vec4 outPixel; + outPixel.rgb = srcPixel.rgb - slideAmt.rgb; + outPixel.a = srcPixel.a + slideAmt.a; // alpha behaves the same in both modes (just easier to work with) + gl_FragColor.x = (outPixel.x<0.0) ? outPixel.x+1.0 : outPixel.x; + gl_FragColor.y = (outPixel.y<0.0) ? outPixel.y+1.0 : outPixel.y; + gl_FragColor.z = (outPixel.z<0.0) ? outPixel.z+1.0 : outPixel.z; + //gl_FragColor.a = (outPixel.a<0.0) ? outPixel.a+1.0 : outPixel.a; + gl_FragColor.a = (outPixel.a>1.0) ? outPixel.a-1.0 : outPixel.a; + } + else { + vec4 outPixel = srcPixel+slideAmt; + gl_FragColor.x = (outPixel.x>1.0) ? outPixel.x-1.0 : outPixel.x; + gl_FragColor.y = (outPixel.y>1.0) ? outPixel.y-1.0 : outPixel.y; + gl_FragColor.z = (outPixel.z>1.0) ? outPixel.z-1.0 : outPixel.z; + gl_FragColor.a = (outPixel.a>1.0) ? outPixel.a-1.0 : outPixel.a; + } +} diff --git a/ISF/Checkerboard.fs b/ISF/Checkerboard.fs new file mode 100644 index 0000000..c90c5c4 --- /dev/null +++ b/ISF/Checkerboard.fs @@ -0,0 +1,68 @@ +/*{ + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Generator" + ], + "INPUTS": [ + { + "NAME": "width", + "TYPE": "float", + "DEFAULT": 0.25 + }, + { + "NAME": "offset", + "TYPE": "point2D", + "DEFAULT": [ + 0, + 0 + ] + }, + { + "NAME": "color1", + "TYPE": "color", + "DEFAULT": [ + 1.0, + 1.0, + 1.0, + 1.0 + ] + }, + { + "NAME": "color2", + "TYPE": "color", + "DEFAULT": [ + 0.0, + 0.0, + 0.0, + 1.0 + ] + } + ] +}*/ + + + +void main() { + // determine if we are on an even or odd line + // math goes like.. + // mod(((coord+offset) / width),2) + + + vec4 out_color = color2; + vec2 coord = isf_FragNormCoord * RENDERSIZE; + vec2 shift = offset; + float size = width * RENDERSIZE.x; + + if (size == 0.0) { + out_color = color1; + } + else if ((mod(((coord.x+shift.x) / size),2.0) < 1.0)&&(mod(((coord.y+shift.y) / size),2.0) > 1.0)) { + out_color = color1; + } + else if ((mod(((coord.x+shift.x) / size),2.0) > 1.0)&&(mod(((coord.y+shift.y) / size),2.0) < 1.0)) { + out_color = color1; + } + + gl_FragColor = out_color; +} \ No newline at end of file diff --git a/ISF/Chroma Desaturation Mask.fs b/ISF/Chroma Desaturation Mask.fs new file mode 100755 index 0000000..7f61e7c --- /dev/null +++ b/ISF/Chroma Desaturation Mask.fs @@ -0,0 +1,350 @@ +/*{ + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Color Effect", "Masking" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "LABEL": "Master Threshold", + "NAME": "threshold", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.5 + }, + { + "LABEL": "Key Color", + "NAME": "mask_color", + "TYPE": "color", + "DEFAULT": [ + 0.24, + 0.77, + 0.38, + 1.0 + ] + }, + { + "LABEL": "HUE- Tol.", + "NAME": "hueTol", + "TYPE": "float", + "MIN": 0.0, + "MAX": 0.25, + "DEFAULT": 0.0 + }, + { + "LABEL": "HUE- Min. Bracket", + "NAME": "hueMinBracket", + "TYPE": "float", + "MIN": 0.0, + "MAX": 0.5, + "DEFAULT": 0.25 + }, + { + "LABEL": "HUE- Max Bracket", + "NAME": "hueMaxBracket", + "TYPE": "float", + "MIN": 0.0, + "MAX": 0.5, + "DEFAULT": 0.25 + }, + { + "LABEL": "SAT- Tol.", + "NAME": "satTol", + "TYPE": "float", + "MIN": 0.0, + "MAX": 0.5, + "DEFAULT": 0.0 + }, + { + "LABEL": "SAT- Min. Bracket", + "NAME": "satMinBracket", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.5 + }, + { + "LABEL": "SAT- Max Bracket", + "NAME": "satMaxBracket", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.5 + }, + { + "LABEL": "VAL- Tol.", + "NAME": "valTol", + "TYPE": "float", + "MIN": 0.0, + "MAX": 0.5, + "DEFAULT": 0.0 + }, + { + "LABEL": "VAL- Min. Bracket", + "NAME": "valMinBracket", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.5 + }, + { + "LABEL": "VAL- Max Bracket", + "NAME": "valMaxBracket", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.5 + }, + { + "LABEL": "Dilate", + "NAME": "dilate", + "TYPE": "float", + "MIN": 0.0, + "MAX": 6.0, + "DEFAULT": 0.0 + }, + { + "LABEL": "Blur", + "NAME": "blur", + "TYPE": "float", + "MIN": 0.0, + "MAX": 6.0, + "DEFAULT": 0.0 + } + ], + "PASSES": [ + { + "TARGET": "alphaPass" + }, + { + "TARGET": "horizDilate" + }, + { + "TARGET": "vertDilate" + }, + { + "TARGET": "horizBlur" + }, + { + "TARGET": "vertBlur" + } + ] +}*/ + + + +vec3 rgb2hsv(vec3 c); +vec3 hsv2rgb(vec3 c); + +void main() { + // generally speaking, sample a bunch of pixels, for each sample convert color val to HSV, if luma is greater than max luma, that's the new color + vec2 tmpCoord; + float maxAlpha; + vec4 sampleColorRGB; + vec4 src_rgb; + + if (PASSINDEX==0) { + // the goal is to calculate a new float value for the alpha channel, and/or desaturate the color, if this pixel is "close" to the mask color + // get the src pixel's color (as RGB), convert to HSV values + src_rgb = IMG_PIXEL(inputImage, gl_FragCoord.xy); + vec3 src_hsl = rgb2hsv(src_rgb.rgb); + // convert the passed color (which is RGB) to HSV values + vec3 color_hsl = rgb2hsv(mask_color.rgb); + + +/* -minBracket -tolerance color_hsl +tolerance +maxBracket + | | | | | val being examined + ---------------------------------------------------------------- + | | | alpha + 1.0 0.0 1.0 */ + + + float hueAlpha; + float satAlpha; + float valAlpha; + // use a 'for' loop to generate the hue/sat/val alpha values + int i = 0; + float source; + float color; + float tolerance; + vec2 bracket; + float alpha; + float minVal; + float maxVal; + for (i=0; i<3; ++i) { + source = src_hsl[i]; + color = color_hsl[i]; + if (i==0) { + tolerance = hueTol; + bracket = vec2(hueMinBracket, hueMaxBracket); + } + else if (i==1) { + tolerance = satTol; + bracket = vec2(satMinBracket, satMaxBracket); + } + else if (i==2) { + tolerance = valTol; + bracket = vec2(valMinBracket, valMaxBracket); + } + + // if the source sat is < the mask color sat + if (source < color) { + // the minVal is the bracket and tolerance, the maxVal is the mask color + minVal = color - tolerance - bracket.x; + maxVal = color; + // as i go from minVal to maxVal, the alpha goes from 1 to 0 + alpha = 1.0 - smoothstep(minVal, maxVal, source); + } + // else if the source sat is > the mask color sat + else if (source > color) { + // the minVal is the mask color, the maxVal is the tolerance and bracket + minVal = color; + maxVal = color + tolerance + bracket.y; + // as i go from minVal to maxVal, the alpha goes from 0 to 1 + alpha = smoothstep(minVal, maxVal, source); + } + // else the source sat == the mask color sat, the alpha should be 0 + else + alpha = 0.0; + + if (i==0) { + hueAlpha = alpha; + } + else if (i==1) { + satAlpha = alpha; + } + else if (i==2) { + valAlpha = alpha; + } + } + + + // calculate the alpha i'll be applying + src_rgb.a = sqrt(max(hueAlpha,max(satAlpha, valAlpha))); + + // desaturate the color if appropriate, use the desaturated color + if (hueAlpha < 1.0) { + //src_hsl.y = 0.0; + src_hsl.y = mix(0.0, src_hsl.y, hueAlpha); + src_rgb.rgb = hsv2rgb(src_hsl.xyz); + } + + + gl_FragColor = src_rgb; + //gl_FragColor = vec4(src_rgb.a, src_rgb.a, src_rgb.a, 1.0); + } + + else if (PASSINDEX==1) { + // 'dilate' samples on either side + the source pixel = 2*dilate+1 total samples + for (float i=0.; i<=float(int(dilate)); ++i) { + tmpCoord = vec2(clamp(gl_FragCoord.x+i,0.,RENDERSIZE.x), gl_FragCoord.y); + sampleColorRGB = IMG_PIXEL(alphaPass, tmpCoord); + // if this is the first sample for this fragment, don't bother comparing- just set the max luma stuff + if (i == 0.) { + maxAlpha = sampleColorRGB.a; + src_rgb = sampleColorRGB; + } + // else this isn't the first sample... + else { + // compare, determine if it's the max luma + if (sampleColorRGB.a < maxAlpha) { + maxAlpha = sampleColorRGB.a; + } + // do another sample for the negative coordinate + tmpCoord = vec2(clamp(gl_FragCoord.x-i,0.,RENDERSIZE.x), gl_FragCoord.y); + sampleColorRGB = IMG_PIXEL(alphaPass, tmpCoord); + if (sampleColorRGB.a < maxAlpha) { + maxAlpha = sampleColorRGB.a; + } + } + } + gl_FragColor = vec4(src_rgb.rgb, maxAlpha); + } + else if (PASSINDEX==2) { + // 'dilate' samples up and down + the source pixel = 2*dilate+1 total samples + for (float i=0.; i<=float(int(dilate)); ++i) { + tmpCoord = vec2(gl_FragCoord.x, clamp(gl_FragCoord.y+i,0.,RENDERSIZE.y)); + sampleColorRGB = IMG_PIXEL(horizDilate, tmpCoord); + // if this is the first sample for this fragment, don't bother comparing- just set the max luma stuff + if (i == 0.) { + maxAlpha = sampleColorRGB.a; + src_rgb = sampleColorRGB; + } + // else this isn't the first sample... + else { + // compare, determine if it's the max luma + if (sampleColorRGB.a < maxAlpha) { + maxAlpha = sampleColorRGB.a; + } + // do another sample for the negative coordinate + tmpCoord = vec2(gl_FragCoord.x, clamp(gl_FragCoord.y-i,0.,RENDERSIZE.y)); + sampleColorRGB = IMG_PIXEL(horizDilate, tmpCoord); + if (sampleColorRGB.a < maxAlpha) { + maxAlpha = sampleColorRGB.a; + } + } + } + gl_FragColor = vec4(src_rgb.rgb, maxAlpha); + } + else if (PASSINDEX==3) { + float tmpRadius = float(int(blur)); + vec4 tmpColor; + vec4 srcColor; + float totalAlpha = 0.0; + for (float i=-1.*tmpRadius; i<=tmpRadius; ++i) { + tmpColor = IMG_PIXEL(vertDilate, gl_FragCoord.xy+vec2(i,0.0)); + totalAlpha += tmpColor.a; + if (i==0.0) + srcColor = tmpColor; + } + totalAlpha /= ((tmpRadius*2.)+1.); + gl_FragColor = vec4(srcColor.r, srcColor.g, srcColor.b, totalAlpha); + } + else if (PASSINDEX==4) { + float tmpRadius = float(int(blur)); + vec4 tmpColor; + vec4 srcColor; + float totalAlpha = 0.0; + for (float i=-1.*tmpRadius; i<=tmpRadius; ++i) { + tmpColor = IMG_PIXEL(horizBlur, gl_FragCoord.xy+vec2(0.0,i)); + totalAlpha += tmpColor.a; + if (i==0.0) + srcColor = tmpColor; + } + totalAlpha /= ((tmpRadius*2.)+1.); + + if (totalAlpha > threshold) { + srcColor = IMG_PIXEL(inputImage,gl_FragCoord.xy); + float gray = (srcColor.r + srcColor.g + srcColor.b) / 3.0; + gl_FragColor = vec4(gray, gray, gray, srcColor.a); + } + else + gl_FragColor = IMG_PIXEL(inputImage,gl_FragCoord.xy); + } +} + + + + +vec3 rgb2hsv(vec3 c) { + vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); + //vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g)); + //vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r)); + vec4 p = c.g < c.b ? vec4(c.bg, K.wz) : vec4(c.gb, K.xy); + vec4 q = c.r < p.x ? vec4(p.xyw, c.r) : vec4(c.r, p.yzx); + + float d = q.x - min(q.w, q.y); + float e = 1.0e-10; + return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x); +} + +vec3 hsv2rgb(vec3 c) { + vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); + vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www); + return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y); +} \ No newline at end of file diff --git a/ISF/Chroma Mask.fs b/ISF/Chroma Mask.fs new file mode 100755 index 0000000..2295d25 --- /dev/null +++ b/ISF/Chroma Mask.fs @@ -0,0 +1,399 @@ +/*{ + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Color Effect", "Masking" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "LABEL": "Key Color", + "NAME": "mask_color", + "TYPE": "color", + "DEFAULT": [ + 0.24, + 0.77, + 0.38, + 1.0 + ] + }, + { + "LABEL": "Show Alpha", + "NAME": "showAlpha", + "TYPE": "bool", + "DEFAULT": false + }, + { + "NAME": "applyAlpha", + "TYPE": "bool", + "DEFAULT": 0.0 + }, + { + "LABEL": "Hard Cutoff", + "NAME": "applyCutOff", + "TYPE": "bool", + "DEFAULT": false + }, + { + "NAME": "alphaMode", + "LABEL": "Alpha Mode", + "TYPE": "long", + "VALUES": [ + 0, + 1, + 2 + ], + "LABELS": [ + "Additive", + "Multiply", + "Replace" + ], + "DEFAULT": 1 + }, + { + "LABEL": "Cutoff Thresh", + "NAME": "cutoffThresh", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.5 + }, + { + "LABEL": "HUE- Tol.", + "NAME": "hueTol", + "TYPE": "float", + "MIN": 0.0, + "MAX": 0.25, + "DEFAULT": 0.0 + }, + { + "LABEL": "HUE- Min. Bracket", + "NAME": "hueMinBracket", + "TYPE": "float", + "MIN": 0.0, + "MAX": 0.5, + "DEFAULT": 0.25 + }, + { + "LABEL": "HUE- Max Bracket", + "NAME": "hueMaxBracket", + "TYPE": "float", + "MIN": 0.0, + "MAX": 0.5, + "DEFAULT": 0.25 + }, + { + "LABEL": "SAT- Tol.", + "NAME": "satTol", + "TYPE": "float", + "MIN": 0.0, + "MAX": 0.5, + "DEFAULT": 0.0 + }, + { + "LABEL": "SAT- Min. Bracket", + "NAME": "satMinBracket", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.5 + }, + { + "LABEL": "SAT- Max Bracket", + "NAME": "satMaxBracket", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.5 + }, + { + "LABEL": "VAL- Tol.", + "NAME": "valTol", + "TYPE": "float", + "MIN": 0.0, + "MAX": 0.5, + "DEFAULT": 0.0 + }, + { + "LABEL": "VAL- Min. Bracket", + "NAME": "valMinBracket", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.5 + }, + { + "LABEL": "VAL- Max Bracket", + "NAME": "valMaxBracket", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.5 + }, + { + "LABEL": "Dilate", + "NAME": "dilate", + "TYPE": "float", + "MIN": 0.0, + "MAX": 6.0, + "DEFAULT": 0.0 + }, + { + "LABEL": "Blur", + "NAME": "blur", + "TYPE": "float", + "MIN": 0.0, + "MAX": 6.0, + "DEFAULT": 0.0 + } + ], + "PASSES": [ + { + "TARGET": "alphaPass" + }, + { + "TARGET": "horizDilate" + }, + { + "TARGET": "vertDilate" + }, + { + "TARGET": "horizBlur" + }, + { + "TARGET": "vertBlur" + } + ] +}*/ + + + +vec3 rgb2hsv(vec3 c); +vec3 hsv2rgb(vec3 c); + +void main() { + // generally speaking, sample a bunch of pixels, for each sample convert color val to HSV, if luma is greater than max luma, that's the new color + vec2 tmpCoord; + float maxAlpha; + vec4 sampleColorRGB; + vec4 src_rgb; + + if (PASSINDEX==0) { + // the goal is to calculate a new float value for the alpha channel, and/or desaturate the color, if this pixel is "close" to the mask color + // get the src pixel's color (as RGB), convert to HSV values + src_rgb = IMG_PIXEL(inputImage, gl_FragCoord.xy); + vec3 src_hsl = rgb2hsv(src_rgb.rgb); + // convert the passed color (which is RGB) to HSV values + vec3 color_hsl = rgb2hsv(mask_color.rgb); + + +/* -minBracket -tolerance color_hsl +tolerance +maxBracket + | | | | | val being examined + ---------------------------------------------------------------- + | | | alpha + 1.0 0.0 1.0 */ + + + float hueAlpha; + float satAlpha; + float valAlpha; + // use a 'for' loop to generate the hue/sat/val alpha values + int i = 0; + float source; + float color; + float tolerance; + vec2 bracket; + float alpha; + float minVal; + float maxVal; + for (i=0; i<3; ++i) { + source = src_hsl[i]; + color = color_hsl[i]; + if (i==0) { + tolerance = hueTol; + bracket = vec2(hueMinBracket, hueMaxBracket); + } + else if (i==1) { + tolerance = satTol; + bracket = vec2(satMinBracket, satMaxBracket); + } + else if (i==2) { + tolerance = valTol; + bracket = vec2(valMinBracket, valMaxBracket); + } + + // if the source sat is < the mask color sat + if (source < color) { + // the minVal is the bracket and tolerance, the maxVal is the mask color + minVal = color - tolerance - bracket.x; + maxVal = color; + // as i go from minVal to maxVal, the alpha goes from 1 to 0 + alpha = 1.0 - smoothstep(minVal, maxVal, source); + } + // else if the source sat is > the mask color sat + else if (source > color) { + // the minVal is the mask color, the maxVal is the tolerance and bracket + minVal = color; + maxVal = color + tolerance + bracket.y; + // as i go from minVal to maxVal, the alpha goes from 0 to 1 + alpha = smoothstep(minVal, maxVal, source); + } + // else the source sat == the mask color sat, the alpha should be 0 + else + alpha = 0.0; + + if (i==0) { + hueAlpha = alpha; + } + else if (i==1) { + satAlpha = alpha; + } + else if (i==2) { + valAlpha = alpha; + } + } + + + // calculate the alpha i'll be applying + src_rgb.a = sqrt(max(hueAlpha,max(satAlpha, valAlpha))); + + // if we're doing a hard cutoff on the alpha, set it to 0.0 if below it + if ((applyCutOff) && (src_rgb.a < cutoffThresh)) { + src_rgb.a = 0.0; + } + // otherwise, desaturate the color if appropriate, use the desaturated color + else if (hueAlpha < 1.0) { + //src_hsl.y = 0.0; + src_hsl.y = mix(0.0, src_hsl.y, hueAlpha); + src_rgb.rgb = hsv2rgb(src_hsl.xyz); + } + + + gl_FragColor = src_rgb; + //gl_FragColor = vec4(src_rgb.a, src_rgb.a, src_rgb.a, 1.0); + } + + else if (PASSINDEX==1) { + // 'dilate' samples on either side + the source pixel = 2*dilate+1 total samples + for (float i=0.; i<=float(int(dilate)); ++i) { + tmpCoord = vec2(clamp(gl_FragCoord.x+i,0.,RENDERSIZE.x), gl_FragCoord.y); + sampleColorRGB = IMG_PIXEL(alphaPass, tmpCoord); + // if this is the first sample for this fragment, don't bother comparing- just set the max luma stuff + if (i == 0.) { + maxAlpha = sampleColorRGB.a; + src_rgb = sampleColorRGB; + } + // else this isn't the first sample... + else { + // compare, determine if it's the max luma + if (sampleColorRGB.a < maxAlpha) { + maxAlpha = sampleColorRGB.a; + } + // do another sample for the negative coordinate + tmpCoord = vec2(clamp(gl_FragCoord.x-i,0.,RENDERSIZE.x), gl_FragCoord.y); + sampleColorRGB = IMG_PIXEL(alphaPass, tmpCoord); + if (sampleColorRGB.a < maxAlpha) { + maxAlpha = sampleColorRGB.a; + } + } + } + gl_FragColor = vec4(src_rgb.rgb, maxAlpha); + } + else if (PASSINDEX==2) { + // 'dilate' samples up and down + the source pixel = 2*dilate+1 total samples + for (float i=0.; i<=float(int(dilate)); ++i) { + tmpCoord = vec2(gl_FragCoord.x, clamp(gl_FragCoord.y+i,0.,RENDERSIZE.y)); + sampleColorRGB = IMG_PIXEL(horizDilate, tmpCoord); + // if this is the first sample for this fragment, don't bother comparing- just set the max luma stuff + if (i == 0.) { + maxAlpha = sampleColorRGB.a; + src_rgb = sampleColorRGB; + } + // else this isn't the first sample... + else { + // compare, determine if it's the max luma + if (sampleColorRGB.a < maxAlpha) { + maxAlpha = sampleColorRGB.a; + } + // do another sample for the negative coordinate + tmpCoord = vec2(gl_FragCoord.x, clamp(gl_FragCoord.y-i,0.,RENDERSIZE.y)); + sampleColorRGB = IMG_PIXEL(horizDilate, tmpCoord); + if (sampleColorRGB.a < maxAlpha) { + maxAlpha = sampleColorRGB.a; + } + } + } + gl_FragColor = vec4(src_rgb.rgb, maxAlpha); + } + else if (PASSINDEX==3) { + float tmpRadius = float(int(blur)); + vec4 tmpColor; + vec4 srcColor; + float totalAlpha = 0.0; + for (float i=-1.*tmpRadius; i<=tmpRadius; ++i) { + tmpColor = IMG_PIXEL(vertDilate, gl_FragCoord.xy+vec2(i,0.0)); + totalAlpha += tmpColor.a; + if (i==0.0) + srcColor = tmpColor; + } + totalAlpha /= ((tmpRadius*2.)+1.); + gl_FragColor = vec4(srcColor.r, srcColor.g, srcColor.b, totalAlpha); + } + else if (PASSINDEX==4) { + float tmpRadius = float(int(blur)); + vec4 tmpColor; + vec4 srcColor; + float totalAlpha = 0.0; + for (float i=-1.*tmpRadius; i<=tmpRadius; ++i) { + tmpColor = IMG_PIXEL(horizBlur, gl_FragCoord.xy+vec2(0.0,i)); + totalAlpha += tmpColor.a; + if (i==0.0) + srcColor = tmpColor; + } + totalAlpha /= ((tmpRadius*2.)+1.); + + // if multiplying the alpha (eg this is being used with multiple chroma mask fx) + if (alphaMode == 0) { + vec4 originalColor = IMG_PIXEL(inputImage, gl_FragCoord.xy); + totalAlpha = originalColor.a + totalAlpha; + } + else if (alphaMode == 1) { + vec4 originalColor = IMG_PIXEL(inputImage, gl_FragCoord.xy); + totalAlpha = originalColor.a * totalAlpha; + } + + if (showAlpha) { + gl_FragColor = vec4(totalAlpha, totalAlpha, totalAlpha, 1.0); + } + else { + if (applyAlpha) + gl_FragColor = vec4(srcColor.r*totalAlpha, srcColor.g*totalAlpha, srcColor.b*totalAlpha, 1.0); + else + gl_FragColor = vec4(srcColor.r, srcColor.g, srcColor.b, totalAlpha); + } + } +} + + + + +vec3 rgb2hsv(vec3 c) { + vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); + //vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g)); + //vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r)); + vec4 p = c.g < c.b ? vec4(c.bg, K.wz) : vec4(c.gb, K.xy); + vec4 q = c.r < p.x ? vec4(p.xyw, c.r) : vec4(c.r, p.yzx); + + float d = q.x - min(q.w, q.y); + float e = 1.0e-10; + return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x); +} + +vec3 hsv2rgb(vec3 c) { + vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); + vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www); + return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y); +} \ No newline at end of file diff --git a/ISF/Chroma Zoom.fs b/ISF/Chroma Zoom.fs new file mode 100644 index 0000000..7cc815d --- /dev/null +++ b/ISF/Chroma Zoom.fs @@ -0,0 +1,72 @@ +/*{ + "CREDIT": "by toneburst", + "ISFVSN": "2", + "CATEGORIES": [ + "Toneburst", "Stylize" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "master_zoom", + "TYPE": "float", + "MIN": 0.1, + "MAX": 2.0, + "DEFAULT": 1.0 + }, + { + "NAME": "red_zoom", + "TYPE": "float", + "MIN": 1.0, + "MAX": 1.5, + "DEFAULT": 1.0 + }, + { + "NAME": "green_zoom", + "TYPE": "float", + "MIN": 1.0, + "MAX": 1.5, + "DEFAULT": 1.0 + }, + { + "NAME": "blue_zoom", + "TYPE": "float", + "MIN": 1.0, + "MAX": 1.5, + "DEFAULT": 1.0 + }, + { + "NAME": "center", + "TYPE": "point2D", + "DEFAULT": [ + 0.5, + 0.5 + ] + } + ] +}*/ + +void main() { + vec2 loc; + vec2 modifiedCenter; + + loc = isf_FragNormCoord; + modifiedCenter = center / RENDERSIZE; + + vec2 locR = (loc - modifiedCenter)*(1.0/(red_zoom*master_zoom)) + modifiedCenter; + vec2 locG = (loc - modifiedCenter)*(1.0/(green_zoom*master_zoom)) + modifiedCenter; + vec2 locB = (loc - modifiedCenter)*(1.0/(blue_zoom*master_zoom)) + modifiedCenter; + + vec4 outPix; + outPix.r = IMG_NORM_PIXEL(inputImage,locR).r; + outPix.g = IMG_NORM_PIXEL(inputImage,locG).g; + outPix.b = IMG_NORM_PIXEL(inputImage,locB).b; + + loc.x = (loc.x - modifiedCenter.x)*(1.0/master_zoom) + modifiedCenter.x; + loc.y = (loc.y - modifiedCenter.y)*(1.0/master_zoom) + modifiedCenter.y; + + outPix.a = IMG_NORM_PIXEL(inputImage,loc).a; + gl_FragColor = outPix; +} diff --git a/ISF/Circle Splash Distortion.fs b/ISF/Circle Splash Distortion.fs new file mode 100644 index 0000000..1b6313d --- /dev/null +++ b/ISF/Circle Splash Distortion.fs @@ -0,0 +1,92 @@ +/*{ + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Distortion Effect" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "radius", + "TYPE": "float", + "MIN": 0.0, + "MAX": 0.75, + "DEFAULT": 0.125 + }, + { + "NAME": "streaks", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.0 + }, + { + "NAME": "center", + "TYPE": "point2D", + "DEFAULT": [ + 0.5, + 0.5 + ] + } + ] +}*/ + + + + +// Pretty simple – if we're inside the radius, draw as normal +// If we're outside the circle grab the last color along the angle + +#ifndef GL_ES +float distance (vec2 center, vec2 pt) +{ + float tmp = pow(center.x-pt.x,2.0)+pow(center.y-pt.y,2.0); + return pow(tmp,0.5); +} +#endif + +void main() { + vec2 uv = vec2(isf_FragNormCoord[0],isf_FragNormCoord[1]); + vec2 texSize = RENDERSIZE; + vec2 tc = uv * texSize; + vec2 tc2 = uv * texSize; + vec2 modifiedCenter = center; + float r = distance(modifiedCenter, tc); + float render_length = length(RENDERSIZE); + float a = atan ((tc.y-modifiedCenter.y),(tc.x-modifiedCenter.x)); + float radius_sized = clamp(radius * render_length, 1.0, render_length); + + tc -= modifiedCenter; + tc2 -= modifiedCenter; + + if (r < radius_sized) { + tc.x = r * cos(a); + tc.y = r * sin(a); + tc2 = tc; + } + else { + tc.x = radius_sized * cos(a); + tc.y = radius_sized * sin(a); + tc2.x = (radius_sized + streaks * render_length) * cos(a); + tc2.y = (radius_sized + streaks * render_length) * sin(a); + } + tc += modifiedCenter; + tc2 += modifiedCenter; + vec2 loc = tc / texSize; + + if ((loc.x < 0.0)||(loc.y < 0.0)||(loc.x > 1.0)||(loc.y > 1.0)) { + gl_FragColor = vec4(0.0); + } + else { + vec4 result = IMG_NORM_PIXEL(inputImage, loc); + if (streaks > 0.0) { + vec2 loc2 = tc2 / texSize; + vec4 mixColor = IMG_NORM_PIXEL(inputImage, loc2); + result = mix(result, mixColor, clamp(2.0*((r - radius_sized)/(render_length))*streaks,0.0,1.0)); + } + gl_FragColor = result; + } +} \ No newline at end of file diff --git a/ISF/Circle Wrap Distortion.fs b/ISF/Circle Wrap Distortion.fs new file mode 100644 index 0000000..023cbcc --- /dev/null +++ b/ISF/Circle Wrap Distortion.fs @@ -0,0 +1,88 @@ +/*{ + "DESCRIPTION": "Wraps the video into a circular shape", + "CREDIT": "VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Distortion Effect" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "inputAngle", + "TYPE": "float", + "DEFAULT": 0.5, + "MIN": 0.0, + "MAX": 1.0 + }, + { + "NAME": "inputRadius", + "TYPE": "float", + "DEFAULT": 1.0, + "MIN": 0.0, + "MAX": 2.0 + }, + { + "NAME": "inputCenter", + "TYPE": "point2D", + "DEFAULT": [ + 0, + 0 + ] + }, + { + "NAME": "mirror", + "TYPE": "bool", + "DEFAULT": false + }, + { + "NAME": "correctAspect", + "TYPE": "bool", + "DEFAULT": true + } + ] + +}*/ + + +const float tau = 6.28318530718; +const float pi = 3.14159265359; +const float halfpi = 1.57079632679; + + +void main() { + vec4 inputPixelColor; + if (inputRadius > 0.0) { + + vec2 loc = isf_FragNormCoord.xy; + vec2 center = inputCenter / RENDERSIZE.xy; + + // account for aspect ratio so we stay circle + if (correctAspect) { + loc.x = loc.x * RENDERSIZE.x/RENDERSIZE.y; + center.x = center.x * RENDERSIZE.x/RENDERSIZE.y; + } + // translate from polar coords back to cart for this point + // the effect translates (x,y) to (r,theta) + float r = distance(loc,center); + float theta = (inputAngle * tau + pi + atan(loc.x-center.x,loc.y-center.y))/tau; + + theta = mod(theta, 1.0); + + //loc = vec2((r * 2.0)/inputRadius, theta / pi); + loc = vec2(theta, (r * 2.0)/inputRadius); + + if ((loc.x < 0.0)||(loc.x > 1.0)||(loc.y < 0.0)||(loc.y > 1.0)) + inputPixelColor = vec4(0.0); + else { + loc.y = 1.0 - loc.y; + if (mirror) { + loc.x = (loc.x < 0.5) ? loc.x * 2.0 : 2.0 - loc.x * 2.0; + } + inputPixelColor = IMG_NORM_PIXEL(inputImage, loc); + } + } + gl_FragColor = inputPixelColor; +} diff --git a/ISF/Circular Screen.fs b/ISF/Circular Screen.fs new file mode 100644 index 0000000..3df3370 --- /dev/null +++ b/ISF/Circular Screen.fs @@ -0,0 +1,90 @@ +/*{ + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Halftone Effect" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "sharpness", + "TYPE": "float", + "MIN": 0.0, + "MAX": 10.0, + "DEFAULT": 1.0 + }, + { + "NAME": "offset", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.0 + }, + { + "NAME": "scale", + "TYPE": "float", + "MIN": 0.0, + "MAX": 2.0, + "DEFAULT": 1.0 + }, + { + "NAME": "colorize", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.0 + }, + { + "NAME": "center", + "TYPE": "point2D", + "DEFAULT": [ + 0.5, + 0.5 + ] + } + ] +}*/ + +varying vec2 left_coord; +varying vec2 right_coord; +varying vec2 above_coord; +varying vec2 below_coord; + +varying vec2 lefta_coord; +varying vec2 righta_coord; +varying vec2 leftb_coord; +varying vec2 rightb_coord; + +const float tau = 6.28318530718; + +float pattern() { + float s = 0.0; + float c = 1.0; + vec2 tex = isf_FragNormCoord * RENDERSIZE; + vec2 point = vec2( c * tex.x - s * tex.y, s * tex.x + c * tex.y ); + float d = distance(point, center) * max(scale,0.001); + return ( sin(d + offset * tau) ) * 4.0; +} + +void main() { + vec4 color = IMG_THIS_PIXEL(inputImage); + vec4 colorL = IMG_NORM_PIXEL(inputImage, left_coord); + vec4 colorR = IMG_NORM_PIXEL(inputImage, right_coord); + vec4 colorA = IMG_NORM_PIXEL(inputImage, above_coord); + vec4 colorB = IMG_NORM_PIXEL(inputImage, below_coord); + + vec4 colorLA = IMG_NORM_PIXEL(inputImage, lefta_coord); + vec4 colorRA = IMG_NORM_PIXEL(inputImage, righta_coord); + vec4 colorLB = IMG_NORM_PIXEL(inputImage, leftb_coord); + vec4 colorRB = IMG_NORM_PIXEL(inputImage, rightb_coord); + + vec4 final = color + sharpness * (8.0*color - colorL - colorR - colorA - colorB - colorLA - colorRA - colorLB - colorRB); + + float average = ( final.r + final.g + final.b ) / 3.0; + final = vec4( vec3( average * 10.0 - 5.0 + pattern() ), color.a ); + final = mix (color * final, final, 1.0-colorize); + gl_FragColor = final; +} \ No newline at end of file diff --git a/ISF/Circular Screen.vs b/ISF/Circular Screen.vs new file mode 100644 index 0000000..c8b60f7 --- /dev/null +++ b/ISF/Circular Screen.vs @@ -0,0 +1,27 @@ +varying vec2 left_coord; +varying vec2 right_coord; +varying vec2 above_coord; +varying vec2 below_coord; + +varying vec2 lefta_coord; +varying vec2 righta_coord; +varying vec2 leftb_coord; +varying vec2 rightb_coord; + + +void main() +{ + isf_vertShaderInit(); + vec2 texc = vec2(isf_FragNormCoord[0],isf_FragNormCoord[1]); + vec2 d = 1.0/RENDERSIZE; + + left_coord = clamp(vec2(texc.xy + vec2(-d.x , 0)),0.0,1.0); + right_coord = clamp(vec2(texc.xy + vec2(d.x , 0)),0.0,1.0); + above_coord = clamp(vec2(texc.xy + vec2(0,d.y)),0.0,1.0); + below_coord = clamp(vec2(texc.xy + vec2(0,-d.y)),0.0,1.0); + + lefta_coord = clamp(vec2(texc.xy + vec2(-d.x , d.x)),0.0,1.0); + righta_coord = clamp(vec2(texc.xy + vec2(d.x , d.x)),0.0,1.0); + leftb_coord = clamp(vec2(texc.xy + vec2(-d.x , -d.x)),0.0,1.0); + rightb_coord = clamp(vec2(texc.xy + vec2(d.x , -d.x)),0.0,1.0); +} \ No newline at end of file diff --git a/ISF/City Lights.fs b/ISF/City Lights.fs new file mode 100644 index 0000000..c7dc4df --- /dev/null +++ b/ISF/City Lights.fs @@ -0,0 +1,284 @@ +/*{ + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Stylize" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "blurAmount", + "TYPE": "float", + "MIN": 0.0, + "MAX": 12.0, + "DEFAULT": 4.0 + }, + { + "NAME": "intensity", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.5 + }, + { + "NAME": "edgeIntensity", + "TYPE": "float", + "MIN": 0.0, + "MAX": 100.0, + "DEFAULT": 15.0 + }, + { + "NAME": "edgeThreshold", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.0 + }, + { + "NAME": "erodeIntensity", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.25 + }, + { + "NAME": "erodeRadius", + "TYPE": "float", + "MIN": 1.0, + "MAX": 15.0, + "DEFAULT": 1.0 + } + ], + "PASSES": [ + { + "TARGET": "edges", + "DESCRIPTION": "PASSINDEX is 0", + "DESCRIPTION": "Pass 0" + }, + { + "TARGET": "halfSize", + "WIDTH": "floor($WIDTH/2.0)", + "HEIGHT": "floor($HEIGHT/2.0)", + "DESCRIPTION": "pass 1, 1x horiz sampling (3 wide total) to prevent data loss" + }, + { + "TARGET": "quarterSizePassA", + "WIDTH": "floor($WIDTH/4.0)", + "HEIGHT": "floor($HEIGHT/4.0)", + "DESCRIPTION": "pass 2, vert sampling, use erodeRadius (size is being reduced, halve coords deltas when sampling)" + }, + { + "TARGET": "quarterSizePassB", + "WIDTH": "floor($WIDTH/4.0)", + "HEIGHT": "floor($HEIGHT/4.0)", + "DESCRIPTION": "pass 3, horiz sampling, use erodeRadius" + }, + { + "TARGET": "quarterGaussA", + "WIDTH": "floor($WIDTH/4.0)", + "HEIGHT": "floor($HEIGHT/4.0)", + "DESCRIPTION": "Pass 4" + }, + { + "TARGET": "quarterGaussB", + "WIDTH": "floor($WIDTH/4.0)", + "HEIGHT": "floor($HEIGHT/4.0)", + "DESCRIPTION": "Pass 5" + }, + { + "TARGET": "fullGaussA", + "DESCRIPTION": "Pass 6" + }, + { + "TARGET": "fullGaussB", + "DESCRIPTION": "Pass 7" + } + ] +}*/ + + +varying vec2 left_coord; +varying vec2 right_coord; +varying vec2 above_coord; +varying vec2 below_coord; + +varying vec2 lefta_coord; +varying vec2 righta_coord; +varying vec2 leftb_coord; +varying vec2 rightb_coord; + +varying vec2 texOffsets[5]; + +vec3 rgb2hsv(vec3 c); +float gray(vec4 n); + + + +void main() { + int blurLevel = int(floor(blurAmount/6.0)); + float blurLevelModulus = mod(blurAmount, 6.0); + // first pass draws edges + if (PASSINDEX==0) { + vec4 color = IMG_THIS_PIXEL(inputImage); + vec4 colorL = IMG_NORM_PIXEL(inputImage, left_coord); + vec4 colorR = IMG_NORM_PIXEL(inputImage, right_coord); + vec4 colorA = IMG_NORM_PIXEL(inputImage, above_coord); + vec4 colorB = IMG_NORM_PIXEL(inputImage, below_coord); + + vec4 colorLA = IMG_NORM_PIXEL(inputImage, lefta_coord); + vec4 colorRA = IMG_NORM_PIXEL(inputImage, righta_coord); + vec4 colorLB = IMG_NORM_PIXEL(inputImage, leftb_coord); + vec4 colorRB = IMG_NORM_PIXEL(inputImage, rightb_coord); + + float gx = (-1.0 * gray(colorLA)) + (-2.0 * gray(colorL)) + (-1.0 * gray(colorLB)) + (1.0 * gray(colorRA)) + (2.0 * gray(colorR)) + (1.0 * gray(colorRB)); + float gy = (1.0 * gray(colorLA)) + (2.0 * gray(colorA)) + (1.0 * gray(colorRA)) + (-1.0 * gray(colorRB)) + (-2.0 * gray(colorB)) + (-1.0 * gray(colorLB)); + + float bright = pow(gx*gx + gy*gy,0.5); + vec4 final = color * bright; + + // if the brightness is below the threshold draw black + if (bright < edgeThreshold) { + final = vec4(0.0, 0.0, 0.0, 1.0); + } + else { + final = final * edgeIntensity; + final.a = 1.0; + } + + gl_FragColor = final; + } + // next three passes are doing an erode. the first and third are doing horizontal sampling, the second is doing vert sampling + else if (PASSINDEX==1 || PASSINDEX==2 || PASSINDEX==3) { + // generally speaking, sample a bunch of pixels, for each sample convert color val to HSV, if luma is greater than max luma, that's the new color + vec2 tmpCoord; + float maxLuma; + vec4 maxLumaRGBColor = vec4(0.0); + vec4 sampleColorRGB; + vec4 sampleColorHSV; + vec2 pixelWidth = 1.0/RENDERSIZE.xy; + float localBlurRadius; + bool vertFlag = false; + + // pass 0 and 2 are doing horizontal erosion + if (PASSINDEX==2) + vertFlag = true; + // the first pass should have a blur radius of 1.0 simply to prevent the loss of information while reducing resolution + if (PASSINDEX==1) + localBlurRadius = 1.0; + // other passes go by the blur radius! + else + localBlurRadius = float(int(erodeRadius)); + // sample pixels as per the blur radius... + for (float i=0.; i<=localBlurRadius; ++i) { + if (PASSINDEX==1) { + tmpCoord = vec2(clamp(isf_FragNormCoord.x+(i*pixelWidth.x), 0., 1.), isf_FragNormCoord.y); + sampleColorRGB = IMG_NORM_PIXEL(edges, tmpCoord); + } + else if (PASSINDEX==2) { + tmpCoord = vec2(isf_FragNormCoord.x, clamp(isf_FragNormCoord.y+(i*pixelWidth.y), 0., 1.)); + sampleColorRGB = IMG_NORM_PIXEL(halfSize, tmpCoord); + } + else if (PASSINDEX==3) { + tmpCoord = vec2(clamp(isf_FragNormCoord.x+(i*pixelWidth.x), 0., 1.), isf_FragNormCoord.y); + sampleColorRGB = IMG_NORM_PIXEL(quarterSizePassA, tmpCoord); + } + // if this is the first sample for this fragment, don't bother comparing- just set the max luma stuff + if (i == 0.) { + maxLuma = rgb2hsv(sampleColorRGB.rgb).b; + maxLumaRGBColor = sampleColorRGB; + } + // else this isn't the first sample... + else { + // compare, determine if it's the max luma + sampleColorRGB = mix(maxLumaRGBColor, sampleColorRGB, 1.*erodeIntensity/i); + sampleColorHSV.rgb = rgb2hsv(sampleColorRGB.rgb); + if (sampleColorHSV.b > maxLuma) { + maxLuma = sampleColorHSV.b; + maxLumaRGBColor = sampleColorRGB; + } + // do another sample for the negative coordinate + if (PASSINDEX==1) { + tmpCoord = vec2(clamp(isf_FragNormCoord.x-(i*pixelWidth.x), 0., 1.), isf_FragNormCoord.y); + sampleColorRGB = IMG_NORM_PIXEL(edges, tmpCoord); + } + else if (PASSINDEX==2) { + tmpCoord = vec2(isf_FragNormCoord.x, clamp(isf_FragNormCoord.y-(i*pixelWidth.y), 0., 1.)); + sampleColorRGB = IMG_NORM_PIXEL(halfSize, tmpCoord); + } + else if (PASSINDEX==3) { + tmpCoord = vec2(clamp(isf_FragNormCoord.x-(i*pixelWidth.x), 0., 1.), isf_FragNormCoord.y); + sampleColorRGB = IMG_NORM_PIXEL(quarterSizePassA, tmpCoord); + } + sampleColorRGB = mix(maxLumaRGBColor, sampleColorRGB, 1.*erodeIntensity/i); + sampleColorHSV.rgb = rgb2hsv(sampleColorRGB.rgb); + if (sampleColorHSV.b > maxLuma) { + maxLuma = sampleColorHSV.b; + maxLumaRGBColor = sampleColorRGB; + } + } + } + gl_FragColor = maxLumaRGBColor; + + } + // start reading from the previous stage- each two passes completes a gaussian blur, then + // we increase the resolution & blur (the lower-res blurred image from the previous pass) again... + else if (PASSINDEX == 4) { + vec4 sample0 = IMG_NORM_PIXEL(quarterSizePassB,texOffsets[0]); + vec4 sample1 = IMG_NORM_PIXEL(quarterSizePassB,texOffsets[1]); + vec4 sample2 = IMG_NORM_PIXEL(quarterSizePassB,texOffsets[2]); + vec4 sample3 = IMG_NORM_PIXEL(quarterSizePassB,texOffsets[3]); + vec4 sample4 = IMG_NORM_PIXEL(quarterSizePassB,texOffsets[4]); + //gl_FragColor = vec4((sample0 + sample1 + sample2).rgb / (3.0), 1.0); + gl_FragColor = vec4((sample0 + sample1 + sample2 + sample3 + sample4).rgb / (5.0), 1.0); + } + else if (PASSINDEX == 5) { + vec4 sample0 = IMG_NORM_PIXEL(quarterGaussA,texOffsets[0]); + vec4 sample1 = IMG_NORM_PIXEL(quarterGaussA,texOffsets[1]); + vec4 sample2 = IMG_NORM_PIXEL(quarterGaussA,texOffsets[2]); + vec4 sample3 = IMG_NORM_PIXEL(quarterGaussA,texOffsets[3]); + vec4 sample4 = IMG_NORM_PIXEL(quarterGaussA,texOffsets[4]); + //gl_FragColor = vec4((sample0 + sample1 + sample2).rgb / (3.0), 1.0); + gl_FragColor = vec4((sample0 + sample1 + sample2 + sample3 + sample4).rgb / (5.0), 1.0); + } + // ...writes into the full-size + else if (PASSINDEX == 6) { + vec4 sample0 = IMG_NORM_PIXEL(quarterGaussB,texOffsets[0]); + vec4 sample1 = IMG_NORM_PIXEL(quarterGaussB,texOffsets[1]); + vec4 sample2 = IMG_NORM_PIXEL(quarterGaussB,texOffsets[2]); + gl_FragColor = vec4((sample0 + sample1 + sample2).rgb / (3.0), 1.0); + } + else if (PASSINDEX == 7) { + // this is the last pass- calculate the blurred image as i have in previous passes, then mix it in with the full-size input image using the blur amount so i get a smooth transition into the blur at low blur levels + vec4 sample0 = IMG_NORM_PIXEL(fullGaussA,texOffsets[0]); + vec4 sample1 = IMG_NORM_PIXEL(fullGaussA,texOffsets[1]); + vec4 sample2 = IMG_NORM_PIXEL(fullGaussA,texOffsets[2]); + vec4 blurredImg = vec4((sample0 + sample1 + sample2).rgb / (3.0), 1.0); + vec4 originalImg = IMG_NORM_PIXEL(edges,isf_FragNormCoord); + if (blurLevel == 0) + blurredImg = mix(originalImg, blurredImg, (blurLevelModulus/6.0)); + + gl_FragColor = max(mix(originalImg,blurredImg*1.9,intensity), originalImg); + } + +} + + + +vec3 rgb2hsv(vec3 c) { + vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); + //vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g)); + //vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r)); + vec4 p = c.g < c.b ? vec4(c.bg, K.wz) : vec4(c.gb, K.xy); + vec4 q = c.r < p.x ? vec4(p.xyw, c.r) : vec4(c.r, p.yzx); + + float d = q.x - min(q.w, q.y); + float e = 1.0e-10; + return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x); +} +float gray(vec4 n) +{ + return (n.r + n.g + n.b)/3.0; +} diff --git a/ISF/City Lights.vs b/ISF/City Lights.vs new file mode 100644 index 0000000..c65656d --- /dev/null +++ b/ISF/City Lights.vs @@ -0,0 +1,91 @@ +varying vec2 left_coord; +varying vec2 right_coord; +varying vec2 above_coord; +varying vec2 below_coord; + +varying vec2 lefta_coord; +varying vec2 righta_coord; +varying vec2 leftb_coord; +varying vec2 rightb_coord; + +varying vec2 texOffsets[5]; + +void main(void) { + // load the main shader stuff + isf_vertShaderInit(); + + + int blurLevel = int(floor(blurAmount/6.0)); + float blurLevelModulus = mod(blurAmount, 6.0); + float blurRadius = 0.0; + float blurRadiusInPixels = 0.0; + // first pass draws edges + if (PASSINDEX==0) { + vec2 texc = vec2(isf_FragNormCoord[0],isf_FragNormCoord[1]); + vec2 d = 1.0/RENDERSIZE; + + left_coord = clamp(vec2(texc.xy + vec2(-d.x , 0)),0.0,1.0); + right_coord = clamp(vec2(texc.xy + vec2(d.x , 0)),0.0,1.0); + above_coord = clamp(vec2(texc.xy + vec2(0,d.y)),0.0,1.0); + below_coord = clamp(vec2(texc.xy + vec2(0,-d.y)),0.0,1.0); + + lefta_coord = clamp(vec2(texc.xy + vec2(-d.x , d.x)),0.0,1.0); + righta_coord = clamp(vec2(texc.xy + vec2(d.x , d.x)),0.0,1.0); + leftb_coord = clamp(vec2(texc.xy + vec2(-d.x , -d.x)),0.0,1.0); + rightb_coord = clamp(vec2(texc.xy + vec2(d.x , -d.x)),0.0,1.0); + } + // next three passes are just drawing the texture- do nothing + + // the next four passes do gaussion blurs on the various levels + else if (PASSINDEX==4 || PASSINDEX==6) { + float pixelWidth = 1.0/RENDERSIZE.x; + // pass 4 is sampling 1/8, but writing to 1/4 + if (PASSINDEX==4) { + if (blurLevel==1) + blurRadius = blurLevelModulus/1.5; + else if (blurLevel>1) + blurRadius = 4.0; + } + // pass 6 is sampling 1/4 and writing to full-size + else if (PASSINDEX==6) { + if (blurLevel==0) + blurRadius = blurLevelModulus; + else if (blurLevel>0) + blurRadius = 6.0; + } + blurRadiusInPixels = pixelWidth * blurRadius; + texOffsets[0] = isf_FragNormCoord; + texOffsets[1] = (blurRadius==0.0) ? isf_FragNormCoord : clamp(vec2(isf_FragNormCoord[0]-blurRadiusInPixels, isf_FragNormCoord[1]),0.0,1.0); + texOffsets[2] = (blurRadius==0.0) ? isf_FragNormCoord : clamp(vec2(isf_FragNormCoord[0]+blurRadiusInPixels, isf_FragNormCoord[1]),0.0,1.0); + if (PASSINDEX==4) { + texOffsets[3] = (blurRadius==0.0) ? isf_FragNormCoord : clamp(vec2(isf_FragNormCoord[0]-(2.0*blurRadiusInPixels), isf_FragNormCoord[1]),0.0,1.0); + texOffsets[4] = (blurRadius==0.0) ? isf_FragNormCoord : clamp(vec2(isf_FragNormCoord[0]+(2.0*blurRadiusInPixels), isf_FragNormCoord[1]),0.0,1.0); + } + } + else if (PASSINDEX==5 || PASSINDEX==7) { + float pixelHeight = 1.0/RENDERSIZE.y; + // pass 5 is sampling 1/14, but writing to 1/4 + if (PASSINDEX==5) { + if (blurLevel==1) + blurRadius = blurLevelModulus/1.5; + else if (blurLevel>1) + blurRadius = 4.0; + } + // pass 7 is sampling 1/4 and writing to full-size + else if (PASSINDEX==7) { + if (blurLevel==0) + blurRadius = blurLevelModulus; + else if (blurLevel>0) + blurRadius = 6.0; + } + blurRadiusInPixels = pixelHeight * blurRadius; + texOffsets[0] = isf_FragNormCoord; + texOffsets[1] = (blurRadius==0.0) ? isf_FragNormCoord : clamp(vec2(isf_FragNormCoord[0], isf_FragNormCoord[1]-blurRadiusInPixels),0.0,1.0); + texOffsets[2] = (blurRadius==0.0) ? isf_FragNormCoord : clamp(vec2(isf_FragNormCoord[0], isf_FragNormCoord[1]+blurRadiusInPixels),0.0,1.0); + if (PASSINDEX==5) { + texOffsets[3] = (blurRadius==0.0) ? isf_FragNormCoord : clamp(vec2(isf_FragNormCoord[0], isf_FragNormCoord[1]-(2.0*blurRadiusInPixels)),0.0,1.0); + texOffsets[4] = (blurRadius==0.0) ? isf_FragNormCoord : clamp(vec2(isf_FragNormCoord[0], isf_FragNormCoord[1]+(2.0*blurRadiusInPixels)),0.0,1.0); + } + } + +} diff --git a/ISF/Collage.fs b/ISF/Collage.fs new file mode 100644 index 0000000..2b9df9d --- /dev/null +++ b/ISF/Collage.fs @@ -0,0 +1,113 @@ + +/*{ + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Geometry Adjustment", "Glitch" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "seed", + "TYPE": "float", + "MIN": 0.01, + "MAX": 1.0, + "DEFAULT": 0.5 + }, + { + "NAME": "cell_size", + "TYPE": "float", + "MIN": 0.01, + "MAX": 1.0, + "DEFAULT": 0.125 + }, + { + "NAME": "allow_flips_h", + "TYPE": "bool", + "DEFAULT": 1.0 + }, + { + "NAME": "allow_flips_v", + "TYPE": "bool", + "DEFAULT": 0.0 + } + + ] +}*/ + +float rand(vec2 co){ + return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453); +} + +void main() +{ +// CALCULATE EDGES OF CURRENT CELL + // At 0.0 just do a pass-thru + if (cell_size == 0.0) { + gl_FragColor = IMG_THIS_PIXEL(inputImage); + } + else { + // Position of current pixel + vec2 xy; + xy.x = isf_FragNormCoord[0]; + xy.y = isf_FragNormCoord[1]; + + + // Left and right of tile + float CellWidth = cell_size; + float CellHeight = cell_size; + + /* + float x1 = floor(xy.x / CellWidth)*CellWidth; + float x2 = clamp((ceil(xy.x / CellWidth)*CellWidth), 0.0, 1.0); + // Top and bottom of tile + float y1 = floor(xy.y / CellHeight)*CellHeight; + float y2 = clamp((ceil(xy.y / CellHeight)*CellHeight), 0.0, 1.0); + */ + + // divide 1 by the cell width and cell height to determine the count + float rows = floor(1.0/CellHeight); + float cols = floor(1.0/CellWidth); + float count = floor(rows * cols); + + // figure out the ID # of the region + float region = cols*floor(xy.x / CellWidth) + floor(xy.y / CellHeight); + + // use this to draw the gradient of the regions as gray colors.. + //gl_FragColor = vec4(vec3(region/count),1.0); + + // now translate this region to another random region using our seed and region + float translated = clamp(rand(vec2(region/count, seed)),0.0,1.0); + //translated = region/count; + //gl_FragColor = vec4(vec3(translated),1.0); + + // quantize the translated! + translated = floor(count * translated); + //gl_FragColor = vec4(vec3(translated),1.0); + // now convert the translated region back to an xy location + // get the relative position within the original block and then add on the translated amount + xy.x = (xy.x - floor(xy.x / CellWidth)*CellWidth) + CellWidth * floor(translated / rows); + //xy.x = (xy.x - floor(xy.x / CellWidth)*CellWidth); + xy.y = xy.y - floor(xy.y / CellHeight)*CellHeight + CellHeight * floor(mod(translated , cols)); + + // lastly if flips are allowed, randomly flip h + if (allow_flips_h) { + float flipx = rand(vec2(translated, seed)); + if (flipx > 0.5) { + xy.x = 1.0-xy.x; + } + } + if (allow_flips_v) { + float flipy = rand(vec2(translated, seed)); + if (flipy > 0.5) { + xy.y = 1.0-xy.y; + } + } + + gl_FragColor = IMG_NORM_PIXEL(inputImage, xy); + + } +} \ No newline at end of file diff --git a/ISF/Color Bars.fs b/ISF/Color Bars.fs new file mode 100644 index 0000000..d2d028b --- /dev/null +++ b/ISF/Color Bars.fs @@ -0,0 +1,74 @@ +/*{ + "DESCRIPTION": "", + "CREDIT": "VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Generator" + ], + "INPUTS": [ + { + "NAME": "colorShift", + "LABEL": "Color Shift", + "TYPE": "float", + "DEFAULT": 0.0, + "MIN": 0.0, + "MAX": 1.0 + } + ] + +}*/ + + + + +vec4 colorsArray[9]; + + + + +void main() { + vec4 outputPixelColor = vec4(0.0); + vec2 loc = isf_FragNormCoord.xy; + + // figure out if we are in the top, middle or bottom sections + // these are broken into the ratios 3/4, 1/8, 1/8 + + // if we are in the top section figure out which of the 9 colors to use + if (loc.y > 0.25) { + colorsArray[0] = vec4(0.412, 0.412, 0.412, 1.0); + colorsArray[1] = vec4(0.757, 0.757, 0.757, 1.0); + colorsArray[2] = vec4(0.757, 0.757, 0.000, 1.0); + colorsArray[3] = vec4(0.000, 0.757, 0.757, 1.0); + colorsArray[4] = vec4(0.000, 0.757, 0.000, 1.0); + colorsArray[5] = vec4(0.757, 0.000, 0.757, 1.0); + colorsArray[6] = vec4(0.757, 0.000, 0.000, 1.0); + colorsArray[7] = vec4(0.000, 0.000, 0.757, 1.0); + colorsArray[8] = vec4(0.412, 0.412, 0.412, 1.0); + + int colorIndex = int((9.0 * mod(loc.x + colorShift, 1.0))); + + outputPixelColor = colorsArray[colorIndex]; + } + // in the 'middle section we draw the black to white image + else if (loc.y > 0.125) { + outputPixelColor.rgb = vec3(loc.x); + outputPixelColor.a = 1.0; + } + else { + colorsArray[0] = vec4(0.169, 0.169, 0.169, 1.0); + colorsArray[1] = vec4(0.019, 0.019, 0.019, 1.0); + colorsArray[2] = vec4(1.000, 1.000, 1.000, 1.0); + colorsArray[3] = vec4(1.000, 1.000, 1.000, 1.0); + colorsArray[4] = vec4(0.019, 0.019, 0.019, 1.0); + colorsArray[5] = vec4(0.000, 0.000, 0.000, 1.0); + colorsArray[6] = vec4(0.019, 0.019, 0.019, 1.0); + colorsArray[7] = vec4(0.038, 0.038, 0.038, 1.0); + colorsArray[8] = vec4(0.169, 0.169, 0.169, 1.0); + + int colorIndex = int((9.0 * loc.x)); + + outputPixelColor = colorsArray[colorIndex]; + } + + gl_FragColor = outputPixelColor; +} diff --git a/ISF/Color Blowout.fs b/ISF/Color Blowout.fs new file mode 100644 index 0000000..1e8551c --- /dev/null +++ b/ISF/Color Blowout.fs @@ -0,0 +1,104 @@ +/* +{ + "CATEGORIES" : [ + "Stylize", "Color Effect" + ], + "ISFVSN" : "2", + "INPUTS" : [ + { + "NAME" : "inputImage", + "TYPE" : "image" + }, + { + "NAME" : "intensity", + "TYPE" : "float", + "MAX" : 1, + "DEFAULT" : 0, + "MIN" : -1 + } + ], + "PASSES" : [ + { + "TARGET" : "pass1" + }, + { + "TARGET" : "pass2" + }, + { + "TARGET" : "pass3" + } + ], + "CREDIT" : "by VIDVOX" +} +*/ + + +varying vec2 left_coord; +varying vec2 right_coord; +varying vec2 above_coord; +varying vec2 below_coord; + +varying vec2 lefta_coord; +varying vec2 righta_coord; +varying vec2 leftb_coord; +varying vec2 rightb_coord; + +float gray(vec4 n) +{ + return (n.r + n.g + n.b)/3.0; +} + +void main() +{ + vec4 final = vec4(0.0); + + if (PASSINDEX == 0) { + vec4 color = IMG_THIS_PIXEL(inputImage); + vec4 colorL = (IMG_NORM_PIXEL(inputImage, left_coord)); + vec4 colorR = (IMG_NORM_PIXEL(inputImage, right_coord)); + vec4 colorA = (IMG_NORM_PIXEL(inputImage, above_coord)); + vec4 colorB = (IMG_NORM_PIXEL(inputImage, below_coord)); + + vec4 colorLA = (IMG_NORM_PIXEL(inputImage, lefta_coord)); + vec4 colorRA = (IMG_NORM_PIXEL(inputImage, righta_coord)); + vec4 colorLB = (IMG_NORM_PIXEL(inputImage, leftb_coord)); + vec4 colorRB = (IMG_NORM_PIXEL(inputImage, rightb_coord)); + + final = color - color * intensity * (8.0*gray(color) - colorL - colorR - colorA - colorB - colorLA - colorRA - colorLB - colorRB); + final.a = color.a; + } + else if (PASSINDEX == 1) { + vec4 color = IMG_THIS_PIXEL(pass1); + vec4 colorL = (IMG_NORM_PIXEL(pass1, left_coord)); + vec4 colorR = (IMG_NORM_PIXEL(pass1, right_coord)); + vec4 colorA = (IMG_NORM_PIXEL(pass1, above_coord)); + vec4 colorB = (IMG_NORM_PIXEL(pass1, below_coord)); + + vec4 colorLA = (IMG_NORM_PIXEL(pass1, lefta_coord)); + vec4 colorRA = (IMG_NORM_PIXEL(pass1, righta_coord)); + vec4 colorLB = (IMG_NORM_PIXEL(pass1, leftb_coord)); + vec4 colorRB = (IMG_NORM_PIXEL(pass1, rightb_coord)); + + final = (1.0 - abs(intensity)) * color + abs(intensity) * (colorL + colorR + colorA + colorB + colorLA + colorRA + colorLB + colorRB) / 8.0; + final.a = color.a; + } + else if (PASSINDEX == 2) { + vec4 color = IMG_THIS_PIXEL(pass2); + vec4 colorL = (IMG_NORM_PIXEL(pass2, left_coord)); + vec4 colorR = (IMG_NORM_PIXEL(pass2, right_coord)); + vec4 colorA = (IMG_NORM_PIXEL(pass2, above_coord)); + vec4 colorB = (IMG_NORM_PIXEL(pass2, below_coord)); + + vec4 colorLA = (IMG_NORM_PIXEL(pass2, lefta_coord)); + vec4 colorRA = (IMG_NORM_PIXEL(pass2, righta_coord)); + vec4 colorLB = (IMG_NORM_PIXEL(pass2, leftb_coord)); + vec4 colorRB = (IMG_NORM_PIXEL(pass2, rightb_coord)); + + final = color - color * intensity * (8.0*gray(color) - colorL - colorR - colorA - colorB - colorLA - colorRA - colorLB - colorRB); + final.a = color.a; + } + + + + gl_FragColor = final; +} \ No newline at end of file diff --git a/ISF/Color Blowout.vs b/ISF/Color Blowout.vs new file mode 100644 index 0000000..c8b60f7 --- /dev/null +++ b/ISF/Color Blowout.vs @@ -0,0 +1,27 @@ +varying vec2 left_coord; +varying vec2 right_coord; +varying vec2 above_coord; +varying vec2 below_coord; + +varying vec2 lefta_coord; +varying vec2 righta_coord; +varying vec2 leftb_coord; +varying vec2 rightb_coord; + + +void main() +{ + isf_vertShaderInit(); + vec2 texc = vec2(isf_FragNormCoord[0],isf_FragNormCoord[1]); + vec2 d = 1.0/RENDERSIZE; + + left_coord = clamp(vec2(texc.xy + vec2(-d.x , 0)),0.0,1.0); + right_coord = clamp(vec2(texc.xy + vec2(d.x , 0)),0.0,1.0); + above_coord = clamp(vec2(texc.xy + vec2(0,d.y)),0.0,1.0); + below_coord = clamp(vec2(texc.xy + vec2(0,-d.y)),0.0,1.0); + + lefta_coord = clamp(vec2(texc.xy + vec2(-d.x , d.x)),0.0,1.0); + righta_coord = clamp(vec2(texc.xy + vec2(d.x , d.x)),0.0,1.0); + leftb_coord = clamp(vec2(texc.xy + vec2(-d.x , -d.x)),0.0,1.0); + rightb_coord = clamp(vec2(texc.xy + vec2(d.x , -d.x)),0.0,1.0); +} \ No newline at end of file diff --git a/ISF/Color Controls.fs b/ISF/Color Controls.fs new file mode 100644 index 0000000..ec214da --- /dev/null +++ b/ISF/Color Controls.fs @@ -0,0 +1,92 @@ +/*{ + "CREDIT": "by zoidberg", + "ISFVSN": "2", + "CATEGORIES": [ + "Color Adjustment" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "bright", + "TYPE": "float", + "MIN": -1.0, + "MAX": 1.0, + "DEFAULT": 0.0 + }, + { + "NAME": "contrast", + "TYPE": "float", + "MIN": -4.0, + "MAX": 4.0, + "DEFAULT": 1.0 + }, + { + "NAME": "hue", + "TYPE": "float", + "MIN": -1.0, + "MAX": 1.0, + "DEFAULT": 0.0 + }, + { + "NAME": "saturation", + "TYPE": "float", + "MIN": 0.0, + "MAX": 4.0, + "DEFAULT": 1.0 + } + ] +}*/ + + +vec3 rgb2hsv(vec3 c); +vec3 hsv2rgb(vec3 c); + +void main() { + vec4 tmpColorA = IMG_THIS_PIXEL(inputImage); + vec4 tmpColorB; + // bright + tmpColorB = tmpColorA + vec4(bright, bright, bright, 0.0); + // contrast + tmpColorA.rgb = ((vec3(2.0) * (tmpColorB.rgb - vec3(0.5))) * vec3(contrast) / vec3(2.0)) + vec3(0.5); + tmpColorA.a = ((2.0 * (tmpColorB.a - 0.5)) * abs(contrast) / 2.0) + 0.5; + + // convert RGB to HSV + tmpColorB.xyz = rgb2hsv(clamp(tmpColorA.rgb, 0.0, 1.0)); + tmpColorB.a = tmpColorA.a; + + + // hue + tmpColorB.x = mod((tmpColorB.x + hue), 1.0); + // saturation + tmpColorB.y = tmpColorB.y * saturation; + + + // convert HSV back to RGB + tmpColorA.rgb = hsv2rgb(clamp(tmpColorB.xyz, 0.0, 1.0)); + tmpColorA.a = tmpColorB.a; + + + gl_FragColor = clamp(tmpColorA, 0.0, 1.0); +} + + +vec3 rgb2hsv(vec3 c) { + vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); + //vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g)); + //vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r)); + vec4 p = c.g < c.b ? vec4(c.bg, K.wz) : vec4(c.gb, K.xy); + vec4 q = c.r < p.x ? vec4(p.xyw, c.r) : vec4(c.r, p.yzx); + + float d = q.x - min(q.w, q.y); + float e = 1.0e-10; + return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x); +} + +vec3 hsv2rgb(vec3 c) { + vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); + vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www); + return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y); +} diff --git a/ISF/Color Invert.fs b/ISF/Color Invert.fs new file mode 100644 index 0000000..59cfb46 --- /dev/null +++ b/ISF/Color Invert.fs @@ -0,0 +1,18 @@ +/*{ + "CREDIT": "by zoidberg", + "ISFVSN": "2", + "CATEGORIES": [ + "Color Effect" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + } + ] +}*/ + +void main() { + vec4 srcPixel = IMG_THIS_PIXEL(inputImage); + gl_FragColor = vec4(1.0-srcPixel.r, 1.0-srcPixel.g, 1.0-srcPixel.b, srcPixel.a); +} \ No newline at end of file diff --git a/ISF/Color Levels.fs b/ISF/Color Levels.fs new file mode 100644 index 0000000..928cbc9 --- /dev/null +++ b/ISF/Color Levels.fs @@ -0,0 +1,156 @@ +/*{ + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Color Adjustment" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "minLevel", + "LABEL": "Minimum Point", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.2 + }, + { + "NAME": "midLevel", + "LABEL": "Mid Point", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.5 + }, + { + "NAME": "maxLevel", + "LABEL": "Maximum Point", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.8 + }, + { + "NAME": "offset1", + "TYPE": "color", + "DEFAULT": [ + 0.5, + 0.5, + 0.5, + 0.5 + ] + }, + { + "NAME": "offset2", + "TYPE": "color", + "DEFAULT": [ + 0.5, + 0.5, + 0.5, + 0.5 + ] + }, + { + "NAME": "offset3", + "TYPE": "color", + "DEFAULT": [ + 0.5, + 0.5, + 0.5, + 0.5 + ] + }, + { + "NAME": "offset4", + "TYPE": "color", + "DEFAULT": [ + 0.5, + 0.5, + 0.5, + 0.5 + ] + }, + { + "NAME": "offset5", + "TYPE": "color", + "DEFAULT": [ + 0.5, + 0.5, + 0.5, + 0.5 + ] + }, + { + "NAME": "offset6", + "TYPE": "color", + "DEFAULT": [ + 0.5, + 0.5, + 0.5, + 0.5 + ] + }, + { + "NAME": "levelsMode", + "LABEL": "Levels Mode", + "TYPE": "bool", + "DEFAULT": 0.0 + } + ] +}*/ + + + +void main() { + vec4 tmpColor = IMG_THIS_PIXEL(inputImage); + float brightness = (tmpColor.r + tmpColor.g + tmpColor.b) * tmpColor.a / 3.0; + + // all adjustments + if (brightness <= minLevel) { + tmpColor = tmpColor + offset1 - 0.5; + } + else if (brightness <= (minLevel + midLevel)/2.0) { + tmpColor = tmpColor + offset2 - 0.5; + } + else if (brightness <= midLevel) { + tmpColor = tmpColor + offset3 - 0.5; + } + else if (brightness <= (maxLevel + midLevel)/2.0) { + tmpColor = tmpColor + offset4 - 0.5; + } + else if (brightness <= maxLevel) { + tmpColor = tmpColor + offset5 - 0.5; + } + else { + tmpColor = tmpColor + offset6 - 0.5; + } + + if (levelsMode) { + // all adjustments + tmpColor.rgb = vec3(1.0); + + if (brightness <= minLevel) { + tmpColor.a = 0.0; + } + else if (brightness <= (minLevel + midLevel)/2.0) { + tmpColor.a = 1.0/5.0; + } + else if (brightness <= midLevel) { + tmpColor.a = 2.0/5.0; + } + else if (brightness <= (maxLevel + midLevel)/2.0) { + tmpColor.a = 3.0/5.0; + } + else if (brightness <= maxLevel) { + tmpColor.a = 4.0/5.0; + } + else { + tmpColor.a = 1.0; + } + } + gl_FragColor = clamp(tmpColor, 0.0, 1.0); +} + diff --git a/ISF/Color Monochrome.fs b/ISF/Color Monochrome.fs new file mode 100644 index 0000000..006e91d --- /dev/null +++ b/ISF/Color Monochrome.fs @@ -0,0 +1,44 @@ +/*{ + "CREDIT": "by zoidberg", + "ISFVSN": "2", + "CATEGORIES": [ + "Color Effect" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "intensity", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 1.0 + }, + { + "NAME": "color", + "TYPE": "color", + "DEFAULT": [ + 0.6, + 0.45, + 0.3, + 1.0 + ] + } + ] +}*/ + + +//const vec4 lumcoeff = vec4(0.299, 0.587, 0.114, 0.0); +const vec4 lumcoeff = vec4(0.2126, 0.7152, 0.0722, 0.0); + +void main() { + vec4 srcPixel = IMG_THIS_PIXEL(inputImage); + float luminance = dot(srcPixel,lumcoeff); + //float luminance = (srcPixel.r + srcPixel.g + srcPixel.b)/3.0; + vec4 dstPixel = (luminance >= 0.50) + ? mix(color, vec4(1,1,1,srcPixel.a), (luminance-0.5)*2.0) + : mix(vec4(0,0,0,srcPixel.a), color, luminance*2.0); + gl_FragColor = mix(srcPixel, dstPixel, intensity); +} \ No newline at end of file diff --git a/ISF/Color Posterize.fs b/ISF/Color Posterize.fs new file mode 100644 index 0000000..92f548c --- /dev/null +++ b/ISF/Color Posterize.fs @@ -0,0 +1,30 @@ +/*{ + "CREDIT": "by zoidberg", + "ISFVSN": "2", + "CATEGORIES": [ + "Color Effect" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "levels", + "TYPE": "float", + "MIN": 2.0, + "MAX": 30.0, + "DEFAULT": 30.0 + } + ] +}*/ + +void main() { + // get the src pixel, convert to HSL, posterize the 'L', convert back to RGB + vec4 srcPixel = IMG_THIS_PIXEL(inputImage); + vec4 amountPerLevel = vec4(1.0/levels); + vec4 numOfLevels = floor(srcPixel/amountPerLevel); + vec4 outColor = numOfLevels * (vec4(1.0) / (vec4(levels) - vec4(1.0))); + outColor.a = srcPixel.a; + gl_FragColor = outColor; +} diff --git a/ISF/Color Relookup.fs b/ISF/Color Relookup.fs new file mode 100644 index 0000000..f6d4bb3 --- /dev/null +++ b/ISF/Color Relookup.fs @@ -0,0 +1,38 @@ +/*{ + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Glitch" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "lookupImage", + "TYPE": "image" + }, + { + "NAME": "mix_amount", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.5 + } + ] +}*/ + +void main() { + vec4 thisColor = IMG_THIS_PIXEL(inputImage); + vec2 lookupCoord; + lookupCoord.x = mix (thisColor.r, thisColor.g, mix_amount); + lookupCoord.x = mix (lookupCoord.x, thisColor.b, mix_amount); + lookupCoord.x = RENDERSIZE.x * lookupCoord.x / 255.0; + + lookupCoord.y = mix (thisColor.r, thisColor.g, mix_amount); + lookupCoord.y = mix (lookupCoord.y, thisColor.b, mix_amount); + lookupCoord.y = RENDERSIZE.y * lookupCoord.y / 255.0; + + gl_FragColor = IMG_NORM_PIXEL(lookupImage, lookupCoord); +} \ No newline at end of file diff --git a/ISF/Color Replacement.fs b/ISF/Color Replacement.fs new file mode 100755 index 0000000..6cc1a79 --- /dev/null +++ b/ISF/Color Replacement.fs @@ -0,0 +1,364 @@ +/*{ + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Color Effect" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "LABEL": "Master Threshold", + "NAME": "threshold", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.5 + }, + { + "LABEL": "Key Color", + "NAME": "mask_color", + "TYPE": "color", + "DEFAULT": [ + 0.24, + 0.77, + 0.38, + 1.0 + ] + }, + { + "LABEL": "Target Color", + "NAME": "target_color", + "TYPE": "color", + "DEFAULT": [ + 0.77, + 0.38, + 0.24, + 1.0 + ] + }, + { + "LABEL": "HUE- Tol.", + "NAME": "hueTol", + "TYPE": "float", + "MIN": 0.0, + "MAX": 0.25, + "DEFAULT": 0.0 + }, + { + "LABEL": "HUE- Min. Bracket", + "NAME": "hueMinBracket", + "TYPE": "float", + "MIN": 0.0, + "MAX": 0.5, + "DEFAULT": 0.25 + }, + { + "LABEL": "HUE- Max Bracket", + "NAME": "hueMaxBracket", + "TYPE": "float", + "MIN": 0.0, + "MAX": 0.5, + "DEFAULT": 0.25 + }, + { + "LABEL": "SAT- Tol.", + "NAME": "satTol", + "TYPE": "float", + "MIN": 0.0, + "MAX": 0.5, + "DEFAULT": 0.0 + }, + { + "LABEL": "SAT- Min. Bracket", + "NAME": "satMinBracket", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.5 + }, + { + "LABEL": "SAT- Max Bracket", + "NAME": "satMaxBracket", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.5 + }, + { + "LABEL": "VAL- Tol.", + "NAME": "valTol", + "TYPE": "float", + "MIN": 0.0, + "MAX": 0.5, + "DEFAULT": 0.0 + }, + { + "LABEL": "VAL- Min. Bracket", + "NAME": "valMinBracket", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.5 + }, + { + "LABEL": "VAL- Max Bracket", + "NAME": "valMaxBracket", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.5 + }, + { + "LABEL": "Dilate", + "NAME": "dilate", + "TYPE": "float", + "MIN": 0.0, + "MAX": 6.0, + "DEFAULT": 0.0 + }, + { + "LABEL": "Blur", + "NAME": "blur", + "TYPE": "float", + "MIN": 0.0, + "MAX": 6.0, + "DEFAULT": 0.0 + } + ], + "PASSES": [ + { + "TARGET": "alphaPass" + }, + { + "TARGET": "horizDilate" + }, + { + "TARGET": "vertDilate" + }, + { + "TARGET": "horizBlur" + }, + { + "TARGET": "vertBlur" + } + ] +}*/ + + + +vec3 rgb2hsv(vec3 c); +vec3 hsv2rgb(vec3 c); + +void main() { + // generally speaking, sample a bunch of pixels, for each sample convert color val to HSV, if luma is greater than max luma, that's the new color + vec2 tmpCoord; + float maxAlpha; + vec4 sampleColorRGB; + vec4 src_rgb; + + if (PASSINDEX==0) { + // the goal is to calculate a new float value for the alpha channel, and/or desaturate the color, if this pixel is "close" to the mask color + // get the src pixel's color (as RGB), convert to HSV values + src_rgb = IMG_PIXEL(inputImage, gl_FragCoord.xy); + vec3 src_hsl = rgb2hsv(src_rgb.rgb); + // convert the passed color (which is RGB) to HSV values + vec3 color_hsl = rgb2hsv(mask_color.rgb); + + +/* -minBracket -tolerance color_hsl +tolerance +maxBracket + | | | | | val being examined + ---------------------------------------------------------------- + | | | alpha + 1.0 0.0 1.0 */ + + + float hueAlpha; + float satAlpha; + float valAlpha; + // use a 'for' loop to generate the hue/sat/val alpha values + int i = 0; + float source; + float color; + float tolerance; + vec2 bracket; + float alpha; + float minVal; + float maxVal; + for (i=0; i<3; ++i) { + source = src_hsl[i]; + color = color_hsl[i]; + if (i==0) { + tolerance = hueTol; + bracket = vec2(hueMinBracket, hueMaxBracket); + } + else if (i==1) { + tolerance = satTol; + bracket = vec2(satMinBracket, satMaxBracket); + } + else if (i==2) { + tolerance = valTol; + bracket = vec2(valMinBracket, valMaxBracket); + } + + // if the source sat is < the mask color sat + if (source < color) { + // the minVal is the bracket and tolerance, the maxVal is the mask color + minVal = color - tolerance - bracket.x; + maxVal = color; + // as i go from minVal to maxVal, the alpha goes from 1 to 0 + alpha = 1.0 - smoothstep(minVal, maxVal, source); + } + // else if the source sat is > the mask color sat + else if (source > color) { + // the minVal is the mask color, the maxVal is the tolerance and bracket + minVal = color; + maxVal = color + tolerance + bracket.y; + // as i go from minVal to maxVal, the alpha goes from 0 to 1 + alpha = smoothstep(minVal, maxVal, source); + } + // else the source sat == the mask color sat, the alpha should be 0 + else + alpha = 0.0; + + if (i==0) { + hueAlpha = alpha; + } + else if (i==1) { + satAlpha = alpha; + } + else if (i==2) { + valAlpha = alpha; + } + } + + + // calculate the alpha i'll be applying + src_rgb.a = sqrt(max(hueAlpha,max(satAlpha, valAlpha))); + + // desaturate the color if appropriate, use the desaturated color + if (hueAlpha < 1.0) { + //src_hsl.y = 0.0; + src_hsl.y = mix(0.0, src_hsl.y, hueAlpha); + src_rgb.rgb = hsv2rgb(src_hsl.xyz); + } + + + gl_FragColor = src_rgb; + //gl_FragColor = vec4(src_rgb.a, src_rgb.a, src_rgb.a, 1.0); + } + + else if (PASSINDEX==1) { + // 'dilate' samples on either side + the source pixel = 2*dilate+1 total samples + for (float i=0.; i<=float(int(dilate)); ++i) { + tmpCoord = vec2(clamp(gl_FragCoord.x+i,0.,RENDERSIZE.x), gl_FragCoord.y); + sampleColorRGB = IMG_PIXEL(alphaPass, tmpCoord); + // if this is the first sample for this fragment, don't bother comparing- just set the max luma stuff + if (i == 0.) { + maxAlpha = sampleColorRGB.a; + src_rgb = sampleColorRGB; + } + // else this isn't the first sample... + else { + // compare, determine if it's the max luma + if (sampleColorRGB.a < maxAlpha) { + maxAlpha = sampleColorRGB.a; + } + // do another sample for the negative coordinate + tmpCoord = vec2(clamp(gl_FragCoord.x-i,0.,RENDERSIZE.x), gl_FragCoord.y); + sampleColorRGB = IMG_PIXEL(alphaPass, tmpCoord); + if (sampleColorRGB.a < maxAlpha) { + maxAlpha = sampleColorRGB.a; + } + } + } + gl_FragColor = vec4(src_rgb.rgb, maxAlpha); + } + else if (PASSINDEX==2) { + // 'dilate' samples up and down + the source pixel = 2*dilate+1 total samples + for (float i=0.; i<=float(int(dilate)); ++i) { + tmpCoord = vec2(gl_FragCoord.x, clamp(gl_FragCoord.y+i,0.,RENDERSIZE.y)); + sampleColorRGB = IMG_PIXEL(horizDilate, tmpCoord); + // if this is the first sample for this fragment, don't bother comparing- just set the max luma stuff + if (i == 0.) { + maxAlpha = sampleColorRGB.a; + src_rgb = sampleColorRGB; + } + // else this isn't the first sample... + else { + // compare, determine if it's the max luma + if (sampleColorRGB.a < maxAlpha) { + maxAlpha = sampleColorRGB.a; + } + // do another sample for the negative coordinate + tmpCoord = vec2(gl_FragCoord.x, clamp(gl_FragCoord.y-i,0.,RENDERSIZE.y)); + sampleColorRGB = IMG_PIXEL(horizDilate, tmpCoord); + if (sampleColorRGB.a < maxAlpha) { + maxAlpha = sampleColorRGB.a; + } + } + } + gl_FragColor = vec4(src_rgb.rgb, maxAlpha); + } + else if (PASSINDEX==3) { + float tmpRadius = float(int(blur)); + vec4 tmpColor; + vec4 srcColor; + float totalAlpha = 0.0; + for (float i=-1.*tmpRadius; i<=tmpRadius; ++i) { + tmpColor = IMG_PIXEL(vertDilate, gl_FragCoord.xy+vec2(i,0.0)); + totalAlpha += tmpColor.a; + if (i==0.0) + srcColor = tmpColor; + } + totalAlpha /= ((tmpRadius*2.)+1.); + gl_FragColor = vec4(srcColor.r, srcColor.g, srcColor.b, totalAlpha); + } + else if (PASSINDEX==4) { + float tmpRadius = float(int(blur)); + vec4 tmpColor; + vec4 srcColor; + float totalAlpha = 0.0; + for (float i=-1.*tmpRadius; i<=tmpRadius; ++i) { + tmpColor = IMG_PIXEL(horizBlur, gl_FragCoord.xy+vec2(0.0,i)); + totalAlpha += tmpColor.a; + if (i==0.0) + srcColor = tmpColor; + } + totalAlpha /= ((tmpRadius*2.)+1.); + // if it's above the threshold draw the original + if (totalAlpha > threshold) { + gl_FragColor = IMG_PIXEL(inputImage,gl_FragCoord.xy); + } + // otherwise replace with a shade of the target_color + else { + srcColor = IMG_PIXEL(inputImage,gl_FragCoord.xy); + //float gray = (srcColor.r + srcColor.g + srcColor.b) / 3.0; + float gray = 1.0 - totalAlpha; + gl_FragColor = target_color * vec4(gray, gray, gray, srcColor.a); + } + } +} + + + + +vec3 rgb2hsv(vec3 c) { + vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); + //vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g)); + //vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r)); + vec4 p = c.g < c.b ? vec4(c.bg, K.wz) : vec4(c.gb, K.xy); + vec4 q = c.r < p.x ? vec4(p.xyw, c.r) : vec4(c.r, p.yzx); + + float d = q.x - min(q.w, q.y); + float e = 1.0e-10; + return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x); +} + +vec3 hsv2rgb(vec3 c) { + vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); + vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www); + return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y); +} \ No newline at end of file diff --git a/ISF/Color Schemes.fs b/ISF/Color Schemes.fs new file mode 100644 index 0000000..80ee657 --- /dev/null +++ b/ISF/Color Schemes.fs @@ -0,0 +1,267 @@ +/*{ + "DESCRIPTION": "Creates variations on a base color using a given algorithm.", + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Generator" + ], + "INPUTS": [ + { + "LABEL": "Base Color", + "NAME": "baseColor", + "TYPE": "color", + "DEFAULT": [ + 0.25, + 0.59, + 0.9, + 1.0 + ] + }, + { + "LABEL": "Color Mode", + "NAME": "colorModeOverride", + "TYPE": "long", + "VALUES": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7 + ], + "LABELS": [ + "Overview", + "Basic Complementary", + "Split Complementary", + "Compound Complementary", + "Spectrum", + "Shades", + "Analogous", + "Compound Analogous" + ], + "DEFAULT": 1 + }, + { + "LABEL": "Color Count", + "NAME": "colorCount", + "TYPE": "long", + "VALUES": [ + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15 + ], + "LABELS": [ + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9", + "10", + "11", + "12", + "13", + "14", + "15" + ], + "DEFAULT": 5 + } + ] +}*/ + + + + +vec3 rgb2hsv(vec3 c) { + vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); + //vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g)); + //vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r)); + vec4 p = c.g < c.b ? vec4(c.bg, K.wz) : vec4(c.gb, K.xy); + vec4 q = c.r < p.x ? vec4(p.xyw, c.r) : vec4(c.r, p.yzx); + + float d = q.x - min(q.w, q.y); + float e = 1.0e-10; + return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x); +} + +vec3 hsv2rgb(vec3 c) { + vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); + vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www); + return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y); +} + + + + +void main() +{ + vec4 inColor = baseColor; + float index = floor(isf_FragNormCoord.x * float(colorCount)); + float variation = 0.3236; // 1/5 the golden ratio + int colorMode = 0; + if (colorModeOverride == 0) { + colorMode = int(floor((1.0-isf_FragNormCoord.y) * 6.99)); + } + else { + colorMode = colorModeOverride - 1; + } + + inColor.rgb = rgb2hsv(inColor.rgb); + + vec4 outColor = inColor; + + // Basic complimentary – saturation and brightness variations on two fixed 180 degree opposite hues + if (colorMode == 0) { + if (mod(index, 2.0) >= 1.0) { + outColor.r = outColor.r + 0.5; + outColor.r = outColor.r - floor(outColor.r); + } + + outColor.g = outColor.g - variation * floor(index / 2.0); + + if (outColor.g < 0.1) { + outColor.g = outColor.g + variation * floor(index / 2.0); + outColor.g = outColor.g - floor(outColor.g); + } + + outColor.b = outColor.b - variation * floor(index / 4.0); + if (outColor.b < 0.2) { + outColor.b = outColor.b + variation * floor(index / 4.0); + outColor.b = outColor.b - floor(outColor.b); + } + } + // Split complimentary – saturation and brightness variations on a 3 fixed 120 degree hues + else if (colorMode == 1) { + float divisor = 3.0; + float ratio = 0.45; + if (mod(index, 3.0) >= 2.0) { + outColor.r = outColor.r - ratio; + } + else if (mod(index, 3.0) >= 1.0) { + outColor.r = outColor.r + ratio; + } + + //outColor.g = outColor.g + variation * floor(index / divisor); + + if (mod(index, 5.0) >= 3.0) { + outColor.g = outColor.g - variation; + outColor.g = outColor.g - floor(outColor.g); + } + outColor.b = outColor.b - variation * floor(index / (divisor)); + if (outColor.b < 0.1) { + outColor.b = outColor.b + variation * floor(index / (divisor)); + outColor.b = outColor.b - floor(outColor.b); + } + } + // Compound complimentary – a combination of shades, complimentary and analogous colors with slight shifts + else if (colorMode == 2) { + if (mod(index, 3.0) >= 2.0) { + outColor.r = outColor.r + 0.5; + outColor.r = outColor.r + variation * index * 1.0 / float(colorCount - 1) / 4.0; + } + else { + outColor.r = outColor.r + variation * index * 1.0 / float(colorCount - 1); + } + outColor.r = outColor.r - floor(outColor.r); + + + if (mod(index, 2.0) >= 1.0) { + outColor.g = outColor.g + index * variation / 2.0; + } + else if (mod(index, 3.0) >= 2.0) { + outColor.g = outColor.g - variation / 2.0; + } + else { + outColor.g = outColor.g - index * variation / float(colorCount - 1); + } + if (outColor.g > 1.0) { + outColor.g = outColor.g - floor(outColor.g); + } + } + // Spectrum – hue shifts based on number of colors with minor saturation shifts + else if (colorMode == 3) { + outColor.r = outColor.r + index * 1.0 / float(colorCount); + if (mod(index, 3.0) >= 2.0) { + outColor.g = outColor.g - variation / 2.0; + outColor.g = outColor.g - floor(outColor.g); + } + else if (mod(index, 4.0) >= 3.0) { + outColor.g = outColor.g + variation / 2.0; + //outColor.g = outColor.g - floor(outColor.g); + } + } + // Shades – saturation and brightness variations on a single fixed hue + else if (colorMode == 4) { + if (mod(index, 2.0) >= 1.0) { + outColor.b = outColor.b - (index * variation) / float(colorCount-1); + } + else { + outColor.b = outColor.b + (index * variation) / float(colorCount-1); + outColor.b = outColor.b - floor(outColor.b); + } + if (outColor.b < 0.075) { + outColor.b = 1.0 - outColor.b * variation; + } + + if (mod(index, 3.0) >= 2.0) { + outColor.g = outColor.g - (index * variation) / 2.0; + } + else if (mod(index, 4.0) >= 3.0) { + outColor.g = outColor.g + (index * variation) / 2.0; + } + + if ((outColor.g > 1.0) || (outColor.g < 0.05)) { + outColor.g = outColor.g - floor(outColor.g); + } + } + // Analogous – small hue and saturation shifts + else if (colorMode == 5) { + + outColor.r = outColor.r + variation * index * 1.0 / float(colorCount - 1); + + if (mod(index, 3.0) >= 1.0) { + outColor.g = outColor.g - variation / 2.0; + if (outColor.g < 0.0) { + outColor.g = outColor.g + variation / 2.0; + } + if (outColor.g > 1.0) { + outColor.g = outColor.g - floor(outColor.g); + } + } + } + // Compound Analogous – similar to analogous but with negative hue shifts + else if (colorMode == 6) { + if (mod(index, 3.0) >= 1.0) { + outColor.r = outColor.r + variation * index * 1.0 / float(colorCount - 1); + } + else { + outColor.r = outColor.r - variation * index * 0.5 / float(colorCount - 1); + } + if (mod(index, 3.0) >= 1.0) { + outColor.g = outColor.g - variation / 2.0; + if (outColor.g < 0.0) { + outColor.g = outColor.g + variation / 2.0; + } + if (outColor.g > 1.0) { + outColor.g = outColor.g - floor(outColor.g); + } + } + } + + gl_FragColor = vec4(hsv2rgb(outColor.rgb), inColor.a); +} diff --git a/ISF/Color Test Grid.fs b/ISF/Color Test Grid.fs new file mode 100644 index 0000000..dc38389 --- /dev/null +++ b/ISF/Color Test Grid.fs @@ -0,0 +1,87 @@ +/*{ + "DESCRIPTION": "", + "CREDIT": "VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Generator" + ], + "INPUTS": [ + { + "NAME": "gridCols", + "LABEL": "Grid Columns", + "TYPE": "float", + "DEFAULT": 16.0, + "MIN": 1.0, + "MAX": 32.0 + }, + { + "NAME": "gridRows", + "LABEL": "Grid Rows", + "TYPE": "float", + "DEFAULT": 9.0, + "MIN": 1.0, + "MAX": 32.0 + }, + { + "NAME": "colorShift", + "LABEL": "Color Shift", + "TYPE": "float", + "DEFAULT": 0.0, + "MIN": 0.0, + "MAX": 1.0 + }, + { + "NAME": "colorRange", + "LABEL": "Color Range", + "TYPE": "float", + "DEFAULT": 1.0, + "MIN": 0.0, + "MAX": 1.0 + } + ] + +}*/ + + + + +vec3 rgb2hsv(vec3 c) { + vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); + //vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g)); + //vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r)); + vec4 p = c.g < c.b ? vec4(c.bg, K.wz) : vec4(c.gb, K.xy); + vec4 q = c.r < p.x ? vec4(p.xyw, c.r) : vec4(c.r, p.yzx); + + float d = q.x - min(q.w, q.y); + float e = 1.0e-10; + return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x); +} + +vec3 hsv2rgb(vec3 c) { + vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); + vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www); + return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y); +} + + + + +void main() { + vec4 outputPixelColor = vec4(1.0); + vec2 loc = isf_FragNormCoord.xy; + vec2 gridLoc = loc * vec2(gridCols, gridRows); + + // figure out which grid square we are in, normalized, and use it for the hue + outputPixelColor.r = (floor(gridLoc.x) + gridCols * floor(mod(gridLoc.y, gridRows))) / (gridCols * gridRows - 1.0); + + // scale to the hue range + outputPixelColor.r = outputPixelColor.r * colorRange; + + // apply the hue shift + outputPixelColor.r = mod(outputPixelColor.r + colorShift, 1.0); + + // finally convert to RGB + outputPixelColor.rgb = hsv2rgb(outputPixelColor.rgb); + + gl_FragColor = outputPixelColor; +} diff --git a/ISF/Convergence.fs b/ISF/Convergence.fs new file mode 100644 index 0000000..bf09757 --- /dev/null +++ b/ISF/Convergence.fs @@ -0,0 +1,108 @@ +/*{ + "DESCRIPTION": "", + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Glitch" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "horizontal_magnitude", + "TYPE": "float", + "MIN": 0.00, + "MAX": 1.0, + "DEFAULT": 0.125 + }, + { + "NAME": "vertical_magnitude", + "TYPE": "float", + "MIN": 0.00, + "MAX": 1.0, + "DEFAULT": 0.125 + }, + { + "NAME": "color_magnitude", + "TYPE": "float", + "MIN": 0.00, + "MAX": 2.0, + "DEFAULT": 1.0 + }, + { + "NAME": "mode", + "VALUES": [ + 0, + 1, + 2, + 3 + ], + "LABELS": [ + "add", + "add mod", + "multiply", + "difference" + ], + "DEFAULT": 0, + "TYPE": "long" + } + ] + +}*/ + + + +// adapted from maxilla inc's https://github.com/maxillacult/ofxPostGlitch/ + + + +float rand(vec2 co){ + return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453); +} + + + +void main() +{ + + vec2 texCoord = isf_FragNormCoord; + + vec4 col = IMG_NORM_PIXEL(inputImage,texCoord); + + vec4 col_r = vec4(0.0); + vec4 col_l = vec4(0.0); + vec4 col_g = vec4(0.0); + + vec2 rand_offset = texCoord + vec2((horizontal_magnitude * rand(vec2(TIME,0.213))-horizontal_magnitude/2.0), (vertical_magnitude * rand(vec2(TIME,0.463467))) - vertical_magnitude / 2.0); + col_r = IMG_NORM_PIXEL(inputImage,rand_offset); + rand_offset = texCoord + vec2((horizontal_magnitude * rand(vec2(TIME,0.5345))-horizontal_magnitude/2.0), (vertical_magnitude * rand(vec2(TIME,0.7875))) - vertical_magnitude / 2.0); + col_l = IMG_NORM_PIXEL(inputImage,rand_offset); + rand_offset = texCoord + vec2((horizontal_magnitude * rand(vec2(TIME,0.456345))-horizontal_magnitude/2.0), (vertical_magnitude * rand(vec2(TIME,0.9432))) - vertical_magnitude / 2.0); + col_g = IMG_NORM_PIXEL(inputImage,rand_offset); + + vec4 color_shift; + color_shift.b = color_magnitude*col_r.b*max(1.0,sin(texCoord.y*1.2)*2.5)*rand(vec2(TIME,0.0342)); + color_shift.r = color_magnitude*col_l.r*max(1.0,sin(texCoord.y*1.2)*2.5)*rand(vec2(TIME,0.5253)); + color_shift.g = color_magnitude*col_g.g*max(1.0,sin(texCoord.y*1.2)*2.5)*rand(vec2(TIME,0.1943)); + + // if doing add maths + if (mode == 0) { + col = col + color_shift; + } + // add mod + else if (mode == 1) { + col = mod(col + color_shift,1.001); + } + // multiply + else if (mode == 2) { + col = mix(col, col * (color_magnitude + color_shift),0.9); + } + // difference + else if (mode == 3) { + col = abs(color_shift - col); + } + + gl_FragColor = col; +} diff --git a/ISF/Cubic Warp.fs b/ISF/Cubic Warp.fs new file mode 100644 index 0000000..2628c1d --- /dev/null +++ b/ISF/Cubic Warp.fs @@ -0,0 +1,73 @@ +/*{ + "CREDIT": "by carter rosenberg", + "ISFVSN": "2", + "CATEGORIES": [ + "Distortion Effect" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "level", + "TYPE": "float", + "MIN": 0.0, + "MAX": 100.0, + "DEFAULT": 1.0 + }, + { + "NAME": "center", + "TYPE": "point2D", + "DEFAULT": [ + 0.5, + 0.5 + ] + } + ] +}*/ + +const float pi = 3.14159265359; + +#ifndef GL_ES +float distance (vec2 center, vec2 pt) +{ + float tmp = pow(center.x-pt.x,2.0)+pow(center.y-pt.y,2.0); + return pow(tmp,0.5); +} +#endif + +void main() { + vec2 loc; + vec2 modifiedCenter; + + loc = isf_FragNormCoord; + modifiedCenter = center / RENDERSIZE; + + // lens distortion coefficient + float k = -0.15; + + float r2 = (loc.x-modifiedCenter.x) * (loc.x-modifiedCenter.x) + (loc.y-modifiedCenter.y) * (loc.y-modifiedCenter.y); + float f = 0.0; + + //only compute the cubic distortion if necessary + if(level == 0.0){ + f = 1.0 + r2 * k; + } + else { + f = 1.0 + r2 * (k + level * sqrt(r2)); + }; + + float zoom = max(sqrt(level),1.0); + + // get the right pixel for the current position + loc.x = f*(loc.x-modifiedCenter.x)/zoom+modifiedCenter.x; + loc.y = f*(loc.y-modifiedCenter.y)/zoom+modifiedCenter.y; + + if ((loc.x < 0.0)||(loc.y < 0.0)||(loc.x > 1.0)||(loc.y > 1.0)) { + gl_FragColor = vec4(0.0); + } + else { + gl_FragColor = IMG_NORM_PIXEL(inputImage,loc); + } +} diff --git a/ISF/Deinterlace.fs b/ISF/Deinterlace.fs new file mode 100644 index 0000000..c7df873 --- /dev/null +++ b/ISF/Deinterlace.fs @@ -0,0 +1,31 @@ +/*{ + "CREDIT": "by zoidberg", + "ISFVSN": "2", + "CATEGORIES": [ + "Geometry Adjustment" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + } + ] +}*/ + +const vec2 pointOffset = vec2(0.0, 1.0); + +void main() { + vec4 outColor; + // "upper" (a.k.a. "the top row") + if (fract((gl_FragCoord.y+0.5)/2.0) == 0.0) { + //gl_FragColor = vec4(1,0,0,1); + outColor = (IMG_PIXEL(inputImage, gl_FragCoord.xy) + IMG_PIXEL(inputImage, gl_FragCoord.xy - pointOffset))/2.0; + gl_FragColor = outColor; + } + // "lower" (a.k.a. "the bottom row") + else { + //gl_FragColor = vec4(0,1,0,1); + outColor = (IMG_PIXEL(inputImage, gl_FragCoord.xy) + IMG_PIXEL(inputImage, gl_FragCoord.xy + pointOffset))/2.0; + gl_FragColor = outColor; + } +} \ No newline at end of file diff --git a/ISF/Diagonal Blur.fs b/ISF/Diagonal Blur.fs new file mode 100644 index 0000000..a71e745 --- /dev/null +++ b/ISF/Diagonal Blur.fs @@ -0,0 +1,78 @@ +/*{ + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Blur" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "width", + "LABEL": "Width", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.0 + }, + { + "NAME": "angle", + "LABEL": "Angle", + "TYPE": "float", + "MIN": -1.0, + "MAX": 1.0, + "DEFAULT": 0.125 + }, + { + "NAME": "quality", + "LABEL": "Quality", + "VALUES": [ + 12, + 8, + 4, + 2 + ], + "LABELS": [ + "Low", + "Mid", + "High", + "Best" + ], + "DEFAULT": 4, + "TYPE": "long" + } + ] +}*/ + + +const float pi = 3.14159265359; + + +void main() { + vec2 loc = isf_FragNormCoord * RENDERSIZE; + + vec2 p1 = vec2(0.0); + vec2 p2 = vec2(1.0); + vec2 vector = vec2(cos(pi * angle),sin(pi * angle)); + + vec4 returnMe; + + if (width > 0.0) { + p1 = loc - width * RENDERSIZE * vector; + p2 = loc + width * RENDERSIZE * vector; + + // now we have the two points to smear between, + float i; + float count = clamp(width * max(RENDERSIZE.x,RENDERSIZE.y) / float(quality), 5.0, 125.0); + vec2 diff = p2 - p1; + for (i = 0.0; i < count; ++i) { + returnMe = returnMe + IMG_PIXEL(inputImage, p1 + diff * (i / (count - 1.0))) / count; + } + } + else { + returnMe = IMG_THIS_PIXEL(inputImage); + } + gl_FragColor = returnMe; +} \ No newline at end of file diff --git a/ISF/Diagonalize.fs b/ISF/Diagonalize.fs new file mode 100644 index 0000000..e16ae1c --- /dev/null +++ b/ISF/Diagonalize.fs @@ -0,0 +1,108 @@ +/*{ + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Stylize" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "width", + "LABEL": "Width", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.0 + }, + { + "NAME": "angle", + "LABEL": "Angle", + "TYPE": "float", + "MIN": -0.5, + "MAX": 0.5, + "DEFAULT": 0.125 + } + ] +}*/ + + +const float pi = 3.14159265359; + + +void main() { + vec2 loc = isf_FragNormCoord * RENDERSIZE; + + // for starters let's just do y = x * tan(angle) + b + + float b = 0.0; + float tanVal = 0.0; + vec2 p1 = vec2(0.0); + vec2 p2 = vec2(1.0); + + if (abs(angle) != 0.5) { + tanVal = tan(pi * angle); + b = (loc.y - loc.x * tanVal)/RENDERSIZE.y; + + if (width > 0.0) { + float w = width * (1.0+abs(tanVal)); + b = w * floor(b/w); + } + b = b * RENDERSIZE.y; + + // if p1 is offscreen, adjust to an onscreen point + p1 = vec2(0.0, b); + + // in this case instead of using where it hits the left edge, use where it hits the bottom, solving x for y = 0.0 (x = (y - b) / tanVal) + if (p1.y < 0.0) { + p1 = vec2(0.0-b / tanVal, 0.0); + } + // in this case instead of using where it hits the left edge, use where it hits the top, solving x for y = 1.0 (x = (y - b) / tanVal) + else if (p1.y > RENDERSIZE.y) { + p1 = vec2((RENDERSIZE.x - b) / tanVal, RENDERSIZE.y); + } + + // get the right side edge + p2 = vec2(RENDERSIZE.x, RENDERSIZE.x * tanVal + b); + + // if p2 is offscreen, adjust to an onscreen point + // in this case instead of using where it hits the right edge, use where it hits the bottom, solving x for y = 0.0 (x = (y - b) / tanVal) + if (p2.y < 0.0) { + p2 = vec2(- b / tanVal, 0.0); + } + // in this case instead of using where it hits the right edge, use where it hits the top, solving x for y = 1.0 (x = (y - b) / tanVal) + else if (p2.y > RENDERSIZE.y) { + p2 = vec2((RENDERSIZE.y - b) / tanVal, RENDERSIZE.y); + } + + } + // vertical lines! set p1 & p2 to fixed x with y = 0.0 and 1.0 + else { + if (angle > 0.0) { + p1 = vec2(loc.x, 0.0); + p2 = vec2(loc.x, RENDERSIZE.y); + } + else { + p2 = vec2(loc.x, 0.0); + p1 = vec2(loc.x, RENDERSIZE.y); + } + if (width > 0.0) { + p1.x = RENDERSIZE.x * width * floor((loc.x/RENDERSIZE.x) / width); + p2.x = p1.x; + } + } + + // now average 5 points on the line, p1, p2, their midpoint, and the mid points of those + // midpoint of the line + vec2 mid = (p1 + p2) / 2.0; + + vec4 returnMe = (IMG_PIXEL(inputImage, p1) + IMG_PIXEL(inputImage, (p1 + mid) / 2.0) + IMG_PIXEL(inputImage, mid) + IMG_PIXEL(inputImage, (p2 + mid) / 2.0) + IMG_PIXEL(inputImage, p2)) / 5.0; + //vec4 returnMe = IMG_PIXEL(inputImage, p2); + + gl_FragColor = returnMe; +} + + + diff --git a/ISF/Digital Clock.fs b/ISF/Digital Clock.fs new file mode 100644 index 0000000..c84d5ed --- /dev/null +++ b/ISF/Digital Clock.fs @@ -0,0 +1,187 @@ +/* +{ + "CATEGORIES" : [ + "Generator", + "Clock" + ], + "DESCRIPTION" : "Shows the current time of day or time since the composition started", + "ISFVSN" : "2", + "INPUTS" : [ + { + "NAME" : "colorInput", + "TYPE" : "color", + "DEFAULT" : [ + 1, + 0.5899132640831176, + 0, + 1 + ], + "LABEL" : "Color" + }, + { + "VALUES" : [ + 0, + 1, + 2 + ], + "NAME" : "clockMode", + "TYPE" : "long", + "DEFAULT" : 0, + "LABEL" : "Clock Mode", + "LABELS" : [ + "Time", + "Countdown", + "Counter" + ] + }, + { + "NAME" : "yOffset", + "TYPE" : "float", + "MAX" : 1, + "DEFAULT" : 0, + "MIN" : -1, + "LABEL" : "Y Offset" + }, + { + "NAME" : "blinkingColons", + "TYPE" : "bool", + "DEFAULT" : 1, + "LABEL" : "Blink" + }, + { + "NAME" : "twentyFourHourStyle", + "TYPE" : "bool", + "LABEL" : "24 Hour" + } + ], + "PASSES" : [ + { + + } + ], + "CREDIT" : "VIDVOX" +} +*/ + + + +float segment(vec2 uv, bool On) { + return (On) ? (1.0 - smoothstep(0.05,0.15,abs(uv.x))) * + (1.-smoothstep(0.35,0.55,abs(uv.y)+abs(uv.x))) + : 0.; +} + +float digit(vec2 uv,int num) { + float seg= 0.; + seg += segment(uv.yx+vec2(-1., 0.),num!=-1 && num!=1 && num!=4 ); + seg += segment(uv.xy+vec2(-.5,-.5),num!=-1 && num!=1 && num!=2 && num!=3 && num!=7); + seg += segment(uv.xy+vec2( .5,-.5),num!=-1 && num!=5 && num!=6 ); + seg += segment(uv.yx+vec2( 0., 0.),num!=-1 && num!=0 && num!=1 && num!=7 ); + seg += segment(uv.xy+vec2(-.5, .5),num==0 || num==2 || num==6 || num==8 ); + seg += segment(uv.xy+vec2( .5, .5),num!=-1 && num!=2 ); + seg += segment(uv.yx+vec2( 1., 0.),num!=-1 && num!=1 && num!=4 && num!=7 ); + return seg; +} + +float showNum(vec2 uv,int nr, bool zeroTrim) { // nr: 2 digits + sgn . zeroTrim: trim leading "0" + if (abs(uv.x)>2.*1.5 || abs(uv.y)>1.2) return 0.; + + if (nr<0) { + nr = -nr; + if (uv.x>1.5) { + uv.x -= 2.; + return segment(uv.yx,true); // minus sign. + } + } + + if (uv.x>0.) { + nr /= 10; if (nr==0 && zeroTrim) nr = -1; + uv -= vec2(.75,0.); + } else { + uv += vec2(.75,0.); + nr = int(mod(float(nr),10.)); + } + + return digit(uv,nr); +} + +float colon(vec2 uv, vec2 cCenter, float cRadius) { + float returnMe = distance(uv,cCenter); + if (returnMe > cRadius) + returnMe = 0.0; + else + returnMe = 1.0 - pow(returnMe / cRadius,4.0); + return returnMe; +} + + + +// a simplfied version of the number drawing from http://www.interactiveshaderformat.com/sketches/120 + + + + +void main() { + vec4 returnMe = vec4(0.0); + vec2 uv = isf_FragNormCoord; + float adjustedOffset = (yOffset*1.2*(RENDERSIZE.y/RENDERSIZE.x)); + vec2 loc = uv; + loc.y = loc.y - adjustedOffset; + + // The first element of the vector is the year, the second element is the month, + // the third element is the day, and the fourth element is the time (in seconds) within the day. + vec4 currentDate = DATE; + if (clockMode == 1) + currentDate.a = 86400.0 - currentDate.a; + else if (clockMode == 2) + currentDate = vec4(TIME); + + float tmpVal = currentDate.a; + float h = 0.0; + float m = 0.0; + float s = 0.0; + + s = mod(tmpVal,60.0); + tmpVal = tmpVal / 60.0; + m = mod(tmpVal,60.0); + tmpVal = tmpVal / 60.0; + h = mod(tmpVal,60.0); + if ((!twentyFourHourStyle)&&(clockMode == 0)) { + h = mod(h,12.0); + if (h < 1.0) + h = 12.0; + } + + float seg = 0.0; + int displayTime = 0; + + if (loc.x < 0.3) { + loc.x = 1.0 - (loc.x + 0.37); + loc = (loc * 3.0 - 1.5) * 4.0; + displayTime = int(h); + } + else if (loc.x < 0.6) { + loc.x = 1.0 - (loc.x+0.05); + loc = (loc * 3.0 - 1.5) * 4.0; + displayTime = int(m); + } + else { + loc.x = 1.0 - (loc.x - 0.3); + loc = (loc * 3.0 - 1.5) * 4.0; + displayTime = int(s); + } + + seg = showNum(loc,displayTime,false); + + if ((!blinkingColons)||(mod(currentDate.a,1.0)<0.5)) { + seg += colon(uv,vec2(0.293,0.53+adjustedOffset),0.015); + seg += colon(uv,vec2(0.293,0.47+adjustedOffset),0.015); + + seg += colon(uv,vec2(0.633,0.53+adjustedOffset),0.015); + seg += colon(uv,vec2(0.633,0.47+adjustedOffset),0.015); + } + if (seg > 0.0) + returnMe = colorInput * seg; + + gl_FragColor = returnMe; +} diff --git a/ISF/Dilate-Fast.fs b/ISF/Dilate-Fast.fs new file mode 100644 index 0000000..546dfbb --- /dev/null +++ b/ISF/Dilate-Fast.fs @@ -0,0 +1,152 @@ +/*{ + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Stylize", + "Blur" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "intensity", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.25 + }, + { + "NAME": "radius", + "TYPE": "float", + "MIN": 1.0, + "MAX": 15.0, + "DEFAULT": 6.0 + } + ], + "PASSES": [ + { + "TARGET": "halfSize", + "WIDTH": "floor($WIDTH/2.0)", + "HEIGHT": "floor($HEIGHT/2.0)", + "DESCRIPTION": "pass 0, 1x horiz sampling (3 wide total) to prevent data loss" + }, + { + "TARGET": "quarterSize", + "WIDTH": "floor($WIDTH/4.0)", + "HEIGHT": "floor($HEIGHT/4.0)", + "DESCRIPTION": "pass 1, vert sampling, use radius (size is being reduced, halve coords deltas when sampling)" + }, + { + "TARGET": "quarterSizePassB", + "WIDTH": "floor($WIDTH/2.0)", + "HEIGHT": "floor($HEIGHT/2.0)", + "DESCRIPTION": "pass 2, horiz sampling, use radius (size is being increased, use normal coords deltas)" + }, + { + "DESCRIPTION": "pass 3, last pass- samples the input image and the quarterSizePassB to generate the final image at the full original resolution" + } + ] +}*/ + + + +vec3 rgb2hsv(vec3 c); + +void main() +{ + + // generally speaking, sample a bunch of pixels, for each sample convert color val to HSV, if luma is greater than max luma, that's the new color + vec2 tmpCoord; + float maxLuma; + vec4 maxLumaRGBColor = vec4(0.0); + vec4 sampleColorRGB; + vec4 sampleColorHSV; + vec2 pixelWidth = 1.0/RENDERSIZE.xy; + float localBlurRadius; + bool vertFlag = false; + + if (PASSINDEX != 3) { + // pass 0 and 2 are doing horizontal erosion + if (PASSINDEX==1) + vertFlag = true; + // the first pass should have a blur radius of 1.0 simply to prevent the loss of information while reducing resolution + if (PASSINDEX==0) + localBlurRadius = 1.0; + // other passes go by the blur radius! + else + localBlurRadius = float(int(radius)); + // sample pixels as per the blur radius... + for (float i=0.; i<=localBlurRadius; ++i) { + if (PASSINDEX==0) { + tmpCoord = vec2(clamp(isf_FragNormCoord.x+(i*pixelWidth.x), 0., 1.), isf_FragNormCoord.y); + sampleColorRGB = IMG_NORM_PIXEL(inputImage, tmpCoord); + } + else if (PASSINDEX==1) { + tmpCoord = vec2(isf_FragNormCoord.x, clamp(isf_FragNormCoord.y+(i*pixelWidth.y/2.), 0., 1.)); + sampleColorRGB = IMG_NORM_PIXEL(halfSize, tmpCoord); + } + else if (PASSINDEX==2) { + tmpCoord = vec2(clamp(isf_FragNormCoord.x+(i*pixelWidth.x), 0., 1.), isf_FragNormCoord.y); + sampleColorRGB = IMG_NORM_PIXEL(quarterSize, tmpCoord); + } + // if this is the first sample for this fragment, don't bother comparing- just set the max luma stuff + if (i == 0.) { + maxLuma = rgb2hsv(sampleColorRGB.rgb).b; + maxLumaRGBColor = sampleColorRGB; + } + // else this isn't the first sample... + else { + // compare, determine if it's the max luma + sampleColorRGB = mix(maxLumaRGBColor, sampleColorRGB, 1.*intensity/i); + sampleColorHSV.rgb = rgb2hsv(sampleColorRGB.rgb); + if (sampleColorHSV.b < maxLuma) { + maxLuma = sampleColorHSV.b; + maxLumaRGBColor = sampleColorRGB; + } + // do another sample for the negative coordinate + if (PASSINDEX==0) { + tmpCoord = vec2(clamp(isf_FragNormCoord.x-(i*pixelWidth.x), 0., 1.), isf_FragNormCoord.y); + sampleColorRGB = IMG_NORM_PIXEL(inputImage, tmpCoord); + } + else if (PASSINDEX==1) { + tmpCoord = vec2(isf_FragNormCoord.x, clamp(isf_FragNormCoord.y-(i*pixelWidth.y/2.), 0., 1.)); + sampleColorRGB = IMG_NORM_PIXEL(halfSize, tmpCoord); + } + else if (PASSINDEX==2) { + tmpCoord = vec2(clamp(isf_FragNormCoord.x-(i*pixelWidth.x), 0., 1.), isf_FragNormCoord.y); + sampleColorRGB = IMG_NORM_PIXEL(quarterSize, tmpCoord); + } + sampleColorRGB = mix(maxLumaRGBColor, sampleColorRGB, 1.*intensity/i); + sampleColorHSV.rgb = rgb2hsv(sampleColorRGB.rgb); + if (sampleColorHSV.b < maxLuma) { + maxLuma = sampleColorHSV.b; + maxLumaRGBColor = sampleColorRGB; + } + } + } + gl_FragColor = maxLumaRGBColor; + } + // last pass + else if (PASSINDEX==3) { + vec4 origPixel = IMG_NORM_PIXEL(inputImage,isf_FragNormCoord); + vec4 erodedPixel = IMG_NORM_PIXEL(quarterSizePassB,isf_FragNormCoord); + vec4 finalPixel = min(origPixel,erodedPixel); + gl_FragColor = mix(origPixel,finalPixel, clamp(min(radius-1.0, intensity*10.0), 0., 1.)); + } +} + + +vec3 rgb2hsv(vec3 c) { + vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); + //vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g)); + //vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r)); + vec4 p = c.g < c.b ? vec4(c.bg, K.wz) : vec4(c.gb, K.xy); + vec4 q = c.r < p.x ? vec4(p.xyw, c.r) : vec4(c.r, p.yzx); + + float d = q.x - min(q.w, q.y); + float e = 1.0e-10; + return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x); +} + diff --git a/ISF/Dilate.fs b/ISF/Dilate.fs new file mode 100644 index 0000000..9fb1d72 --- /dev/null +++ b/ISF/Dilate.fs @@ -0,0 +1,133 @@ +/*{ + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Stylize", + "Blur" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "intensity", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.0 + }, + { + "NAME": "radius", + "TYPE": "float", + "MIN": 1.0, + "MAX": 15.0, + "DEFAULT": 2.0 + } + ], + "PASSES": [ + { + "TARGET": "firstPass" + }, + { + + } + ] +}*/ + + + +vec3 rgb2hsv(vec3 c); + +void main() +{ + + // generally speaking, sample a bunch of pixels, for each sample convert color val to HSV, if luma is greater than max luma, that's the new color + vec2 tmpCoord; + float maxLuma; + vec4 maxLumaRGBColor = vec4(0.0); + vec4 sampleColorRGB; + vec4 sampleColorHSV; + + if (PASSINDEX==0) { + // 5 samples on either side + the source pixel = 11 total samples + for (float i=0.; i<=float(int(radius)); ++i) { + tmpCoord = vec2(clamp(gl_FragCoord.x+i,0.,RENDERSIZE.x), gl_FragCoord.y); + sampleColorRGB = IMG_PIXEL(inputImage, tmpCoord); + // if this is the first sample for this fragment, don't bother comparing- just set the max luma stuff + if (i == 0.) { + maxLuma = rgb2hsv(sampleColorRGB.rgb).b; + maxLumaRGBColor = sampleColorRGB; + } + // else this isn't the first sample... + else { + // compare, determine if it's the max luma + sampleColorRGB = mix(maxLumaRGBColor, sampleColorRGB, 1.*intensity/i); + sampleColorHSV.rgb = rgb2hsv(sampleColorRGB.rgb); + if (sampleColorHSV.b < maxLuma) { + maxLuma = sampleColorHSV.b; + maxLumaRGBColor = sampleColorRGB; + } + // do another sample for the negative coordinate + tmpCoord = vec2(clamp(gl_FragCoord.x-i,0.,RENDERSIZE.x), gl_FragCoord.y); + sampleColorRGB = IMG_PIXEL(inputImage, tmpCoord); + sampleColorRGB = mix(maxLumaRGBColor, sampleColorRGB, 1.*intensity/i); + sampleColorHSV.rgb = rgb2hsv(sampleColorRGB.rgb); + if (sampleColorHSV.b < maxLuma) { + maxLuma = sampleColorHSV.b; + maxLumaRGBColor = sampleColorRGB; + } + } + } + gl_FragColor = maxLumaRGBColor; + + } + else if (PASSINDEX==1) { + // 5 samples up and down + the source pixel = 11 total samples + for (float i=0.; i<=float(int(radius)); ++i) { + tmpCoord = vec2(gl_FragCoord.x, clamp(gl_FragCoord.y+i,0.,RENDERSIZE.y)); + sampleColorRGB = IMG_PIXEL(firstPass, tmpCoord); + // if this is the first sample for this fragment, don't bother comparing- just set the max luma stuff + if (i == 0.) { + maxLuma = rgb2hsv(sampleColorRGB.rgb).b; + maxLumaRGBColor = sampleColorRGB; + } + // else this isn't the first sample... + else { + // compare, determine if it's the max luma + sampleColorRGB = mix(maxLumaRGBColor, sampleColorRGB, 1.*intensity/i); + sampleColorHSV.rgb = rgb2hsv(sampleColorRGB.rgb); + if (sampleColorHSV.b < maxLuma) { + maxLuma = sampleColorHSV.b; + maxLumaRGBColor = sampleColorRGB; + } + // do another sample for the negative coordinate + tmpCoord = vec2(gl_FragCoord.x, clamp(gl_FragCoord.y-i,0.,RENDERSIZE.y)); + sampleColorRGB = IMG_PIXEL(firstPass, tmpCoord); + sampleColorRGB = mix(maxLumaRGBColor, sampleColorRGB, 1.*intensity/i); + sampleColorHSV.rgb = rgb2hsv(sampleColorRGB.rgb); + if (sampleColorHSV.b < maxLuma) { + maxLuma = sampleColorHSV.b; + maxLumaRGBColor = sampleColorRGB; + } + } + } + gl_FragColor = maxLumaRGBColor; + + } + +} + + +vec3 rgb2hsv(vec3 c) { + vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); + //vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g)); + //vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r)); + vec4 p = c.g < c.b ? vec4(c.bg, K.wz) : vec4(c.gb, K.xy); + vec4 q = c.r < p.x ? vec4(p.xyw, c.r) : vec4(c.r, p.yzx); + + float d = q.x - min(q.w, q.y); + float e = 1.0e-10; + return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x); +} + diff --git a/ISF/Dirty Lens.fs b/ISF/Dirty Lens.fs new file mode 100644 index 0000000..e0d987f --- /dev/null +++ b/ISF/Dirty Lens.fs @@ -0,0 +1,166 @@ +/* +{ + "CATEGORIES" : [ + "Film", + "Masking" + ], + "DESCRIPTION" : "Value Noise", + "INPUTS" : [ + { + "NAME" : "inputImage", + "TYPE" : "image" + }, + { + "NAME" : "scale", + "TYPE" : "float", + "MAX" : 100, + "DEFAULT" : 9, + "MIN" : 0, + "LABEL" : "Dirt Size" + }, + { + "NAME" : "brightness", + "TYPE" : "float", + "MAX" : 4, + "DEFAULT" : 0.5, + "MIN" : 0, + "LABEL" : "Dirt Thickness" + }, + { + "NAME" : "brightnessCurve", + "TYPE" : "float", + "MAX" : 4, + "DEFAULT" : 1, + "LABEL" : "Dirt Shape", + "MIN" : 1 + }, + { + "NAME" : "radius", + "TYPE" : "float", + "MAX" : 1, + "DEFAULT" : 0.5, + "LABEL" : "Dirt Spread", + "MIN" : 0 + }, + { + "NAME" : "noiseSeed", + "TYPE" : "float", + "MAX" : 1, + "DEFAULT" : 0, + "MIN" : 0, + "LABEL" : "Dirt Seed" + }, + { + "LABELS" : [ + "Original", + "Multiply", + "Replace" + ], + "NAME" : "alphaMode", + "TYPE" : "long", + "IDENTITY" : 0, + "LABEL" : "Alpha Mode", + "VALUES" : [ + 0, + 1, + 2 + ] + } + ], + "ISFVSN" : "2", + "CREDIT" : "Inigo Quilez ported by @colin_movecraft and VIDVOX" +} +*/ + + + +// Value Noise (http://en.wikipedia.org/wiki/Value_noise), not to be confused with Perlin's +// Noise, is probably the simplest way to generate noise (a random smooth signal with +// mostly all its energy in the low frequencies) suitable for procedural texturing/shading, +// modeling and animation. +// +// It produces lowe quality noise than Gradient Noise (https://www.shadertoy.com/view/XdXGW8) +// but it is slightly faster to compute. When used in a fractal construction, the blockyness +// of Value Noise gets qcuikly hidden, making it a very popular alternative to Gradient Noise. +// +// The princpiple is to create a virtual grid/latice all over the plane, and assign one +// random value to every vertex in the grid. When querying/requesting a noise value at +// an arbitrary point in the plane, the grid cell in which the query is performed is +// determined (line 30), the four vertices of the grid are determined and their random +// value fetched (lines 35 to 38) and then bilinearly interpolated (lines 35 to 38 again) +// with a smooth interpolant (line 31 and 33). + + +// Value Noise 2D, Derivatives: https://www.shadertoy.com/view/4dXBRH +// Gradient Noise 2D, Derivatives: https://www.shadertoy.com/view/XdXBRH +// Value Noise 3D, Derivatives: https://www.shadertoy.com/view/XsXfRH +// Gradient Noise 3D, Derivatives: https://www.shadertoy.com/view/4dffRH +// Value Noise 2D : https://www.shadertoy.com/view/lsf3WH +// Value Noise 3D : https://www.shadertoy.com/view/4sfGzS +// Gradient Noise 2D : https://www.shadertoy.com/view/XdXGW8 +// Gradient Noise 3D : https://www.shadertoy.com/view/Xsl3Dl +// Simplex Noise 2D : https://www.shadertoy.com/view/Msf3WH + + +float hash(vec2 p) // replace this by something better +{ + p = 50.0*fract(noiseSeed + p*0.3183099 + vec2(0.71,0.113)); + return -1.0+2.0*fract( p.x*p.y*(p.x+p.y) ); +} + +float noise( in vec2 p ) +{ + vec2 i = floor( p ); + vec2 f = fract( p ); + + vec2 u = f*f*(3.0-2.0*f); + + return mix( mix( hash( i + vec2(0.0,0.0) ), + hash( i + vec2(1.0,0.0) ), u.x), + mix( hash( i + vec2(0.0,1.0) ), + hash( i + vec2(1.0,1.0) ), u.x), u.y); +} + +float map(float n, float i1, float i2, float o1, float o2){ + return o1 + (o2-o1) * (n-i1)/(i2-i1); + +} + +void main(){ + vec2 p = gl_FragCoord.xy / RENDERSIZE; + + vec2 uv = p*vec2(RENDERSIZE.x/RENDERSIZE.y,1.0); + float f = 0.0; + + //fbm - fractal noise (4 octaves) + { + uv *= scale; + mat2 m = mat2( 1.6, 1.2, -1.2, 1.6 ); + f = 0.5000*noise( uv ); uv = m*uv; + f += 0.2500*noise( uv ); uv = m*uv; + f += 0.1250*noise( uv ); uv = m*uv; + f += 0.0625*noise( uv ); uv = m*uv; + } + + f = 1.0-pow(f,(5.0-brightnessCurve))*brightness; + + float d = distance(isf_FragNormCoord,vec2(0.5)); + if (d > radius) { + f = f + (d-radius); + } + + f = (f > 1.0) ? 1.0 : f; + + vec4 returnMe = IMG_THIS_PIXEL(inputImage) * vec4( f, f, f, 1.0 ); + if (alphaMode == 1) + returnMe.a *= f; + else if (alphaMode == 2) + returnMe.a = f; + gl_FragColor = returnMe; +} + + + +// The MIT License +// Copyright © 2013 Inigo Quilez +// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/ISF/Displace.fs b/ISF/Displace.fs new file mode 100644 index 0000000..7c31d07 --- /dev/null +++ b/ISF/Displace.fs @@ -0,0 +1,108 @@ +/* +{ + "CATEGORIES" : [ + "Distortion Effect" + ], + "DESCRIPTION" : "Simple Displace", + "ISFVSN" : "2", + "INPUTS" : [ + { + "NAME" : "inputImage", + "TYPE" : "image" + }, + { + "NAME" : "displaceImage", + "TYPE" : "image", + "LABEL" : "displace image" + }, + { + "NAME" : "uDisplaceAmt", + "TYPE" : "float", + "MAX" : 2, + "DEFAULT" : 0, + "MIN" : -2 + }, + { + "LABELS" : [ + "Luma", + "R", + "G", + "B", + "A" + ], + "NAME" : "xComponent", + "TYPE" : "long", + "DEFAULT" : 1, + "VALUES" : [ + 0, + 1, + 2, + 3, + 4 + ] + }, + { + "LABELS" : [ + "Luma", + "R", + "G", + "B", + "A" + ], + "NAME" : "yComponent", + "TYPE" : "long", + "DEFAULT" : 2, + "VALUES" : [ + 0, + 1, + 2, + 3, + 4 + ] + }, + { + "NAME" : "relativeShift", + "TYPE" : "bool", + "DEFAULT" : 0 + } + ], + "CREDIT" : "by @colin_movecraft" +} +*/ + + + +void main(){ + vec2 p = isf_FragNormCoord.xy; + vec4 displacePixel = IMG_NORM_PIXEL(displaceImage, p); + + float r = (displacePixel.r); + float g = (displacePixel.g); + float b = (displacePixel.b); + float a = (displacePixel.a); + float avg = (r+g+b)/3.0; + + vec2 displace = vec2(avg,avg); + if (xComponent==1) + displace.x = r; + else if (xComponent==2) + displace.x = g; + else if (xComponent==3) + displace.x = b; + else if (xComponent==4) + displace.x = a; + + if (yComponent==1) + displace.y = r; + else if (yComponent==2) + displace.y = g; + else if (yComponent==3) + displace.y = b; + else if (yComponent==4) + displace.y = a; + + displace = (relativeShift) ? 2.0 * (displace - vec2(0.5)) : displace; + displace *= uDisplaceAmt; + + gl_FragColor = IMG_NORM_PIXEL(inputImage,p+displace); +} \ No newline at end of file diff --git a/ISF/Dither-Bayer.fs b/ISF/Dither-Bayer.fs new file mode 100644 index 0000000..f9c8690 --- /dev/null +++ b/ISF/Dither-Bayer.fs @@ -0,0 +1,216 @@ +/*{ + "DESCRIPTION": "Bayer style dithering", + "CREDIT": "Hugh Kennedy, adapted by David Lublin", + "CATEGORIES": [ + "Utility", "Color Effect","Halftone Effect" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "colorize", + "TYPE": "float", + "DEFAULT": 0.0, + "MIN": 0.0, + "MAX": 1.0 + }, + { + "NAME": "matrixMode", + "TYPE": "long", + "VALUES": [ + 0, + 1, + 2 + ], + "LABELS": [ + "2x2", + "4x4", + "8x8" + ], + "DEFAULT": 2 + } + ] + +}*/ + + + +// based on https://github.com/hughsk/glsl-dither + +float luma(vec3 color) { + return (color.r + color.g + color.b) / 3.0; +} + +float luma(vec4 color) { + return color.a * (color.r + color.g + color.b) / 3.0; +} + +float dither8x8(vec2 position, float brightness) { + int x = int(mod(position.x, 8.0)); + int y = int(mod(position.y, 8.0)); + int index = x + y * 8; + float limit = 0.0; + + if (x < 8) { + if (index == 0) limit = 0.015625; + if (index == 1) limit = 0.515625; + if (index == 2) limit = 0.140625; + if (index == 3) limit = 0.640625; + if (index == 4) limit = 0.046875; + if (index == 5) limit = 0.546875; + if (index == 6) limit = 0.171875; + if (index == 7) limit = 0.671875; + if (index == 8) limit = 0.765625; + if (index == 9) limit = 0.265625; + if (index == 10) limit = 0.890625; + if (index == 11) limit = 0.390625; + if (index == 12) limit = 0.796875; + if (index == 13) limit = 0.296875; + if (index == 14) limit = 0.921875; + if (index == 15) limit = 0.421875; + if (index == 16) limit = 0.203125; + if (index == 17) limit = 0.703125; + if (index == 18) limit = 0.078125; + if (index == 19) limit = 0.578125; + if (index == 20) limit = 0.234375; + if (index == 21) limit = 0.734375; + if (index == 22) limit = 0.109375; + if (index == 23) limit = 0.609375; + if (index == 24) limit = 0.953125; + if (index == 25) limit = 0.453125; + if (index == 26) limit = 0.828125; + if (index == 27) limit = 0.328125; + if (index == 28) limit = 0.984375; + if (index == 29) limit = 0.484375; + if (index == 30) limit = 0.859375; + if (index == 31) limit = 0.359375; + if (index == 32) limit = 0.0625; + if (index == 33) limit = 0.5625; + if (index == 34) limit = 0.1875; + if (index == 35) limit = 0.6875; + if (index == 36) limit = 0.03125; + if (index == 37) limit = 0.53125; + if (index == 38) limit = 0.15625; + if (index == 39) limit = 0.65625; + if (index == 40) limit = 0.8125; + if (index == 41) limit = 0.3125; + if (index == 42) limit = 0.9375; + if (index == 43) limit = 0.4375; + if (index == 44) limit = 0.78125; + if (index == 45) limit = 0.28125; + if (index == 46) limit = 0.90625; + if (index == 47) limit = 0.40625; + if (index == 48) limit = 0.25; + if (index == 49) limit = 0.75; + if (index == 50) limit = 0.125; + if (index == 51) limit = 0.625; + if (index == 52) limit = 0.21875; + if (index == 53) limit = 0.71875; + if (index == 54) limit = 0.09375; + if (index == 55) limit = 0.59375; + if (index == 56) limit = 1.0; + if (index == 57) limit = 0.5; + if (index == 58) limit = 0.875; + if (index == 59) limit = 0.375; + if (index == 60) limit = 0.96875; + if (index == 61) limit = 0.46875; + if (index == 62) limit = 0.84375; + if (index == 63) limit = 0.34375; + } + + return brightness < limit ? 0.0 : 1.0; +} + +vec3 dither8x8(vec2 position, vec3 color) { + return color * dither8x8(position, luma(color)); +} + +vec4 dither8x8(vec2 position, vec4 color) { + return vec4(color.rgb * dither8x8(position, luma(color)), 1.0); +} + +float dither4x4(vec2 position, float brightness) { + int x = int(mod(position.x, 4.0)); + int y = int(mod(position.y, 4.0)); + int index = x + y * 4; + float limit = 0.0; + + if (x < 8) { + if (index == 0) limit = 0.0625; + if (index == 1) limit = 0.5625; + if (index == 2) limit = 0.1875; + if (index == 3) limit = 0.6875; + if (index == 4) limit = 0.8125; + if (index == 5) limit = 0.3125; + if (index == 6) limit = 0.9375; + if (index == 7) limit = 0.4375; + if (index == 8) limit = 0.25; + if (index == 9) limit = 0.75; + if (index == 10) limit = 0.125; + if (index == 11) limit = 0.625; + if (index == 12) limit = 1.0; + if (index == 13) limit = 0.5; + if (index == 14) limit = 0.875; + if (index == 15) limit = 0.375; + } + + return brightness < limit ? 0.0 : 1.0; +} + +vec3 dither4x4(vec2 position, vec3 color) { + return color * dither4x4(position, luma(color)); +} + +vec4 dither4x4(vec2 position, vec4 color) { + return vec4(color.rgb * dither4x4(position, luma(color)), 1.0); +} + +float dither2x2(vec2 position, float brightness) { + int x = int(mod(position.x, 2.0)); + int y = int(mod(position.y, 2.0)); + int index = x + y * 2; + float limit = 0.0; + + if (x < 8) { + if (index == 0) limit = 0.25; + if (index == 1) limit = 0.75; + if (index == 2) limit = 1.00; + if (index == 3) limit = 0.50; + } + + return brightness < limit ? 0.0 : 1.0; +} + +vec3 dither2x2(vec2 position, vec3 color) { + return color * dither2x2(position, luma(color)); +} + +vec4 dither2x2(vec2 position, vec4 color) { + return vec4(color.rgb * dither2x2(position, luma(color)), 1.0); +} + + +void main() { + vec4 inputPixelColor = vec4(0.0); + vec2 loc = gl_FragCoord.xy; + // both of these are the same + inputPixelColor = IMG_THIS_PIXEL(inputImage); + + float val = 1.0; + + if (matrixMode == 0) { + val = dither2x2(loc, luma(inputPixelColor)); + } + else if (matrixMode == 1) { + val = dither4x4(loc, luma(inputPixelColor)); + } + else if (matrixMode == 2) { + val = dither8x8(loc, luma(inputPixelColor)); + } + + inputPixelColor = inputPixelColor * vec4(val,val,val,1.0); + + gl_FragColor = mix(vec4(val,val,val,inputPixelColor.a),inputPixelColor,colorize); +} diff --git a/ISF/Dot Screen.fs b/ISF/Dot Screen.fs new file mode 100644 index 0000000..e6f1a8a --- /dev/null +++ b/ISF/Dot Screen.fs @@ -0,0 +1,88 @@ +/*{ + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Halftone Effect" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "sharpness", + "TYPE": "float", + "MIN": 0.0, + "MAX": 10.0, + "DEFAULT": 1.0 + }, + { + "NAME": "angle", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.0 + }, + { + "NAME": "scale", + "TYPE": "float", + "MIN": 0.0, + "MAX": 2.0, + "DEFAULT": 1.0 + }, + { + "NAME": "colorize", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.0 + }, + { + "NAME": "center", + "TYPE": "point2D", + "DEFAULT": [ + 0.5, + 0.5 + ] + } + ] +}*/ + +varying vec2 left_coord; +varying vec2 right_coord; +varying vec2 above_coord; +varying vec2 below_coord; + +varying vec2 lefta_coord; +varying vec2 righta_coord; +varying vec2 leftb_coord; +varying vec2 rightb_coord; + +const float tau = 6.28318530718; + +float pattern() { + float s = sin( angle * tau ), c = cos( angle * tau ); + vec2 tex = isf_FragNormCoord * RENDERSIZE - center; + vec2 point = vec2( c * tex.x - s * tex.y, s * tex.x + c * tex.y ) * max(scale,0.001); + return ( sin( point.x ) * sin( point.y ) ) * 4.0; +} + +void main() { + vec4 color = IMG_THIS_PIXEL(inputImage); + vec4 colorL = IMG_NORM_PIXEL(inputImage, left_coord); + vec4 colorR = IMG_NORM_PIXEL(inputImage, right_coord); + vec4 colorA = IMG_NORM_PIXEL(inputImage, above_coord); + vec4 colorB = IMG_NORM_PIXEL(inputImage, below_coord); + + vec4 colorLA = IMG_NORM_PIXEL(inputImage, lefta_coord); + vec4 colorRA = IMG_NORM_PIXEL(inputImage, righta_coord); + vec4 colorLB = IMG_NORM_PIXEL(inputImage, leftb_coord); + vec4 colorRB = IMG_NORM_PIXEL(inputImage, rightb_coord); + + vec4 final = color + sharpness * (8.0*color - colorL - colorR - colorA - colorB - colorLA - colorRA - colorLB - colorRB); + + float average = ( final.r + final.g + final.b ) / 3.0; + final = vec4( vec3( average * 10.0 - 5.0 + pattern() ), color.a ); + final = mix (color * final, final, 1.0-colorize); + gl_FragColor = final; +} \ No newline at end of file diff --git a/ISF/Dot Screen.vs b/ISF/Dot Screen.vs new file mode 100644 index 0000000..c8b60f7 --- /dev/null +++ b/ISF/Dot Screen.vs @@ -0,0 +1,27 @@ +varying vec2 left_coord; +varying vec2 right_coord; +varying vec2 above_coord; +varying vec2 below_coord; + +varying vec2 lefta_coord; +varying vec2 righta_coord; +varying vec2 leftb_coord; +varying vec2 rightb_coord; + + +void main() +{ + isf_vertShaderInit(); + vec2 texc = vec2(isf_FragNormCoord[0],isf_FragNormCoord[1]); + vec2 d = 1.0/RENDERSIZE; + + left_coord = clamp(vec2(texc.xy + vec2(-d.x , 0)),0.0,1.0); + right_coord = clamp(vec2(texc.xy + vec2(d.x , 0)),0.0,1.0); + above_coord = clamp(vec2(texc.xy + vec2(0,d.y)),0.0,1.0); + below_coord = clamp(vec2(texc.xy + vec2(0,-d.y)),0.0,1.0); + + lefta_coord = clamp(vec2(texc.xy + vec2(-d.x , d.x)),0.0,1.0); + righta_coord = clamp(vec2(texc.xy + vec2(d.x , d.x)),0.0,1.0); + leftb_coord = clamp(vec2(texc.xy + vec2(-d.x , -d.x)),0.0,1.0); + rightb_coord = clamp(vec2(texc.xy + vec2(d.x , -d.x)),0.0,1.0); +} \ No newline at end of file diff --git a/ISF/Double Vision.fs b/ISF/Double Vision.fs new file mode 100644 index 0000000..161defe --- /dev/null +++ b/ISF/Double Vision.fs @@ -0,0 +1,69 @@ + +/*{ + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Stylize" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "hShift", + "LABEL": "H Shift", + "TYPE": "float", + "MIN": -0.05, + "MAX": 0.05, + "DEFAULT": 0.0 + }, + { + "NAME": "vShift", + "LABEL": "V Shift", + "TYPE": "float", + "MIN": -0.05, + "MAX": 0.05, + "DEFAULT": 0.0 + }, + { + "NAME": "mixAmount1", + "LABEL": "Shift Mix", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.5 + }, + { + "NAME": "mixAmount2", + "LABEL": "Original Mix", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.5 + } + ] +}*/ + + + +void main() +{ + vec2 loc = isf_FragNormCoord; + vec2 shift = vec2(hShift, vShift); + + // zoom slightly so that there aren't out of range pixels + float zoomAmount = 1.0 + 2.0 * max(hShift, vShift); + vec2 modifiedCenter = vec2(0.5,0.5); + loc.x = (loc.x - modifiedCenter.x)*(1.0/zoomAmount) + modifiedCenter.x; + loc.y = (loc.y - modifiedCenter.y)*(1.0/zoomAmount) + modifiedCenter.y; + + vec4 color = IMG_NORM_PIXEL(inputImage, isf_FragNormCoord); + vec4 colorL = IMG_NORM_PIXEL(inputImage, clamp(loc - shift,0.0,1.0)); + vec4 colorR = IMG_NORM_PIXEL(inputImage, clamp(loc + shift,0.0,1.0)); + + vec4 outColor = mix(min(colorL, colorR), max(colorL, colorR), mixAmount1); + outColor = mix(min(outColor, color), max(outColor, color), mixAmount2); + + gl_FragColor = outColor; +} \ No newline at end of file diff --git a/ISF/Dual Side Scroller And Flip.fs b/ISF/Dual Side Scroller And Flip.fs new file mode 100644 index 0000000..564de45 --- /dev/null +++ b/ISF/Dual Side Scroller And Flip.fs @@ -0,0 +1,91 @@ +/*{ + "CREDIT": "Inspired by Side Scroller and Flip by BrianChasalow", + "ISFVSN": "2", + "CATEGORIES": [ + "Geometry Adjustment" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "slidetop", + "TYPE": "float", + "MIN": 0.0, + "MAX": 2.0, + "DEFAULT": 0.0 + }, + { + "NAME": "shifttop", + "TYPE": "float", + "MIN": 0.0, + "MAX": 2.0, + "DEFAULT": 0.0 + }, + { + "NAME": "mirrorHorizontaltop", + "TYPE": "bool", + "MIN": false, + "MAX": true, + "DEFAULT": true + }, + { + "NAME": "mirrorVerticaltop", + "TYPE": "bool", + "MIN": false, + "MAX": true, + "DEFAULT": true + }, + { + "NAME": "slidebot", + "TYPE": "float", + "MIN": 0.0, + "MAX": 2.0, + "DEFAULT": 0.0 + }, + { + "NAME": "shiftbot", + "TYPE": "float", + "MIN": 0.0, + "MAX": 2.0, + "DEFAULT": 0.0 + }, + { + "NAME": "mirrorHorizontalbot", + "TYPE": "bool", + "MIN": false, + "MAX": true, + "DEFAULT": true + }, + { + "NAME": "mirrorVerticalbot", + "TYPE": "bool", + "MIN": false, + "MAX": true, + "DEFAULT": true + } + + ] + }*/ + +void main(void) +{ + vec2 pt = isf_FragNormCoord; + float slide = (isf_FragNormCoord.y > 0.5) ? slidetop : slidebot; + float shift = (isf_FragNormCoord.x < 0.5) ? shifttop : shiftbot; + + bool mirrorHorizontal = (isf_FragNormCoord.y > 0.5) ? mirrorHorizontaltop : mirrorHorizontalbot; + bool mirrorVertical = (isf_FragNormCoord.x < 0.5) ? mirrorVerticaltop : mirrorVerticalbot; + pt.x += slide; + pt.y += shift; + vec2 moddedRetard = mod(pt,1.0); + + if(mirrorHorizontal && pt.x >= 1.0 && pt.x <= 2.0) + moddedRetard = vec2(1.0-moddedRetard.x, moddedRetard.y); + if(mirrorVertical && pt.y >= 1.0 && pt.y <= 2.0) + moddedRetard = vec2(moddedRetard.x, 1.0-moddedRetard.y); + + vec4 pixel = IMG_NORM_PIXEL(inputImage, moddedRetard); + gl_FragColor = pixel; +} \ No newline at end of file diff --git a/ISF/Duotone.fs b/ISF/Duotone.fs new file mode 100644 index 0000000..088c96a --- /dev/null +++ b/ISF/Duotone.fs @@ -0,0 +1,85 @@ +/*{ + "CREDIT": "by zoidberg", + "ISFVSN": "2", + "CATEGORIES": [ + "Color Effect" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "threshold", + "TYPE": "float", + "DEFAULT": 0.50 + }, + { + "NAME": "softness", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1, + "DEFAULT": 0.0 + }, + { + "NAME": "brightColor", + "TYPE": "color", + "DEFAULT": [ + 1.0, + 1.0, + 1.0, + 1.0 + ] + }, + { + "NAME": "darkColor", + "TYPE": "color", + "DEFAULT": [ + 0.0, + 0.0, + 0.0, + 1.0 + ] + } + ] +}*/ + +//const vec4 lumcoeff = vec4(0.299, 0.587, 0.114, 0.0); +const vec4 lumcoeff = vec4(0.2126, 0.7152, 0.0722, 0.0); + +void main() { + vec4 srcPixel = IMG_THIS_PIXEL(inputImage); + float luminance = dot(srcPixel,lumcoeff); + //gl_FragColor = (luminance>=threshold) ? (brightColor) : (darkColor); + + // if i'm doing hard edges, it's either one color or the other + if (softness<=0.0) { + gl_FragColor = (luminance>=threshold) ? vec4(brightColor.rgb, srcPixel.a) : vec4(darkColor.rgb, srcPixel.a); + } + // else i'm doing soft edges... + else { + // 'softness' is normalized proportion of luminance on either side of threshold to be interpolated + // e.g.: 'softness' is 0.5 and 'threshold' is 0.5: vals < 0.25 are "dark", vals from 0.25-0.75 are "interpolated", and vals > 0.75 are "light" + vec4 midColor = (brightColor+darkColor)/vec4(2.0); + vec4 dstPixel; + if (luminance>=threshold) { + gl_FragColor = mix(midColor, brightColor, smoothstep(threshold, threshold+((1.0-threshold)*softness), luminance)); + } + else { + gl_FragColor = mix(darkColor, midColor, smoothstep(threshold-((1.0-threshold)*softness), threshold, luminance)); + } + + /* + // 'softness' is the absolute width (in luminance) on either side of the threshold to be interpolated + // e.g.: if softness is 0.25 and threshold is 0.5, vals < 0.25 are "dark", vals from 0.25-0.75 are "smoothed", and vals > 0.75 are "light" + vec4 midColor = (brightColor+darkColor)/vec4(2.0); + vec4 dstPixel; + if (luminance>=threshold) { + gl_FragColor = mix(midColor, brightColor, smoothstep(threshold, threshold+softness, luminance)); + } + else { + gl_FragColor = mix(darkColor, midColor, smoothstep(threshold-softness, threshold, luminance)); + } + */ + } +} diff --git a/ISF/Echo Trace.fs b/ISF/Echo Trace.fs new file mode 100644 index 0000000..0a03777 --- /dev/null +++ b/ISF/Echo Trace.fs @@ -0,0 +1,70 @@ +/*{ + "DESCRIPTION": "Pixel with brightness levels below the threshold do not update.", + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Glitch" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "thresh", + "LABEL": "Threshold", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.0 + }, + { + "NAME": "gain", + "LABEL": "Gain", + "TYPE": "float", + "MIN": 0.0, + "MAX": 2.0, + "DEFAULT": 1.0 + }, + { + "NAME": "hardCutoff", + "LABEL": "Hard Cutoff", + "TYPE": "bool", + "DEFAULT": true + }, + { + "NAME": "invert", + "LABEL": "Invert", + "TYPE": "bool", + "DEFAULT": false + } + ], + "PASSES": [ + { + "TARGET":"bufferVariableNameA", + "FLOAT": true, + "PERSISTENT": true + }, + { + + } + ] + +}*/ + +void main() +{ + vec4 freshPixel = IMG_PIXEL(inputImage,gl_FragCoord.xy); + vec4 stalePixel = IMG_PIXEL(bufferVariableNameA,gl_FragCoord.xy); + float brightLevel = (freshPixel.r + freshPixel.b + freshPixel.g) / 3.0; + if (invert) + brightLevel = 1.0 - brightLevel; + brightLevel = brightLevel * gain; + if (hardCutoff) { + if (brightLevel < thresh) + brightLevel = 1.0; + else + brightLevel = 0.0; + } + gl_FragColor = mix(freshPixel,stalePixel, brightLevel); +} diff --git a/ISF/Edge Blowout.fs b/ISF/Edge Blowout.fs new file mode 100644 index 0000000..bb1fa84 --- /dev/null +++ b/ISF/Edge Blowout.fs @@ -0,0 +1,232 @@ +/* +{ + "CATEGORIES" : [ + "Stylize", + "Glitch" + ], + "DESCRIPTION" : "Stretches the edges out a region of the video", + "INPUTS" : [ + { + "NAME" : "inputImage", + "TYPE" : "image" + }, + { + "MIN" : 0, + "IDENTITY" : 0, + "DEFAULT" : 0.25, + "LABEL" : "Left Edge", + "TYPE" : "float", + "MAX" : 1, + "NAME" : "leftEdge" + }, + { + "MIN" : 0, + "IDENTITY" : 1, + "DEFAULT" : 0.75, + "LABEL" : "Right Edge", + "TYPE" : "float", + "MAX" : 1, + "NAME" : "rightEdge" + }, + { + "MIN" : 0, + "IDENTITY" : 0, + "DEFAULT" : 0.25, + "LABEL" : "Bottom Edge", + "TYPE" : "float", + "MAX" : 1, + "NAME" : "bottomEdge" + }, + { + "MIN" : 0, + "IDENTITY" : 1, + "DEFAULT" : 0.75, + "LABEL" : "Top Edge", + "TYPE" : "float", + "MAX" : 1, + "NAME" : "topEdge" + }, + { + "NAME" : "doHorizontal", + "TYPE" : "bool", + "DEFAULT" : true, + "LABEL" : "Horizontal Bleed" + }, + { + "NAME" : "doVertical", + "TYPE" : "bool", + "DEFAULT" : true, + "LABEL" : "Vertical Bleed" + }, + { + "NAME" : "insideBleed", + "TYPE" : "bool", + "DEFAULT" : true, + "LABEL" : "Inside Bleed" + }, + { + "NAME" : "outsideBleed", + "TYPE" : "bool", + "DEFAULT" : true, + "LABEL" : "Outside Bleed" + } + ], + "ISFVSN" : "2", + "CREDIT" : "VIDVOX" +} +*/ + +void main() { + vec4 outputPixelColor; + float realLeftEdge = (leftEdge < rightEdge) ? leftEdge : rightEdge; + float realRightEdge = (leftEdge > rightEdge) ? leftEdge : rightEdge; + + float realBottomEdge = (bottomEdge < topEdge) ? bottomEdge : topEdge; + float realTopEdge = (bottomEdge > topEdge) ? bottomEdge : topEdge; + + vec2 sampleCoord = isf_FragNormCoord.xy; + + bool insideBox = false; + + vec2 region = vec2(0.0,0.0); + + if (sampleCoord.x < realLeftEdge) { + region.x = 0.0; + } + else if (sampleCoord.x > realRightEdge) { + region.x = 2.0; + } + else { + region.x = 1.0; + } + + if (sampleCoord.y < realBottomEdge) { + region.y = 0.0; + } + else if (sampleCoord.y > realTopEdge) { + region.y = 2.0; + } + else { + region.y = 1.0; + } + + if ((region.x == 1.0) && (region.y == 1.0) && (insideBleed == true)) { + insideBox = true; + } + else if (outsideBleed == true) { + // if we are in the bottom left... + if ((region.x == 0.0) && (region.y == 0.0)) { + if ((doHorizontal) && (doVertical)) { + insideBox = true; + realRightEdge = realLeftEdge; + realLeftEdge = 0.0; + realTopEdge = realBottomEdge; + realBottomEdge = 0.0; + } + } + else if ((region.x == 1.0) && (region.y == 0.0)) { + if ((doHorizontal) && (doVertical)) { + insideBox = true; + realTopEdge = realBottomEdge; + realBottomEdge = 0.0; + } + else if (doVertical) { + insideBox = true; + realTopEdge = realBottomEdge; + realBottomEdge = 0.0; + } + } + else if ((region.x == 2.0) && (region.y == 0.0)) { + if ((doHorizontal) && (doVertical)) { + insideBox = true; + realLeftEdge = realRightEdge; + realRightEdge = 1.0; + realTopEdge = realBottomEdge; + realBottomEdge = 0.0; + } + } + else if ((region.x == 0.0) && (region.y == 1.0)) { + if (doHorizontal) { + insideBox = true; + realRightEdge = realLeftEdge; + realLeftEdge = 0.0; + } + } + else if ((region.x == 2.0) && (region.y == 1.0)) { + if (doHorizontal) { + insideBox = true; + realLeftEdge = realRightEdge; + realRightEdge = 1.0; + } + } + else if ((region.x == 0.0) && (region.y == 2.0)) { + if ((doHorizontal) && (doVertical)) { + insideBox = true; + realRightEdge = realLeftEdge; + realLeftEdge = 0.0; + realBottomEdge = realTopEdge; + realTopEdge = 1.0; + } + } + else if ((region.x == 1.0) && (region.y == 2.0)) { + if (doVertical) { + insideBox = true; + realBottomEdge = realTopEdge; + realTopEdge = 1.0; + } + } + else if ((region.x == 2.0) && (region.y == 2.0)) { + if ((doHorizontal) && (doVertical)) { + insideBox = true; + realLeftEdge = realRightEdge; + realRightEdge = 1.0; + realBottomEdge = realTopEdge; + realTopEdge = 1.0; + } + } + } + + // if we're doing inside bleed + if (insideBox) { + + // how close are we to each edge? + if ((doHorizontal) && (doVertical)) { + float leftDistance = sampleCoord.x - realLeftEdge; + float rightDistance = realRightEdge - sampleCoord.x; + float bottomDistance = sampleCoord.y - realBottomEdge; + float topDistance = realTopEdge - sampleCoord.y; + float totalDistance = (leftDistance + rightDistance + bottomDistance + topDistance); + + vec4 leftPixel = IMG_NORM_PIXEL(inputImage, vec2(realLeftEdge, sampleCoord.y)); + vec4 rightPixel = IMG_NORM_PIXEL(inputImage, vec2(realRightEdge, sampleCoord.y)); + vec4 bottomPixel = IMG_NORM_PIXEL(inputImage, vec2(sampleCoord.x, realBottomEdge)); + vec4 topPixel = IMG_NORM_PIXEL(inputImage, vec2(sampleCoord.x, realTopEdge)); + + outputPixelColor = (rightDistance * leftPixel + leftDistance * rightPixel + topDistance * bottomPixel + bottomDistance * topPixel) / totalDistance; + } + else if (doHorizontal) { + float leftDistance = sampleCoord.x - realLeftEdge; + float rightDistance = realRightEdge - sampleCoord.x; + float totalDistance = leftDistance + rightDistance; + vec4 leftPixel = IMG_NORM_PIXEL(inputImage, vec2(realLeftEdge, sampleCoord.y)); + vec4 rightPixel = IMG_NORM_PIXEL(inputImage, vec2(realRightEdge, sampleCoord.y)); + outputPixelColor = (rightDistance * leftPixel + leftDistance * rightPixel) / totalDistance; + } + else if (doVertical) { + float bottomDistance = sampleCoord.y - realBottomEdge; + float topDistance = realTopEdge - sampleCoord.y; + float totalDistance = bottomDistance + topDistance; + vec4 bottomPixel = IMG_NORM_PIXEL(inputImage, vec2(sampleCoord.x, realBottomEdge)); + vec4 topPixel = IMG_NORM_PIXEL(inputImage, vec2(sampleCoord.x, realTopEdge)); + outputPixelColor = (topDistance * bottomPixel + bottomDistance * topPixel) / totalDistance; + } + else { + outputPixelColor = IMG_NORM_PIXEL(inputImage, sampleCoord); + } + } + else { + outputPixelColor = IMG_NORM_PIXEL(inputImage, sampleCoord); + } + + gl_FragColor = outputPixelColor; +} diff --git a/ISF/Edge Blur.fs b/ISF/Edge Blur.fs new file mode 100644 index 0000000..99684ff --- /dev/null +++ b/ISF/Edge Blur.fs @@ -0,0 +1,171 @@ +/*{ + "CREDIT": "by zoidberg", + "ISFVSN": "2", + "CATEGORIES": [ + "Blur" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "intensity", + "TYPE": "float", + "MIN": 0.0, + "MAX": 20.0, + "DEFAULT": 5.0 + }, + { + "NAME": "blurAmount", + "TYPE": "float", + "MIN": 0.0, + "MAX": 24.0, + "DEFAULT": 10.0 + }, + { + "NAME": "invert_map", + "TYPE": "bool", + "DEFAULT": 0.0 + } + ], + "PASSES": [ + { + "TARGET": "halfSizeBaseRender", + "WIDTH": "floor($WIDTH/2.0)", + "HEIGHT": "floor($HEIGHT/2.0)", + "DESCRIPTION": "Pass 0" + }, + { + "TARGET": "quarterSizeBaseRender", + "WIDTH": "floor($WIDTH/4.0)", + "HEIGHT": "floor($HEIGHT/4.0)", + "DESCRIPTION": "Pass 1" + }, + { + "TARGET": "eighthSizeBaseRender", + "WIDTH": "floor($WIDTH/8.0)", + "HEIGHT": "floor($HEIGHT/8.0)", + "DESCRIPTION": "Pass 2" + }, + { + "TARGET": "quarterGaussA", + "WIDTH": "floor($WIDTH/4.0)", + "HEIGHT": "floor($HEIGHT/4.0)", + "DESCRIPTION": "Pass 3" + }, + { + "TARGET": "quarterGaussB", + "WIDTH": "floor($WIDTH/4.0)", + "HEIGHT": "floor($HEIGHT/4.0)", + "DESCRIPTION": "Pass 4" + }, + { + "TARGET": "fullGaussA", + "DESCRIPTION": "Pass 5" + }, + { + "TARGET": "fullGaussB", + "DESCRIPTION": "Pass 6" + } + ] +}*/ + + +varying vec2 left_coord; +varying vec2 right_coord; +varying vec2 above_coord; +varying vec2 below_coord; + +varying vec2 lefta_coord; +varying vec2 righta_coord; +varying vec2 leftb_coord; +varying vec2 rightb_coord; + +varying vec2 texOffsets[5]; + +float gray(vec4 n) +{ + return (n.r + n.g + n.b)/3.0; +} + + +void main() { + int blurLevel = int(floor(blurAmount/6.0)); + float blurLevelModulus = mod(blurAmount, 6.0); + // first three passes are just copying the input image into the buffer at varying sizes + if (PASSINDEX==0) { + gl_FragColor = IMG_NORM_PIXEL(inputImage, isf_FragNormCoord); + } + else if (PASSINDEX==1) { + gl_FragColor = IMG_NORM_PIXEL(halfSizeBaseRender, isf_FragNormCoord); + } + else if (PASSINDEX==2) { + gl_FragColor = IMG_NORM_PIXEL(quarterSizeBaseRender, isf_FragNormCoord); + } + // start reading from the previous stage- each two passes completes a gaussian blur, then + // we increase the resolution & blur (the lower-res blurred image from the previous pass) again... + else if (PASSINDEX == 3) { + vec4 sample0 = IMG_NORM_PIXEL(eighthSizeBaseRender,texOffsets[0]); + vec4 sample1 = IMG_NORM_PIXEL(eighthSizeBaseRender,texOffsets[1]); + vec4 sample2 = IMG_NORM_PIXEL(eighthSizeBaseRender,texOffsets[2]); + vec4 sample3 = IMG_NORM_PIXEL(eighthSizeBaseRender,texOffsets[3]); + vec4 sample4 = IMG_NORM_PIXEL(eighthSizeBaseRender,texOffsets[4]); + //gl_FragColor = vec4((sample0 + sample1 + sample2).rgb / (3.0), 1.0); + gl_FragColor = vec4((sample0 + sample1 + sample2 + sample3 + sample4).rgba / (5.0)); + } + else if (PASSINDEX == 4) { + vec4 sample0 = IMG_NORM_PIXEL(quarterGaussA,texOffsets[0]); + vec4 sample1 = IMG_NORM_PIXEL(quarterGaussA,texOffsets[1]); + vec4 sample2 = IMG_NORM_PIXEL(quarterGaussA,texOffsets[2]); + vec4 sample3 = IMG_NORM_PIXEL(quarterGaussA,texOffsets[3]); + vec4 sample4 = IMG_NORM_PIXEL(quarterGaussA,texOffsets[4]); + //gl_FragColor = vec4((sample0 + sample1 + sample2).rgb / (3.0), 1.0); + gl_FragColor = vec4((sample0 + sample1 + sample2 + sample3 + sample4).rgba / (5.0)); + } + // ...writes into the full-size + else if (PASSINDEX == 5) { + vec4 sample0 = IMG_NORM_PIXEL(quarterGaussB,texOffsets[0]); + vec4 sample1 = IMG_NORM_PIXEL(quarterGaussB,texOffsets[1]); + vec4 sample2 = IMG_NORM_PIXEL(quarterGaussB,texOffsets[2]); + gl_FragColor = vec4((sample0 + sample1 + sample2).rgba / (3.0)); + } + else if (PASSINDEX == 6) { + // this is the last pass- calculate the blurred image as i have in previous passes, then mix it in with the full-size input image using the blur amount so i get a smooth transition into the blur at low blur levels + vec4 sample0 = IMG_NORM_PIXEL(fullGaussA,texOffsets[0]); + vec4 sample1 = IMG_NORM_PIXEL(fullGaussA,texOffsets[1]); + vec4 sample2 = IMG_NORM_PIXEL(fullGaussA,texOffsets[2]); + vec4 blurredImg = vec4((sample0 + sample1 + sample2).rgba / (3.0)); + vec4 origImg = IMG_NORM_PIXEL(inputImage,isf_FragNormCoord); + + + + vec4 colorL = IMG_NORM_PIXEL(inputImage, left_coord); + vec4 colorR = IMG_NORM_PIXEL(inputImage, right_coord); + vec4 colorA = IMG_NORM_PIXEL(inputImage, above_coord); + vec4 colorB = IMG_NORM_PIXEL(inputImage, below_coord); + + vec4 colorLA = IMG_NORM_PIXEL(inputImage, lefta_coord); + vec4 colorRA = IMG_NORM_PIXEL(inputImage, righta_coord); + vec4 colorLB = IMG_NORM_PIXEL(inputImage, leftb_coord); + vec4 colorRB = IMG_NORM_PIXEL(inputImage, rightb_coord); + + float gx = (-1.0 * gray(colorLA)) + (-2.0 * gray(colorL)) + (-1.0 * gray(colorLB)) + (1.0 * gray(colorRA)) + (2.0 * gray(colorR)) + (1.0 * gray(colorRB)); + float gy = (1.0 * gray(colorLA)) + (2.0 * gray(colorA)) + (1.0 * gray(colorRA)) + (-1.0 * gray(colorRB)) + (-2.0 * gray(colorB)) + (-1.0 * gray(colorLB)); + float edge = 0.0; + edge = intensity * pow(gx*gx + gy*gy,0.5); + if (invert_map) { + edge = 1.0 - edge; + } + + blurredImg = mix(blurredImg, origImg, edge); + + + + if (blurLevel == 0) + gl_FragColor = mix(origImg, blurredImg, (blurLevelModulus/6.1)); + else + gl_FragColor = blurredImg; + } + +} diff --git a/ISF/Edge Blur.vs b/ISF/Edge Blur.vs new file mode 100644 index 0000000..e426d72 --- /dev/null +++ b/ISF/Edge Blur.vs @@ -0,0 +1,89 @@ +varying vec2 texOffsets[5]; + +varying vec2 left_coord; +varying vec2 right_coord; +varying vec2 above_coord; +varying vec2 below_coord; + +varying vec2 lefta_coord; +varying vec2 righta_coord; +varying vec2 leftb_coord; +varying vec2 rightb_coord; + +void main(void) { + // load the main shader stuff + isf_vertShaderInit(); + + + int blurLevel = int(floor(blurAmount/6.0)); + float blurLevelModulus = mod(blurAmount, 6.0); + float blurRadius = 0.0; + float blurRadiusInPixels = 0.0; + // first three passes are just drawing the texture- do nothing + + // the next four passes do gaussion blurs on the various levels + if (PASSINDEX==3 || PASSINDEX==5) { + float pixelWidth = 1.0/RENDERSIZE.x; + // pass 3 is sampling 1/12, but writing to 1/4 + if (PASSINDEX==3) { + if (blurLevel==1) + blurRadius = blurLevelModulus/1.5; + else if (blurLevel>1) + blurRadius = 4.0; + } + // pass 5 is sampling 1/4 and writing to full-size + else if (PASSINDEX==5) { + if (blurLevel==0) + blurRadius = blurLevelModulus; + else if (blurLevel>0) + blurRadius = 6.0; + } + blurRadiusInPixels = pixelWidth * blurRadius; + texOffsets[0] = isf_FragNormCoord; + texOffsets[1] = (blurRadius==0.0) ? isf_FragNormCoord : clamp(vec2(isf_FragNormCoord[0]-blurRadiusInPixels, isf_FragNormCoord[1]),0.0,1.0); + texOffsets[2] = (blurRadius==0.0) ? isf_FragNormCoord : clamp(vec2(isf_FragNormCoord[0]+blurRadiusInPixels, isf_FragNormCoord[1]),0.0,1.0); + if (PASSINDEX==3) { + texOffsets[3] = (blurRadius==0.0) ? isf_FragNormCoord : clamp(vec2(isf_FragNormCoord[0]-(2.0*blurRadiusInPixels), isf_FragNormCoord[1]),0.0,1.0); + texOffsets[4] = (blurRadius==0.0) ? isf_FragNormCoord : clamp(vec2(isf_FragNormCoord[0]+(2.0*blurRadiusInPixels), isf_FragNormCoord[1]),0.0,1.0); + } + } + else if (PASSINDEX==4 || PASSINDEX==6) { + float pixelHeight = 1.0/RENDERSIZE.y; + // pass 4 is sampling 1/12, but writing to 1/4 + if (PASSINDEX==4) { + if (blurLevel==1) + blurRadius = blurLevelModulus/1.5; + else if (blurLevel>1) + blurRadius = 4.0; + } + // pass 6 is sampling 1/4 and writing to full-size + else if (PASSINDEX==6) { + if (blurLevel==0) + blurRadius = blurLevelModulus; + else if (blurLevel>0) + blurRadius = 6.0; + + vec2 texc = vec2(isf_FragNormCoord[0],isf_FragNormCoord[1]); + vec2 d = 1.0/RENDERSIZE; + + left_coord = clamp(vec2(texc.xy + vec2(-d.x , 0)),0.0,1.0); + right_coord = clamp(vec2(texc.xy + vec2(d.x , 0)),0.0,1.0); + above_coord = clamp(vec2(texc.xy + vec2(0,d.y)),0.0,1.0); + below_coord = clamp(vec2(texc.xy + vec2(0,-d.y)),0.0,1.0); + + lefta_coord = clamp(vec2(texc.xy + vec2(-d.x , d.x)),0.0,1.0); + righta_coord = clamp(vec2(texc.xy + vec2(d.x , d.x)),0.0,1.0); + leftb_coord = clamp(vec2(texc.xy + vec2(-d.x , -d.x)),0.0,1.0); + rightb_coord = clamp(vec2(texc.xy + vec2(d.x , -d.x)),0.0,1.0); + } + blurRadiusInPixels = pixelHeight * blurRadius; + texOffsets[0] = isf_FragNormCoord; + texOffsets[1] = (blurRadius==0.0) ? isf_FragNormCoord : clamp(vec2(isf_FragNormCoord[0], isf_FragNormCoord[1]-blurRadiusInPixels),0.0,1.0); + texOffsets[2] = (blurRadius==0.0) ? isf_FragNormCoord : clamp(vec2(isf_FragNormCoord[0], isf_FragNormCoord[1]+blurRadiusInPixels),0.0,1.0); + if (PASSINDEX==4) { + texOffsets[3] = (blurRadius==0.0) ? isf_FragNormCoord : clamp(vec2(isf_FragNormCoord[0], isf_FragNormCoord[1]-(2.0*blurRadiusInPixels)),0.0,1.0); + texOffsets[4] = (blurRadius==0.0) ? isf_FragNormCoord : clamp(vec2(isf_FragNormCoord[0], isf_FragNormCoord[1]+(2.0*blurRadiusInPixels)),0.0,1.0); + } + } + +} diff --git a/ISF/Edge Distort.fs b/ISF/Edge Distort.fs new file mode 100644 index 0000000..7f76954 --- /dev/null +++ b/ISF/Edge Distort.fs @@ -0,0 +1,85 @@ +/*{ + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Distortion Effect" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "intensity", + "TYPE": "float", + "MIN": 0.0, + "MAX": 10.0, + "DEFAULT": 0.2 + }, + { + "NAME": "invert_map", + "TYPE": "bool", + "DEFAULT": 0.0 + } + ] +}*/ + + +varying vec2 left_coord; +varying vec2 right_coord; +varying vec2 above_coord; +varying vec2 below_coord; + +varying vec2 lefta_coord; +varying vec2 righta_coord; +varying vec2 leftb_coord; +varying vec2 rightb_coord; + +float gray(vec4 n) +{ + return (n.r + n.g + n.b)/3.0; +} + +const float tau = 6.28318530718; + +void main() +{ + + vec4 color = IMG_THIS_PIXEL(inputImage); + vec4 colorL = IMG_NORM_PIXEL(inputImage, left_coord); + vec4 colorR = IMG_NORM_PIXEL(inputImage, right_coord); + vec4 colorA = IMG_NORM_PIXEL(inputImage, above_coord); + vec4 colorB = IMG_NORM_PIXEL(inputImage, below_coord); + + vec4 colorLA = IMG_NORM_PIXEL(inputImage, lefta_coord); + vec4 colorRA = IMG_NORM_PIXEL(inputImage, righta_coord); + vec4 colorLB = IMG_NORM_PIXEL(inputImage, leftb_coord); + vec4 colorRB = IMG_NORM_PIXEL(inputImage, rightb_coord); + + + + float gx = (-1.0 * gray(colorLA)) + (-1.0 * gray(colorL)) + (-1.0 * gray(colorLB)) + (1.0 * gray(colorRA)) + (1.0 * gray(colorR)) + (1.0 * gray(colorRB)); + float gy = (1.0 * gray(colorLA)) + (1.0 * gray(colorA)) + (1.0 * gray(colorRA)) + (-1.0 * gray(colorRB)) + (-1.0 * gray(colorB)) + (-1.0 * gray(colorLB)); + + float edge = pow(gx*gx + gy*gy,0.5); + float brightness = (color.r + color.g + color.b) / 3.0; + + vec2 tc = isf_FragNormCoord; + vec2 modifiedCenter = vec2(0.5,0.5); + float r = distance(modifiedCenter, tc); + float a = atan ((tc.y-modifiedCenter.y),(tc.x-modifiedCenter.x)); + + // adjust the angle and radius based on the brightness and edge level + if (invert_map) { + edge = 1.0 - edge; + } + r = r + intensity * (1.0-edge) * (brightness - 0.5); + //a = a + intensity * pow(1.0+edge,brightness); + + tc.x = r * cos(a) + 0.5; + tc.y = r * sin(a) + 0.5; + + vec4 final = IMG_NORM_PIXEL(inputImage, tc); + + gl_FragColor = final; +} \ No newline at end of file diff --git a/ISF/Edge Distort.vs b/ISF/Edge Distort.vs new file mode 100644 index 0000000..c8b60f7 --- /dev/null +++ b/ISF/Edge Distort.vs @@ -0,0 +1,27 @@ +varying vec2 left_coord; +varying vec2 right_coord; +varying vec2 above_coord; +varying vec2 below_coord; + +varying vec2 lefta_coord; +varying vec2 righta_coord; +varying vec2 leftb_coord; +varying vec2 rightb_coord; + + +void main() +{ + isf_vertShaderInit(); + vec2 texc = vec2(isf_FragNormCoord[0],isf_FragNormCoord[1]); + vec2 d = 1.0/RENDERSIZE; + + left_coord = clamp(vec2(texc.xy + vec2(-d.x , 0)),0.0,1.0); + right_coord = clamp(vec2(texc.xy + vec2(d.x , 0)),0.0,1.0); + above_coord = clamp(vec2(texc.xy + vec2(0,d.y)),0.0,1.0); + below_coord = clamp(vec2(texc.xy + vec2(0,-d.y)),0.0,1.0); + + lefta_coord = clamp(vec2(texc.xy + vec2(-d.x , d.x)),0.0,1.0); + righta_coord = clamp(vec2(texc.xy + vec2(d.x , d.x)),0.0,1.0); + leftb_coord = clamp(vec2(texc.xy + vec2(-d.x , -d.x)),0.0,1.0); + rightb_coord = clamp(vec2(texc.xy + vec2(d.x , -d.x)),0.0,1.0); +} \ No newline at end of file diff --git a/ISF/Edge Trace.fs b/ISF/Edge Trace.fs new file mode 100644 index 0000000..0255501 --- /dev/null +++ b/ISF/Edge Trace.fs @@ -0,0 +1,75 @@ +/*{ + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Stylize" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "intensity", + "TYPE": "float", + "MIN": 0.0, + "MAX": 50.0, + "DEFAULT": 2.5 + }, + { + "NAME": "spread", + "TYPE": "float", + "MIN": 1.0, + "MAX": 20.0, + "DEFAULT": 5.0 + }, + { + "NAME": "invert_lines", + "TYPE": "bool", + "DEFAULT": 0 + } + ] +}*/ + + +varying vec2 left_coord; +varying vec2 right_coord; +varying vec2 above_coord; +varying vec2 below_coord; + +varying vec2 lefta_coord; +varying vec2 righta_coord; +varying vec2 leftb_coord; +varying vec2 rightb_coord; + +float gray(vec4 n) +{ + return (n.r + n.g + n.b)/3.0; +} + +void main() +{ + + vec4 color = IMG_THIS_PIXEL(inputImage); + vec4 colorL = IMG_NORM_PIXEL(inputImage, left_coord); + vec4 colorR = IMG_NORM_PIXEL(inputImage, right_coord); + vec4 colorA = IMG_NORM_PIXEL(inputImage, above_coord); + vec4 colorB = IMG_NORM_PIXEL(inputImage, below_coord); + + vec4 colorLA = IMG_NORM_PIXEL(inputImage, lefta_coord); + vec4 colorRA = IMG_NORM_PIXEL(inputImage, righta_coord); + vec4 colorLB = IMG_NORM_PIXEL(inputImage, leftb_coord); + vec4 colorRB = IMG_NORM_PIXEL(inputImage, rightb_coord); + + float gx = (-1.0 * gray(colorLA)) + (-1.0 * gray(colorL)) + (-1.0 * gray(colorLB)) + (1.0 * gray(colorRA)) + (1.0 * gray(colorR)) + (1.0 * gray(colorRB)); + float gy = (1.0 * gray(colorLA)) + (1.0 * gray(colorA)) + (1.0 * gray(colorRA)) + (-1.0 * gray(colorRB)) + (-1.0 * gray(colorB)) + (-1.0 * gray(colorLB)); + + vec4 blurred = (colorL + colorR + colorA + colorLA + colorLB + colorRB) / 8.0; + float bright = pow(gx*gx + gy*gy,0.5); + vec4 final = color * bright; + + final.rgb = (invert_lines) ? blurred.rgb + final.rgb * intensity : blurred.rgb - final.rgb * intensity; + final.a = color.a; + + gl_FragColor = final; +} \ No newline at end of file diff --git a/ISF/Edge Trace.vs b/ISF/Edge Trace.vs new file mode 100644 index 0000000..1325b80 --- /dev/null +++ b/ISF/Edge Trace.vs @@ -0,0 +1,27 @@ +varying vec2 left_coord; +varying vec2 right_coord; +varying vec2 above_coord; +varying vec2 below_coord; + +varying vec2 lefta_coord; +varying vec2 righta_coord; +varying vec2 leftb_coord; +varying vec2 rightb_coord; + + +void main() +{ + isf_vertShaderInit(); + vec2 texc = vec2(isf_FragNormCoord[0],isf_FragNormCoord[1]); + vec2 d = spread/RENDERSIZE; + + left_coord = clamp(vec2(texc.xy + vec2(-d.x , 0)),0.0,1.0); + right_coord = clamp(vec2(texc.xy + vec2(d.x , 0)),0.0,1.0); + above_coord = clamp(vec2(texc.xy + vec2(0,d.y)),0.0,1.0); + below_coord = clamp(vec2(texc.xy + vec2(0,-d.y)),0.0,1.0); + + lefta_coord = clamp(vec2(texc.xy + vec2(-d.x , d.x)),0.0,1.0); + righta_coord = clamp(vec2(texc.xy + vec2(d.x , d.x)),0.0,1.0); + leftb_coord = clamp(vec2(texc.xy + vec2(-d.x , -d.x)),0.0,1.0); + rightb_coord = clamp(vec2(texc.xy + vec2(d.x , -d.x)),0.0,1.0); +} \ No newline at end of file diff --git a/ISF/Edges.fs b/ISF/Edges.fs new file mode 100644 index 0000000..b4cf2e0 --- /dev/null +++ b/ISF/Edges.fs @@ -0,0 +1,99 @@ +/*{ + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Stylize" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "intensity", + "TYPE": "float", + "MIN": 0.0, + "MAX": 50.0, + "DEFAULT": 50.0 + }, + { + "NAME": "threshold", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.0 + }, + { + "NAME": "sobel", + "TYPE": "bool", + "DEFAULT": 1.0 + }, + { + "NAME": "opaque", + "TYPE": "bool", + "DEFAULT": true + } + ] +}*/ + + +varying vec2 left_coord; +varying vec2 right_coord; +varying vec2 above_coord; +varying vec2 below_coord; + +varying vec2 lefta_coord; +varying vec2 righta_coord; +varying vec2 leftb_coord; +varying vec2 rightb_coord; + +float gray(vec4 n) +{ + return (n.r + n.g + n.b)/3.0; +} + +void main() +{ + + vec4 color = IMG_THIS_PIXEL(inputImage); + vec4 colorL = IMG_NORM_PIXEL(inputImage, left_coord); + vec4 colorR = IMG_NORM_PIXEL(inputImage, right_coord); + vec4 colorA = IMG_NORM_PIXEL(inputImage, above_coord); + vec4 colorB = IMG_NORM_PIXEL(inputImage, below_coord); + + vec4 colorLA = IMG_NORM_PIXEL(inputImage, lefta_coord); + vec4 colorRA = IMG_NORM_PIXEL(inputImage, righta_coord); + vec4 colorLB = IMG_NORM_PIXEL(inputImage, leftb_coord); + vec4 colorRB = IMG_NORM_PIXEL(inputImage, rightb_coord); + + float gx = (0.0); + float gy = (0.0); + if (sobel) { + gx = (-1.0 * gray(colorLA)) + (-2.0 * gray(colorL)) + (-1.0 * gray(colorLB)) + (1.0 * gray(colorRA)) + (2.0 * gray(colorR)) + (1.0 * gray(colorRB)); + gy = (1.0 * gray(colorLA)) + (2.0 * gray(colorA)) + (1.0 * gray(colorRA)) + (-1.0 * gray(colorRB)) + (-2.0 * gray(colorB)) + (-1.0 * gray(colorLB)); + } + else { + gx = (-1.0 * gray(colorLA)) + (-1.0 * gray(colorL)) + (-1.0 * gray(colorLB)) + (1.0 * gray(colorRA)) + (1.0 * gray(colorR)) + (1.0 * gray(colorRB)); + gy = (1.0 * gray(colorLA)) + (1.0 * gray(colorA)) + (1.0 * gray(colorRA)) + (-1.0 * gray(colorRB)) + (-1.0 * gray(colorB)) + (-1.0 * gray(colorLB)); + } + + float bright = pow(gx*gx + gy*gy,0.5); + vec4 final = color * bright; + + // if the brightness is below the threshold draw black + if (bright < threshold) { + if (opaque) + final = vec4(0.0, 0.0, 0.0, 1.0); + else + final = vec4(0.0, 0.0, 0.0, 0.0); + } + else { + final.rgb = final.rgb * intensity; + if (opaque) + final.a = 1.0; + else + final.a = color.a; + } + + gl_FragColor = final; +} \ No newline at end of file diff --git a/ISF/Edges.vs b/ISF/Edges.vs new file mode 100644 index 0000000..c8b60f7 --- /dev/null +++ b/ISF/Edges.vs @@ -0,0 +1,27 @@ +varying vec2 left_coord; +varying vec2 right_coord; +varying vec2 above_coord; +varying vec2 below_coord; + +varying vec2 lefta_coord; +varying vec2 righta_coord; +varying vec2 leftb_coord; +varying vec2 rightb_coord; + + +void main() +{ + isf_vertShaderInit(); + vec2 texc = vec2(isf_FragNormCoord[0],isf_FragNormCoord[1]); + vec2 d = 1.0/RENDERSIZE; + + left_coord = clamp(vec2(texc.xy + vec2(-d.x , 0)),0.0,1.0); + right_coord = clamp(vec2(texc.xy + vec2(d.x , 0)),0.0,1.0); + above_coord = clamp(vec2(texc.xy + vec2(0,d.y)),0.0,1.0); + below_coord = clamp(vec2(texc.xy + vec2(0,-d.y)),0.0,1.0); + + lefta_coord = clamp(vec2(texc.xy + vec2(-d.x , d.x)),0.0,1.0); + righta_coord = clamp(vec2(texc.xy + vec2(d.x , d.x)),0.0,1.0); + leftb_coord = clamp(vec2(texc.xy + vec2(-d.x , -d.x)),0.0,1.0); + rightb_coord = clamp(vec2(texc.xy + vec2(d.x , -d.x)),0.0,1.0); +} \ No newline at end of file diff --git a/ISF/Emboss.fs b/ISF/Emboss.fs new file mode 100644 index 0000000..1de1b42 --- /dev/null +++ b/ISF/Emboss.fs @@ -0,0 +1,65 @@ +/*{ + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Stylize" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "intensity", + "TYPE": "float", + "MIN": 0.0, + "MAX": 10.0, + "DEFAULT": 2.0 + }, + { + "NAME": "colorize", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 1.0 + }, + { + "NAME": "brightness", + "TYPE": "float", + "MIN": 0.25, + "MAX": 0.75, + "DEFAULT": 0.5 + } + ] +}*/ + + +varying vec2 left_coord; +varying vec2 right_coord; +varying vec2 above_coord; +varying vec2 below_coord; + +varying vec2 lefta_coord; +varying vec2 rightb_coord; + +float gray(vec4 n) +{ + return (n.r + n.g + n.b)/3.0; +} + +void main() +{ + + vec4 colorL = IMG_NORM_PIXEL(inputImage, left_coord); + vec4 colorR = IMG_NORM_PIXEL(inputImage, right_coord); + vec4 colorA = IMG_NORM_PIXEL(inputImage, above_coord); + vec4 colorB = IMG_NORM_PIXEL(inputImage, below_coord); + + vec4 colorLA = IMG_NORM_PIXEL(inputImage, lefta_coord); + vec4 colorRB = IMG_NORM_PIXEL(inputImage, rightb_coord); + + vec4 final = intensity * (colorR + colorB + colorRB - colorL - colorA - colorLA) + brightness; + float grayscale = gray(final); + final = mix(vec4(grayscale,grayscale,grayscale,final.a),final,colorize); + gl_FragColor = final; +} \ No newline at end of file diff --git a/ISF/Emboss.vs b/ISF/Emboss.vs new file mode 100644 index 0000000..b7052d4 --- /dev/null +++ b/ISF/Emboss.vs @@ -0,0 +1,23 @@ +varying vec2 left_coord; +varying vec2 right_coord; +varying vec2 above_coord; +varying vec2 below_coord; + +varying vec2 lefta_coord; +varying vec2 rightb_coord; + + +void main() +{ + isf_vertShaderInit(); + vec2 texc = vec2(isf_FragNormCoord[0],isf_FragNormCoord[1]); + vec2 d = 1.0/RENDERSIZE; + + left_coord = clamp(vec2(texc.xy + vec2(-d.x , 0)),0.0,1.0); + right_coord = clamp(vec2(texc.xy + vec2(d.x , 0)),0.0,1.0); + above_coord = clamp(vec2(texc.xy + vec2(0,d.y)),0.0,1.0); + below_coord = clamp(vec2(texc.xy + vec2(0,-d.y)),0.0,1.0); + + lefta_coord = clamp(vec2(texc.xy + vec2(-d.x , d.x)),0.0,1.0); + rightb_coord = clamp(vec2(texc.xy + vec2(d.x , -d.x)),0.0,1.0); +} \ No newline at end of file diff --git a/ISF/Erode-Fast.fs b/ISF/Erode-Fast.fs new file mode 100644 index 0000000..65d0889 --- /dev/null +++ b/ISF/Erode-Fast.fs @@ -0,0 +1,152 @@ +/*{ + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Stylize", + "Blur" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "intensity", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.25 + }, + { + "NAME": "radius", + "TYPE": "float", + "MIN": 1.0, + "MAX": 15.0, + "DEFAULT": 6.0 + } + ], + "PASSES": [ + { + "TARGET": "halfSize", + "WIDTH": "floor($WIDTH/2.0)", + "HEIGHT": "floor($HEIGHT/2.0)", + "DESCRIPTION": "pass 0, 1x horiz sampling (3 wide total) to prevent data loss" + }, + { + "TARGET": "quarterSize", + "WIDTH": "floor($WIDTH/4.0)", + "HEIGHT": "floor($HEIGHT/4.0)", + "DESCRIPTION": "pass 1, vert sampling, use radius (size is being reduced, halve coords deltas when sampling)" + }, + { + "TARGET": "quarterSizePassB", + "WIDTH": "floor($WIDTH/2.0)", + "HEIGHT": "floor($HEIGHT/2.0)", + "DESCRIPTION": "pass 2, horiz sampling, use radius (size is being increased, use normal coords deltas)" + }, + { + "DESCRIPTION": "pass 3, last pass- samples the input image and the quarterSizePassB to generate the final image at the full original resolution" + } + ] +}*/ + + + +vec3 rgb2hsv(vec3 c); + +void main() +{ + + // generally speaking, sample a bunch of pixels, for each sample convert color val to HSV, if luma is greater than max luma, that's the new color + vec2 tmpCoord; + float maxLuma; + vec4 maxLumaRGBColor = vec4(0.0); + vec4 sampleColorRGB; + vec4 sampleColorHSV; + vec2 pixelWidth = 1.0/RENDERSIZE.xy; + float localBlurRadius; + bool vertFlag = false; + + if (PASSINDEX != 3) { + // pass 0 and 2 are doing horizontal erosion + if (PASSINDEX==1) + vertFlag = true; + // the first pass should have a blur radius of 1.0 simply to prevent the loss of information while reducing resolution + if (PASSINDEX==0) + localBlurRadius = 1.0; + // other passes go by the blur radius! + else + localBlurRadius = float(int(radius)); + // sample pixels as per the blur radius... + for (float i=0.; i<=localBlurRadius; ++i) { + if (PASSINDEX==0) { + tmpCoord = vec2(clamp(isf_FragNormCoord.x+(i*pixelWidth.x), 0., 1.), isf_FragNormCoord.y); + sampleColorRGB = IMG_NORM_PIXEL(inputImage, tmpCoord); + } + else if (PASSINDEX==1) { + tmpCoord = vec2(isf_FragNormCoord.x, clamp(isf_FragNormCoord.y+(i*pixelWidth.y/2.), 0., 1.)); + sampleColorRGB = IMG_NORM_PIXEL(halfSize, tmpCoord); + } + else if (PASSINDEX==2) { + tmpCoord = vec2(clamp(isf_FragNormCoord.x+(i*pixelWidth.x), 0., 1.), isf_FragNormCoord.y); + sampleColorRGB = IMG_NORM_PIXEL(quarterSize, tmpCoord); + } + // if this is the first sample for this fragment, don't bother comparing- just set the max luma stuff + if (i == 0.) { + maxLuma = rgb2hsv(sampleColorRGB.rgb).b; + maxLumaRGBColor = sampleColorRGB; + } + // else this isn't the first sample... + else { + // compare, determine if it's the max luma + sampleColorRGB = mix(maxLumaRGBColor, sampleColorRGB, 1.*intensity/i); + sampleColorHSV.rgb = rgb2hsv(sampleColorRGB.rgb); + if (sampleColorHSV.b > maxLuma) { + maxLuma = sampleColorHSV.b; + maxLumaRGBColor = sampleColorRGB; + } + // do another sample for the negative coordinate + if (PASSINDEX==0) { + tmpCoord = vec2(clamp(isf_FragNormCoord.x-(i*pixelWidth.x), 0., 1.), isf_FragNormCoord.y); + sampleColorRGB = IMG_NORM_PIXEL(inputImage, tmpCoord); + } + else if (PASSINDEX==1) { + tmpCoord = vec2(isf_FragNormCoord.x, clamp(isf_FragNormCoord.y-(i*pixelWidth.y/2.), 0., 1.)); + sampleColorRGB = IMG_NORM_PIXEL(halfSize, tmpCoord); + } + else if (PASSINDEX==2) { + tmpCoord = vec2(clamp(isf_FragNormCoord.x-(i*pixelWidth.x), 0., 1.), isf_FragNormCoord.y); + sampleColorRGB = IMG_NORM_PIXEL(quarterSize, tmpCoord); + } + sampleColorRGB = mix(maxLumaRGBColor, sampleColorRGB, 1.*intensity/i); + sampleColorHSV.rgb = rgb2hsv(sampleColorRGB.rgb); + if (sampleColorHSV.b > maxLuma) { + maxLuma = sampleColorHSV.b; + maxLumaRGBColor = sampleColorRGB; + } + } + } + gl_FragColor = maxLumaRGBColor; + } + // last pass + else if (PASSINDEX==3) { + vec4 origPixel = IMG_NORM_PIXEL(inputImage,isf_FragNormCoord); + vec4 erodedPixel = IMG_NORM_PIXEL(quarterSizePassB,isf_FragNormCoord); + vec4 finalPixel = max(origPixel,erodedPixel); + gl_FragColor = mix(origPixel,finalPixel, clamp(min(radius-1.0, intensity*10.0), 0., 1.)); + } +} + + +vec3 rgb2hsv(vec3 c) { + vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); + //vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g)); + //vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r)); + vec4 p = c.g < c.b ? vec4(c.bg, K.wz) : vec4(c.gb, K.xy); + vec4 q = c.r < p.x ? vec4(p.xyw, c.r) : vec4(c.r, p.yzx); + + float d = q.x - min(q.w, q.y); + float e = 1.0e-10; + return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x); +} + diff --git a/ISF/Erode.fs b/ISF/Erode.fs new file mode 100644 index 0000000..0e692f6 --- /dev/null +++ b/ISF/Erode.fs @@ -0,0 +1,133 @@ +/*{ + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Stylize", + "Blur" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "intensity", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.0 + }, + { + "NAME": "bleedRadius", + "TYPE": "float", + "MIN": 1.0, + "MAX": 15.0, + "DEFAULT": 2.0 + } + ], + "PASSES": [ + { + "TARGET": "firstPass" + }, + { + + } + ] +}*/ + + + +vec3 rgb2hsv(vec3 c); + +void main() +{ + + // generally speaking, sample a bunch of pixels, for each sample convert color val to HSV, if luma is greater than max luma, that's the new color + vec2 tmpCoord; + float maxLuma; + vec4 maxLumaRGBColor = vec4(0.0); + vec4 sampleColorRGB; + vec4 sampleColorHSV; + + if (PASSINDEX==0) { + // 5 samples on either side + the source pixel = 11 total samples + for (float i=0.; i<=float(int(bleedRadius)); ++i) { + tmpCoord = vec2(clamp(gl_FragCoord.x+i,0.,RENDERSIZE.x), gl_FragCoord.y); + sampleColorRGB = IMG_PIXEL(inputImage, tmpCoord); + // if this is the first sample for this fragment, don't bother comparing- just set the max luma stuff + if (i == 0.) { + maxLuma = rgb2hsv(sampleColorRGB.rgb).b; + maxLumaRGBColor = sampleColorRGB; + } + // else this isn't the first sample... + else { + // compare, determine if it's the max luma + sampleColorRGB = mix(maxLumaRGBColor, sampleColorRGB, 1.*intensity/i); + sampleColorHSV.rgb = rgb2hsv(sampleColorRGB.rgb); + if (sampleColorHSV.b > maxLuma) { + maxLuma = sampleColorHSV.b; + maxLumaRGBColor = sampleColorRGB; + } + // do another sample for the negative coordinate + tmpCoord = vec2(clamp(gl_FragCoord.x-i,0.,RENDERSIZE.x), gl_FragCoord.y); + sampleColorRGB = IMG_PIXEL(inputImage, tmpCoord); + sampleColorRGB = mix(maxLumaRGBColor, sampleColorRGB, 1.*intensity/i); + sampleColorHSV.rgb = rgb2hsv(sampleColorRGB.rgb); + if (sampleColorHSV.b > maxLuma) { + maxLuma = sampleColorHSV.b; + maxLumaRGBColor = sampleColorRGB; + } + } + } + gl_FragColor = maxLumaRGBColor; + + } + else if (PASSINDEX==1) { + // 5 samples up and down + the source pixel = 11 total samples + for (float i=0.; i<=float(int(bleedRadius)); ++i) { + tmpCoord = vec2(gl_FragCoord.x, clamp(gl_FragCoord.y+i,0.,RENDERSIZE.y)); + sampleColorRGB = IMG_PIXEL(firstPass, tmpCoord); + // if this is the first sample for this fragment, don't bother comparing- just set the max luma stuff + if (i == 0.) { + maxLuma = rgb2hsv(sampleColorRGB.rgb).b; + maxLumaRGBColor = sampleColorRGB; + } + // else this isn't the first sample... + else { + // compare, determine if it's the max luma + sampleColorRGB = mix(maxLumaRGBColor, sampleColorRGB, 1.*intensity/i); + sampleColorHSV.rgb = rgb2hsv(sampleColorRGB.rgb); + if (sampleColorHSV.b > maxLuma) { + maxLuma = sampleColorHSV.b; + maxLumaRGBColor = sampleColorRGB; + } + // do another sample for the negative coordinate + tmpCoord = vec2(gl_FragCoord.x, clamp(gl_FragCoord.y-i,0.,RENDERSIZE.y)); + sampleColorRGB = IMG_PIXEL(firstPass, tmpCoord); + sampleColorRGB = mix(maxLumaRGBColor, sampleColorRGB, 1.*intensity/i); + sampleColorHSV.rgb = rgb2hsv(sampleColorRGB.rgb); + if (sampleColorHSV.b > maxLuma) { + maxLuma = sampleColorHSV.b; + maxLumaRGBColor = sampleColorRGB; + } + } + } + gl_FragColor = maxLumaRGBColor; + + } + +} + + +vec3 rgb2hsv(vec3 c) { + vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); + //vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g)); + //vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r)); + vec4 p = c.g < c.b ? vec4(c.bg, K.wz) : vec4(c.gb, K.xy); + vec4 q = c.r < p.x ? vec4(p.xyw, c.r) : vec4(c.r, p.yzx); + + float d = q.x - min(q.w, q.y); + float e = 1.0e-10; + return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x); +} + diff --git a/ISF/Etch-a-Sketch.fs b/ISF/Etch-a-Sketch.fs new file mode 100644 index 0000000..b755fb7 --- /dev/null +++ b/ISF/Etch-a-Sketch.fs @@ -0,0 +1,139 @@ +/* +{ + "CATEGORIES" : [ + "Generator" + ], + "DESCRIPTION" : "Draw images one pixel at a time", + "ISFVSN" : "2", + "INPUTS" : [ + { + "NAME" : "moveUp", + "TYPE" : "event" + }, + { + "NAME" : "moveDown", + "TYPE" : "event" + }, + { + "NAME" : "moveLeft", + "TYPE" : "event" + }, + { + "NAME" : "moveRight", + "TYPE" : "event" + }, + { + "NAME" : "penColor", + "TYPE" : "color", + "DEFAULT" : [ + 0.5, + 0.5, + 0.5, + 1 + ] + }, + { + "NAME" : "penSize", + "TYPE" : "float", + "MAX" : 1, + "DEFAULT" : 0.05, + "MIN" : 0 + }, + { + "NAME" : "resetPosition", + "TYPE" : "event" + }, + { + "NAME" : "clearBuffer", + "TYPE" : "event" + }, + { + "NAME" : "clearColor", + "TYPE" : "color", + "DEFAULT" : [ + 0, + 0, + 0, + 0 + ] + } + ], + "PASSES" : [ + { + "PERSISTENT" : true, + "WIDTH" : "1", + "HEIGHT" : "1", + "TARGET" : "currentPosition", + "FLOAT" : true + }, + { + "TARGET" : "lastState", + "PERSISTENT" : true + } + ], + "CREDIT" : "VIDVOX" +} +*/ + + +float round (float x) { + if (fract(x) < 0.5) + return floor(x); + else + return ceil(x); +} + + +void main() { + vec4 inputPixelColor = vec4(0.0); + + if (PASSINDEX == 0) { + if ((FRAMEINDEX==0)||(resetPosition)) + inputPixelColor = vec4(0.5,0.5,0.0,1.0); + else + inputPixelColor = IMG_THIS_PIXEL(currentPosition); + + vec2 pos = inputPixelColor.rg; + vec2 outputSize = IMG_SIZE(lastState); + vec2 penSizeInPixels = vec2(penSize * min(outputSize.x,outputSize.y)); + penSizeInPixels.x = (penSizeInPixels.x < 1.0) ? (1.0) : (penSizeInPixels.x); + penSizeInPixels.y = (penSizeInPixels.y < 1.0) ? (1.0) : (penSizeInPixels.y); + vec2 normalizedPenSize = penSizeInPixels / outputSize; + + if ((moveUp)&&(pos.y<1.0-normalizedPenSize.y)) { + pos.y = pos.y + normalizedPenSize.y; + } + else if ((moveDown)&&(pos.y>0.0)) { + pos.y = pos.y - normalizedPenSize.y; + } + else if ((moveLeft)&&(pos.x>0.0)) { + pos.x = pos.x - normalizedPenSize.x; + } + else if ((moveRight)&&(pos.x<1.0-normalizedPenSize.x)) { + pos.x = pos.x + normalizedPenSize.x; + } + pos = min(pos,vec2(1.0)-normalizedPenSize); + pos = max(pos,vec2(0.0)); + inputPixelColor.rg = pos; + } + else if (PASSINDEX == 1) { + if ((FRAMEINDEX==0)||(clearBuffer)) { + inputPixelColor = clearColor; + } + else { + vec4 posPixel = IMG_PIXEL(currentPosition,vec2(0.0)); + vec2 pos = posPixel.rg * RENDERSIZE; + vec2 penSizeInPixels = vec2(penSize * min(RENDERSIZE.x,RENDERSIZE.y)); + penSizeInPixels.x = (penSizeInPixels.x < 1.0) ? (1.0) : (penSizeInPixels.x); + penSizeInPixels.y = (penSizeInPixels.y < 1.0) ? (1.0) : (penSizeInPixels.y); + //pos.x = round(pos.x); + //pos.y = round(pos.y); + if (((gl_FragCoord.x) >= pos.x)&&((gl_FragCoord.y) >= pos.y)&&((gl_FragCoord.x) < pos.x + penSizeInPixels.x)&&((gl_FragCoord.y) < pos.y + penSizeInPixels.y)) + inputPixelColor = penColor; + else + inputPixelColor = IMG_THIS_PIXEL(lastState); + } + } + + gl_FragColor = inputPixelColor; +} diff --git a/ISF/Exposure Adjust.fs b/ISF/Exposure Adjust.fs new file mode 100644 index 0000000..32133f0 --- /dev/null +++ b/ISF/Exposure Adjust.fs @@ -0,0 +1,30 @@ +/*{ + "CREDIT": "by carter rosenberg", + "ISFVSN": "2", + "CATEGORIES": [ + "Color Adjustment" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "inputEV", + "TYPE": "float", + "MIN": -10.0, + "MAX": 10.0, + "DEFAULT": 0.5 + } + ] +}*/ + + + +void main() { + // based on + // https://developer.apple.com/library/mac/documentation/graphicsimaging/reference/CoreImageFilterReference/Reference/reference.html#//apple_ref/doc/filter/ci/CIExposureAdjust + vec4 tmpColorA = IMG_THIS_PIXEL(inputImage); + tmpColorA.rgb = tmpColorA.rgb * pow(2.0, inputEV); + gl_FragColor = tmpColorA; +} diff --git a/ISF/FFT Color Lines.fs b/ISF/FFT Color Lines.fs new file mode 100644 index 0000000..7cc7f8b --- /dev/null +++ b/ISF/FFT Color Lines.fs @@ -0,0 +1,135 @@ +/* +{ + "CATEGORIES" : [ + "Generator" + ], + "ISFVSN": "2", + "DESCRIPTION" : "Visualizes an FFT analysis image with custom set colors for frequency domain", + "INPUTS" : [ + { + "NAME" : "fftImage", + "TYPE" : "audioFFT" + }, + { + "NAME" : "waveImage", + "TYPE" : "audio" + }, + { + "NAME" : "gainFFT", + "TYPE" : "float", + "MAX" : 5, + "DEFAULT" : 1, + "MIN" : 0 + }, + { + "NAME" : "rangeFFT", + "TYPE" : "float", + "MAX" : 1, + "DEFAULT" : 0.9, + "MIN" : 0 + }, + { + "NAME" : "waveSize", + "TYPE" : "float", + "MAX" : 0.5, + "DEFAULT" : 0.05, + "MIN" : 0 + }, + { + "NAME" : "vertical", + "TYPE" : "bool", + "DEFAULT" : 1 + }, + { + "NAME" : "stereo", + "TYPE" : "bool", + "DEFAULT" : 1 + }, + { + "NAME" : "color1", + "TYPE" : "color", + "DEFAULT" : [ + 0.2087394440714313, + 0.9861069917678833, + 0.1871179742814854, + 1 + ] + }, + { + "NAME" : "color2", + "TYPE" : "color", + "DEFAULT" : [ + 0, + 0.5, + 1, + 1 + ] + }, + { + "NAME" : "color3", + "TYPE" : "color", + "DEFAULT" : [ + 0, + 1, + 0, + 1 + ] + }, + { + "NAME" : "wavecolor", + "TYPE" : "color", + "DEFAULT" : [ + 1, + 1, + 1, + 1 + ] + } + ], + "CREDIT" : "by VIDVOX" +} +*/ + + + +void main() { + + vec2 loc = isf_FragNormCoord; + + if (vertical) { + loc.x = isf_FragNormCoord[1]; + loc.y = isf_FragNormCoord[0]; + } + + vec4 mixColor = color1; + + if (loc.y > 0.5) { + mixColor = mix (color2,color3,(loc.y-0.5)*2.0); + } + else { + mixColor = mix (color1,color2,(loc.y*2.0)); + } + + loc.y = loc.y * rangeFFT; + + vec2 fftSize = IMG_SIZE(fftImage); + vec2 rawSize = IMG_SIZE(waveImage); + float channel = 0.5; + float offset = 0.0; + if (stereo == true) { + channel = (loc.x > 0.5) ? 0.0 : 1.0; + offset = (loc.x > 0.5) ? 0.25 : -0.25; + } + + vec4 fft = IMG_NORM_PIXEL(fftImage, vec2(loc.y,channel)); + fft = mixColor * fft.r * 3.0; + fft.rgb = gainFFT * fft.rgb; + vec2 waveLoc = vec2(loc.y,channel); + vec4 wave = IMG_NORM_PIXEL(waveImage, waveLoc)+offset; + //wave = vec4(wave.r); + vec4 waveAdd = ((1.0 - smoothstep(0.0, waveSize, abs(wave - loc.x))) * wavecolor) * wavecolor.a; + fft += waveAdd; + fft.a = mixColor.a + clamp((waveAdd.r + waveAdd.g + waveAdd.b) * wavecolor.a,0.0,1.0); + + gl_FragColor = fft; +} \ No newline at end of file diff --git a/ISF/FFT Filled Waveform.fs b/ISF/FFT Filled Waveform.fs new file mode 100644 index 0000000..218d0bf --- /dev/null +++ b/ISF/FFT Filled Waveform.fs @@ -0,0 +1,95 @@ +/*{ + "DESCRIPTION": "Visualizes an FFT analysis image with custom set colors for frequency domain", + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Generator" + ], + "INPUTS": [ + { + "NAME": "fftImage", + "TYPE": "audioFFT" + }, + { + "NAME": "strokeSize", + "TYPE": "float", + "MIN": 0.0, + "MAX": 0.25, + "DEFAULT": 0.1 + }, + { + "NAME": "gain", + "TYPE": "float", + "MIN": 1.0, + "MAX": 5.0, + "DEFAULT": 1.0 + }, + { + "NAME": "minRange", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.1 + }, + { + "NAME": "maxRange", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.9 + }, + { + "NAME": "topColor", + "TYPE": "color", + "DEFAULT": [ + 0.0, + 0.0, + 0.0, + 0.0 + ] + }, + { + "NAME": "bottomColor", + "TYPE": "color", + "DEFAULT": [ + 0.0, + 0.5, + 0.9, + 1.0 + ] + }, + { + "NAME": "strokeColor", + "TYPE": "color", + "DEFAULT": [ + 0.25, + 0.25, + 0.25, + 1.0 + ] + } + ] +}*/ + + + +void main() { + + vec2 loc = isf_FragNormCoord; + + // the fftImage is 256 steps + loc.x = loc.x * abs(maxRange - minRange) + minRange; + + vec4 fft = IMG_NORM_PIXEL(fftImage, vec2(loc.x,0.5)); + float fftVal = gain * (fft.r + fft.g + fft.b) / 3.0; + if (loc.y > fftVal) + fft = topColor; + else + fft = bottomColor; + if ((strokeSize > 0.0) && (abs(fftVal - loc.y) < strokeSize)) { + fft = mix(strokeColor, fft, abs(fftVal - loc.y) / strokeSize); + } + + //(smoothstep(0.0, stroke, abs(fftVal - loc.y))) * strokeColor); + gl_FragColor = fft; +} \ No newline at end of file diff --git a/ISF/FFT Spectrogram.fs b/ISF/FFT Spectrogram.fs new file mode 100644 index 0000000..192d3c4 --- /dev/null +++ b/ISF/FFT Spectrogram.fs @@ -0,0 +1,159 @@ +/*{ + "DESCRIPTION": "Buffers the incoming FFTs for timed display", + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Generator" + ], + "INPUTS": [ + { + "NAME": "fftImage", + "TYPE": "audioFFT" + }, + { + "NAME": "clear", + "TYPE": "event" + }, + { + "NAME": "gain", + "TYPE": "float", + "MIN": 0.0, + "MAX": 2.0, + "DEFAULT":1.0 + }, + { + "NAME": "range", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 1.0 + }, + { + "NAME": "axis_scale", + "TYPE": "float", + "MIN": 1.0, + "MAX": 6.0, + "DEFAULT": 1.25 + }, + { + "NAME": "lumaMode", + "TYPE": "bool", + "DEFAULT": 0.0 + }, + { + "NAME": "color1", + "TYPE": "color", + "DEFAULT": [ + 0.0, + 0.5, + 1.0, + 1.0 + ] + }, + { + "NAME": "color2", + "TYPE": "color", + "DEFAULT": [ + 1.0, + 0.0, + 0.0, + 1.0 + ] + }, + { + "NAME": "color3", + "TYPE": "color", + "DEFAULT": [ + 0.0, + 1.0, + 0.0, + 1.0 + ] + } + ], + "PASSES": [ + { + "TARGET": "fftValues", + "DESCRIPTION": "This buffer stores all of the previous fft values", + "HEIGHT": "512", + "FLOAT": true, + "PERSISTENT": true + }, + { + + } + ] + +}*/ + +void main() +{ + // first pass- read the value from the fft image, store it in the "fftValues" persistent buffer + if (PASSINDEX==0) { + // the first column of pixels is copied from the newly received fft image + if (clear) { + gl_FragColor = vec4(0.0); + } + else if (gl_FragCoord.x<1.0) { + vec2 loc = vec2(isf_FragNormCoord.y, isf_FragNormCoord.x); + vec4 rawColor = IMG_NORM_PIXEL(fftImage, loc); + gl_FragColor = rawColor; + } + // all other columns of pixels come from the "fftValues" persistent buffer (we're scrolling) + else { + gl_FragColor = IMG_PIXEL(fftValues, vec2(gl_FragCoord.x-1.0, gl_FragCoord.y)); + } + } + // second pass- read from the buffer of raw values, apply gain/range and colors + else if (PASSINDEX==1) { + vec2 loc = vec2(isf_FragNormCoord.x, pow(isf_FragNormCoord.y*range, axis_scale)); + vec4 rawColor = IMG_NORM_PIXEL(fftValues, loc); + + rawColor = rawColor * vec4(gain); + + float mixVal = 0.0; + + if (lumaMode) { + float locus_1 = 0.20; + float locus_2 = 0.50; + float locus_3 = 0.75; + + if (rawColor.r < locus_1) { + mixVal = (rawColor.r)/(locus_1); + gl_FragColor = mix(vec4(0,0,0,0), color1, mixVal); + } + else if (rawColor.r>=locus_1 && rawColor.r=locus_2 && rawColor.r=locus_3) { + mixVal = (rawColor.r - locus_3); + gl_FragColor = mix(color3, vec4(1,1,1,1), mixVal); + } + } + else { + float locus_1 = 0.25; + float locus_2 = 0.5; + float locus_3 = 0.75; + + if (loc.y < locus_1) { + gl_FragColor = rawColor.r * color1; + } + else if (loc.y>=locus_1 && loc.y=locus_2 && loc.y locus_3) { + gl_FragColor = rawColor.r * color3; + } + } + } +} \ No newline at end of file diff --git a/ISF/False Color.fs b/ISF/False Color.fs new file mode 100644 index 0000000..ec23b2a --- /dev/null +++ b/ISF/False Color.fs @@ -0,0 +1,42 @@ +/*{ + "CREDIT": "by zoidberg", + "ISFVSN": "2", + "CATEGORIES": [ + "Color Effect" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "brightColor", + "TYPE": "color", + "DEFAULT": [ + 1.0, + 0.9, + 0.8, + 1.0 + ] + }, + { + "NAME": "darkColor", + "TYPE": "color", + "DEFAULT": [ + 0.3, + 0.0, + 0.0, + 1.0 + ] + } + ] +}*/ + +//const vec4 lumcoeff = vec4(0.299, 0.587, 0.114, 0.0); +const vec4 lumcoeff = vec4(0.2126, 0.7152, 0.0722, 0.0); + +void main() { + vec4 srcPixel = IMG_THIS_PIXEL(inputImage); + float luminance = dot(srcPixel,lumcoeff); + gl_FragColor = mix(vec4(darkColor.rgb, srcPixel.a), vec4(brightColor.rgb, srcPixel.a), luminance); +} diff --git a/ISF/Fast Blur.fs b/ISF/Fast Blur.fs new file mode 100644 index 0000000..e986ff0 --- /dev/null +++ b/ISF/Fast Blur.fs @@ -0,0 +1,119 @@ +/*{ + "CREDIT": "by zoidberg WOOP WOOP WOOP WOOP WOOP", + "ISFVSN": "2", + "CATEGORIES": [ + "Blur" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "blurAmount", + "TYPE": "float", + "MIN": 0.0, + "MAX": 12.0, + "DEFAULT": 12.0 + } + ], + "PASSES": [ + { + "TARGET": "halfSizeBaseRender", + "WIDTH": "floor($WIDTH/2.0)", + "HEIGHT": "floor($HEIGHT/2.0)", + "DESCRIPTION": "Pass 0" + }, + { + "TARGET": "quarterSizeBaseRender", + "WIDTH": "floor($WIDTH/4.0)", + "HEIGHT": "floor($HEIGHT/4.0)", + "DESCRIPTION": "Pass 1" + }, + { + "TARGET": "eighthSizeBaseRender", + "WIDTH": "floor($WIDTH/8.0)", + "HEIGHT": "floor($HEIGHT/8.0)", + "DESCRIPTION": "Pass 2" + }, + { + "TARGET": "quarterGaussA", + "WIDTH": "floor($WIDTH/4.0)", + "HEIGHT": "floor($HEIGHT/4.0)", + "DESCRIPTION": "Pass 3" + }, + { + "TARGET": "quarterGaussB", + "WIDTH": "floor($WIDTH/4.0)", + "HEIGHT": "floor($HEIGHT/4.0)", + "DESCRIPTION": "Pass 4" + }, + { + "TARGET": "fullGaussA", + "DESCRIPTION": "Pass 5" + }, + { + "TARGET": "fullGaussB", + "DESCRIPTION": "Pass 6" + } + ] +}*/ + + + +varying vec2 texOffsets[5]; + + +void main() { + int blurLevel = int(floor(blurAmount/6.0)); + float blurLevelModulus = mod(blurAmount, 6.0); + // first three passes are just copying the input image into the buffer at varying sizes + if (PASSINDEX==0) { + gl_FragColor = IMG_NORM_PIXEL(inputImage, isf_FragNormCoord); + } + else if (PASSINDEX==1) { + gl_FragColor = IMG_NORM_PIXEL(halfSizeBaseRender, isf_FragNormCoord); + } + else if (PASSINDEX==2) { + gl_FragColor = IMG_NORM_PIXEL(quarterSizeBaseRender, isf_FragNormCoord); + } + // start reading from the previous stage- each two passes completes a gaussian blur, then + // we increase the resolution & blur (the lower-res blurred image from the previous pass) again... + else if (PASSINDEX == 3) { + vec4 sample0 = IMG_NORM_PIXEL(eighthSizeBaseRender,texOffsets[0]); + vec4 sample1 = IMG_NORM_PIXEL(eighthSizeBaseRender,texOffsets[1]); + vec4 sample2 = IMG_NORM_PIXEL(eighthSizeBaseRender,texOffsets[2]); + vec4 sample3 = IMG_NORM_PIXEL(eighthSizeBaseRender,texOffsets[3]); + vec4 sample4 = IMG_NORM_PIXEL(eighthSizeBaseRender,texOffsets[4]); + //gl_FragColor = vec4((sample0 + sample1 + sample2).rgb / (3.0), 1.0); + gl_FragColor = vec4((sample0 + sample1 + sample2 + sample3 + sample4).rgba / (5.0)); + } + else if (PASSINDEX == 4) { + vec4 sample0 = IMG_NORM_PIXEL(quarterGaussA,texOffsets[0]); + vec4 sample1 = IMG_NORM_PIXEL(quarterGaussA,texOffsets[1]); + vec4 sample2 = IMG_NORM_PIXEL(quarterGaussA,texOffsets[2]); + vec4 sample3 = IMG_NORM_PIXEL(quarterGaussA,texOffsets[3]); + vec4 sample4 = IMG_NORM_PIXEL(quarterGaussA,texOffsets[4]); + //gl_FragColor = vec4((sample0 + sample1 + sample2).rgb / (3.0), 1.0); + gl_FragColor = vec4((sample0 + sample1 + sample2 + sample3 + sample4).rgba / (5.0)); + } + // ...writes into the full-size + else if (PASSINDEX == 5) { + vec4 sample0 = IMG_NORM_PIXEL(quarterGaussB,texOffsets[0]); + vec4 sample1 = IMG_NORM_PIXEL(quarterGaussB,texOffsets[1]); + vec4 sample2 = IMG_NORM_PIXEL(quarterGaussB,texOffsets[2]); + gl_FragColor = vec4((sample0 + sample1 + sample2).rgba / (3.0)); + } + else if (PASSINDEX == 6) { + // this is the last pass- calculate the blurred image as i have in previous passes, then mix it in with the full-size input image using the blur amount so i get a smooth transition into the blur at low blur levels + vec4 sample0 = IMG_NORM_PIXEL(fullGaussA,texOffsets[0]); + vec4 sample1 = IMG_NORM_PIXEL(fullGaussA,texOffsets[1]); + vec4 sample2 = IMG_NORM_PIXEL(fullGaussA,texOffsets[2]); + vec4 blurredImg = vec4((sample0 + sample1 + sample2).rgba / (3.0)); + if (blurLevel == 0) + gl_FragColor = mix(IMG_NORM_PIXEL(inputImage,isf_FragNormCoord), blurredImg, (blurLevelModulus/6.1)); + else + gl_FragColor = blurredImg; + } + +} diff --git a/ISF/Fast Blur.vs b/ISF/Fast Blur.vs new file mode 100644 index 0000000..b775ebf --- /dev/null +++ b/ISF/Fast Blur.vs @@ -0,0 +1,66 @@ +varying vec2 texOffsets[5]; + +void main(void) { + // load the main shader stuff + isf_vertShaderInit(); + + + int blurLevel = int(floor(blurAmount/6.0)); + float blurLevelModulus = mod(blurAmount, 6.0); + float blurRadius = 0.0; + float blurRadiusInPixels = 0.0; + // first three passes are just drawing the texture- do nothing + + // the next four passes do gaussion blurs on the various levels + if (PASSINDEX==3 || PASSINDEX==5) { + float pixelWidth = 1.0/RENDERSIZE.x; + // pass 3 is sampling 1/12, but writing to 1/4 + if (PASSINDEX==3) { + if (blurLevel==1) + blurRadius = blurLevelModulus/1.5; + else if (blurLevel>1) + blurRadius = 4.0; + } + // pass 5 is sampling 1/4 and writing to full-size + else if (PASSINDEX==5) { + if (blurLevel==0) + blurRadius = blurLevelModulus; + else if (blurLevel>0) + blurRadius = 6.0; + } + blurRadiusInPixels = pixelWidth * blurRadius; + texOffsets[0] = isf_FragNormCoord; + texOffsets[1] = (blurRadius==0.0) ? isf_FragNormCoord : clamp(vec2(isf_FragNormCoord[0]-blurRadiusInPixels, isf_FragNormCoord[1]),0.0,1.0); + texOffsets[2] = (blurRadius==0.0) ? isf_FragNormCoord : clamp(vec2(isf_FragNormCoord[0]+blurRadiusInPixels, isf_FragNormCoord[1]),0.0,1.0); + if (PASSINDEX==3) { + texOffsets[3] = (blurRadius==0.0) ? isf_FragNormCoord : clamp(vec2(isf_FragNormCoord[0]-(2.0*blurRadiusInPixels), isf_FragNormCoord[1]),0.0,1.0); + texOffsets[4] = (blurRadius==0.0) ? isf_FragNormCoord : clamp(vec2(isf_FragNormCoord[0]+(2.0*blurRadiusInPixels), isf_FragNormCoord[1]),0.0,1.0); + } + } + else if (PASSINDEX==4 || PASSINDEX==6) { + float pixelHeight = 1.0/RENDERSIZE.y; + // pass 4 is sampling 1/12, but writing to 1/4 + if (PASSINDEX==4) { + if (blurLevel==1) + blurRadius = blurLevelModulus/1.5; + else if (blurLevel>1) + blurRadius = 4.0; + } + // pass 6 is sampling 1/4 and writing to full-size + else if (PASSINDEX==6) { + if (blurLevel==0) + blurRadius = blurLevelModulus; + else if (blurLevel>0) + blurRadius = 6.0; + } + blurRadiusInPixels = pixelHeight * blurRadius; + texOffsets[0] = isf_FragNormCoord; + texOffsets[1] = (blurRadius==0.0) ? isf_FragNormCoord : clamp(vec2(isf_FragNormCoord[0], isf_FragNormCoord[1]-blurRadiusInPixels),0.0,1.0); + texOffsets[2] = (blurRadius==0.0) ? isf_FragNormCoord : clamp(vec2(isf_FragNormCoord[0], isf_FragNormCoord[1]+blurRadiusInPixels),0.0,1.0); + if (PASSINDEX==4) { + texOffsets[3] = (blurRadius==0.0) ? isf_FragNormCoord : clamp(vec2(isf_FragNormCoord[0], isf_FragNormCoord[1]-(2.0*blurRadiusInPixels)),0.0,1.0); + texOffsets[4] = (blurRadius==0.0) ? isf_FragNormCoord : clamp(vec2(isf_FragNormCoord[0], isf_FragNormCoord[1]+(2.0*blurRadiusInPixels)),0.0,1.0); + } + } + +} diff --git a/ISF/FastMosh.fs b/ISF/FastMosh.fs new file mode 100644 index 0000000..c537c89 --- /dev/null +++ b/ISF/FastMosh.fs @@ -0,0 +1,147 @@ +/*{ + "DESCRIPTION": "Does a fast faked data-mosh style", + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Glitch" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "update_keyframe", + "TYPE": "bool", + "DEFAULT": 1.0 + }, + { + "NAME": "update_rate", + "TYPE": "float", + "MIN": 0.01, + "MAX": 1.0, + "DEFAULT": 0.95 + }, + { + "NAME": "sharpen", + "TYPE": "float", + "MIN": 0.0, + "MAX": 10.0, + "DEFAULT": 1.0 + }, + { + "NAME": "blur", + "TYPE": "float", + "MIN": 0.0, + "MAX": 2.0, + "DEFAULT": 0.25 + }, + { + "NAME": "posterize", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.25 + }, + { + "NAME": "mode", + "VALUES": [ + 0, + 1, + 2 + ], + "LABELS": [ + "relative", + "absolute", + "difference" + ], + "DEFAULT": 0, + "TYPE": "long" + } + ], + "PASSES": [ + { + "TARGET":"keyFrameBuffer1", + "PERSISTENT": true, + "WIDTH": "$WIDTH/16.0", + "HEIGHT": "$HEIGHT/16.0" + }, + { + "TARGET":"keyFrameBuffer2", + "PERSISTENT": true, + "WIDTH": "$WIDTH", + "HEIGHT": "$HEIGHT" + } + ] + +}*/ + +varying vec2 left_coord; +varying vec2 right_coord; +varying vec2 above_coord; +varying vec2 below_coord; + +varying vec2 lefta_coord; +varying vec2 righta_coord; +varying vec2 leftb_coord; +varying vec2 rightb_coord; + +void main() +{ + + // first pass: read the "inputImage"- remember, we're drawing to the persistent buffer "keyFrameBuffer1" on the first pass + // store it if we're taking in a new keyframe + if (PASSINDEX == 0) { + vec4 stalePixel = IMG_THIS_NORM_PIXEL(keyFrameBuffer1); + vec4 freshPixel = IMG_THIS_NORM_PIXEL(inputImage); + if (update_keyframe==true) { + gl_FragColor = freshPixel; + } + else { + gl_FragColor = stalePixel; + } + } + // second pass: read from "bufferVariableNameA". output looks chunky and low-res. + else if (PASSINDEX == 1) { + vec4 stalePixel1 = IMG_THIS_NORM_PIXEL(keyFrameBuffer1); + vec4 stalePixel2 = IMG_THIS_NORM_PIXEL(keyFrameBuffer2); + vec4 color = IMG_THIS_NORM_PIXEL(inputImage); + vec4 colorL = IMG_NORM_PIXEL(inputImage, left_coord); + vec4 colorR = IMG_NORM_PIXEL(inputImage, right_coord); + vec4 colorA = IMG_NORM_PIXEL(inputImage, above_coord); + vec4 colorB = IMG_NORM_PIXEL(inputImage, below_coord); + + vec4 colorLA = IMG_NORM_PIXEL(inputImage, lefta_coord); + vec4 colorRA = IMG_NORM_PIXEL(inputImage, righta_coord); + vec4 colorLB = IMG_NORM_PIXEL(inputImage, leftb_coord); + vec4 colorRB = IMG_NORM_PIXEL(inputImage, rightb_coord); + + vec4 final = color; + vec4 diff = (color - stalePixel2); + if (blur > 0.0) { + float blurAmount = blur / 8.0; + diff = diff * (1.0 - blur) + (colorL + colorR + colorA + colorB + colorLA + colorRA + colorLB + colorRB) * blurAmount; + } + + if (mode == 0) { + final = mix(stalePixel2,(diff + stalePixel1),update_rate); + } + else if (mode == 1) { + final = mix(stalePixel2,abs(diff) + stalePixel1,update_rate); + } + else if (mode == 2) { + final = mix(stalePixel2,abs(diff + stalePixel2) * stalePixel1,update_rate); + } + + if (posterize > 0.0) { + float qLevel = 128.0 - posterize * 126.0; + final = floor(final*qLevel)/qLevel; + } + + if (sharpen > 0.0) { + final = final + sharpen * (8.0*color - colorL - colorR - colorA - colorB - colorLA - colorRA - colorLB - colorRB); + } + + gl_FragColor = final; + } +} diff --git a/ISF/FastMosh.vs b/ISF/FastMosh.vs new file mode 100644 index 0000000..c8b60f7 --- /dev/null +++ b/ISF/FastMosh.vs @@ -0,0 +1,27 @@ +varying vec2 left_coord; +varying vec2 right_coord; +varying vec2 above_coord; +varying vec2 below_coord; + +varying vec2 lefta_coord; +varying vec2 righta_coord; +varying vec2 leftb_coord; +varying vec2 rightb_coord; + + +void main() +{ + isf_vertShaderInit(); + vec2 texc = vec2(isf_FragNormCoord[0],isf_FragNormCoord[1]); + vec2 d = 1.0/RENDERSIZE; + + left_coord = clamp(vec2(texc.xy + vec2(-d.x , 0)),0.0,1.0); + right_coord = clamp(vec2(texc.xy + vec2(d.x , 0)),0.0,1.0); + above_coord = clamp(vec2(texc.xy + vec2(0,d.y)),0.0,1.0); + below_coord = clamp(vec2(texc.xy + vec2(0,-d.y)),0.0,1.0); + + lefta_coord = clamp(vec2(texc.xy + vec2(-d.x , d.x)),0.0,1.0); + righta_coord = clamp(vec2(texc.xy + vec2(d.x , d.x)),0.0,1.0); + leftb_coord = clamp(vec2(texc.xy + vec2(-d.x , -d.x)),0.0,1.0); + rightb_coord = clamp(vec2(texc.xy + vec2(d.x , -d.x)),0.0,1.0); +} \ No newline at end of file diff --git a/ISF/Flip H.fs b/ISF/Flip H.fs new file mode 100644 index 0000000..ca74d68 --- /dev/null +++ b/ISF/Flip H.fs @@ -0,0 +1,24 @@ +/*{ + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Geometry Adjustment" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + } + ] +}*/ + +void main() { + vec2 normSrcCoord; + + normSrcCoord.x = isf_FragNormCoord[0]; + normSrcCoord.y = isf_FragNormCoord[1]; + + normSrcCoord.x = (1.0-normSrcCoord.x); + + gl_FragColor = IMG_NORM_PIXEL(inputImage, normSrcCoord); +} \ No newline at end of file diff --git a/ISF/Flip V.fs b/ISF/Flip V.fs new file mode 100644 index 0000000..95ba34e --- /dev/null +++ b/ISF/Flip V.fs @@ -0,0 +1,24 @@ +/*{ + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Geometry Adjustment" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + } + ] +}*/ + +void main() { + vec2 normSrcCoord; + + normSrcCoord.x = isf_FragNormCoord[0]; + normSrcCoord.y = isf_FragNormCoord[1]; + + normSrcCoord.y = (1.0-normSrcCoord.y); + + gl_FragColor = IMG_NORM_PIXEL(inputImage, normSrcCoord); +} \ No newline at end of file diff --git a/ISF/Flipbook.fs b/ISF/Flipbook.fs new file mode 100644 index 0000000..b19e155 --- /dev/null +++ b/ISF/Flipbook.fs @@ -0,0 +1,142 @@ +/* +{ + "CATEGORIES" : [ + "Stylize" + ], + "DESCRIPTION" : "Creates a flipbook like effect", + "ISFVSN" : "2", + "INPUTS" : [ + { + "NAME" : "inputImage", + "TYPE" : "image" + }, + { + "NAME" : "flipRate", + "TYPE" : "float", + "MAX" : 1, + "DEFAULT" : 0.1, + "MIN" : 0 + }, + { + "NAME" : "stretchMode", + "TYPE" : "bool", + "DEFAULT" : 1 + }, + { + "LABELS" : [ + "Left", + "Right", + "Up", + "Down" + ], + "NAME" : "flipDirection", + "TYPE" : "long", + "DEFAULT" : 3, + "VALUES" : [ + 0, + 1, + 2, + 3 + ] + }, + { + "NAME" : "holdTime", + "TYPE" : "float", + "MAX" : 1, + "DEFAULT" : 0, + "MIN" : 0 + } + ], + "PASSES" : [ + { + "FLOAT" : true, + "WIDTH" : "1", + "HEIGHT" : "1", + "TARGET" : "writePos", + "PERSISTENT" : true + }, + { + "TARGET" : "frameGrab", + "PERSISTENT" : true + }, + { + "TARGET" : "lastOutput", + "PERSISTENT" : true + } + ], + "CREDIT" : "VIDVOX" +} +*/ + +void main() { + vec4 inputPixelColor = vec4(0.0); + + if (PASSINDEX == 0) { + inputPixelColor = (FRAMEINDEX <= 1) ? vec4(0.0) : IMG_PIXEL(writePos, vec2(0.0)); + float oldG = inputPixelColor.g; + inputPixelColor.g = inputPixelColor.g + flipRate; + inputPixelColor.b = 1.0; + inputPixelColor.a = 1.0; + if (inputPixelColor.g > 1.0 + flipRate) { + //inputPixelColor.g = 0.0; + if (inputPixelColor.r >= holdTime) { + inputPixelColor.b = 0.0; + inputPixelColor.g = (holdTime > 0.0) ? 0.0 : mod(oldG,1.0); + } + else { + inputPixelColor.r = inputPixelColor.r + TIMEDELTA; + inputPixelColor.g = oldG; + } + } + else { + inputPixelColor.r = 0.0; + } + } + else if (PASSINDEX == 1) { + vec4 tmpColor = (FRAMEINDEX <= 1) ? vec4(0.0) : IMG_PIXEL(writePos, vec2(0.0)); + // update the image buffer + if (tmpColor.b == 0.0) { + inputPixelColor = IMG_THIS_PIXEL(inputImage); + } + // + else { + inputPixelColor = IMG_THIS_PIXEL(frameGrab); + } + } + else if (PASSINDEX == 2) { + if (FRAMEINDEX <= 1) { + inputPixelColor = IMG_THIS_PIXEL(frameGrab); + } + else { + vec4 tmpColor = (FRAMEINDEX <= 1) ? vec4(0.0) : IMG_PIXEL(writePos, vec2(0.0)); + vec2 loc = isf_FragNormCoord; + float grabTime = (tmpColor.g > 1.0) ? 1.0 : tmpColor.g; + float transTime = 0.0; + if (flipDirection == 0) { + transTime = loc.x; + loc.x = (stretchMode) ? 1.0 - (1.0 - loc.x) / (grabTime) : loc.x - (1.0 - grabTime); + } + else if (flipDirection == 1) { + transTime = 1.0 - loc.x; + loc.x = (stretchMode) ? loc.x / (grabTime) : loc.x + (1.0 - grabTime); + } + else if (flipDirection == 2) { + transTime = 1.0 - loc.y; + loc.y = (stretchMode) ? loc.y / (grabTime) : loc.y + (1.0 - grabTime); + } + else if (flipDirection == 3) { + transTime = loc.y; + loc.y = (stretchMode) ? 1.0 - (1.0 - loc.y) / (grabTime) : loc.y - (1.0 - grabTime); + } + + if (transTime <= 1.0 - grabTime) { + inputPixelColor = IMG_THIS_PIXEL(lastOutput); + } + else { + inputPixelColor = IMG_NORM_PIXEL(frameGrab, loc); + } + } + } + + gl_FragColor = inputPixelColor; +} diff --git a/ISF/Freeze Frame.fs b/ISF/Freeze Frame.fs new file mode 100644 index 0000000..81dee5b --- /dev/null +++ b/ISF/Freeze Frame.fs @@ -0,0 +1,38 @@ +/*{ + "DESCRIPTION": "Holds the output on the captured freeze frame", + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Utility" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "freeze", + "TYPE": "bool", + "DEFAULT": 0.0 + } + ], + "PASSES": [ + { + "TARGET":"freezeBuffer", + "PERSISTENT": true, + } + ] + +}*/ + +// Essentially the same as a feedback buffer where you can only set it to a mix of 1.0 + +void main() +{ + if (freeze) { + gl_FragColor = IMG_THIS_PIXEL(freezeBuffer); + } + else { + gl_FragColor = IMG_THIS_PIXEL(inputImage); + } +} diff --git a/ISF/Frosted Glass.fs b/ISF/Frosted Glass.fs new file mode 100644 index 0000000..30b82fe --- /dev/null +++ b/ISF/Frosted Glass.fs @@ -0,0 +1,130 @@ +/*{ + "DESCRIPTION": "", + "CREDIT": "geeks3d", + "ISFVSN": "2", + "CATEGORIES": [ + "Distortion Effect" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "magnitude", + "LABEL": "Magnitude", + "TYPE": "float", + "DEFAULT": 0.01, + "MIN": 0.0, + "MAX": 0.1 + }, + { + "NAME": "seed", + "LABEL": "Seed", + "TYPE": "float", + "DEFAULT": 0.345, + "MIN": 0.0, + "MAX": 1.0 + } + ] + +}*/ + +/* + + adapted from http://www.geeks3d.com/20101228/shader-library-frosted-glass-post-processing-shader-glsl/ + +*/ + + +const float vx_offset = 0.5; + +vec4 spline(float x, vec4 c1, vec4 c2, vec4 c3, vec4 c4, vec4 c5, vec4 c6, vec4 c7, vec4 c8, vec4 c9) +{ + float w1, w2, w3, w4, w5, w6, w7, w8, w9; + w1 = 0.0; + w2 = 0.0; + w3 = 0.0; + w4 = 0.0; + w5 = 0.0; + w6 = 0.0; + w7 = 0.0; + w8 = 0.0; + w9 = 0.0; + float tmp = x * 8.0; + if (tmp<=1.0) { + w1 = 1.0 - tmp; + w2 = tmp; + } + else if (tmp<=2.0) { + tmp = tmp - 1.0; + w2 = 1.0 - tmp; + w3 = tmp; + } + else if (tmp<=3.0) { + tmp = tmp - 2.0; + w3 = 1.0-tmp; + w4 = tmp; + } + else if (tmp<=4.0) { + tmp = tmp - 3.0; + w4 = 1.0-tmp; + w5 = tmp; + } + else if (tmp<=5.0) { + tmp = tmp - 4.0; + w5 = 1.0-tmp; + w6 = tmp; + } + else if (tmp<=6.0) { + tmp = tmp - 5.0; + w6 = 1.0-tmp; + w7 = tmp; + } + else if (tmp<=7.0) { + tmp = tmp - 6.0; + w7 = 1.0 - tmp; + w8 = tmp; + } + else { + //tmp = saturate(tmp - 7.0); + // http://www.ozone3d.net/blogs/lab/20080709/saturate-function-in-glsl/ + tmp = clamp(tmp - 7.0, 0.0, 1.0); + w8 = 1.0-tmp; + w9 = tmp; + } + return w1*c1 + w2*c2 + w3*c3 + w4*c4 + w5*c5 + w6*c6 + w7*c7 + w8*c8 + w9*c9; +} + +float rand(vec2 co){ + return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453); +} + +void main() { + vec2 uv = isf_FragNormCoord.xy; + vec4 tc = vec4(1.0, 0.0, 0.0, 0.0); + + float DeltaX = magnitude / 2.0; + float DeltaY = magnitude / 2.0; + vec2 ox = vec2(DeltaX,0.0); + vec2 oy = vec2(0.0,DeltaY); + vec2 PP = uv - oy; + vec4 C00 = IMG_NORM_PIXEL(inputImage,PP - ox); + vec4 C01 = IMG_NORM_PIXEL(inputImage,PP); + vec4 C02 = IMG_NORM_PIXEL(inputImage,PP + ox); + PP = uv; + vec4 C10 = IMG_NORM_PIXEL(inputImage,PP - ox); + vec4 C11 = IMG_NORM_PIXEL(inputImage,PP); + vec4 C12 = IMG_NORM_PIXEL(inputImage,PP + ox); + PP = uv + oy; + vec4 C20 = IMG_NORM_PIXEL(inputImage,PP - ox); + vec4 C21 = IMG_NORM_PIXEL(inputImage,PP); + vec4 C22 = IMG_NORM_PIXEL(inputImage,PP + ox); + + float n = rand(seed*uv); + n = mod(n, 0.111111)/0.111111; + vec4 result = spline(n,C00,C01,C02,C10,C11,C12,C20,C21,C22); + tc = result.rgba; + + gl_FragColor = tc; +} diff --git a/ISF/Gamma Correction.fs b/ISF/Gamma Correction.fs new file mode 100644 index 0000000..3873164 --- /dev/null +++ b/ISF/Gamma Correction.fs @@ -0,0 +1,33 @@ +/*{ + "CREDIT": "by zoidberg", + "ISFVSN": "2", + "CATEGORIES": [ + "Color Adjustment" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "gamma", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.5 + } + ] +}*/ + + + +void main() { + // the input gamma range is 0.0-1.0 (normalized). the actual gamma range i want to use is 0.0 - 5.0. + // however, actual gamma 0.0-1.0 is just as interesting as actual gamma 1.0-5.0, so we scale the normalized input to match... + float realGamma = (gamma<=0.5) ? (gamma * 2.0) : (((gamma-0.5) * 2.0 * 4.0) + 1.0); + vec4 tmpColorA = IMG_THIS_PIXEL(inputImage); + vec4 tmpColorB; + tmpColorB.rgb = pow(tmpColorA.rgb, vec3(1.0/realGamma)); + tmpColorB.a = tmpColorA.a; + gl_FragColor = tmpColorB; +} diff --git a/ISF/Ghosting.fs b/ISF/Ghosting.fs new file mode 100644 index 0000000..63b2f88 --- /dev/null +++ b/ISF/Ghosting.fs @@ -0,0 +1,121 @@ +/*{ + "DESCRIPTION": "", + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Film" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "uBias", + "LABEL": "Bias", + "TYPE": "float", + "MIN": -1.0, + "MAX": 0.0, + "DEFAULT": -0.5 + }, + { + "NAME": "uScale", + "LABEL": "Scale", + "TYPE": "float", + "MIN": 0.0, + "MAX": 2.0, + "DEFAULT": 0.5 + }, + { + "NAME": "uGhosts", + "LABEL": "Ghosts", + "TYPE": "float", + "MIN": 0.0, + "MAX": 5.0, + "DEFAULT": 5.0 + }, + { + "NAME": "uGhostDispersal", + "LABEL": "Ghost Dispersal", + "TYPE": "float", + "MIN": 0.0, + "MAX": 0.1, + "DEFAULT": 0.0125 + }, + { + "NAME": "uAdditive", + "LABEL": "Additive Mode", + "TYPE": "bool", + "DEFAULT": 1.0 + }, + { + "NAME": "uDirection", + "LABEL": "Direction", + "TYPE": "point2D", + "DEFAULT": [ + 0.5, + 0.5 + ] + }, + { + "NAME": "uLensColor", + "LABEL": "Lens Color", + "TYPE": "color", + "DEFAULT": [ + 0.9, + 0.8, + 0.7, + 1.0 + ] + } + ], + "PASSES": [ + { + "TARGET": "downsampleAndThresholdImage", + "WIDTH": "floor($WIDTH/1.0)", + "HEIGHT": "floor($HEIGHT/1.0)", + "DESCRIPTION": "Downsample and threshold" + }, + { + + } + ] + +}*/ + + + + +void main() +{ + + if (PASSINDEX == 0) { + vec2 loc = isf_FragNormCoord; + gl_FragColor = max(vec4(0.0), IMG_NORM_PIXEL(inputImage,loc) + uBias) * uScale; + } + else if (PASSINDEX == 1) { + vec2 texcoord = isf_FragNormCoord; + vec2 texelSize = 1.0 / RENDERSIZE; + vec2 direction = vec2(1.0) - uDirection / RENDERSIZE; + vec2 ghostVec = (direction - texcoord) * uGhostDispersal; + //vec2 direction = vec2(0.5,0.5); + vec4 result = vec4(0.0); + for (int i = 0; i < 5; ++i) { + if (float(i)>uGhosts) + break; + vec2 offset = fract(texcoord + ghostVec * float(i)); + + result += IMG_NORM_PIXEL(downsampleAndThresholdImage, offset) * uLensColor; + } + // apply the alpha + result.rgb = result.rgb * uLensColor.a; + if (uAdditive) { + result = result + IMG_NORM_PIXEL(inputImage, texcoord); + } + else { + result = result * IMG_NORM_PIXEL(inputImage, texcoord); + } + gl_FragColor = result; + } + +} \ No newline at end of file diff --git a/ISF/Glitch Shifter.fs b/ISF/Glitch Shifter.fs new file mode 100644 index 0000000..c19ba78 --- /dev/null +++ b/ISF/Glitch Shifter.fs @@ -0,0 +1,146 @@ +/*{ + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Glitch" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "glitch_size", + "LABEL": "Size", + "TYPE": "float", + "MIN": 0.0, + "MAX": 0.5, + "DEFAULT": 0.1 + }, + { + "NAME": "glitch_horizontal", + "LABEL": "Horizontal Amount", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.2 + }, + { + "NAME": "glitch_vertical", + "LABEL": "Vertical Amount", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.0 + }, + { + "NAME": "randomize_size", + "LABEL": "Randomize Size", + "TYPE": "bool", + "DEFAULT": 1.0 + }, + { + "NAME": "randomize_zoom", + "LABEL": "Randomize Zoom", + "TYPE": "bool", + "DEFAULT": 0.0 + }, + { + "NAME": "use_alt_image", + "LABEL": "Use Alt Image", + "TYPE": "bool", + "DEFAULT": 0.0 + }, + { + "NAME": "altImage", + "TYPE": "image" + }, + { + "NAME": "offset", + "LABEL": "Offset", + "TYPE": "point2D", + "DEFAULT": [ + 0, + 0 + ] + } + ] +}*/ + +float rand(vec2 co){ + return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453); +} + +void main() +{ + vec2 xy; + vec4 returnMe; + bool shifted = false; + xy.x = isf_FragNormCoord[0]; + xy.y = isf_FragNormCoord[1]; + + // quantize the xy to the glitch_amount size + //xy = floor(xy / glitch_size) * glitch_size; + vec2 random; + + float local_glitch_size = glitch_size; + float random_offset = 0.0; + + if (randomize_size) { + random_offset = mod(rand(vec2(TIME,TIME)), 1.0); + local_glitch_size = random_offset * glitch_size; + } + + if (local_glitch_size > 0.0) { + random.x = rand(vec2(floor(random_offset + xy.y / local_glitch_size) * local_glitch_size, TIME)); + random.y = rand(vec2(floor(random_offset + xy.x / local_glitch_size) * local_glitch_size, TIME)); + } + else { + random.x = rand(vec2(xy.x, TIME)); + random.y = rand(vec2(xy.y, TIME)); + } + + if (randomize_zoom) { + if ((random.x < glitch_horizontal)&&(random.y < glitch_vertical)) { + float level = rand(vec2(random.x, random.y)) / 5.0 + 0.90; + xy = (xy - vec2(0.5))*(1.0/level) + vec2(0.5); + } + else if (random.x < glitch_horizontal) { + float level = (random.x) + 0.98; + xy = (xy - vec2(0.5))*(1.0/level) + vec2(0.5); + } + else if (random.y < glitch_vertical) { + float level = (random.y) + 0.98; + xy = (xy - vec2(0.5))*(1.0/level) + vec2(0.5); + } + } + + // if doing a horizontal glitch do a random shift + if ((random.x < glitch_horizontal)&&(random.y < glitch_vertical)) { + vec2 shift = (offset / RENDERSIZE - 0.5); + shift = shift * rand(shift + random); + xy.x = mod(xy.x + random.x, 1.0); + xy.y = mod(xy.y + random.y, 1.0); + xy = xy + shift; + shifted = true; + } + else if (random.x < glitch_horizontal) { + vec2 shift = (offset / RENDERSIZE - 0.5); + shift = shift * rand(shift + random); + xy = mod(xy + vec2(0.0, random.x) + shift, 1.0); + shifted = true; + } + else if (random.y < glitch_vertical) { + vec2 shift = (offset / RENDERSIZE - 0.5); + shift = shift * rand(shift + random); + xy = mod(xy + vec2(random.y, 0.0) + shift, 1.0); + shifted = true; + } + + if ((shifted) && (use_alt_image) && (rand(vec2(TIME, xy.x)) < 0.5)) + returnMe = IMG_NORM_PIXEL(altImage, xy); + else + returnMe = IMG_NORM_PIXEL(inputImage, xy); + + gl_FragColor = returnMe; +} diff --git a/ISF/Gloom.fs b/ISF/Gloom.fs new file mode 100644 index 0000000..f34d26d --- /dev/null +++ b/ISF/Gloom.fs @@ -0,0 +1,127 @@ +/*{ + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Stylize", + "Blur" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "blurAmount", + "TYPE": "float", + "MIN": 0.0, + "MAX": 12.0, + "DEFAULT": 12.0 + }, + { + "NAME": "intensity", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.0 + } + ], + "PASSES": [ + { + "TARGET": "halfSizeBaseRender", + "WIDTH": "floor($WIDTH/2.0)", + "HEIGHT": "floor($HEIGHT/2.0)", + "DESCRIPTION": "Pass 0" + }, + { + "TARGET": "quarterSizeBaseRender", + "WIDTH": "floor($WIDTH/4.0)", + "HEIGHT": "floor($HEIGHT/4.0)", + "DESCRIPTION": "Pass 1" + }, + { + "TARGET": "eighthSizeBaseRender", + "WIDTH": "floor($WIDTH/8.0)", + "HEIGHT": "floor($HEIGHT/8.0)", + "DESCRIPTION": "Pass 2" + }, + { + "TARGET": "quarterGaussA", + "WIDTH": "floor($WIDTH/4.0)", + "HEIGHT": "floor($HEIGHT/4.0)", + "DESCRIPTION": "Pass 3" + }, + { + "TARGET": "quarterGaussB", + "WIDTH": "floor($WIDTH/4.0)", + "HEIGHT": "floor($HEIGHT/4.0)", + "DESCRIPTION": "Pass 4" + }, + { + "TARGET": "fullGaussA", + "DESCRIPTION": "Pass 5" + }, + { + "TARGET": "fullGaussB", + "DESCRIPTION": "Pass 6" + } + ] +}*/ + + + +varying vec2 texOffsets[5]; + + +void main() { + int blurLevel = int(floor(blurAmount/6.0)); + float blurLevelModulus = mod(blurAmount, 6.0); + // first three passes are just copying the input image into the buffer at varying sizes + if (PASSINDEX==0) { + gl_FragColor = IMG_NORM_PIXEL(inputImage, isf_FragNormCoord); + } + else if (PASSINDEX==1) { + gl_FragColor = IMG_NORM_PIXEL(halfSizeBaseRender, isf_FragNormCoord); + } + else if (PASSINDEX==2) { + gl_FragColor = IMG_NORM_PIXEL(quarterSizeBaseRender, isf_FragNormCoord); + } + // start reading from the previous stage- each two passes completes a gaussian blur, then + // we increase the resolution & blur (the lower-res blurred image from the previous pass) again... + else if (PASSINDEX == 3) { + vec4 sample0 = IMG_NORM_PIXEL(eighthSizeBaseRender,texOffsets[0]); + vec4 sample1 = IMG_NORM_PIXEL(eighthSizeBaseRender,texOffsets[1]); + vec4 sample2 = IMG_NORM_PIXEL(eighthSizeBaseRender,texOffsets[2]); + vec4 sample3 = IMG_NORM_PIXEL(eighthSizeBaseRender,texOffsets[3]); + vec4 sample4 = IMG_NORM_PIXEL(eighthSizeBaseRender,texOffsets[4]); + //gl_FragColor = vec4((sample0 + sample1 + sample2).rgb / (3.0), 1.0); + gl_FragColor = vec4((sample0 + sample1 + sample2 + sample3 + sample4).rgb / (5.0), 1.0); + } + else if (PASSINDEX == 4) { + vec4 sample0 = IMG_NORM_PIXEL(quarterGaussA,texOffsets[0]); + vec4 sample1 = IMG_NORM_PIXEL(quarterGaussA,texOffsets[1]); + vec4 sample2 = IMG_NORM_PIXEL(quarterGaussA,texOffsets[2]); + vec4 sample3 = IMG_NORM_PIXEL(quarterGaussA,texOffsets[3]); + vec4 sample4 = IMG_NORM_PIXEL(quarterGaussA,texOffsets[4]); + //gl_FragColor = vec4((sample0 + sample1 + sample2).rgb / (3.0), 1.0); + gl_FragColor = vec4((sample0 + sample1 + sample2 + sample3 + sample4).rgb / (5.0), 1.0); + } + // ...writes into the full-size + else if (PASSINDEX == 5) { + vec4 sample0 = IMG_NORM_PIXEL(quarterGaussB,texOffsets[0]); + vec4 sample1 = IMG_NORM_PIXEL(quarterGaussB,texOffsets[1]); + vec4 sample2 = IMG_NORM_PIXEL(quarterGaussB,texOffsets[2]); + gl_FragColor = vec4((sample0 + sample1 + sample2).rgb / (3.0), 1.0); + } + else if (PASSINDEX == 6) { + // this is the last pass- calculate the blurred image as i have in previous passes, then mix it in with the full-size input image using the blur amount so i get a smooth transition into the blur at low blur levels + vec4 sample0 = IMG_NORM_PIXEL(fullGaussA,texOffsets[0]); + vec4 sample1 = IMG_NORM_PIXEL(fullGaussA,texOffsets[1]); + vec4 sample2 = IMG_NORM_PIXEL(fullGaussA,texOffsets[2]); + vec4 blurredImg = vec4((sample0 + sample1 + sample2).rgb / (3.0), 1.0); + vec4 originalImg = IMG_NORM_PIXEL(inputImage,isf_FragNormCoord); + if (blurLevel == 0) + blurredImg = mix(originalImg, blurredImg, (blurLevelModulus/6.0)); + + gl_FragColor = min(mix(originalImg,blurredImg*0.9,intensity), originalImg); + } +} \ No newline at end of file diff --git a/ISF/Gloom.vs b/ISF/Gloom.vs new file mode 100644 index 0000000..b775ebf --- /dev/null +++ b/ISF/Gloom.vs @@ -0,0 +1,66 @@ +varying vec2 texOffsets[5]; + +void main(void) { + // load the main shader stuff + isf_vertShaderInit(); + + + int blurLevel = int(floor(blurAmount/6.0)); + float blurLevelModulus = mod(blurAmount, 6.0); + float blurRadius = 0.0; + float blurRadiusInPixels = 0.0; + // first three passes are just drawing the texture- do nothing + + // the next four passes do gaussion blurs on the various levels + if (PASSINDEX==3 || PASSINDEX==5) { + float pixelWidth = 1.0/RENDERSIZE.x; + // pass 3 is sampling 1/12, but writing to 1/4 + if (PASSINDEX==3) { + if (blurLevel==1) + blurRadius = blurLevelModulus/1.5; + else if (blurLevel>1) + blurRadius = 4.0; + } + // pass 5 is sampling 1/4 and writing to full-size + else if (PASSINDEX==5) { + if (blurLevel==0) + blurRadius = blurLevelModulus; + else if (blurLevel>0) + blurRadius = 6.0; + } + blurRadiusInPixels = pixelWidth * blurRadius; + texOffsets[0] = isf_FragNormCoord; + texOffsets[1] = (blurRadius==0.0) ? isf_FragNormCoord : clamp(vec2(isf_FragNormCoord[0]-blurRadiusInPixels, isf_FragNormCoord[1]),0.0,1.0); + texOffsets[2] = (blurRadius==0.0) ? isf_FragNormCoord : clamp(vec2(isf_FragNormCoord[0]+blurRadiusInPixels, isf_FragNormCoord[1]),0.0,1.0); + if (PASSINDEX==3) { + texOffsets[3] = (blurRadius==0.0) ? isf_FragNormCoord : clamp(vec2(isf_FragNormCoord[0]-(2.0*blurRadiusInPixels), isf_FragNormCoord[1]),0.0,1.0); + texOffsets[4] = (blurRadius==0.0) ? isf_FragNormCoord : clamp(vec2(isf_FragNormCoord[0]+(2.0*blurRadiusInPixels), isf_FragNormCoord[1]),0.0,1.0); + } + } + else if (PASSINDEX==4 || PASSINDEX==6) { + float pixelHeight = 1.0/RENDERSIZE.y; + // pass 4 is sampling 1/12, but writing to 1/4 + if (PASSINDEX==4) { + if (blurLevel==1) + blurRadius = blurLevelModulus/1.5; + else if (blurLevel>1) + blurRadius = 4.0; + } + // pass 6 is sampling 1/4 and writing to full-size + else if (PASSINDEX==6) { + if (blurLevel==0) + blurRadius = blurLevelModulus; + else if (blurLevel>0) + blurRadius = 6.0; + } + blurRadiusInPixels = pixelHeight * blurRadius; + texOffsets[0] = isf_FragNormCoord; + texOffsets[1] = (blurRadius==0.0) ? isf_FragNormCoord : clamp(vec2(isf_FragNormCoord[0], isf_FragNormCoord[1]-blurRadiusInPixels),0.0,1.0); + texOffsets[2] = (blurRadius==0.0) ? isf_FragNormCoord : clamp(vec2(isf_FragNormCoord[0], isf_FragNormCoord[1]+blurRadiusInPixels),0.0,1.0); + if (PASSINDEX==4) { + texOffsets[3] = (blurRadius==0.0) ? isf_FragNormCoord : clamp(vec2(isf_FragNormCoord[0], isf_FragNormCoord[1]-(2.0*blurRadiusInPixels)),0.0,1.0); + texOffsets[4] = (blurRadius==0.0) ? isf_FragNormCoord : clamp(vec2(isf_FragNormCoord[0], isf_FragNormCoord[1]+(2.0*blurRadiusInPixels)),0.0,1.0); + } + } + +} diff --git a/ISF/Glow-Fast.fs b/ISF/Glow-Fast.fs new file mode 100644 index 0000000..d48822d --- /dev/null +++ b/ISF/Glow-Fast.fs @@ -0,0 +1,151 @@ +/*{ + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Stylize", + "Blur" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "intensity", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 1.0 + }, + { + "NAME": "blurAmount", + "TYPE": "float", + "MIN": 0.0, + "MAX": 12.0, + "DEFAULT": 12.0 + } + ], + "PASSES": [ + { + "TARGET": "halfSizeBaseRender", + "WIDTH": "floor($WIDTH/2.0)", + "HEIGHT": "floor($HEIGHT/2.0)", + "DESCRIPTION": "Pass 0" + }, + { + "TARGET": "quarterSizeBaseRender", + "WIDTH": "floor($WIDTH/4.0)", + "HEIGHT": "floor($HEIGHT/4.0)", + "DESCRIPTION": "Pass 1" + }, + { + "TARGET": "eighthSizeBaseRender", + "WIDTH": "floor($WIDTH/8.0)", + "HEIGHT": "floor($HEIGHT/8.0)", + "DESCRIPTION": "Pass 2" + }, + { + "TARGET": "quarterGaussA", + "WIDTH": "floor($WIDTH/4.0)", + "HEIGHT": "floor($HEIGHT/4.0)", + "DESCRIPTION": "Pass 3" + }, + { + "TARGET": "quarterGaussB", + "WIDTH": "floor($WIDTH/4.0)", + "HEIGHT": "floor($HEIGHT/4.0)", + "DESCRIPTION": "Pass 4" + }, + { + "TARGET": "fullGaussA", + "DESCRIPTION": "Pass 5" + }, + { + "TARGET": "fullGaussB", + "DESCRIPTION": "Pass 6" + } + ] +}*/ + + +// original blur implementation as v002.blur in QC by anton marini and tom butterworth, ported by zoidberg + + +varying vec2 texOffsets[5]; + + +void main() { + int blurLevel = int(floor(blurAmount/6.0)); + float blurLevelModulus = mod(blurAmount, 6.0); + // first three passes are just copying the input image into the buffer at varying sizes + if (PASSINDEX==0) { + gl_FragColor = IMG_NORM_PIXEL(inputImage, isf_FragNormCoord); + } + else if (PASSINDEX==1) { + gl_FragColor = IMG_NORM_PIXEL(halfSizeBaseRender, isf_FragNormCoord); + } + else if (PASSINDEX==2) { + gl_FragColor = IMG_NORM_PIXEL(quarterSizeBaseRender, isf_FragNormCoord); + } + // start reading from the previous stage- each two passes completes a gaussian blur, then + // we increase the resolution & blur (the lower-res blurred image from the previous pass) again... + else if (PASSINDEX == 3) { + vec4 sample0 = IMG_NORM_PIXEL(eighthSizeBaseRender,texOffsets[0]); + vec4 sample1 = IMG_NORM_PIXEL(eighthSizeBaseRender,texOffsets[1]); + vec4 sample2 = IMG_NORM_PIXEL(eighthSizeBaseRender,texOffsets[2]); + vec4 sample3 = IMG_NORM_PIXEL(eighthSizeBaseRender,texOffsets[3]); + vec4 sample4 = IMG_NORM_PIXEL(eighthSizeBaseRender,texOffsets[4]); + //gl_FragColor = vec4((sample0 + sample1 + sample2).rgb / (3.0), 1.0); + //gl_FragColor = vec4((sample0 + sample1 + sample2 + sample3 + sample4).rgb / (5.0), 1.0); + vec4 final = vec4((sample0 + sample1 + sample2 + sample3 + sample4).rgba / (5.0)); + final = mix(sample0, final, intensity); + gl_FragColor = final; + } + else if (PASSINDEX == 4) { + vec4 sample0 = IMG_NORM_PIXEL(quarterGaussA,texOffsets[0]); + vec4 sample1 = IMG_NORM_PIXEL(quarterGaussA,texOffsets[1]); + vec4 sample2 = IMG_NORM_PIXEL(quarterGaussA,texOffsets[2]); + vec4 sample3 = IMG_NORM_PIXEL(quarterGaussA,texOffsets[3]); + vec4 sample4 = IMG_NORM_PIXEL(quarterGaussA,texOffsets[4]); + //gl_FragColor = vec4((sample0 + sample1 + sample2).rgb / (3.0), 1.0); + //gl_FragColor = vec4((sample0 + sample1 + sample2 + sample3 + sample4).rgb / (5.0), 1.0); + vec4 final = vec4((sample0 + sample1 + sample2 + sample3 + sample4).rgba / (5.0)); + final = mix(sample0, final, intensity); + gl_FragColor = final; + } + // ...writes into the full-size + else if (PASSINDEX == 5) { + vec4 sample0 = IMG_NORM_PIXEL(quarterGaussB,texOffsets[0]); + vec4 sample1 = IMG_NORM_PIXEL(quarterGaussB,texOffsets[1]); + vec4 sample2 = IMG_NORM_PIXEL(quarterGaussB,texOffsets[2]); + //gl_FragColor = vec4((sample0 + sample1 + sample2).rgb / (3.0), 1.0); + vec4 final = vec4((sample0 + sample1 + sample2).rgba / (3.0)); + final = mix(sample0, final, intensity); + gl_FragColor = final; + } + else if (PASSINDEX == 6) { + // this is the last pass- calculate the blurred image as i have in previous passes, then mix it in with the full-size input image using the blur amount so i get a smooth transition into the blur at low blur levels + vec4 sample0 = IMG_NORM_PIXEL(fullGaussA,texOffsets[0]); + vec4 sample1 = IMG_NORM_PIXEL(fullGaussA,texOffsets[1]); + vec4 sample2 = IMG_NORM_PIXEL(fullGaussA,texOffsets[2]); + vec4 final = vec4((sample0 + sample1 + sample2).rgba / (3.0)); + vec4 original = IMG_NORM_PIXEL(inputImage,isf_FragNormCoord); + final = mix(original, min((final*original),1.0), intensity); + // First do a gloom, + // then a bright / contrast tweak based on the amount + // then a bloom + vec4 tmpColorA = final; + float bright = intensity*0.222; + vec4 tmpColorB = tmpColorA + vec4(bright,bright,bright,bright); + // contrast + float contrast = 1.0 + intensity * (2.893); + tmpColorA.rgba = ((vec4(2.0) * (tmpColorB.rgba - vec4(0.5))) * vec4(contrast) / vec4(2.0)) + vec4(0.5); + final = min((tmpColorA + tmpColorA * original), 1.0); + gl_FragColor = final; + //if (blurLevel == 0) + // gl_FragColor = mix(IMG_NORM_PIXEL(inputImage,isf_FragNormCoord), blurredImg, (blurLevelModulus/6.1)); + //else + // gl_FragColor = blurredImg; + } + +} diff --git a/ISF/Glow-Fast.vs b/ISF/Glow-Fast.vs new file mode 100644 index 0000000..b775ebf --- /dev/null +++ b/ISF/Glow-Fast.vs @@ -0,0 +1,66 @@ +varying vec2 texOffsets[5]; + +void main(void) { + // load the main shader stuff + isf_vertShaderInit(); + + + int blurLevel = int(floor(blurAmount/6.0)); + float blurLevelModulus = mod(blurAmount, 6.0); + float blurRadius = 0.0; + float blurRadiusInPixels = 0.0; + // first three passes are just drawing the texture- do nothing + + // the next four passes do gaussion blurs on the various levels + if (PASSINDEX==3 || PASSINDEX==5) { + float pixelWidth = 1.0/RENDERSIZE.x; + // pass 3 is sampling 1/12, but writing to 1/4 + if (PASSINDEX==3) { + if (blurLevel==1) + blurRadius = blurLevelModulus/1.5; + else if (blurLevel>1) + blurRadius = 4.0; + } + // pass 5 is sampling 1/4 and writing to full-size + else if (PASSINDEX==5) { + if (blurLevel==0) + blurRadius = blurLevelModulus; + else if (blurLevel>0) + blurRadius = 6.0; + } + blurRadiusInPixels = pixelWidth * blurRadius; + texOffsets[0] = isf_FragNormCoord; + texOffsets[1] = (blurRadius==0.0) ? isf_FragNormCoord : clamp(vec2(isf_FragNormCoord[0]-blurRadiusInPixels, isf_FragNormCoord[1]),0.0,1.0); + texOffsets[2] = (blurRadius==0.0) ? isf_FragNormCoord : clamp(vec2(isf_FragNormCoord[0]+blurRadiusInPixels, isf_FragNormCoord[1]),0.0,1.0); + if (PASSINDEX==3) { + texOffsets[3] = (blurRadius==0.0) ? isf_FragNormCoord : clamp(vec2(isf_FragNormCoord[0]-(2.0*blurRadiusInPixels), isf_FragNormCoord[1]),0.0,1.0); + texOffsets[4] = (blurRadius==0.0) ? isf_FragNormCoord : clamp(vec2(isf_FragNormCoord[0]+(2.0*blurRadiusInPixels), isf_FragNormCoord[1]),0.0,1.0); + } + } + else if (PASSINDEX==4 || PASSINDEX==6) { + float pixelHeight = 1.0/RENDERSIZE.y; + // pass 4 is sampling 1/12, but writing to 1/4 + if (PASSINDEX==4) { + if (blurLevel==1) + blurRadius = blurLevelModulus/1.5; + else if (blurLevel>1) + blurRadius = 4.0; + } + // pass 6 is sampling 1/4 and writing to full-size + else if (PASSINDEX==6) { + if (blurLevel==0) + blurRadius = blurLevelModulus; + else if (blurLevel>0) + blurRadius = 6.0; + } + blurRadiusInPixels = pixelHeight * blurRadius; + texOffsets[0] = isf_FragNormCoord; + texOffsets[1] = (blurRadius==0.0) ? isf_FragNormCoord : clamp(vec2(isf_FragNormCoord[0], isf_FragNormCoord[1]-blurRadiusInPixels),0.0,1.0); + texOffsets[2] = (blurRadius==0.0) ? isf_FragNormCoord : clamp(vec2(isf_FragNormCoord[0], isf_FragNormCoord[1]+blurRadiusInPixels),0.0,1.0); + if (PASSINDEX==4) { + texOffsets[3] = (blurRadius==0.0) ? isf_FragNormCoord : clamp(vec2(isf_FragNormCoord[0], isf_FragNormCoord[1]-(2.0*blurRadiusInPixels)),0.0,1.0); + texOffsets[4] = (blurRadius==0.0) ? isf_FragNormCoord : clamp(vec2(isf_FragNormCoord[0], isf_FragNormCoord[1]+(2.0*blurRadiusInPixels)),0.0,1.0); + } + } + +} diff --git a/ISF/Glow.fs b/ISF/Glow.fs new file mode 100644 index 0000000..9b8fefd --- /dev/null +++ b/ISF/Glow.fs @@ -0,0 +1,156 @@ +/*{ + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Stylize", + "Blur" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "intensity", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 1.0 + } + ], + "PASSES": [ + { + "TARGET": "smallA", + "WIDTH": "floor($WIDTH*min((0.2),1.0))", + "HEIGHT": "floor($HEIGHT*min((0.2),1.0))" + }, + { + "TARGET": "smallB", + "WIDTH": "floor($WIDTH*min((0.2),1.0))", + "HEIGHT": "floor($HEIGHT*min((0.2),1.0))" + }, + { + "TARGET": "smallC", + "WIDTH": "floor($WIDTH*min((0.3),1.0))", + "HEIGHT": "floor($HEIGHT*min((0.3),1.0))" + }, + { + "TARGET": "smallD", + "WIDTH": "floor($WIDTH*min((0.3),1.0))", + "HEIGHT": "floor($HEIGHT*min((0.3),1.0))" + }, + { + "TARGET": "smallE", + "WIDTH": "floor($WIDTH*min((0.5),1.0))", + "HEIGHT": "floor($HEIGHT*min((0.5),1.0))" + }, + { + "TARGET": "smallF", + "WIDTH": "floor($WIDTH*min((0.5),1.0))", + "HEIGHT": "floor($HEIGHT*min((0.5),1.0))" + }, + { + "TARGET": "smallG", + "WIDTH": "floor($WIDTH*min((0.8),1.0))", + "HEIGHT": "floor($HEIGHT*min((0.8),1.0))" + }, + { + "TARGET": "smallH", + "WIDTH": "floor($WIDTH*min((0.8),1.0))", + "HEIGHT": "floor($HEIGHT*min((0.8),1.0))" + }, + { + "TARGET": "smallI" + }, + { + + } + ] +}*/ + + +// original blur implementation as v002.blur in QC by anton marini and tom butterworth, ported by zoidberg + + +varying vec2 texOffsets[3]; + + +void main() { + vec4 sample0; + vec4 sample1; + vec4 sample2; + if (PASSINDEX == 0) { + sample0 = IMG_NORM_PIXEL(inputImage,texOffsets[0]); + sample1 = IMG_NORM_PIXEL(inputImage,texOffsets[1]); + sample2 = IMG_NORM_PIXEL(inputImage,texOffsets[2]); + } + else if (PASSINDEX == 1) { + sample0 = IMG_NORM_PIXEL(smallA,texOffsets[0]); + sample1 = IMG_NORM_PIXEL(smallA,texOffsets[1]); + sample2 = IMG_NORM_PIXEL(smallA,texOffsets[2]); + } + else if (PASSINDEX == 2) { + sample0 = IMG_NORM_PIXEL(smallB,texOffsets[0]); + sample1 = IMG_NORM_PIXEL(smallB,texOffsets[1]); + sample2 = IMG_NORM_PIXEL(smallB,texOffsets[2]); + } + else if (PASSINDEX == 3) { + sample0 = IMG_NORM_PIXEL(smallC,texOffsets[0]); + sample1 = IMG_NORM_PIXEL(smallC,texOffsets[1]); + sample2 = IMG_NORM_PIXEL(smallC,texOffsets[2]); + } + else if (PASSINDEX == 4) { + sample0 = IMG_NORM_PIXEL(smallD,texOffsets[0]); + sample1 = IMG_NORM_PIXEL(smallD,texOffsets[1]); + sample2 = IMG_NORM_PIXEL(smallD,texOffsets[2]); + } + else if (PASSINDEX == 5) { + sample0 = IMG_NORM_PIXEL(smallE,texOffsets[0]); + sample1 = IMG_NORM_PIXEL(smallE,texOffsets[1]); + sample2 = IMG_NORM_PIXEL(smallE,texOffsets[2]); + } + else if (PASSINDEX == 6) { + sample0 = IMG_NORM_PIXEL(smallF,texOffsets[0]); + sample1 = IMG_NORM_PIXEL(smallF,texOffsets[1]); + sample2 = IMG_NORM_PIXEL(smallF,texOffsets[2]); + } + else if (PASSINDEX == 7) { + sample0 = IMG_NORM_PIXEL(smallG,texOffsets[0]); + sample1 = IMG_NORM_PIXEL(smallG,texOffsets[1]); + sample2 = IMG_NORM_PIXEL(smallG,texOffsets[2]); + } + else if (PASSINDEX == 8) { + sample0 = IMG_NORM_PIXEL(smallH,texOffsets[0]); + sample1 = IMG_NORM_PIXEL(smallH,texOffsets[1]); + sample2 = IMG_NORM_PIXEL(smallH,texOffsets[2]); + } + else if (PASSINDEX == 9) { + sample0 = IMG_NORM_PIXEL(smallI,texOffsets[0]); + sample1 = IMG_NORM_PIXEL(smallI,texOffsets[1]); + sample2 = IMG_NORM_PIXEL(smallI,texOffsets[2]); + } + else { + sample0 = vec4(1,0,0,1); + sample1 = vec4(1,0,0,1); + sample2 = vec4(1,0,0,1); + } + vec4 final = vec4((sample0 + sample1 + sample2).rgba / (3.0)); + vec4 original = IMG_NORM_PIXEL(inputImage,texOffsets[0]); + if (PASSINDEX == 9) { + final = mix(original,min((final * original), 1.0), intensity); + // First do a gloom, + // then a bright / contrast tweak based on the amount + // then a bloom + vec4 tmpColorA = final; + float bright = intensity * 0.222; + vec4 tmpColorB = tmpColorA + vec4(bright, bright, bright, bright); + // contrast + float contrast = 1.0 + intensity * (2.893); + tmpColorA.rgba = ((vec4(2.0) * (tmpColorB.rgba - vec4(0.5))) * vec4(contrast) / vec4(2.0)) + vec4(0.5); + final = min((tmpColorA + tmpColorA * original), 1.0); + } + else { + final = mix(sample0, final, intensity); + } + gl_FragColor = final; +} diff --git a/ISF/Glow.vs b/ISF/Glow.vs new file mode 100644 index 0000000..3720baf --- /dev/null +++ b/ISF/Glow.vs @@ -0,0 +1,28 @@ +varying vec2 texOffsets[3]; +const float radius = 10.0; + +void main(void) { + // load the main shader stuff + isf_vertShaderInit(); + + if (PASSINDEX==0 || PASSINDEX==2 || PASSINDEX==4 || PASSINDEX==6 || PASSINDEX==8) { + float pixelWidth = 1.0/RENDERSIZE[0]*radius; + if (PASSINDEX >= 2) + pixelWidth *= .7; + else if (PASSINDEX >= 6) + pixelWidth *= 1.0; + texOffsets[0] = isf_FragNormCoord; + texOffsets[1] = clamp(vec2(isf_FragNormCoord[0]-pixelWidth, isf_FragNormCoord[1]),0.0,1.0); + texOffsets[2] = clamp(vec2(isf_FragNormCoord[0]+pixelWidth, isf_FragNormCoord[1]),0.0,1.0); + } + else if (PASSINDEX==1 || PASSINDEX==3 || PASSINDEX==5 || PASSINDEX==7 || PASSINDEX==9) { + float pixelHeight = 1.0/RENDERSIZE[1]*radius; + if (PASSINDEX >= 3) + pixelHeight *= .7; + else if (PASSINDEX >= 6) + pixelHeight *= 1.0; + texOffsets[0] = isf_FragNormCoord; + texOffsets[1] = clamp(vec2(isf_FragNormCoord[0], isf_FragNormCoord[1]-pixelHeight),0.0,1.0); + texOffsets[2] = clamp(vec2(isf_FragNormCoord[0], isf_FragNormCoord[1]+pixelHeight),0.0,1.0); + } +} diff --git a/ISF/God Rays.fs b/ISF/God Rays.fs new file mode 100644 index 0000000..bbeba3c --- /dev/null +++ b/ISF/God Rays.fs @@ -0,0 +1,82 @@ +/*{ + "DESCRIPTION": "adapted from https://github.com/neilmendoza/ofxPostProcessing/blob/master/src/GodRaysPass.cpp", + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Stylize" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "lightDirDOTviewDir", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.5 + }, + { + "NAME": "lightPositionOnScreen", + "TYPE": "point2D", + "DEFAULT": [ + 0.5, + 0.5 + ] + }, + { + "NAME": "quality", + "VALUES": [ + 5, + 10, + 25 + ], + "LABELS": [ + "Low", + "Mid", + "High" + ], + "DEFAULT": 10, + "TYPE": "long" + } + ] +}*/ + + +void main(void) +{ + vec4 origColor = IMG_THIS_PIXEL(inputImage); + vec4 raysColor = IMG_THIS_PIXEL(inputImage); + int NUM_SAMPLES = quality; + + if (lightDirDOTviewDir>0.0){ + float exposure = 0.1/float(NUM_SAMPLES); + float decay = 1.0 ; + float density = 0.5; + float weight = 6.0; + float illuminationDecay = 1.0; + vec2 normSrcCoord; + + normSrcCoord.x = isf_FragNormCoord[0]; + normSrcCoord.y = isf_FragNormCoord[1]; + + vec2 deltaTextCoord = vec2(normSrcCoord.st - lightPositionOnScreen/RENDERSIZE); + vec2 textCoo = normSrcCoord; + deltaTextCoord *= 1.0 / float(NUM_SAMPLES) * density; + + for(int i=0; i < NUM_SAMPLES ; i++) { + textCoo -= deltaTextCoord; + vec4 tsample = IMG_NORM_PIXEL(inputImage, textCoo); + tsample *= illuminationDecay * weight; + raysColor += tsample; + illuminationDecay *= decay; + } + raysColor *= exposure * lightDirDOTviewDir; + float p = 0.3 *raysColor.g + 0.59*raysColor.r + 0.11*raysColor.b; + gl_FragColor = origColor + p; + } + else { + gl_FragColor = origColor; + } +} \ No newline at end of file diff --git a/ISF/Graph Paper.fs b/ISF/Graph Paper.fs new file mode 100644 index 0000000..68e0567 --- /dev/null +++ b/ISF/Graph Paper.fs @@ -0,0 +1,172 @@ +/* +{ + "CATEGORIES" : [ + "Generator" + ], + "DESCRIPTION" : "Draws basic graph paper", + "ISFVSN" : "2", + "INPUTS" : [ + { + "NAME" : "bgColor", + "TYPE" : "color", + "DEFAULT" : [ + 0.93999999761581421, + 0.93999999761581421, + 0.97000002861022949, + 1 + ] + }, + { + "NAME" : "lineColor", + "TYPE" : "color", + "DEFAULT" : [ + 0.63999998569488525, + 0.76999998092651367, + 0.95999997854232788, + 1 + ] + }, + { + "LABELS" : [ + "0", + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9", + "10", + "11", + "12", + "13", + "14", + "15", + "16" + ], + "NAME" : "majorDivisions", + "TYPE" : "long", + "DEFAULT" : 3, + "VALUES" : [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16 + ] + }, + { + "LABELS" : [ + "0", + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8" + ], + "NAME" : "minorHDivisions", + "TYPE" : "long", + "DEFAULT" : 2, + "VALUES" : [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8 + ] + }, + { + "LABELS" : [ + "0", + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8" + ], + "NAME" : "minorVDivisions", + "TYPE" : "long", + "DEFAULT" : 2, + "VALUES" : [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8 + ] + }, + { + "NAME" : "majorDivisionLineWidth", + "TYPE" : "float", + "MAX" : 5, + "DEFAULT" : 3, + "MIN" : 1 + }, + { + "NAME" : "square", + "TYPE" : "bool", + "DEFAULT" : true + } + ], + "CREDIT" : "VIDVOX" +} +*/ + + +const float minorDivisionLineWidth = 1.0; + + +void main() { + vec4 inputPixelColor = bgColor; + vec2 loc = gl_FragCoord.xy; + vec2 divisionSize = (square) ? vec2(max(RENDERSIZE.x,RENDERSIZE.y)) : RENDERSIZE; + divisionSize = (divisionSize - majorDivisionLineWidth) / (1.0 + float(majorDivisions)); + vec2 modLoc = mod(loc,divisionSize); + if ((modLoc.x < majorDivisionLineWidth)||(modLoc.y < majorDivisionLineWidth)) { + inputPixelColor = lineColor; + } + if (minorHDivisions > 0) { + vec2 locDivisionSize = (divisionSize) / (1.0+float(minorHDivisions)); + modLoc = mod(loc,locDivisionSize); + if (modLoc.x < minorDivisionLineWidth) { + inputPixelColor = lineColor; + } + } + if (minorVDivisions > 0) { + vec2 locDivisionSize = (divisionSize) / (1.0+float(minorVDivisions)); + modLoc = mod(loc,locDivisionSize); + if (modLoc.y < minorDivisionLineWidth) { + inputPixelColor = lineColor; + } + } + + gl_FragColor = inputPixelColor; +} diff --git a/ISF/HSVtoRGB.fs b/ISF/HSVtoRGB.fs new file mode 100644 index 0000000..09a5b3b --- /dev/null +++ b/ISF/HSVtoRGB.fs @@ -0,0 +1,44 @@ +/*{ + "DESCRIPTION": "swizzles RGBA to BGRA and vice versa", + "CREDIT": "by zoidberg", + "ISFVSN": "2", + "CATEGORIES": [ + "Glitch","Color Effect" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + } + ] +}*/ + + + + +vec3 rgb2hsv(vec3 c) { + vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); + //vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g)); + //vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r)); + vec4 p = c.g < c.b ? vec4(c.bg, K.wz) : vec4(c.gb, K.xy); + vec4 q = c.r < p.x ? vec4(p.xyw, c.r) : vec4(c.r, p.yzx); + + float d = q.x - min(q.w, q.y); + float e = 1.0e-10; + return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x); +} + +vec3 hsv2rgb(vec3 c) { + vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); + vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www); + return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y); +} + + + + +void main() +{ + vec4 inColor = IMG_NORM_PIXEL(inputImage, isf_FragNormCoord); + gl_FragColor = vec4(hsv2rgb(inColor.rgb), inColor.a); +} diff --git a/ISF/Hatch Blur.fs b/ISF/Hatch Blur.fs new file mode 100644 index 0000000..6b1191f --- /dev/null +++ b/ISF/Hatch Blur.fs @@ -0,0 +1,89 @@ +/*{ + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Blur" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "width", + "LABEL": "Width", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.0 + }, + { + "NAME": "angle", + "LABEL": "Angle", + "TYPE": "float", + "MIN": -1.0, + "MAX": 1.0, + "DEFAULT": 0.125 + }, + { + "NAME": "quality", + "LABEL": "Quality", + "VALUES": [ + 24, + 16, + 8, + 4 + ], + "LABELS": [ + "Low", + "Mid", + "High", + "Best" + ], + "DEFAULT": 16, + "TYPE": "long" + } + ] +}*/ + + +const float pi = 3.14159265359; + + +void main() { + vec2 loc = isf_FragNormCoord * RENDERSIZE; + + vec2 p1 = vec2(0.0); + vec2 p2 = vec2(1.0); + vec2 vector = vec2(cos(pi * angle),sin(pi * angle)); + + vec4 returnMe; + + if (width > 0.0) { + p1 = loc - width * RENDERSIZE * vector; + p2 = loc + width * RENDERSIZE * vector; + + // now we have the two points to smear between, + float i; + float count = clamp(width * max(RENDERSIZE.x,RENDERSIZE.y) / float(quality), 5.0, 75.0); + vec2 diff = p2 - p1; + for (i = 0.0; i < count; ++i) { + returnMe = returnMe + IMG_PIXEL(inputImage, p1 + diff * (i / (count - 1.0))) / count; + } + + vector = vec2(cos(pi * (0.5+ angle)),sin(pi * (0.5+ angle))); + p1 = loc - width * RENDERSIZE * vector; + p2 = loc + width * RENDERSIZE * vector; + + // now we have the two points to smear between, + diff = p2 - p1; + for (i = 0.0; i < count; ++i) { + returnMe = returnMe + IMG_PIXEL(inputImage, p1 + diff * (i / (count - 1.0))) / count; + } + returnMe = returnMe / 2.0; + } + else { + returnMe = IMG_THIS_PIXEL(inputImage); + } + gl_FragColor = returnMe; +} \ No newline at end of file diff --git a/ISF/Heart.fs b/ISF/Heart.fs new file mode 100644 index 0000000..59b7077 --- /dev/null +++ b/ISF/Heart.fs @@ -0,0 +1,44 @@ +/*{ + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Generator" + ], + "INPUTS": [ + { + "NAME": "size", + "LABEL": "Size", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.25 + }, + { + "NAME": "color", + "LABEL": "Fill Color", + "TYPE": "color", + "DEFAULT": [ + 1.0, + 0.0, + 0.0, + 1.0 + ] + } + ] +}*/ + + +// Adapted from https://glsl.io/transition/d71472a550601b96d69d + + +bool inHeart (vec2 p, vec2 center, float size) { + if (size == 0.0) return false; + vec2 o = (p-center)/(1.6*size); + return pow(o.x*o.x+o.y*o.y-0.3, 3.0) < o.x*o.x*pow(o.y, 3.0); +} + +void main() { + vec2 p = isf_FragNormCoord; + float m = inHeart(p, vec2(0.5, 0.4), size) ? 1.0 : 0.0; + gl_FragColor = mix(vec4(0.0), color, m); +} \ No newline at end of file diff --git a/ISF/HorizVertHold.fs b/ISF/HorizVertHold.fs new file mode 100644 index 0000000..d35a121 --- /dev/null +++ b/ISF/HorizVertHold.fs @@ -0,0 +1,65 @@ +/*{ + "DESCRIPTION": "", + "CREDIT": "by zoidberg", + "ISFVSN": "2", + "CATEGORIES": [ + "Geometry Adjustment" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "hHold", + "LABEL": "Horiz. Hold", + "TYPE": "float", + "MIN": -0.45, + "MAX": 0.45, + "DEFAULT": 0.0 + }, + { + "NAME": "vHold", + "LABEL": "Vert. Hold", + "TYPE": "float", + "MIN": -0.45, + "MAX": 0.45, + "DEFAULT": 0.0 + }, + { + "NAME": "flashEvent", + "TYPE": "event" + } + ], + "PASSES": [ + { + "TARGET":"lastPosition", + "WIDTH": 1, + "HEIGHT": 1, + "FLOAT": true, + "PERSISTENT": true, + "DESCRIPTION": "this buffer stores the last frame's x/y offset in the first two components of its only pixel- note that it's requesting a FLOAT target buffer..." + }, + { + + } + ] + +}*/ + +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 = IMG_PIXEL(lastPosition,vec2(0.5)); + // i'm only using the X and Y components, which are the X and Y offset (normalized) for the frame + srcPixel.xy = (flashEvent) ? vec2(0.0) : (srcPixel.xy - vec2(hHold,vHold)); + gl_FragColor = mod(srcPixel,1.0); + } + // else this isn't the first pass- read the position value from the buffer which stores it + else { + vec4 lastPosVector = IMG_PIXEL(lastPosition,vec2(0.5)); + vec2 normPixelCoord = mod((isf_FragNormCoord.xy + lastPosVector.xy), 1.0); + gl_FragColor = IMG_NORM_PIXEL(inputImage,normPixelCoord); + } +} diff --git a/ISF/Hyperspace.fs b/ISF/Hyperspace.fs new file mode 100644 index 0000000..42ba612 --- /dev/null +++ b/ISF/Hyperspace.fs @@ -0,0 +1,86 @@ +/* +{ + "CATEGORIES" : [ + "Stylize" + ], + "DESCRIPTION" : "", + "ISFVSN" : "2", + "INPUTS" : [ + { + "NAME" : "inputImage", + "TYPE" : "image" + }, + { + "NAME" : "centerX", + "TYPE" : "float", + "MAX" : 1, + "DEFAULT" : 0.5, + "MIN" : 0 + }, + { + "NAME" : "scrollAmount", + "TYPE" : "float", + "MAX" : 2, + "DEFAULT" : 0, + "MIN" : 0 + }, + { + "NAME" : "rightScrollOffset", + "TYPE" : "float", + "MAX" : 1, + "DEFAULT" : 0, + "MIN" : 0 + }, + { + "NAME" : "midHeight", + "TYPE" : "float", + "MAX" : 1, + "DEFAULT" : 0.5, + "MIN" : 0, + "IDENTITY" : 1 + }, + { + "NAME" : "seamless", + "TYPE" : "bool", + "DEFAULT" : 1 + } + ], + "CREDIT" : "VIDVOX" +} +*/ + +void main() { + vec2 loc = isf_FragNormCoord.xy; + if (centerX == 0.0) { + + } + else if (centerX == 1.0) { + + } + else if (loc.x < centerX) { + loc.x = loc.x / centerX; + loc.y = mix(0.5 + (loc.y-0.5) / midHeight,loc.y,1.0-loc.x); + loc.x = loc.x+scrollAmount; + if (seamless) { + loc.x = ((loc.x <= 1.0)||(loc.x >= 2.0)) ? loc.x : 3.0 - loc.x; + } + loc.x = mod(loc.x,1.0); + } + else { + float rightScroll = mod(rightScrollOffset+scrollAmount,2.0); + loc.x = (1.0-loc.x) / (1.0-centerX); + loc.y = mix(0.5 + (loc.y-0.5) / midHeight,loc.y,1.0-loc.x); + loc.x = loc.x+rightScroll; + if (seamless) { + loc.x = ((loc.x <= 1.0)||(loc.x >= 2.0)) ? loc.x : 3.0 - loc.x; + } + loc.x = mod(loc.x,1.0); + } + + vec4 inputPixelColor = vec4(0.0); + + if ((loc.y >= 0.0)&&(loc.y <= 1.0)) + inputPixelColor = IMG_NORM_PIXEL(inputImage,loc); + + gl_FragColor = inputPixelColor; +} diff --git a/ISF/Interlace Mirror.fs b/ISF/Interlace Mirror.fs new file mode 100644 index 0000000..ae810a3 --- /dev/null +++ b/ISF/Interlace Mirror.fs @@ -0,0 +1,44 @@ +/*{ + "DESCRIPTION": "", + "CREDIT": "by Carter Rosenberg", + "ISFVSN": "2", + "CATEGORIES": [ + "Distortion", "Glitch" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "horizontal", + "LABEL": "Horizontal", + "TYPE": "bool", + "DEFAULT": 1.0 + }, + { + "NAME": "vertical", + "LABEL": "Vertical", + "TYPE": "bool", + "DEFAULT": 0.0 + } + ] + +}*/ + +void main() +{ + vec2 pixelCoord = isf_FragNormCoord * RENDERSIZE; + vec2 loc = pixelCoord; + if (vertical) { + if (mod(pixelCoord.x,2.0)>1.0) { + loc.y = RENDERSIZE.y - pixelCoord.y; + } + } + if (horizontal) { + if (mod(pixelCoord.y,2.0)>1.0) { + loc.x = RENDERSIZE.x - pixelCoord.x; + } + } + gl_FragColor = IMG_PIXEL(inputImage,loc); +} diff --git a/ISF/Interlace.fs b/ISF/Interlace.fs new file mode 100644 index 0000000..b7d8f41 --- /dev/null +++ b/ISF/Interlace.fs @@ -0,0 +1,57 @@ +/*{ + "DESCRIPTION": "", + "CREDIT": "by Carter Rosenberg", + "ISFVSN": "2", + "CATEGORIES": [ + "Film" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "lineSize", + "LABEL": "Line Size", + "TYPE": "float", + "MIN": 1.0, + "MAX": 50.0, + "DEFAULT": 4.0 + } + ], + "PASSES": [ + { + "TARGET":"lastRow", + "WIDTH": "1", + "HEIGHT": "1", + "DESCRIPTION": "this buffer stores the last frame's odd / even state", + "PERSISTENT": true + }, + { + "TARGET":"lastFrame", + "PERSISTENT": true + } + ] + +}*/ + +void main() +{ + // if this is the first pass, i'm going to read the position from the "lastRow" image, and write a new position based on this and the hold variables + if (PASSINDEX == 0) { + vec4 srcPixel = IMG_PIXEL(lastRow,vec2(0.5)); + // i'm only using the X and Y components, which are the X and Y offset (normalized) for the frame + srcPixel.x = (srcPixel.x) > 0.5 ? 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 { + vec4 lastRow = IMG_PIXEL(lastRow,vec2(0.5)); + vec2 pixelCoord = isf_FragNormCoord * RENDERSIZE; + + if (mod(floor(pixelCoord.y),2.0 * lineSize) < lineSize + lineSize * lastRow.x) + gl_FragColor = IMG_NORM_PIXEL(inputImage,isf_FragNormCoord); + else + gl_FragColor = IMG_NORM_PIXEL(lastFrame,isf_FragNormCoord); + } +} diff --git a/ISF/Kaleidoscope Tile.fs b/ISF/Kaleidoscope Tile.fs new file mode 100644 index 0000000..193122c --- /dev/null +++ b/ISF/Kaleidoscope Tile.fs @@ -0,0 +1,122 @@ +/*{ + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Tile Effect" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "size", + "TYPE": "float", + "MIN": 0.0, + "MAX": 2.0, + "DEFAULT": 0.5 + }, + { + "NAME": "sides", + "TYPE": "float", + "MIN": 1.0, + "MAX": 32.0, + "DEFAULT": 6.0 + }, + { + "NAME": "rotation", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.125 + }, + { + "NAME": "angle", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.0 + }, + { + "NAME": "slide1", + "TYPE": "point2D", + "DEFAULT": [ + 0.0, + 0.0 + ] + }, + { + "NAME": "slide2", + "TYPE": "point2D", + "DEFAULT": [ + 0.0, + 0.0 + ] + }, + { + "NAME": "shift", + "TYPE": "point2D", + "DEFAULT": [ + 0.0, + 0.0 + ] + } + ] +}*/ + + +const float tau = 6.28318530718; + + +vec2 pattern() { + float s = sin(tau * rotation); + float c = cos(tau * rotation); + vec2 tex = isf_FragNormCoord * RENDERSIZE; + float scale = 1.0 / max(size,0.001); + vec2 point = vec2( c * tex.x - s * tex.y, s * tex.x + c * tex.y ) * scale; + point = (point - shift) / RENDERSIZE; + // do this to repeat + point = mod(point,1.0); + if (point.x < 0.5) { + point.y = mod(point.y + slide1.y/RENDERSIZE.y, 1.0); + } + else { + point.y = mod(point.y + slide2.y/RENDERSIZE.y, 1.0); + } + if (point.y < 0.5) { + point.x = mod(point.x + slide1.x/RENDERSIZE.x, 1.0); + } + else { + point.x = mod(point.x + slide2.x/RENDERSIZE.x, 1.0); + } + // do this for relections + point = 1.0-abs(1.0-2.0*point); + + // Now let's do a squish based on angle + // convert to polar coordinates + vec2 center = vec2(0.5,0.5); + float r = distance(center, point); + float a = atan ((point.y-center.y),(point.x-center.x)); + + // now do the kaleidoscope + a = mod(a, tau/sides); + a = abs(a - tau/sides/2.); + + s = sin(a + tau * angle); + c = cos(a + tau * angle); + + float zoom = RENDERSIZE.x / RENDERSIZE.y; + + point.x = (r * c)/zoom + 0.5; + point.y = (r * s)/zoom + 0.5; + + return point; +} + + +void main() { + + vec2 pat = pattern(); + + gl_FragColor = IMG_NORM_PIXEL(inputImage,pat); +} \ No newline at end of file diff --git a/ISF/Kaleidoscope.fs b/ISF/Kaleidoscope.fs new file mode 100644 index 0000000..bce1fee --- /dev/null +++ b/ISF/Kaleidoscope.fs @@ -0,0 +1,90 @@ + +/*{ + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Stylize", "Tile Effect" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "sides", + "TYPE": "float", + "MIN": 1.0, + "MAX": 32.0, + "DEFAULT": 6.0 + }, + { + "NAME": "angle", + "TYPE": "float", + "MIN": -1.0, + "MAX": 1.0, + "DEFAULT": 0.0 + }, + { + "NAME": "slidex", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.0 + }, + { + "NAME": "slidey", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.0 + }, + { + "NAME": "center", + "TYPE": "point2D", + "DEFAULT": [ + 0, + 0 + ] + } + ] +}*/ + + +const float tau = 6.28318530718; + + + + +void main() { + // normalize to the center + vec2 loc = RENDERSIZE * vec2(isf_FragNormCoord[0],isf_FragNormCoord[1]); + float r = distance(center, loc); + float a = atan ((loc.y-center.y),(loc.x-center.x)); + + // kaleidoscope + a = mod(a, tau/sides); + a = abs(a - tau/sides/2.); + + loc.x = r * cos(a + tau * angle); + loc.y = r * sin(a + tau * angle); + + loc = (center + loc) / RENDERSIZE; + + loc.x = mod(loc.x + slidex, 1.0); + loc.y = mod(loc.y + slidey, 1.0); + + // sample the image + if (loc.x < 0.0) { + loc.x = mod(abs(loc.x), 1.0); + } + if (loc.y < 0.0) { + loc.y = mod(abs(loc.y),1.0); + } + if (loc.x > 1.0) { + loc.x = mod(abs(1.0-loc.x),1.0); + } + if(loc.y > 1.0) { + loc.y = mod(abs(1.0-loc.y),1.0); + } + gl_FragColor = IMG_NORM_PIXEL(inputImage, loc);; +} \ No newline at end of file diff --git a/ISF/Layer Mask.fs b/ISF/Layer Mask.fs new file mode 100644 index 0000000..651c2cd --- /dev/null +++ b/ISF/Layer Mask.fs @@ -0,0 +1,179 @@ +/*{ + "CREDIT": "by zoidberg", + "ISFVSN": "2", + "DESCRIPTION": "Takes a mask image and applies it to the input image's alpha channel.", + "CATEGORIES": [ + "Color Effect", "Masking" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "maskImage", + "TYPE": "image", + "LABEL": "mask image" + }, + { + "NAME": "maskSizingMode", + "LABEL": "mask size mode", + "TYPE": "long", + "VALUES": [ + 0, + 1, + 2, + 3 + ], + "LABELS": [ + "Fit", + "Fill", + "Stretch", + "Copy" + ], + "DEFAULT": 0 + }, + { + "NAME": "bright", + "TYPE": "float", + "MIN": -1.0, + "MAX": 1.0, + "DEFAULT": 0.0 + }, + { + "NAME": "contrast", + "TYPE": "float", + "MIN": -4.0, + "MAX": 4.0, + "DEFAULT": 1.0 + }, + { + "NAME": "alphaMode", + "LABEL": "Alpha Mode", + "TYPE": "long", + "VALUES": [ + 0, + 1, + 2 + ], + "LABELS": [ + "Additive", + "Multiply", + "Replace" + ], + "DEFAULT": 2 + }, + { + "NAME": "applyAlpha", + "TYPE": "bool", + "DEFAULT": 0.0 + } + ] +}*/ + +const vec4 lumcoeff = vec4(0.299, 0.587, 0.114, 0.0); + +// 'a' and 'b' are rects (x and y are the originx, z and w are the width and height) +// 'm' is the sizing mode as described above (fit/fill/stretch/copy) +vec4 RectThatFitsRectInRect(vec4 a, vec4 b, int m); + + + + +void main() { + vec4 srcPixel = IMG_THIS_PIXEL(inputImage); + + // get the rect of the mask image after it's been resized according to the passed sizing mode. this is in pixel coords relative to the rendering space! + //vec4 rectOfResizedMaskImage = RectThatFitsRectInRect(vec4(0.0, 0.0, _maskImage_imgRect.z, _maskImage_imgRect.w), vec4(0,0,RENDERSIZE.x,RENDERSIZE.y), maskSizingMode); + vec4 rectOfResizedMaskImage = RectThatFitsRectInRect(vec4(0.0, 0.0, IMG_SIZE(maskImage).x, IMG_SIZE(maskImage).y), vec4(0,0,RENDERSIZE.x,RENDERSIZE.y), maskSizingMode); + // i know the pixel coords of this frag in the render space- convert this to NORMALIZED texture coords for the resized mask image + vec2 normMaskSrcCoord; + normMaskSrcCoord.x = (gl_FragCoord.x-rectOfResizedMaskImage.x)/rectOfResizedMaskImage.z; + normMaskSrcCoord.y = (gl_FragCoord.y-rectOfResizedMaskImage.y)/rectOfResizedMaskImage.w; + + // get the color of the pixel from the mask image for these normalized coords + vec4 tmpColorA = IMG_NORM_PIXEL(maskImage, normMaskSrcCoord); + + // apply bright/contrast to this pixel value + vec4 tmpColorB = tmpColorA + vec4(bright, bright, bright, 0.0); + tmpColorA.rgb = ((vec3(2.0) * (tmpColorB.rgb - vec3(0.5))) * vec3(contrast) / vec3(2.0)) + vec3(0.5); + tmpColorA.a = ((2.0 * (tmpColorB.a - 0.5)) * abs(contrast) / 2.0) + 0.5; + + // get the luminance of this pixel value: this will be the new alpha for the source pixel + float luminance = dot(tmpColorA,lumcoeff); + + // if the alpha mode isn't replacing, add or multiply now + // (this makes it possible to stack multiple mask FX or preserve alpha from input) + if (alphaMode == 0) { + luminance = luminance + srcPixel.a; + } + else if (alphaMode == 1) { + luminance = luminance * srcPixel.a; + } + + if (applyAlpha) + gl_FragColor = vec4(luminance*srcPixel.r, luminance*srcPixel.g, luminance*srcPixel.b, 1.0); + else + gl_FragColor = vec4(srcPixel.r, srcPixel.g, srcPixel.b, luminance); +} + + +// rect that fits 'a' in 'b' using sizing mode 'm' +vec4 RectThatFitsRectInRect(vec4 a, vec4 b, int m) { + float bAspect = b.z/b.w; + float aAspect = a.z/a.w; + if (aAspect==bAspect) { + return b; + } + vec4 returnMe = vec4(0.0); + // fit + if (m==0) { + // if the rect i'm trying to fit stuff *into* is wider than the rect i'm resizing + if (bAspect > aAspect) { + returnMe.w = b.w; + returnMe.z = returnMe.w * aAspect; + } + // else if the rect i'm resizing is wider than the rect it's going into + else if (bAspect < aAspect) { + returnMe.z = b.z; + returnMe.w = returnMe.z / aAspect; + } + else { + returnMe.z = b.z; + returnMe.w = b.w; + } + returnMe.x = (b.z-returnMe.z)/2.0+b.x; + returnMe.y = (b.w-returnMe.w)/2.0+b.y; + } + // fill + else if (m==1) { + // if the rect i'm trying to fit stuff *into* is wider than the rect i'm resizing + if (bAspect > aAspect) { + returnMe.z = b.z; + returnMe.w = returnMe.z / aAspect; + } + // else if the rect i'm resizing is wider than the rect it's going into + else if (bAspect < aAspect) { + returnMe.w = b.w; + returnMe.z = returnMe.w * aAspect; + } + else { + returnMe.z = b.z; + returnMe.w = b.w; + } + returnMe.x = (b.z-returnMe.z)/2.0+b.x; + returnMe.y = (b.w-returnMe.w)/2.0+b.y; + } + // stretch + else if (m==2) { + returnMe = vec4(b.x, b.y, b.z, b.w); + } + // copy + else if (m==3) { + returnMe.z = float(int(a.z)); + returnMe.w = float(int(a.w)); + returnMe.x = float(int((b.z-returnMe.z)/2.0+b.x)); + returnMe.y = float(int((b.w-returnMe.w)/2.0+b.y)); + } + return returnMe; +} \ No newline at end of file diff --git a/ISF/Layer Position.fs b/ISF/Layer Position.fs new file mode 100644 index 0000000..0b14004 --- /dev/null +++ b/ISF/Layer Position.fs @@ -0,0 +1,49 @@ +/*{ + "DESCRIPTION": "", + "CREDIT": "", + "ISFVSN": "2", + "CATEGORIES": [ + "Geometry Adjustment", "Utility" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "offset", + "TYPE": "point2D", + "DEFAULT": [ + 0.5, + 0.5 + ] + }, + { + "NAME": "repeatImage", + "TYPE": "bool", + "DEFAULT": 0.0 + } + ] + +}*/ + +void main() { + vec4 outputColor = vec4(0.0); + vec2 newLoc = offset; + vec2 topSize = RENDERSIZE; + + newLoc = offset; + newLoc.x = topSize.x - newLoc.x; + newLoc.y = topSize.y - newLoc.y; + newLoc = (gl_FragCoord.xy + 2.0*newLoc) - topSize; + + if (repeatImage) { + newLoc = mod(newLoc, RENDERSIZE); + } + + if ((newLoc.x >= 0.0)&&(newLoc.x < RENDERSIZE.x)&&(newLoc.y >= 0.0)&&(newLoc.y <= RENDERSIZE.y)) { + outputColor = IMG_PIXEL(inputImage, newLoc); + } + + gl_FragColor = outputColor; +} diff --git a/ISF/Lens Flare.fs b/ISF/Lens Flare.fs new file mode 100644 index 0000000..cf21afe --- /dev/null +++ b/ISF/Lens Flare.fs @@ -0,0 +1,230 @@ +/*{ + "DESCRIPTION": "", + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Film" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "uBias", + "LABEL": "Bias", + "TYPE": "float", + "MIN": -1.0, + "MAX": 0.0, + "DEFAULT": -0.67 + }, + { + "NAME": "uScale", + "LABEL": "Scale", + "TYPE": "float", + "MIN": 0.0, + "MAX": 10.0, + "DEFAULT": 1.25 + }, + { + "NAME": "uSource", + "LABEL": "Source Gain", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 1.0 + }, + { + "NAME": "uChromatic", + "LABEL": "Chromatic Distortion", + "TYPE": "color", + "DEFAULT": [ + 0.75, + 0.875, + 1.0, + 0.75 + ] + }, + { + "NAME": "uGhosts", + "LABEL": "Ghosts", + "TYPE": "float", + "MIN": 0.0, + "MAX": 5.0, + "DEFAULT": 3.0 + }, + { + "NAME": "uGhostDispersal", + "LABEL": "Ghost Dispersal", + "TYPE": "float", + "MIN": 0.125, + "MAX": 0.75, + "DEFAULT": 0.25 + }, + { + "NAME": "uLensColor", + "LABEL": "Lens Color", + "TYPE": "color", + "DEFAULT": [ + 0.67, + 0.5, + 0.75, + 1.0 + ] + }, + { + "NAME": "uHaloWidth", + "LABEL": "Halo Width", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.33 + }, + { + "NAME": "uNoise", + "LABEL": "Dirt", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.25 + }, + { + "NAME": "uCenter", + "LABEL": "Center", + "TYPE": "point2D", + "DEFAULT": [ + 0.5, + 0.5 + ] + } + ], + "PASSES": [ + { + "TARGET": "downsampleAndThresholdImage", + "WIDTH": "floor($WIDTH/2.0)", + "HEIGHT": "floor($HEIGHT/2.0)", + "DESCRIPTION": "Downsample and threshold" + }, + { + "TARGET": "featureGenerationImage", + "WIDTH": "floor($WIDTH/2.0)", + "HEIGHT": "floor($HEIGHT/2.0)", + "DESCRIPTION": "Feature generation" + }, + { + "TARGET": "blurredImage", + "WIDTH": "floor($WIDTH/4.0)", + "HEIGHT": "floor($HEIGHT/4.0)", + "DESCRIPTION": "Blur" + }, + { + + } + ] + +}*/ + + +// as a guide, http://john-chapman-graphics.blogspot.co.uk/2013/02/pseudo-lens-flare.html +// 1 downsample and threshold +// 2 feature generation: ghosts, halos and chromatic distortion +// 3 blur +// 4 upscale / blend + + +varying vec2 left_coord; +varying vec2 right_coord; +varying vec2 above_coord; +varying vec2 below_coord; + +varying vec2 lefta_coord; +varying vec2 righta_coord; +varying vec2 leftb_coord; +varying vec2 rightb_coord; + + +const float seed = 0.87342; + + + +float rand(vec2 co){ + return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453); +} + + + +void main() +{ + + if (PASSINDEX == 0) { + vec2 loc = isf_FragNormCoord; + gl_FragColor = max(vec4(0.0), IMG_NORM_PIXEL(inputImage,loc) + uBias) * uScale; + } + else if (PASSINDEX == 1) { + // flip the coordinates on this pass + vec2 centerVec = uCenter/RENDERSIZE - vec2(1.0); + vec2 texcoord = vec2(1.0) - isf_FragNormCoord; + vec2 texelSize = 1.0 / RENDERSIZE; + vec2 ghostVec = (vec2(0.5) - texcoord + centerVec) * uGhostDispersal; + vec4 result = vec4(0.0); + for (int i = 0; i < 5; ++i) { + if (float(i)>uGhosts) + break; + vec2 offset = fract(texcoord + ghostVec * float(i)); + + //result += IMG_NORM_PIXEL(downsampleAndThresholdImage, offset); + + result.r += IMG_NORM_PIXEL(downsampleAndThresholdImage, offset * uChromatic.r).r * uChromatic.a; + result.g += IMG_NORM_PIXEL(downsampleAndThresholdImage, offset * uChromatic.g).g * uChromatic.a; + result.b += IMG_NORM_PIXEL(downsampleAndThresholdImage, offset * uChromatic.b).b * uChromatic.a; + + } + + //vec4 result = vec4(0.0); + for (int i = 0; i < 5; ++i) { + if (float(i)>uGhosts) + break; + vec2 offset = fract(texcoord + ghostVec * float(i)); + + float weight = length(vec2(0.5) - offset) / length(vec2(0.5)); + weight = pow(1.0 - weight, 10.0); + + result += IMG_NORM_PIXEL(downsampleAndThresholdImage, offset) * weight; + } + + vec2 haloVec = normalize(ghostVec) * uHaloWidth; + float weight = length(vec2(0.5) - fract(texcoord + haloVec)) / length(vec2(0.5)); + weight = pow(1.0 - weight, 5.0); + result += IMG_NORM_PIXEL(downsampleAndThresholdImage, texcoord + haloVec) * weight; + + result *= uLensColor; + + gl_FragColor = result; + } + else if (PASSINDEX == 2) { + vec4 color = IMG_THIS_NORM_PIXEL(featureGenerationImage); + vec4 colorL = IMG_NORM_PIXEL(featureGenerationImage, left_coord); + vec4 colorR = IMG_NORM_PIXEL(featureGenerationImage, right_coord); + vec4 colorA = IMG_NORM_PIXEL(featureGenerationImage, above_coord); + vec4 colorB = IMG_NORM_PIXEL(featureGenerationImage, below_coord); + + vec4 colorLA = IMG_NORM_PIXEL(featureGenerationImage, lefta_coord); + vec4 colorRA = IMG_NORM_PIXEL(featureGenerationImage, righta_coord); + vec4 colorLB = IMG_NORM_PIXEL(featureGenerationImage, leftb_coord); + vec4 colorRB = IMG_NORM_PIXEL(featureGenerationImage, rightb_coord); + + vec4 avg = (color + colorL + colorR + colorA + colorB + colorLA + colorRA + colorLB + colorRB) / 9.0; + //avg = mix(color, (avg + depth*blur)/(1.0+depth), softness); + gl_FragColor = avg; + } + else { + vec2 loc = isf_FragNormCoord; + // SHOULD REPLACE THIS WITH A BETTER / ADJUSTABLE FILM GRAIN OR DIRT GENERATOR + vec4 noise = vec4(0.0); + noise = (1.0 - uNoise) + uNoise * vec4(rand(loc*vec2(uNoise*seed,uChromatic.x)),rand(loc*vec2(uNoise*seed,uChromatic.y)),rand(loc*vec2(uNoise*seed,uChromatic.z)),1.0); + + vec4 srcColor = IMG_NORM_PIXEL(inputImage,loc); + vec4 lensFlareColor = IMG_NORM_PIXEL(blurredImage,loc) * noise; + gl_FragColor = uSource * srcColor + lensFlareColor * lensFlareColor.a; + } +} \ No newline at end of file diff --git a/ISF/Lens Flare.vs b/ISF/Lens Flare.vs new file mode 100644 index 0000000..da454ce --- /dev/null +++ b/ISF/Lens Flare.vs @@ -0,0 +1,27 @@ +varying vec2 left_coord; +varying vec2 right_coord; +varying vec2 above_coord; +varying vec2 below_coord; + +varying vec2 lefta_coord; +varying vec2 righta_coord; +varying vec2 leftb_coord; +varying vec2 rightb_coord; + + +void main() +{ + isf_vertShaderInit(); + vec2 texc = vec2(isf_FragNormCoord[0],isf_FragNormCoord[1]); + vec2 d = 1.0/RENDERSIZE; + + left_coord = clamp(vec2(texc.xy + vec2(-d.x , 0)),0.0,1.0); + right_coord = clamp(vec2(texc.xy + vec2(d.x , 0)),0.0,1.0); + above_coord = clamp(vec2(texc.xy + vec2(0,d.y)),0.0,1.0); + below_coord = clamp(vec2(texc.xy + vec2(0,-d.y)),0.0,1.0); + + lefta_coord = clamp(vec2(texc.xy + vec2(-d.x , d.x)),0.0,1.0); + righta_coord = clamp(vec2(texc.xy + vec2(d.x , d.x)),0.0,1.0); + leftb_coord = clamp(vec2(texc.xy + vec2(-d.x , -d.x)),0.0,1.0); + rightb_coord = clamp(vec2(texc.xy + vec2(d.x , -d.x)),0.0,1.0); +} \ No newline at end of file diff --git a/ISF/Life.fs b/ISF/Life.fs new file mode 100644 index 0000000..1ba5e12 --- /dev/null +++ b/ISF/Life.fs @@ -0,0 +1,143 @@ +/*{ + "DESCRIPTION": "Based on Conway Game of Life", + "CREDIT": "VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Generator" + ], + "INPUTS": [ + { + "NAME": "restartNow", + "TYPE": "event" + }, + { + "NAME": "startThresh", + "TYPE": "float", + "DEFAULT": 0.5, + "MIN": 0.0, + "MAX": 1.0 + }, + { + "NAME": "randomRegrowth", + "TYPE": "float", + "DEFAULT": 0.0, + "MIN": 0.0, + "MAX": 0.1 + }, + { + "NAME": "randomDeath", + "TYPE": "float", + "DEFAULT": 0.0, + "MIN": 0.0, + "MAX": 0.1 + } + ], + "PASSES": [ + { + "TARGET":"lastData", + "PERSISTENT": true + } + ] + +}*/ + + +/* + +Any live cell with fewer than two live neighbours dies, as if caused by under-population. +Any live cell with two or three live neighbours lives on to the next generation. +Any live cell with more than three live neighbours dies, as if by over-population. +Any dead cell with exactly three live neighbours becomes a live cell, as if by reproduction. + +*/ + + + + +varying vec2 left_coord; +varying vec2 right_coord; +varying vec2 above_coord; +varying vec2 below_coord; + +varying vec2 lefta_coord; +varying vec2 righta_coord; +varying vec2 leftb_coord; +varying vec2 rightb_coord; + + + +float gray(vec4 n) +{ + return (n.r + n.g + n.b)/3.0; +} + +float rand(vec2 co){ + return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453); +} + + +void main() { + vec4 inputPixelColor = vec4(0.0); + vec2 loc = gl_FragCoord.xy; + + if ((TIME < 0.1)||(restartNow)) { + // randomize the start conditions + float alive = rand(vec2(TIME+1.0,2.1*TIME+0.1)*loc); + if (alive > 1.0 - startThresh) { + inputPixelColor = vec4(1.0); + } + } + else { + vec4 color = IMG_PIXEL(lastData, loc); + vec4 colorL = IMG_PIXEL(lastData, left_coord); + vec4 colorR = IMG_PIXEL(lastData, right_coord); + vec4 colorA = IMG_PIXEL(lastData, above_coord); + vec4 colorB = IMG_PIXEL(lastData, below_coord); + + vec4 colorLA = IMG_PIXEL(lastData, lefta_coord); + vec4 colorRA = IMG_PIXEL(lastData, righta_coord); + vec4 colorLB = IMG_PIXEL(lastData, leftb_coord); + vec4 colorRB = IMG_PIXEL(lastData, rightb_coord); + + float neighborSum = gray(colorL + colorR + colorA + colorB + colorLA + colorRA + colorLB + colorRB); + float state = gray(color); + + // live cell + if (state > 0.0) { + if (neighborSum < 2.0) { + // under population + inputPixelColor = vec4(0.0); + } + else if (neighborSum < 4.0) { + // status quo + inputPixelColor = vec4(1.0); + + // spontaneous death? + float alive = rand(vec2(TIME+1.0,2.1*TIME+0.1)*loc); + if (alive > 1.0 - randomDeath) { + inputPixelColor = vec4(0.0); + } + } + else { + // over population + inputPixelColor = vec4(0.0); + } + } + // dead cell + else { + if ((neighborSum > 2.0)&&(neighborSum < 4.0)) { + // reproduction + inputPixelColor = vec4(1.0); + } + else if (neighborSum < 2.0) { + // spontaneous reproduction + float alive = rand(vec2(TIME+1.0,2.1*TIME+0.1)*loc); + if (alive > 1.0 - randomRegrowth) { + inputPixelColor = vec4(1.0); + } + } + } + } + + gl_FragColor = inputPixelColor; +} diff --git a/ISF/Life.vs b/ISF/Life.vs new file mode 100644 index 0000000..48ba991 --- /dev/null +++ b/ISF/Life.vs @@ -0,0 +1,26 @@ +varying vec2 left_coord; +varying vec2 right_coord; +varying vec2 above_coord; +varying vec2 below_coord; + +varying vec2 lefta_coord; +varying vec2 righta_coord; +varying vec2 leftb_coord; +varying vec2 rightb_coord; + + +void main() +{ + isf_vertShaderInit(); + vec2 texc = vec2(isf_FragNormCoord[0],isf_FragNormCoord[1]) * RENDERSIZE; + + left_coord = vec2(texc.xy + vec2(-1.0 , 0)); + right_coord = vec2(texc.xy + vec2(1.0 , 0)); + above_coord = vec2(texc.xy + vec2(0,1.0)); + below_coord = vec2(texc.xy + vec2(0,-1.0)); + + lefta_coord = vec2(texc.xy + vec2(-1.0 , 1.0)); + righta_coord = vec2(texc.xy + vec2(1.0 , 1.0)); + leftb_coord = vec2(texc.xy + vec2(-1.0 , -1.0)); + rightb_coord = vec2(texc.xy + vec2(1.0 , -1.0)); +} \ No newline at end of file diff --git a/ISF/Line Screen.fs b/ISF/Line Screen.fs new file mode 100644 index 0000000..cc62e75 --- /dev/null +++ b/ISF/Line Screen.fs @@ -0,0 +1,97 @@ +/*{ + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Halftone Effect" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "sharpness", + "TYPE": "float", + "MIN": 0.0, + "MAX": 10.0, + "DEFAULT": 1.0 + }, + { + "NAME": "offset", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.0 + }, + { + "NAME": "angle", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.5 + }, + { + "NAME": "scale", + "TYPE": "float", + "MIN": 0.0, + "MAX": 2.0, + "DEFAULT": 1.0 + }, + { + "NAME": "colorize", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.0 + }, + { + "NAME": "fill", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.0 + } + ] +}*/ + +varying vec2 left_coord; +varying vec2 right_coord; +varying vec2 above_coord; +varying vec2 below_coord; + +varying vec2 lefta_coord; +varying vec2 righta_coord; +varying vec2 leftb_coord; +varying vec2 rightb_coord; + +const float tau = 6.28318530718; + +float pattern() { + float s = sin(tau * angle * 0.5); + float c = cos(tau * angle * 0.5); + vec2 tex = isf_FragNormCoord * RENDERSIZE; + vec2 point = vec2( c * tex.x - s * tex.y, s * tex.x + c * tex.y ) * max(scale,0.001); + float d = point.y; + + return ( fill + sin(d + offset * tau) ) * 4.0; +} + +void main() { + vec4 color = IMG_THIS_PIXEL(inputImage); + vec4 colorL = IMG_NORM_PIXEL(inputImage, left_coord); + vec4 colorR = IMG_NORM_PIXEL(inputImage, right_coord); + vec4 colorA = IMG_NORM_PIXEL(inputImage, above_coord); + vec4 colorB = IMG_NORM_PIXEL(inputImage, below_coord); + + vec4 colorLA = IMG_NORM_PIXEL(inputImage, lefta_coord); + vec4 colorRA = IMG_NORM_PIXEL(inputImage, righta_coord); + vec4 colorLB = IMG_NORM_PIXEL(inputImage, leftb_coord); + vec4 colorRB = IMG_NORM_PIXEL(inputImage, rightb_coord); + + vec4 final = color + sharpness * (8.0*color - colorL - colorR - colorA - colorB - colorLA - colorRA - colorLB - colorRB); + + float average = ( final.r + final.g + final.b ) / 3.0; + final = vec4( vec3( average * 10.0 - 5.0 + pattern() ), color.a ); + final = mix (color * final, final, 1.0-colorize); + gl_FragColor = final; +} \ No newline at end of file diff --git a/ISF/Line Screen.vs b/ISF/Line Screen.vs new file mode 100644 index 0000000..c8b60f7 --- /dev/null +++ b/ISF/Line Screen.vs @@ -0,0 +1,27 @@ +varying vec2 left_coord; +varying vec2 right_coord; +varying vec2 above_coord; +varying vec2 below_coord; + +varying vec2 lefta_coord; +varying vec2 righta_coord; +varying vec2 leftb_coord; +varying vec2 rightb_coord; + + +void main() +{ + isf_vertShaderInit(); + vec2 texc = vec2(isf_FragNormCoord[0],isf_FragNormCoord[1]); + vec2 d = 1.0/RENDERSIZE; + + left_coord = clamp(vec2(texc.xy + vec2(-d.x , 0)),0.0,1.0); + right_coord = clamp(vec2(texc.xy + vec2(d.x , 0)),0.0,1.0); + above_coord = clamp(vec2(texc.xy + vec2(0,d.y)),0.0,1.0); + below_coord = clamp(vec2(texc.xy + vec2(0,-d.y)),0.0,1.0); + + lefta_coord = clamp(vec2(texc.xy + vec2(-d.x , d.x)),0.0,1.0); + righta_coord = clamp(vec2(texc.xy + vec2(d.x , d.x)),0.0,1.0); + leftb_coord = clamp(vec2(texc.xy + vec2(-d.x , -d.x)),0.0,1.0); + rightb_coord = clamp(vec2(texc.xy + vec2(d.x , -d.x)),0.0,1.0); +} \ No newline at end of file diff --git a/ISF/Linear Gradient.fs b/ISF/Linear Gradient.fs new file mode 100644 index 0000000..2c70665 --- /dev/null +++ b/ISF/Linear Gradient.fs @@ -0,0 +1,95 @@ +/*{ + "CREDIT": "by Carter Rosenberg", + "ISFVSN": "2", + "CATEGORIES": [ + "Generator" + ], + "INPUTS": [ + { + "NAME": "offset", + "TYPE": "float", + "DEFAULT": 0.5 + }, + { + "NAME": "frequency", + "TYPE": "float", + "MAX": 16.0, + "MIN": 1.0, + "DEFAULT": 1.0 + }, + { + "NAME": "curve", + "TYPE": "long", + "VALUES": [ + 0, + 1, + 2 + ], + "LABELS": [ + "Linear", + "Sine", + "Exponential" + ], + "DEFAULT": 0 + }, + { + "NAME": "vertical", + "TYPE": "bool", + "DEFAULT": 0.0 + }, + { + "NAME": "startColor", + "TYPE": "color", + "DEFAULT": [ + 1.0, + 0.75, + 0.0, + 1.0 + ] + }, + { + "NAME": "endColor", + "TYPE": "color", + "DEFAULT": [ + 0.0, + 0.25, + 0.75, + 1.0 + ] + } + ] +}*/ + + + +const float pi = 3.14159265359; +const float e = 2.71828182846; + + + +void main() { + float mixAmount = 0.0; + float phase = offset; + + if (vertical) { + mixAmount = phase + frequency * isf_FragNormCoord[1]; + } + else { + mixAmount = phase + frequency * isf_FragNormCoord[0]; + } + + if (curve == 0) { + mixAmount = mod(2.0 * mixAmount,2.0); + mixAmount = (mixAmount < 1.0) ? mixAmount : 1.0 - (mixAmount - floor(mixAmount)); + } + else if (curve == 1) { + mixAmount = sin(mixAmount * pi * 2.0 - pi / 2.0) * 0.5 + 0.5; + } + else if (curve == 2) { + mixAmount = mod(2.0 * mixAmount, 2.0); + mixAmount = (mixAmount < 1.0) ? mixAmount : 1.0 - (mixAmount - floor(mixAmount)); + mixAmount = pow(mixAmount, 2.0); + } + + gl_FragColor = mix(startColor,endColor,mixAmount); +} \ No newline at end of file diff --git a/ISF/Lines.fs b/ISF/Lines.fs new file mode 100644 index 0000000..67b4f63 --- /dev/null +++ b/ISF/Lines.fs @@ -0,0 +1,97 @@ +/*{ + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Generator" + ], + "INPUTS": [ + { + "NAME": "spacing", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.5 + }, + { + "NAME": "line_width", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.05 + }, + { + "NAME": "angle", + "TYPE": "float", + "MIN": -1.0, + "MAX": 1.0, + "DEFAULT": 0.25 + }, + { + "NAME": "shift", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.0 + }, + { + "NAME": "color1", + "TYPE": "color", + "DEFAULT": [ + 1.0, + 1.0, + 1.0, + 1.0 + ] + }, + { + "NAME": "color2", + "TYPE": "color", + "DEFAULT": [ + 0.0, + 0.0, + 0.0, + 1.0 + ] + } + ] +}*/ + + +const float pi = 3.14159265359; + + +float pattern() { + float s = sin(angle * pi); + float c = cos(angle * pi); + vec2 tex = isf_FragNormCoord * RENDERSIZE; + float spaced = RENDERSIZE.y * spacing; + vec2 point = vec2( c * tex.x - s * tex.y, s * tex.x + c * tex.y ) * max(1.0/spaced,0.001); + float d = point.y; + float w = line_width; + if (w > spacing) { + w = 0.99*spacing; + } + return ( mod(d + shift*spacing + w * 0.5,spacing) ); +} + + +void main() { + // determine if we are on a line + // math goes something like, figure out distance to the closest line, then draw color2 if we're within range + // y = m*x + b + // m = (y1-y0)/(x1-x0) = tan(angle) + + vec4 out_color = color2; + float w = line_width; + if (w > spacing) { + w = 0.99*spacing; + } + float pat = pattern(); + if ((pat > 0.0)&&(pat <= w)) { + float percent = (1.0-abs(w-2.0*pat)/w); + percent = clamp(percent,0.0,1.0); + out_color = mix(color2,color1,percent); + } + + gl_FragColor = out_color; +} \ No newline at end of file diff --git a/ISF/Luminance Posterize.fs b/ISF/Luminance Posterize.fs new file mode 100644 index 0000000..12d7764 --- /dev/null +++ b/ISF/Luminance Posterize.fs @@ -0,0 +1,56 @@ +/*{ + "CREDIT": "by zoidberg", + "ISFVSN": "2", + "CATEGORIES": [ + "Color Effect" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "levels", + "TYPE": "float", + "MIN": 2.0, + "MAX": 30.0, + "DEFAULT": 30.0 + } + ] +}*/ + +vec3 rgb2hsv(vec3 c); +vec3 hsv2rgb(vec3 c); + +void main() { + // get the src pixel, convert to HSL, posterize the 'L', convert back to RGB + + vec4 srcPixel = IMG_THIS_PIXEL(inputImage); + vec4 tmpColor; + tmpColor.xyz = rgb2hsv(srcPixel.rgb); + float amountPerLevel = 1.0/(levels); + float numOfLevels = floor(tmpColor.z/amountPerLevel); + tmpColor.z = numOfLevels*(1.0/(levels-1.0)); + gl_FragColor.rgb = hsv2rgb(tmpColor.xyz); + gl_FragColor.a = srcPixel.a; + +} + + +vec3 rgb2hsv(vec3 c) { + vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); + //vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g)); + //vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r)); + vec4 p = c.g < c.b ? vec4(c.bg, K.wz) : vec4(c.gb, K.xy); + vec4 q = c.r < p.x ? vec4(p.xyw, c.r) : vec4(c.r, p.yzx); + + float d = q.x - min(q.w, q.y); + float e = 1.0e-10; + return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x); +} + +vec3 hsv2rgb(vec3 c) { + vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); + vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www); + return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y); +} \ No newline at end of file diff --git a/ISF/Maximum Component.fs b/ISF/Maximum Component.fs new file mode 100644 index 0000000..4a331d3 --- /dev/null +++ b/ISF/Maximum Component.fs @@ -0,0 +1,19 @@ +/*{ + "CREDIT": "by zoidberg", + "ISFVSN": "2", + "CATEGORIES": [ + "Color Effect" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + } + ] +}*/ + +void main() { + vec4 srcPixel = IMG_THIS_PIXEL(inputImage); + float maxComponent = max(srcPixel.r, max(srcPixel.g, srcPixel.b)); + gl_FragColor = vec4(maxComponent, maxComponent, maxComponent, srcPixel.a); +} \ No newline at end of file diff --git a/ISF/Median.fs b/ISF/Median.fs new file mode 100644 index 0000000..e07fe1e --- /dev/null +++ b/ISF/Median.fs @@ -0,0 +1,70 @@ +/*{ + "DESCRIPTION": "", + "CREDIT": "VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Blur" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "radius", + "LABEL": "Radius", + "TYPE": "float", + "DEFAULT": 4.0, + "MIN": 0.0, + "MAX": 8.0 + } + ] + +}*/ + + + +// adapted from +// 3x3 Median by Morgan McGuire and Kyle Whitson +// http://graphics.cs.williams.edu/papers/MedianShaderX6/median.pix + + + +#define s2(a, b) temp = a; a = min(a, b); b = max(temp, b); +#define mn3(a, b, c) s2(a, b); s2(a, c); +#define mx3(a, b, c) s2(b, c); s2(a, c); + +#define mnmx3(a, b, c) mx3(a, b, c); s2(a, b); // 3 exchanges +#define mnmx4(a, b, c, d) s2(a, b); s2(c, d); s2(a, c); s2(b, d); // 4 exchanges +#define mnmx5(a, b, c, d, e) s2(a, b); s2(c, d); mn3(a, c, e); mx3(b, d, e); // 6 exchanges +#define mnmx6(a, b, c, d, e, f) s2(a, d); s2(b, e); s2(c, f); mn3(a, b, c); mx3(d, e, f); // 7 exchanges + + + + +void main() { + vec4 v[9]; + + // Add the pixels which make up our window to the pixel array. + for(int dX = -1; dX <= 1; ++dX) { + for(int dY = -1; dY <= 1; ++dY) { + vec2 offset = vec2(float(dX), float(dY)); + + // If a pixel in the window is located at (x+dX, y+dY), put it at index (dX + R)(2R + 1) + (dY + R) of the + // pixel array. This will fill the pixel array, with the top left pixel of the window at pixel[0] and the + // bottom right pixel of the window at pixel[N-1]. + v[(dX + 1) * 3 + (dY + 1)] = IMG_PIXEL(inputImage, gl_FragCoord.xy + offset * radius); + //v[(dX + 1) * 3 + (dY + 1)] = IMG_PIXEL(inputImage, gl_FragCoord.xy); + } + } + + vec4 temp; + + // Starting with a subset of size 6, remove the min and max each time + mnmx6(v[0], v[1], v[2], v[3], v[4], v[5]); + mnmx5(v[1], v[2], v[3], v[4], v[6]); + mnmx4(v[2], v[3], v[4], v[7]); + mnmx3(v[3], v[4], v[8]); + + gl_FragColor = v[4]; +} diff --git a/ISF/Meta Image.fs b/ISF/Meta Image.fs new file mode 100755 index 0000000..531fbab --- /dev/null +++ b/ISF/Meta Image.fs @@ -0,0 +1,99 @@ +/*{ + "CREDIT": "by Toneburst", + "ISFVSN": "2", + "CATEGORIES": [ + "Toneburst", "Tile Effect" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "cell_size", + "TYPE": "float", + "MIN": 0.001, + "MAX": 1.0, + "DEFAULT": 0.125 + }, + { + "NAME": "zoom_tile", + "TYPE": "float", + "MIN": 0.0, + "MAX": 2.0, + "DEFAULT": 1.0 + }, + { + "NAME": "mixAmt", + "LABEL": "mix", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.5 + }, + { + "NAME": "mode", + "VALUES": [ + 0, + 1 + ], + "LABELS": [ + "Multiply", + "Mix" + ], + "DEFAULT": 0, + "TYPE": "long" + } + ] +}*/ + +void main() +{ +// CALCULATE EDGES OF CURRENT CELL + // Position of current pixel + vec2 xy = gl_FragCoord.xy / RENDERSIZE.xy; + // Left and right of tile + float CellWidth = cell_size; + float CellHeight = cell_size; + float x1 = floor(xy.x / CellWidth)*CellWidth; + float x2 = clamp((ceil(xy.x / CellWidth)*CellWidth), 0.0, 1.0); + // Top and bottom of tile + float y1 = floor(xy.y / CellHeight)*CellHeight; + float y2 = clamp((ceil(xy.y / CellHeight)*CellHeight), 0.0, 1.0); + + // GET AVERAGE CELL COLOUR + // Average left and right pixels + vec4 avgX = (IMG_NORM_PIXEL(inputImage, vec2(x1, y1))+(IMG_NORM_PIXEL(inputImage, vec2(x2, y1)))) / 2.0; + // Average top and bottom pixels + vec4 avgY = (IMG_NORM_PIXEL(inputImage, vec2(x1, y1))+(IMG_NORM_PIXEL(inputImage, vec2(x1, y2)))) / 2.0; + // Centre pixel + vec4 avgC = IMG_NORM_PIXEL(inputImage, vec2(x1+(CellWidth/2.0), y2+(CellHeight/2.0))); // Average the averages + centre + vec4 avgClr = (avgX+avgY+avgC) / 3.0; + + // GET PIXELS FROM LITTLE IMAGE + // X-position in current cell + float cellPosX = (xy.x - x1) / CellWidth; + // Y-position in current cell + float cellPosY = (xy.y - y1) / CellHeight; + + vec2 loc = vec2(cellPosX, cellPosY); + vec2 modifiedCenter = vec2(0.5); + loc.x = (loc.x - modifiedCenter.x)*(1.0/zoom_tile) + modifiedCenter.x; + loc.y = (loc.y - modifiedCenter.y)*(1.0/zoom_tile) + modifiedCenter.y; + + vec4 littlePix; + if ((loc.x < 0.0)||(loc.y < 0.0)||(loc.x > 1.0)||(loc.y > 1.0)) { + littlePix = vec4(0.0); + } + else { + littlePix = IMG_NORM_PIXEL(inputImage, loc); + } + + // MULTIPLY LITTLE IMAGE COLOUR WITH AVERAGE CELL COLOUR AND OUTPUT + if (mode == 0) { + gl_FragColor = vec4(littlePix * avgClr); + } + else { + gl_FragColor = vec4(mix(littlePix, avgClr, mixAmt)); + } +} diff --git a/ISF/Micro Buffer RGB.fs b/ISF/Micro Buffer RGB.fs new file mode 100644 index 0000000..ace9480 --- /dev/null +++ b/ISF/Micro Buffer RGB.fs @@ -0,0 +1,316 @@ +/* +{ + "CATEGORIES" : [ + "Glitch" + ], + "DESCRIPTION" : "Buffers 8 recent frames", + "ISFVSN" : "2", + "INPUTS" : [ + { + "NAME" : "inputImage", + "TYPE" : "image" + }, + { + "NAME" : "inputRate", + "TYPE" : "float", + "MAX" : 20, + "DEFAULT" : 1, + "LABEL" : "Buffer Lag", + "MIN" : 0 + }, + { + "LABELS" : [ + "Color Picker", + "Image Input" + ], + "NAME" : "delayMode", + "TYPE" : "long", + "LABEL" : "Delay Mode", + "VALUES" : [ + 0, + 1 + ] + }, + { + "NAME" : "inputDelay", + "LABEL" : "Buffer", + "TYPE" : "color" + }, + { + "NAME" : "inputDelayImage", + "TYPE" : "image", + "LABEL" : "Delay Image" + } + ], + "PASSES" : [ + { + "WIDTH" : "1", + "DESCRIPTION" : "this buffer stores the last frame's odd \/ even state", + "HEIGHT" : "1", + "TARGET" : "lastRow", + "PERSISTENT" : true + }, + { + "TARGET" : "buffer8", + "PERSISTENT" : true + }, + { + "TARGET" : "buffer7", + "PERSISTENT" : true + }, + { + "TARGET" : "buffer6", + "PERSISTENT" : true + }, + { + "TARGET" : "buffer5", + "PERSISTENT" : true + }, + { + "TARGET" : "buffer4", + "PERSISTENT" : true + }, + { + "TARGET" : "buffer3", + "PERSISTENT" : true + }, + { + "TARGET" : "buffer2", + "PERSISTENT" : true + }, + { + "TARGET" : "buffer1", + "PERSISTENT" : true + }, + { + + } + ], + "CREDIT" : "by VIDVOX" +} +*/ + +void main() +{ + // first pass: read the "buffer7" into "buffer8" + // apply lag on each pass + // if this is the first pass, i'm going to read the position from the "lastRow" image, and write a new position based on this and the hold variables + if (PASSINDEX == 0) { + vec4 srcPixel = IMG_PIXEL(lastRow,vec2(0.5)); + // i'm only using the X and Y components, which are the X and Y offset (normalized) for the frame + if (inputRate == 0.0) { + srcPixel.x = 0.0; + srcPixel.y = 0.0; + } + else if (inputRate <= 1.0) { + srcPixel.x = (srcPixel.x) > 0.5 ? 0.0 : 1.0; + srcPixel.y = 0.0; + } + else { + srcPixel.x = srcPixel.x + 1.0 / inputRate + srcPixel.y; + if (srcPixel.x > 1.0) { + srcPixel.y = mod(srcPixel.x, 1.0); + srcPixel.x = 0.0; + } + } + gl_FragColor = srcPixel; + } + if (PASSINDEX == 1) { + vec4 lastRow = IMG_PIXEL(lastRow,vec2(0.5)); + if (lastRow.x == 0.0) { + gl_FragColor = IMG_THIS_NORM_PIXEL(buffer7); + } + else { + gl_FragColor = IMG_THIS_NORM_PIXEL(buffer8); + } + } + else if (PASSINDEX == 2) { + vec4 lastRow = IMG_PIXEL(lastRow,vec2(0.5)); + if (lastRow.x == 0.0) { + gl_FragColor = IMG_THIS_NORM_PIXEL(buffer6); + } + else { + gl_FragColor = IMG_THIS_NORM_PIXEL(buffer7); + } + } + else if (PASSINDEX == 3) { + vec4 lastRow = IMG_PIXEL(lastRow,vec2(0.5)); + if (lastRow.x == 0.0) { + gl_FragColor = IMG_THIS_NORM_PIXEL(buffer5); + } + else { + gl_FragColor = IMG_THIS_NORM_PIXEL(buffer6); + } + } + else if (PASSINDEX == 4) { + vec4 lastRow = IMG_PIXEL(lastRow,vec2(0.5)); + if (lastRow.x == 0.0) { + gl_FragColor = IMG_THIS_NORM_PIXEL(buffer4); + } + else { + gl_FragColor = IMG_THIS_NORM_PIXEL(buffer5); + } + } + else if (PASSINDEX == 5) { + vec4 lastRow = IMG_PIXEL(lastRow,vec2(0.5)); + if (lastRow.x == 0.0) { + gl_FragColor = IMG_THIS_NORM_PIXEL(buffer3); + } + else { + gl_FragColor = IMG_THIS_NORM_PIXEL(buffer4); + } + } + else if (PASSINDEX == 6) { + vec4 lastRow = IMG_PIXEL(lastRow,vec2(0.5)); + if (lastRow.x == 0.0) { + gl_FragColor = IMG_THIS_NORM_PIXEL(buffer2); + } + else { + gl_FragColor = IMG_THIS_NORM_PIXEL(buffer3); + } + } + else if (PASSINDEX == 7) { + vec4 lastRow = IMG_PIXEL(lastRow,vec2(0.5)); + if (lastRow.x == 0.0) { + gl_FragColor = IMG_THIS_NORM_PIXEL(buffer1); + } + else { + gl_FragColor = IMG_THIS_NORM_PIXEL(buffer2); + } + } + else if (PASSINDEX == 8) { + vec4 lastRow = IMG_PIXEL(lastRow,vec2(0.5)); + if (lastRow.x == 0.0) { + gl_FragColor = IMG_THIS_NORM_PIXEL(inputImage); + } + else { + gl_FragColor = IMG_THIS_NORM_PIXEL(buffer1); + } + } + else if (PASSINDEX == 9) { + // Figure out which section I'm in and draw the appropriate buffer there + vec2 tex = isf_FragNormCoord; + vec4 color = vec4(0.0); + vec4 pixelBuffer = vec4(0.0); + if (delayMode == 0) { + pixelBuffer = inputDelay * 9.0; + } + else if (delayMode == 1) { + pixelBuffer = IMG_NORM_PIXEL(inputDelayImage, tex) * 9.0; + } + + if (pixelBuffer.r < 1.0) { + color.r = IMG_NORM_PIXEL(inputImage, tex).r; + } + else if (pixelBuffer.r < 2.0) { + color.r = IMG_NORM_PIXEL(buffer1, tex).r; + } + else if (pixelBuffer.r < 3.0) { + color.r = IMG_NORM_PIXEL(buffer2, tex).r; + } + else if (pixelBuffer.r < 4.0) { + color.r = IMG_NORM_PIXEL(buffer3, tex).r; + } + else if (pixelBuffer.r < 5.0) { + color.r = IMG_NORM_PIXEL(buffer4, tex).r; + } + else if (pixelBuffer.r < 6.0) { + color.r = IMG_NORM_PIXEL(buffer5, tex).r; + } + else if (pixelBuffer.r < 7.0) { + color.r = IMG_NORM_PIXEL(buffer6, tex).r; + } + else if (pixelBuffer.r < 8.0) { + color.r = IMG_NORM_PIXEL(buffer7, tex).r; + } + else { + color.r = IMG_NORM_PIXEL(buffer8, tex).r; + } + + if (pixelBuffer.g < 1.0) { + color.g = IMG_NORM_PIXEL(inputImage, tex).g; + } + else if (pixelBuffer.g < 2.0) { + color.g = IMG_NORM_PIXEL(buffer1, tex).g; + } + else if (pixelBuffer.g < 3.0) { + color.g = IMG_NORM_PIXEL(buffer2, tex).g; + } + else if (pixelBuffer.g < 4.0) { + color.g = IMG_NORM_PIXEL(buffer3, tex).g; + } + else if (pixelBuffer.g < 5.0) { + color.g = IMG_NORM_PIXEL(buffer4, tex).g; + } + else if (pixelBuffer.g < 6.0) { + color.g = IMG_NORM_PIXEL(buffer5, tex).g; + } + else if (pixelBuffer.g < 7.0) { + color.g = IMG_NORM_PIXEL(buffer6, tex).g; + } + else if (pixelBuffer.g < 8.0) { + color.g = IMG_NORM_PIXEL(buffer7, tex).g; + } + else { + color.g = IMG_NORM_PIXEL(buffer8, tex).g; + } + + if (pixelBuffer.b < 1.0) { + color.b = IMG_NORM_PIXEL(inputImage, tex).b; + } + else if (pixelBuffer.b < 2.0) { + color.b = IMG_NORM_PIXEL(buffer1, tex).b; + } + else if (pixelBuffer.b < 3.0) { + color.b = IMG_NORM_PIXEL(buffer2, tex).b; + } + else if (pixelBuffer.b < 4.0) { + color.b = IMG_NORM_PIXEL(buffer3, tex).b; + } + else if (pixelBuffer.b < 5.0) { + color.b = IMG_NORM_PIXEL(buffer4, tex).b; + } + else if (pixelBuffer.b < 6.0) { + color.b = IMG_NORM_PIXEL(buffer5, tex).b; + } + else if (pixelBuffer.b < 7.0) { + color.b = IMG_NORM_PIXEL(buffer6, tex).b; + } + else if (pixelBuffer.b < 8.0) { + color.b = IMG_NORM_PIXEL(buffer7, tex).b; + } + else { + color.b = IMG_NORM_PIXEL(buffer8, tex).b; + } + + if (pixelBuffer.a < 1.0) { + color.a = IMG_NORM_PIXEL(inputImage, tex).a; + } + else if (pixelBuffer.a < 2.0) { + color.a = IMG_NORM_PIXEL(buffer1, tex).a; + } + else if (pixelBuffer.a < 3.0) { + color.a = IMG_NORM_PIXEL(buffer2, tex).a; + } + else if (pixelBuffer.a < 4.0) { + color.a = IMG_NORM_PIXEL(buffer3, tex).a; + } + else if (pixelBuffer.a < 5.0) { + color.a = IMG_NORM_PIXEL(buffer4, tex).a; + } + else if (pixelBuffer.a < 6.0) { + color.a = IMG_NORM_PIXEL(buffer5, tex).a; + } + else if (pixelBuffer.a < 7.0) { + color.a = IMG_NORM_PIXEL(buffer6, tex).a; + } + else if (pixelBuffer.a < 8.0) { + color.a = IMG_NORM_PIXEL(buffer7, tex).a; + } + else { + color.a = IMG_NORM_PIXEL(buffer8, tex).a; + } + + gl_FragColor = color; + } +} diff --git a/ISF/Micro Buffer.fs b/ISF/Micro Buffer.fs new file mode 100644 index 0000000..3f9f21f --- /dev/null +++ b/ISF/Micro Buffer.fs @@ -0,0 +1,312 @@ +/*{ + "DESCRIPTION": "Buffers 8 recent frames", + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Glitch" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "inputDelay", + "LABEL": "Buffer", + "TYPE": "float", + "MIN": 0.0, + "MAX": 9.0, + "DEFAULT": 0.0 + }, + { + "NAME": "inputDelay2", + "LABEL": "Buffer 2", + "TYPE": "float", + "MIN": 0.0, + "MAX": 9.0, + "DEFAULT": 0.0 + }, + { + "NAME": "inputDelay3", + "LABEL": "Buffer 3", + "TYPE": "float", + "MIN": 0.0, + "MAX": 9.0, + "DEFAULT": 0.0 + }, + { + "NAME": "inputRate", + "LABEL": "Buffer Lag", + "TYPE": "float", + "MIN": 0.0, + "MAX": 20.0, + "DEFAULT": 1.0 + }, + { + "NAME": "mode", + "VALUES": [ + 0, + 1, + 2 + ], + "LABELS": [ + "Single", + "Double", + "Triple" + ], + "DEFAULT": 0, + "TYPE": "long" + } + ], + "PASSES": [ + { + "TARGET":"lastRow", + "WIDTH": "1", + "HEIGHT": "1", + "PERSISTENT": true, + "DESCRIPTION": "this buffer stores the last frame's odd / even state" + }, + { + "TARGET":"buffer8", + "PERSISTENT": true + }, + { + "TARGET":"buffer7", + "PERSISTENT": true + }, + { + "TARGET":"buffer6", + "PERSISTENT": true + }, + { + "TARGET":"buffer5", + "PERSISTENT": true + }, + { + "TARGET":"buffer4", + "PERSISTENT": true + }, + { + "TARGET":"buffer3", + "PERSISTENT": true + }, + { + "TARGET":"buffer2", + "PERSISTENT": true + }, + { + "TARGET":"buffer1", + "PERSISTENT": true + }, + { + + } + ] + +}*/ + +void main() +{ + // first pass: read the "buffer7" into "buffer8" + // apply lag on each pass + // if this is the first pass, i'm going to read the position from the "lastRow" image, and write a new position based on this and the hold variables + if (PASSINDEX == 0) { + vec4 srcPixel = IMG_PIXEL(lastRow,vec2(0.5)); + // i'm only using the X and Y components, which are the X and Y offset (normalized) for the frame + if (inputRate == 0.0) { + srcPixel.x = 0.0; + srcPixel.y = 0.0; + } + else if (inputRate <= 1.0) { + srcPixel.x = (srcPixel.x) > 0.5 ? 0.0 : 1.0; + srcPixel.y = 0.0; + } + else { + srcPixel.x = srcPixel.x + 1.0 / inputRate + srcPixel.y; + if (srcPixel.x > 1.0) { + srcPixel.y = mod(srcPixel.x, 1.0); + srcPixel.x = 0.0; + } + } + gl_FragColor = srcPixel; + } + if (PASSINDEX == 1) { + vec4 lastRow = IMG_PIXEL(lastRow,vec2(0.5)); + if (lastRow.x == 0.0) { + gl_FragColor = IMG_THIS_NORM_PIXEL(buffer7); + } + else { + gl_FragColor = IMG_THIS_NORM_PIXEL(buffer8); + } + } + else if (PASSINDEX == 2) { + vec4 lastRow = IMG_PIXEL(lastRow,vec2(0.5)); + if (lastRow.x == 0.0) { + gl_FragColor = IMG_THIS_NORM_PIXEL(buffer6); + } + else { + gl_FragColor = IMG_THIS_NORM_PIXEL(buffer7); + } + } + else if (PASSINDEX == 3) { + vec4 lastRow = IMG_PIXEL(lastRow,vec2(0.5)); + if (lastRow.x == 0.0) { + gl_FragColor = IMG_THIS_NORM_PIXEL(buffer5); + } + else { + gl_FragColor = IMG_THIS_NORM_PIXEL(buffer6); + } + } + else if (PASSINDEX == 4) { + vec4 lastRow = IMG_PIXEL(lastRow,vec2(0.5)); + if (lastRow.x == 0.0) { + gl_FragColor = IMG_THIS_NORM_PIXEL(buffer4); + } + else { + gl_FragColor = IMG_THIS_NORM_PIXEL(buffer5); + } + } + else if (PASSINDEX == 5) { + vec4 lastRow = IMG_PIXEL(lastRow,vec2(0.5)); + if (lastRow.x == 0.0) { + gl_FragColor = IMG_THIS_NORM_PIXEL(buffer3); + } + else { + gl_FragColor = IMG_THIS_NORM_PIXEL(buffer4); + } + } + else if (PASSINDEX == 6) { + vec4 lastRow = IMG_PIXEL(lastRow,vec2(0.5)); + if (lastRow.x == 0.0) { + gl_FragColor = IMG_THIS_NORM_PIXEL(buffer2); + } + else { + gl_FragColor = IMG_THIS_NORM_PIXEL(buffer3); + } + } + else if (PASSINDEX == 7) { + vec4 lastRow = IMG_PIXEL(lastRow,vec2(0.5)); + if (lastRow.x == 0.0) { + gl_FragColor = IMG_THIS_NORM_PIXEL(buffer1); + } + else { + gl_FragColor = IMG_THIS_NORM_PIXEL(buffer2); + } + } + else if (PASSINDEX == 8) { + vec4 lastRow = IMG_PIXEL(lastRow,vec2(0.5)); + if (lastRow.x == 0.0) { + gl_FragColor = IMG_THIS_NORM_PIXEL(inputImage); + } + else { + gl_FragColor = IMG_THIS_NORM_PIXEL(buffer1); + } + } + else if (PASSINDEX == 9) { + // Figure out which section I'm in and draw the appropriate buffer there + vec2 tex = isf_FragNormCoord; + vec4 returnMe = vec4(0.0); + vec4 color = vec4(0.0); + float pixelBuffer = inputDelay; + + // If the glitch factor is turned on I might randomly go to another delay point + + if (pixelBuffer < 1.0) { + color = IMG_NORM_PIXEL(inputImage, tex); + } + else if (pixelBuffer < 2.0) { + color = IMG_NORM_PIXEL(buffer1, tex); + } + else if (pixelBuffer < 3.0) { + color = IMG_NORM_PIXEL(buffer2, tex); + } + else if (pixelBuffer < 4.0) { + color = IMG_NORM_PIXEL(buffer3, tex); + } + else if (pixelBuffer < 5.0) { + color = IMG_NORM_PIXEL(buffer4, tex); + } + else if (pixelBuffer < 6.0) { + color = IMG_NORM_PIXEL(buffer5, tex); + } + else if (pixelBuffer < 7.0) { + color = IMG_NORM_PIXEL(buffer6, tex); + } + else if (pixelBuffer < 8.0) { + color = IMG_NORM_PIXEL(buffer7, tex); + } + else { + color = IMG_NORM_PIXEL(buffer8, tex); + } + + returnMe = color; + + if ((mode == 1)||(mode == 2)) { + pixelBuffer = inputDelay2; + if (pixelBuffer < 1.0) { + color = IMG_NORM_PIXEL(inputImage, tex); + } + else if (pixelBuffer < 2.0) { + color = IMG_NORM_PIXEL(buffer1, tex); + } + else if (pixelBuffer < 3.0) { + color = IMG_NORM_PIXEL(buffer2, tex); + } + else if (pixelBuffer < 4.0) { + color = IMG_NORM_PIXEL(buffer3, tex); + } + else if (pixelBuffer < 5.0) { + color = IMG_NORM_PIXEL(buffer4, tex); + } + else if (pixelBuffer < 6.0) { + color = IMG_NORM_PIXEL(buffer5, tex); + } + else if (pixelBuffer < 7.0) { + color = IMG_NORM_PIXEL(buffer6, tex); + } + else if (pixelBuffer < 8.0) { + color = IMG_NORM_PIXEL(buffer7, tex); + } + else { + color = IMG_NORM_PIXEL(buffer8, tex); + } + returnMe = (returnMe + color); + } + + if (mode == 2) { + pixelBuffer = inputDelay3; + if (pixelBuffer < 1.0) { + color = IMG_NORM_PIXEL(inputImage, tex); + } + else if (pixelBuffer < 2.0) { + color = IMG_NORM_PIXEL(buffer1, tex); + } + else if (pixelBuffer < 3.0) { + color = IMG_NORM_PIXEL(buffer2, tex); + } + else if (pixelBuffer < 4.0) { + color = IMG_NORM_PIXEL(buffer3, tex); + } + else if (pixelBuffer < 5.0) { + color = IMG_NORM_PIXEL(buffer4, tex); + } + else if (pixelBuffer < 6.0) { + color = IMG_NORM_PIXEL(buffer5, tex); + } + else if (pixelBuffer < 7.0) { + color = IMG_NORM_PIXEL(buffer6, tex); + } + else if (pixelBuffer < 8.0) { + color = IMG_NORM_PIXEL(buffer7, tex); + } + else { + color = IMG_NORM_PIXEL(buffer8, tex); + } + returnMe = (returnMe + color); + } + + returnMe = returnMe / (1.0+float(mode)); + + gl_FragColor = returnMe; + } +} diff --git a/ISF/Minimum Component.fs b/ISF/Minimum Component.fs new file mode 100644 index 0000000..168ab05 --- /dev/null +++ b/ISF/Minimum Component.fs @@ -0,0 +1,19 @@ +/*{ + "CREDIT": "by zoidberg", + "ISFVSN": "2", + "CATEGORIES": [ + "Color Effect" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + } + ] +}*/ + +void main() { + vec4 srcPixel = IMG_THIS_PIXEL(inputImage); + float minComponent = min(srcPixel.r, min(srcPixel.g, srcPixel.b)); + gl_FragColor = vec4(minComponent, minComponent, minComponent, srcPixel.a); +} \ No newline at end of file diff --git a/ISF/Mirror Edge.fs b/ISF/Mirror Edge.fs new file mode 100644 index 0000000..3bc336d --- /dev/null +++ b/ISF/Mirror Edge.fs @@ -0,0 +1,46 @@ +/*{ + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Tile Effect" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "angle", + "LABEL": "Angle", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.0 + }, + { + "NAME": "shift", + "LABEL": "Shift", + "TYPE": "point2D", + "DEFAULT": [ + 0.0, + 0.5 + ] + } + ] +}*/ + + +varying vec2 translated_coord; + + +void main() { + vec2 loc = translated_coord; + vec2 modifiedCenter = shift / RENDERSIZE; + + loc = mod(loc + modifiedCenter, 1.0); + + // mirror the image so it's repeated 4 times at different reflections + loc = 2.0 * abs(loc - 0.5); + + gl_FragColor = IMG_NORM_PIXEL(inputImage, loc); +} \ No newline at end of file diff --git a/ISF/Mirror Edge.vs b/ISF/Mirror Edge.vs new file mode 100644 index 0000000..be47c0b --- /dev/null +++ b/ISF/Mirror Edge.vs @@ -0,0 +1,18 @@ +varying vec2 translated_coord; + +const float pi = 3.14159265359; + +void main() { + isf_vertShaderInit(); + + vec2 loc = RENDERSIZE * vec2(isf_FragNormCoord[0],isf_FragNormCoord[1]); + + float r = distance(RENDERSIZE/2.0, loc); + float a = atan ((loc.y-RENDERSIZE.y/2.0),(loc.x-RENDERSIZE.x/2.0)); + + loc.x = r * cos(a + 2.0 * pi * angle) + 0.5; + loc.y = r * sin(a + 2.0 * pi * angle) + 0.5; + + translated_coord = loc / RENDERSIZE + vec2(0.5); + +} \ No newline at end of file diff --git a/ISF/Mirror.fs b/ISF/Mirror.fs new file mode 100644 index 0000000..cb83d2f --- /dev/null +++ b/ISF/Mirror.fs @@ -0,0 +1,41 @@ +/*{ + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Geometry Adjustment" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "horizontal", + "TYPE": "bool", + "DEFAULT": 1.0 + }, + { + "NAME": "vertical", + "TYPE": "bool", + "DEFAULT": 0.0 + } + ] +}*/ + +void main() { + // isf_FragNormCoord[0] and isf_FragNormCoord[1] are my normalized x/y coordinates + // if we're not doing a flip in either direction we can just pass thru + vec2 normSrcCoord; + + normSrcCoord.x = isf_FragNormCoord[0]; + normSrcCoord.y = isf_FragNormCoord[1]; + + if ((normSrcCoord.x > 0.5)&&(horizontal)) { + normSrcCoord.x = (1.0-normSrcCoord.x); + } + if ((normSrcCoord.y > 0.5)&&(vertical)) { + normSrcCoord.y = (1.0-normSrcCoord.y); + } + + gl_FragColor = IMG_NORM_PIXEL(inputImage, normSrcCoord); +} \ No newline at end of file diff --git a/ISF/Motion Heat Map.fs b/ISF/Motion Heat Map.fs new file mode 100644 index 0000000..13dffaf --- /dev/null +++ b/ISF/Motion Heat Map.fs @@ -0,0 +1,151 @@ +/*{ + "DESCRIPTION": "Shows where there is motion between frames", + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Color Effect", "Utility" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "motionThreshold", + "LABEL": "Threshold", + "TYPE": "float", + "MAX": 1.0, + "MIN": 0.0, + "DEFAULT": 0.1 + }, + { + "NAME": "motionGain", + "LABEL": "Gain", + "TYPE": "float", + "MAX": 2.0, + "MIN": 0.0, + "DEFAULT": 1.0 + }, + { + "NAME": "motionColor", + "LABEL": "Motion Color", + "TYPE": "bool", + "DEFAULT": 1.0 + }, + { + "NAME": "displayMode", + "LABEL": "Display Mode", + "TYPE": "long", + "VALUES": [ + 0, + 1 + ], + "LABELS": [ + "Motion Only", + "Motion Overlay" + ], + "DEFAULT": 1 + } + ], + "PASSES": [ + { + "TARGET":"differenceBuffer", + "FLOAT": true + }, { + "TARGET":"lastFrameBuffer", + "PERSISTENT": true + }, + { + + } + ] + +}*/ + + +vec4 heatColor(float lum) { + vec4 returnMe = vec4(1.0); + vec4 colors[9]; + // 8 color stages with variable ranges to get this to look right + // black, purple, blue, cyan, green, yellow, orange, red, red + colors[0] = vec4(0.0,0.0,0.0,1.0); + colors[1] = vec4(0.272,0.0,0.4,1.0); // dark deep purple, (RGB: 139, 0, 204) + colors[2] = vec4(0.0,0.0,1.0,1.0); // full blue + colors[3] = vec4(0.0,1.0,1.0,1.0); // cyan + colors[4] = vec4(0.0,1.0,0.0,1.0); // green + colors[5] = vec4(0.0,1.0,0.0,1.0); // green + colors[6] = vec4(1.0,1.0,0.0,1.0); // yellow + colors[7] = vec4(1.0,0.5,0.0,1.0); // orange + colors[8] = vec4(1.0,0.0,0.0,1.0); // red + + int ix = 0; + float range = 1.0 / 8.0; + + // orange to red + if (lum > range * 7.0) { + ix = 7; + } + // yellow to orange + else if (lum > range * 6.0) { + ix = 6; + } + // green to yellow + else if (lum > range * 5.0) { + ix = 5; + } + // green to green + else if (lum > range * 4.0) { + ix = 4; + } + // cyan to green + else if (lum > range * 3.0) { + ix = 3; + } + // blue to cyan + else if (lum > range * 2.0) { + ix = 2; + } + // purple to blue + else if (lum > range) { + ix = 1; + } + + returnMe = colors[ix]; + + return returnMe; +} + + +void main() +{ + vec4 freshPixel = IMG_PIXEL(inputImage,gl_FragCoord.xy); + vec4 returnMe = freshPixel; + + if (PASSINDEX == 0) { + vec4 stalePixel = IMG_PIXEL(lastFrameBuffer,gl_FragCoord.xy); + vec3 rgbChange = abs(freshPixel.rgb - stalePixel.rgb); + float totalChange = (rgbChange.r + rgbChange.g + rgbChange.b) / 3.0; + if (motionColor) + returnMe = heatColor(totalChange * motionGain); + else + returnMe = vec4(totalChange * motionGain); + } + else if (PASSINDEX == 1) { + + } + else { + vec4 differencePixel = IMG_PIXEL(differenceBuffer,gl_FragCoord.xy); + if (displayMode == 0) { + returnMe = differencePixel; + } + else if (displayMode == 1) { + const vec4 lumacoeff = vec4(0.2126, 0.7152, 0.0722, 0.0); + float luma = dot(differencePixel, lumacoeff); + if (luma > motionThreshold) { + returnMe = differencePixel; + } + } + } + + gl_FragColor = returnMe; +} diff --git a/ISF/Motion Mask.fs b/ISF/Motion Mask.fs new file mode 100644 index 0000000..2b1f200 --- /dev/null +++ b/ISF/Motion Mask.fs @@ -0,0 +1,210 @@ +/*{ + "DESCRIPTION": "Masks an image based on the amount of motion", + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Masking" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "LABEL": "Threshold", + "NAME": "threshold", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.25 + }, + { + "LABEL": "Persistence", + "NAME": "persistence", + "TYPE": "float", + "MIN": 0.9, + "MAX": 1.0, + "DEFAULT": 0.95 + }, + { + "LABEL": "Reset BG", + "NAME": "updateBackground", + "TYPE": "event" + }, + { + "LABEL": "Dilate", + "NAME": "dilate", + "TYPE": "float", + "MIN": 0.0, + "MAX": 6.0, + "DEFAULT": 0.0 + }, + { + "LABEL": "Blur", + "NAME": "blur", + "TYPE": "float", + "MIN": 0.0, + "MAX": 6.0, + "DEFAULT": 0.0 + }, + { + "LABEL": "Output Mask", + "NAME": "showAlpha", + "TYPE": "bool", + "DEFAULT": false + }, + { + "LABEL": "Hard Cutoff", + "NAME": "applyCutOff", + "TYPE": "bool", + "DEFAULT": true + } + ], + "PASSES": [ + { + "TARGET":"freezeBuffer", + "PERSISTENT": true + }, + { + "TARGET":"mask" + }, + { + "TARGET": "horizDilate" + }, + { + "TARGET": "vertDilate" + }, + { + "TARGET": "horizBlur" + }, + { + "TARGET": "vertBlur" + }, + { + + } + ] + +}*/ + +// Essentially the same as a feedback buffer where you can only set it to a mix of 1.0 + +void main() +{ + vec2 tmpCoord; + float maxAlpha; + vec4 sampleColorRGB; + vec4 src_rgb; + + if (PASSINDEX==0) { + vec4 srcPixel = IMG_THIS_PIXEL(inputImage); + vec4 oldPixel = IMG_THIS_PIXEL(freezeBuffer); + gl_FragColor = (updateBackground) ? srcPixel : mix(srcPixel,oldPixel,persistence); + } + else if (PASSINDEX==1) { + vec4 srcPixel = IMG_THIS_PIXEL(inputImage); + vec4 oldPixel = IMG_THIS_PIXEL(freezeBuffer); + vec4 resultPixel = vec4(0.0); + float difference = abs(srcPixel.r - oldPixel.r) + abs(srcPixel.g - oldPixel.g) + abs(srcPixel.b - oldPixel.b); + resultPixel = vec4(difference); + gl_FragColor = resultPixel; + } + else if (PASSINDEX==2) { + // 'dilate' samples on either side + the source pixel = 2*dilate+1 total samples + for (float i=0.; i<=dilate; ++i) { + tmpCoord = vec2(clamp(gl_FragCoord.x+i,0.,RENDERSIZE.x), gl_FragCoord.y); + sampleColorRGB = IMG_PIXEL(mask, tmpCoord); + // if this is the first sample for this fragment, don't bother comparing- just set the max luma stuff + if (i == 0.) { + maxAlpha = sampleColorRGB.a; + src_rgb = sampleColorRGB; + } + // else this isn't the first sample... + else { + // compare, determine if it's the max luma + if (sampleColorRGB.a < maxAlpha) { + maxAlpha = sampleColorRGB.a; + } + // do another sample for the negative coordinate + tmpCoord = vec2(clamp(gl_FragCoord.x-i,0.,RENDERSIZE.x), gl_FragCoord.y); + sampleColorRGB = IMG_PIXEL(mask, tmpCoord); + if (sampleColorRGB.a < maxAlpha) { + maxAlpha = sampleColorRGB.a; + } + } + } + gl_FragColor = vec4(src_rgb.rgb, maxAlpha); + } + else if (PASSINDEX==3) { + // 'dilate' samples up and down + the source pixel = 2*dilate+1 total samples + for (float i=0.; i<=float(int(dilate)); ++i) { + tmpCoord = vec2(gl_FragCoord.x, clamp(gl_FragCoord.y+i,0.,RENDERSIZE.y)); + sampleColorRGB = IMG_PIXEL(horizDilate, tmpCoord); + // if this is the first sample for this fragment, don't bother comparing- just set the max luma stuff + if (i == 0.) { + maxAlpha = sampleColorRGB.a; + src_rgb = sampleColorRGB; + } + // else this isn't the first sample... + else { + // compare, determine if it's the max luma + if (sampleColorRGB.a < maxAlpha) { + maxAlpha = sampleColorRGB.a; + } + // do another sample for the negative coordinate + tmpCoord = vec2(gl_FragCoord.x, clamp(gl_FragCoord.y-i,0.,RENDERSIZE.y)); + sampleColorRGB = IMG_PIXEL(horizDilate, tmpCoord); + if (sampleColorRGB.a < maxAlpha) { + maxAlpha = sampleColorRGB.a; + } + } + } + gl_FragColor = vec4(src_rgb.rgb, maxAlpha); + } + else if (PASSINDEX==4) { + float tmpRadius = float(int(blur)); + vec4 tmpColor; + vec4 srcColor; + float totalAlpha = 0.0; + for (float i=-1.*tmpRadius; i<=tmpRadius; ++i) { + tmpColor = IMG_PIXEL(vertDilate, gl_FragCoord.xy+vec2(i,0.0)); + totalAlpha += tmpColor.a; + if (i==0.0) + srcColor = tmpColor; + } + totalAlpha /= ((tmpRadius*2.)+1.); + gl_FragColor = vec4(srcColor.r, srcColor.g, srcColor.b, totalAlpha); + } + else if (PASSINDEX==5) { + float tmpRadius = float(int(blur)); + vec4 tmpColor; + vec4 srcColor; + float totalAlpha = 0.0; + for (float i=-1.*tmpRadius; i<=tmpRadius; ++i) { + tmpColor = IMG_PIXEL(horizBlur, gl_FragCoord.xy+vec2(0.0,i)); + totalAlpha += tmpColor.a; + if (i==0.0) + srcColor = tmpColor; + } + totalAlpha /= ((tmpRadius*2.)+1.); + + gl_FragColor = vec4(srcColor.r, srcColor.g, srcColor.b, totalAlpha); + } + else if (PASSINDEX==6) { + vec4 srcPixel = IMG_THIS_PIXEL(inputImage); + vec4 oldPixel = IMG_THIS_PIXEL(vertBlur); + vec4 resultPixel = vec4(0.0); + float difference = oldPixel.a; + if (difference > threshold) { + if (showAlpha) + resultPixel = vec4(1.0,1.0,1.0,1.0); + else + resultPixel = srcPixel; + + if (!applyCutOff) + resultPixel = resultPixel * difference; + } + gl_FragColor = resultPixel; + } + +} diff --git a/ISF/Multi Hue Shift.fs b/ISF/Multi Hue Shift.fs new file mode 100644 index 0000000..e536ce9 --- /dev/null +++ b/ISF/Multi Hue Shift.fs @@ -0,0 +1,89 @@ +/*{ + "DESCRIPTION": "Performs hue shifts of different amounts depending on brightness levels", + "CREDIT": "VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Color Effect" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "shiftLow", + "TYPE": "float", + "DEFAULT": 0.0, + "MIN": 0.0, + "MAX": 1.0 + }, + { + "NAME": "shiftMid", + "TYPE": "float", + "DEFAULT": 0.0, + "MIN": 0.0, + "MAX": 1.0 + }, + { + "NAME": "shiftHigh", + "TYPE": "float", + "DEFAULT": 0.0, + "MIN": 0.0, + "MAX": 1.0 + } + ] + +}*/ + + + +vec3 rgb2hsv(vec3 c) { + vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); + //vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g)); + //vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r)); + vec4 p = c.g < c.b ? vec4(c.bg, K.wz) : vec4(c.gb, K.xy); + vec4 q = c.r < p.x ? vec4(p.xyw, c.r) : vec4(c.r, p.yzx); + + float d = q.x - min(q.w, q.y); + float e = 1.0e-10; + return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x); +} + +vec3 hsv2rgb(vec3 c) { + vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); + vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www); + return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y); +} + + + +void main() { + vec4 inputPixelColor = IMG_THIS_PIXEL(inputImage); + + // don't bother doing anything if we're not shifting anything + if ((shiftLow > 0.0)||(shiftMid > 0.0)||(shiftHigh > 0.0)) { + // what is the brightness? + float val = (inputPixelColor.r + inputPixelColor.g + inputPixelColor.b) / 3.0; + + // how much do we shift by based on that brightness? + if (val < 0.25) { + val = shiftLow; + } + else if (val < 0.5) { + val = mix(shiftLow, shiftMid, (val-0.25) * 4.0); + } + else if (val < 0.75) { + val = mix(shiftMid, shiftHigh, (val-0.5) * 4.0); + } + else { + val = shiftHigh; + } + + inputPixelColor.rgb = rgb2hsv(inputPixelColor.rgb); + inputPixelColor.r = fract(inputPixelColor.r + val); + inputPixelColor.rgb = hsv2rgb(inputPixelColor.rgb); + + } + + gl_FragColor = inputPixelColor; +} diff --git a/ISF/Multi Pass Gaussian Blur.fs b/ISF/Multi Pass Gaussian Blur.fs new file mode 100644 index 0000000..475d167 --- /dev/null +++ b/ISF/Multi Pass Gaussian Blur.fs @@ -0,0 +1,179 @@ +/*{ + "CREDIT": "original implementation as v002.blur in QC by anton marini and tom butterworth, ported by zoidberg", + "ISFVSN": "2", + "CATEGORIES": [ + "Blur" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "blurAmount", + "TYPE": "float", + "MIN": 0.0, + "MAX": 24.0, + "DEFAULT": 24.0 + } + ], + "PASSES": [ + { + "TARGET": "halfSizeBaseRender", + "WIDTH": "floor($WIDTH/3.0)", + "HEIGHT": "floor($HEIGHT/3.0)", + "DESCRIPTION": "Pass 0" + }, + { + "TARGET": "quarterSizeBaseRender", + "WIDTH": "floor($WIDTH/6.0)", + "HEIGHT": "floor($HEIGHT/6.0)", + "DESCRIPTION": "Pass 1" + }, + { + "TARGET": "eighthSizeBaseRender", + "WIDTH": "floor($WIDTH/12.0)", + "HEIGHT": "floor($HEIGHT/12.0)", + "DESCRIPTION": "Pass 2" + }, + { + "TARGET": "eighthGaussA", + "WIDTH": "floor($WIDTH/12.0)", + "HEIGHT": "floor($HEIGHT/12.0)", + "DESCRIPTION": "Pass 3" + }, + { + "TARGET": "eighthGaussB", + "WIDTH": "floor($WIDTH/12.0)", + "HEIGHT": "floor($HEIGHT/12.0)", + "DESCRIPTION": "Pass 4" + }, + { + "TARGET": "quarterGaussA", + "WIDTH": "floor($WIDTH/6.0)", + "HEIGHT": "floor($HEIGHT/6.0)", + "DESCRIPTION": "Pass 5" + }, + { + "TARGET": "quarterGaussB", + "WIDTH": "floor($WIDTH/6.0)", + "HEIGHT": "floor($HEIGHT/6.0)", + "DESCRIPTION": "Pass 6" + }, + { + "TARGET": "halfGaussA", + "WIDTH": "floor($WIDTH/3.0)", + "HEIGHT": "floor($HEIGHT/3.0)", + "DESCRIPTION": "Pass 7" + }, + { + "TARGET": "halfGaussB", + "WIDTH": "floor($WIDTH/3.0)", + "HEIGHT": "floor($HEIGHT/3.0)", + "DESCRIPTION": "Pass 8" + }, + { + "TARGET": "fullGaussA", + "DESCRIPTION": "Pass 9" + }, + { + "TARGET": "fullGaussB", + "DESCRIPTION": "Pass 10" + } + ] +}*/ + + +/* + eighth + quarter 0 1 2 3 4 5 "blurRadius" (different resolutions have different blur radiuses based on the "blurAmount" and its derived "blurLevel") + half 0 1 2 3 4 5 "blurRadius" + normal 0 1 2 3 4 5 "blurRadius" + 0 1 2 3 4 5 5 "blurRadius" + 0 6 12 18 24 "blurAmount" (attrib) + 0 1 2 3 "blurLevel" (local var) +*/ + + +varying vec2 texOffsets[5]; + + +void main() { + int blurLevel = int(floor(blurAmount/6.0)); + float blurLevelModulus = mod(blurAmount, 6.0); + // first three passes are just copying the input image into the buffer at varying sizes + if (PASSINDEX==0) { + gl_FragColor = IMG_NORM_PIXEL(inputImage, isf_FragNormCoord); + } + else if (PASSINDEX==1) { + gl_FragColor = IMG_NORM_PIXEL(halfSizeBaseRender, isf_FragNormCoord); + } + else if (PASSINDEX==2) { + gl_FragColor = IMG_NORM_PIXEL(quarterSizeBaseRender, isf_FragNormCoord); + } + // start reading from the previous stage- each two passes completes a gaussian blur, then + // we increase the resolution & blur (the lower-res blurred image from the previous pass) again... + else if (PASSINDEX == 3) { + vec4 sample0 = IMG_NORM_PIXEL(eighthSizeBaseRender,texOffsets[0]); + vec4 sample1 = IMG_NORM_PIXEL(eighthSizeBaseRender,texOffsets[1]); + vec4 sample2 = IMG_NORM_PIXEL(eighthSizeBaseRender,texOffsets[2]); + vec4 sample3 = IMG_NORM_PIXEL(eighthSizeBaseRender,texOffsets[3]); + vec4 sample4 = IMG_NORM_PIXEL(eighthSizeBaseRender,texOffsets[4]); + //gl_FragColor = vec4((sample0 + sample1 + sample2).rgb / (3.0), 1.0); + gl_FragColor = vec4((sample0 + sample1 + sample2 + sample3 + sample4).rgba / (5.0)); + } + else if (PASSINDEX == 4) { + vec4 sample0 = IMG_NORM_PIXEL(eighthGaussA,texOffsets[0]); + vec4 sample1 = IMG_NORM_PIXEL(eighthGaussA,texOffsets[1]); + vec4 sample2 = IMG_NORM_PIXEL(eighthGaussA,texOffsets[2]); + vec4 sample3 = IMG_NORM_PIXEL(eighthGaussA,texOffsets[3]); + vec4 sample4 = IMG_NORM_PIXEL(eighthGaussA,texOffsets[4]); + //gl_FragColor = vec4((sample0 + sample1 + sample2).rgb / (3.0), 1.0); + gl_FragColor = vec4((sample0 + sample1 + sample2 + sample3 + sample4).rgba / (5.0)); + } + // ...writes into the quarter-size + else if (PASSINDEX == 5) { + vec4 sample0 = IMG_NORM_PIXEL(eighthGaussB,texOffsets[0]); + vec4 sample1 = IMG_NORM_PIXEL(eighthGaussB,texOffsets[1]); + vec4 sample2 = IMG_NORM_PIXEL(eighthGaussB,texOffsets[2]); + gl_FragColor = vec4((sample0 + sample1 + sample2).rgba / (3.0)); + } + else if (PASSINDEX == 6) { + vec4 sample0 = IMG_NORM_PIXEL(quarterGaussA,texOffsets[0]); + vec4 sample1 = IMG_NORM_PIXEL(quarterGaussA,texOffsets[1]); + vec4 sample2 = IMG_NORM_PIXEL(quarterGaussA,texOffsets[2]); + gl_FragColor = vec4((sample0 + sample1 + sample2).rgba / (3.0)); + } + // ...writes into the half-size + else if (PASSINDEX == 7) { + vec4 sample0 = IMG_NORM_PIXEL(quarterGaussB,texOffsets[0]); + vec4 sample1 = IMG_NORM_PIXEL(quarterGaussB,texOffsets[1]); + vec4 sample2 = IMG_NORM_PIXEL(quarterGaussB,texOffsets[2]); + gl_FragColor = vec4((sample0 + sample1 + sample2).rgba / (3.0)); + } + else if (PASSINDEX == 8) { + vec4 sample0 = IMG_NORM_PIXEL(halfGaussA,texOffsets[0]); + vec4 sample1 = IMG_NORM_PIXEL(halfGaussA,texOffsets[1]); + vec4 sample2 = IMG_NORM_PIXEL(halfGaussA,texOffsets[2]); + gl_FragColor = vec4((sample0 + sample1 + sample2).rgba / (3.0)); + } + // ...writes into the full-size + else if (PASSINDEX == 9) { + vec4 sample0 = IMG_NORM_PIXEL(halfGaussB,texOffsets[0]); + vec4 sample1 = IMG_NORM_PIXEL(halfGaussB,texOffsets[1]); + vec4 sample2 = IMG_NORM_PIXEL(halfGaussB,texOffsets[2]); + gl_FragColor = vec4((sample0 + sample1 + sample2).rgba / (3.0)); + } + else if (PASSINDEX == 10) { + // this is the last pass- calculate the blurred image as i have in previous passes, then mix it in with the full-size input image using the blur amount so i get a smooth transition into the blur at low blur levels + vec4 sample0 = IMG_NORM_PIXEL(fullGaussA,texOffsets[0]); + vec4 sample1 = IMG_NORM_PIXEL(fullGaussA,texOffsets[1]); + vec4 sample2 = IMG_NORM_PIXEL(fullGaussA,texOffsets[2]); + vec4 blurredImg = vec4((sample0 + sample1 + sample2).rgba / (3.0)); + if (blurLevel == 0) + gl_FragColor = mix(IMG_NORM_PIXEL(inputImage,isf_FragNormCoord), blurredImg, (blurLevelModulus/6.0)); + else + gl_FragColor = blurredImg; + } + +} diff --git a/ISF/Multi Pass Gaussian Blur.vs b/ISF/Multi Pass Gaussian Blur.vs new file mode 100644 index 0000000..63e0815 --- /dev/null +++ b/ISF/Multi Pass Gaussian Blur.vs @@ -0,0 +1,94 @@ +varying vec2 texOffsets[5]; + +void main(void) { + // load the main shader stuff + isf_vertShaderInit(); + + + int blurLevel = int(floor(blurAmount/6.0)); + float blurLevelModulus = mod(blurAmount, 6.0); + float blurRadius = 0.0; + float blurRadiusInPixels = 0.0; + // first three passes are just drawing the texture- do nothing + + // the next six passes do gaussion blurs on the various levels + if (PASSINDEX==3 || PASSINDEX==5 || PASSINDEX==7 || PASSINDEX==9) { + float pixelWidth = 1.0/RENDERSIZE.x; + // pass 3 is eighth-size (blurLevel 3) + if (PASSINDEX==3) { + if (blurLevel==3) + blurRadius = blurLevelModulus/2.0; + else if (blurLevel>3) + blurRadius = 3.0; + } + // pass 5 is quarter-size (blurLevel 2) + else if (PASSINDEX==5) { + if (blurLevel==2) + blurRadius = blurLevelModulus/1.5; + else if (blurLevel>2) + blurRadius = 4.0; + } + // pass 7 is half-size (blurLevel 1) + else if (PASSINDEX==7) { + if (blurLevel==1) + blurRadius = blurLevelModulus; + else if (blurLevel>1) + blurRadius = 6.0; + } + // pass 9 is normal-size (blurLevel 0) + else if (PASSINDEX==9) { + if (blurLevel==0) + blurRadius = blurLevelModulus; + else if (blurLevel>0) + blurRadius = 6.0; + } + blurRadiusInPixels = pixelWidth * blurRadius; + texOffsets[0] = isf_FragNormCoord; + texOffsets[1] = (blurRadius==0.0) ? isf_FragNormCoord : clamp(vec2(isf_FragNormCoord[0]-blurRadiusInPixels, isf_FragNormCoord[1]),0.0,1.0); + texOffsets[2] = (blurRadius==0.0) ? isf_FragNormCoord : clamp(vec2(isf_FragNormCoord[0]+blurRadiusInPixels, isf_FragNormCoord[1]),0.0,1.0); + if (PASSINDEX==3) { + texOffsets[3] = (blurRadius==0.0) ? isf_FragNormCoord : clamp(vec2(isf_FragNormCoord[0]-(2.0*blurRadiusInPixels), isf_FragNormCoord[1]),0.0,1.0); + texOffsets[4] = (blurRadius==0.0) ? isf_FragNormCoord : clamp(vec2(isf_FragNormCoord[0]+(2.0*blurRadiusInPixels), isf_FragNormCoord[1]),0.0,1.0); + } + } + else if (PASSINDEX==4 || PASSINDEX==6 || PASSINDEX==8 || PASSINDEX==10) { + float pixelHeight = 1.0/RENDERSIZE.y; + // pass 4 is eighth-size (blurLevel 3) + if (PASSINDEX==4) { + if (blurLevel==3) + blurRadius = blurLevelModulus/2.0; + else if (blurLevel>3) + blurRadius = 3.0; + } + // pass 6 is quarter-size (blurLevel 2) + else if (PASSINDEX==6) { + if (blurLevel==2) + blurRadius = blurLevelModulus/1.5; + else if (blurLevel>2) + blurRadius = 4.0; + } + // pass 8 is half-size (blurLevel 1) + else if (PASSINDEX==8) { + if (blurLevel==1) + blurRadius = blurLevelModulus; + else if (blurLevel>1) + blurRadius = 6.0; + } + // pass 10 is normal-size (blurLevel 0) + else if (PASSINDEX==10) { + if (blurLevel==0) + blurRadius = blurLevelModulus; + else if (blurLevel>0) + blurRadius = 6.0; + } + blurRadiusInPixels = pixelHeight * blurRadius; + texOffsets[0] = isf_FragNormCoord; + texOffsets[1] = (blurRadius==0.0) ? isf_FragNormCoord : clamp(vec2(isf_FragNormCoord[0], isf_FragNormCoord[1]-blurRadiusInPixels),0.0,1.0); + texOffsets[2] = (blurRadius==0.0) ? isf_FragNormCoord : clamp(vec2(isf_FragNormCoord[0], isf_FragNormCoord[1]+blurRadiusInPixels),0.0,1.0); + if (PASSINDEX==4) { + texOffsets[3] = (blurRadius==0.0) ? isf_FragNormCoord : clamp(vec2(isf_FragNormCoord[0], isf_FragNormCoord[1]-(2.0*blurRadiusInPixels)),0.0,1.0); + texOffsets[4] = (blurRadius==0.0) ? isf_FragNormCoord : clamp(vec2(isf_FragNormCoord[0], isf_FragNormCoord[1]+(2.0*blurRadiusInPixels)),0.0,1.0); + } + } + +} diff --git a/ISF/Multi-Pixellate.fs b/ISF/Multi-Pixellate.fs new file mode 100644 index 0000000..81be8b5 --- /dev/null +++ b/ISF/Multi-Pixellate.fs @@ -0,0 +1,140 @@ +/* +{ + "CATEGORIES" : [ + "Stylize" + ], + "ISFVSN" : "2", + "INPUTS" : [ + { + "NAME" : "inputImage", + "TYPE" : "image" + }, + { + "NAME" : "cell_size", + "TYPE" : "float", + "MAX" : 0.5, + "DEFAULT" : 0.125, + "MIN" : 0.001 + }, + { + "NAME" : "min_cell_size", + "TYPE" : "float", + "MAX" : 0.5, + "DEFAULT" : 0.05000000074505806, + "MIN" : 0.001 + }, + { + "NAME" : "rSeed", + "TYPE" : "float", + "MAX" : 1, + "DEFAULT" : 0.25, + "MIN" : 0 + }, + { + "VALUES" : [ + 0, + 1 + ], + "NAME" : "shape", + "TYPE" : "long", + "DEFAULT" : 0, + "LABELS" : [ + "Square", + "Rectangle" + ] + }, + { + "VALUES" : [ + 0, + 2, + 3, + 5 + ], + "NAME" : "round_to_divisions", + "TYPE" : "long", + "DEFAULT" : 2, + "LABELS" : [ + "Off", + "2", + "3", + "5" + ] + } + ], + "CREDIT" : "by VIDVOX" +} +*/ + +#ifndef GL_ES +float distance (vec2 center, vec2 pt) +{ + float tmp = pow(center.x-pt.x,2.0)+pow(center.y-pt.y,2.0); + return pow(tmp,0.5); +} +#endif + +float rand(vec2 co){ + return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453); +} + +void main() +{ +// CALCULATE EDGES OF CURRENT CELL + // At 0.0 just do a pass-thru + if (cell_size == 0.0) { + gl_FragColor = IMG_THIS_PIXEL(inputImage); + } + else { + // Position of current pixel + vec2 xy; + xy.x = isf_FragNormCoord[0]; + xy.y = isf_FragNormCoord[1]; + + + // Left and right of tile + float max_cell_size = cell_size + min_cell_size; + float CellWidth = max_cell_size; + float CellHeight = max_cell_size; + if (shape==0) { + CellHeight = max_cell_size * RENDERSIZE.x / RENDERSIZE.y; + } + + float x1 = floor(xy.x / CellWidth)*CellWidth; + // Top and bottom of tile + float y1 = floor(xy.y / CellHeight)*CellHeight; + + float newCellSize = max_cell_size; + + if (round_to_divisions > 0) { + float maxCount = (min_cell_size > 0.0) ? max_cell_size / min_cell_size : 10.0; + float val = floor(1.0+(maxCount-1.0)*rand(0.1+rSeed+vec2(x1,y1))); + newCellSize = newCellSize / pow(float(round_to_divisions),val); + } + else { + newCellSize = min_cell_size + (cell_size - min_cell_size) * rand(0.1+rSeed+vec2(x1,y1)); + } + + CellWidth = newCellSize; + CellHeight = newCellSize; + if (shape==0) { + CellHeight = newCellSize * RENDERSIZE.x / RENDERSIZE.y; + } + + x1 = floor(xy.x / CellWidth)*CellWidth; + float x2 = clamp((ceil(xy.x / CellWidth)*CellWidth), 0.0, 1.0); + // Top and bottom of tile + y1 = floor(xy.y / CellHeight)*CellHeight; + float y2 = clamp((ceil(xy.y / CellHeight)*CellHeight), 0.0, 1.0); + + // GET AVERAGE CELL COLOUR + // Average left and right pixels + vec4 avgX = (IMG_NORM_PIXEL(inputImage, vec2(x1, y1))+(IMG_NORM_PIXEL(inputImage, vec2(x2, y1)))) / 2.0; + // Average top and bottom pixels + vec4 avgY = (IMG_NORM_PIXEL(inputImage, vec2(x1, y1))+(IMG_NORM_PIXEL(inputImage, vec2(x1, y2)))) / 2.0; + // Centre pixel + vec4 avgC = IMG_NORM_PIXEL(inputImage, vec2(x1+(CellWidth/2.0), y2+(CellHeight/2.0))); // Average the averages + centre + vec4 avgClr = (avgX+avgY+avgC) / 3.0; + + gl_FragColor = vec4(avgClr); + } +} diff --git a/ISF/MultiFrame 2x2.fs b/ISF/MultiFrame 2x2.fs new file mode 100644 index 0000000..fb847a8 --- /dev/null +++ b/ISF/MultiFrame 2x2.fs @@ -0,0 +1,145 @@ +/*{ + "DESCRIPTION": "buffers the last 3 frames and draws a 2x2 grid of the 4 current frames available", + "ISFVSN": "2", + "CREDIT": "by VIDVOX", + "CATEGORIES": [ + "Stylize" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "lag", + "TYPE": "bool", + "DEFAULT": 1.0 + }, + { + "NAME": "hueShift", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.0 + } + ], + "PASSES": [ + { + "TARGET":"buffer3", + "PERSISTENT": true, + "WIDTH": "$WIDTH/2.0", + "HEIGHT": "$HEIGHT/2.0" + }, + { + "TARGET":"buffer2", + "PERSISTENT": true, + "WIDTH": "$WIDTH/2.0", + "HEIGHT": "$HEIGHT/2.0" + }, + { + "TARGET":"buffer1", + "PERSISTENT": true, + "WIDTH": "$WIDTH/2.0", + "HEIGHT": "$HEIGHT/2.0" + }, + { + + } + ] + +}*/ + + + +vec3 rgb2hsv(vec3 c) { + vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); + //vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g)); + //vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r)); + vec4 p = c.g < c.b ? vec4(c.bg, K.wz) : vec4(c.gb, K.xy); + vec4 q = c.r < p.x ? vec4(p.xyw, c.r) : vec4(c.r, p.yzx); + + float d = q.x - min(q.w, q.y); + float e = 1.0e-10; + return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x); +} + +vec3 hsv2rgb(vec3 c) { + vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); + vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www); + return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y); +} + + + +void main() +{ + // first pass: read the "buffer2" into "buffer3" + // apply lag on each pass + if (PASSINDEX == 0) { + if ((lag == false)||(mod(floor(TIME*60.0+2.0),6.0)<=1.0)) { + gl_FragColor = IMG_THIS_NORM_PIXEL(buffer2); + } + else { + gl_FragColor = IMG_THIS_NORM_PIXEL(buffer3); + } + } + // first pass: read the "buffer1" into "buffer2" + else if (PASSINDEX == 1) { + if ((lag == false)||(mod(floor(TIME*60.0+2.0),6.0)<=1.0)) { + gl_FragColor = IMG_THIS_NORM_PIXEL(buffer1); + } + else { + gl_FragColor = IMG_THIS_NORM_PIXEL(buffer2); + } + } + // third pass: read from "inputImage" into "buffer1" + else if (PASSINDEX == 2) { + if ((lag == false)||(mod(floor(TIME*60.0+2.0),6.0)<=1.0)) { + gl_FragColor = IMG_THIS_NORM_PIXEL(inputImage); + } + else { + gl_FragColor = IMG_THIS_NORM_PIXEL(buffer1); + } + } + else if (PASSINDEX == 3) { + // Figure out which section I'm in and draw the appropriate buffer there + vec2 tex = isf_FragNormCoord; + vec4 color = vec4(0.0); + // TL – buffer1 + if ((tex.x < 0.5) && (tex.y > 0.5)) { + tex.x = tex.x * 2.0; + tex.y = (tex.y - 0.5) * 2.0; + color = IMG_NORM_PIXEL(inputImage, tex); + } + // TR – buffer2 + else if ((tex.x > 0.5) && (tex.y > 0.5)) { + tex.x = (tex.x - 0.5) * 2.0; + tex.y = (tex.y - 0.5) * 2.0; + + color = IMG_NORM_PIXEL(buffer1, tex); + color.rgb = rgb2hsv(color.rgb); + color.r = mod(color.r + hueShift, 1.0); + color.rgb = hsv2rgb(color.rgb); + } + // BR – buffer2 + else if ((tex.x < 0.5) && (tex.y < 0.5)) { + tex = tex * 2.0; + + color = IMG_NORM_PIXEL(buffer2, tex); + color.rgb = rgb2hsv(color.rgb); + color.r = mod(color.r + 2.0 * hueShift, 1.0); + color.rgb = hsv2rgb(color.rgb); + } + else { + tex.x = (tex.x - 0.5) * 2.0; + tex.y = tex.y * 2.0; + + color = IMG_NORM_PIXEL(buffer3, tex); + color.rgb = rgb2hsv(color.rgb); + color.r = mod(color.r + 3.0 * hueShift, 1.0); + color.rgb = hsv2rgb(color.rgb); + } + // BL - buffer3 + gl_FragColor = color; + } +} diff --git a/ISF/MultiFrame 3x3.fs b/ISF/MultiFrame 3x3.fs new file mode 100644 index 0000000..360b2c8 --- /dev/null +++ b/ISF/MultiFrame 3x3.fs @@ -0,0 +1,268 @@ +/*{ + "DESCRIPTION": "buffers the last 3 frames and draws a 2x2 grid of the 4 current frames available", + "ISFVSN": "2", + "CREDIT": "by VIDVOX", + "CATEGORIES": [ + "Stylize" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "lag", + "TYPE": "bool", + "DEFAULT": 1.0 + }, + { + "NAME": "hueShift", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.0 + } + ], + "PASSES": [ + { + "TARGET":"buffer8", + "PERSISTENT": true, + "WIDTH": "$WIDTH/3.0", + "HEIGHT": "$HEIGHT/3.0" + }, + { + "TARGET":"buffer7", + "PERSISTENT": true, + "WIDTH": "$WIDTH/3.0", + "HEIGHT": "$HEIGHT/3.0" + }, + { + "TARGET":"buffer6", + "PERSISTENT": true, + "WIDTH": "$WIDTH/3.0", + "HEIGHT": "$HEIGHT/3.0" + }, + { + "TARGET":"buffer5", + "PERSISTENT": true, + "WIDTH": "$WIDTH/3.0", + "HEIGHT": "$HEIGHT/3.0" + }, + { + "TARGET":"buffer4", + "PERSISTENT": true, + "WIDTH": "$WIDTH/3.0", + "HEIGHT": "$HEIGHT/3.0" + }, + { + "TARGET":"buffer3", + "PERSISTENT": true, + "WIDTH": "$WIDTH/3.0", + "HEIGHT": "$HEIGHT/3.0" + }, + { + "TARGET":"buffer2", + "PERSISTENT": true, + "WIDTH": "$WIDTH/3.0", + "HEIGHT": "$HEIGHT/3.0" + }, + { + "TARGET":"buffer1", + "PERSISTENT": true, + "WIDTH": "$WIDTH/3.0", + "HEIGHT": "$HEIGHT/3.0" + }, + { + + } + ] + +}*/ + + + +vec3 rgb2hsv(vec3 c) { + vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); + //vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g)); + //vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r)); + vec4 p = c.g < c.b ? vec4(c.bg, K.wz) : vec4(c.gb, K.xy); + vec4 q = c.r < p.x ? vec4(p.xyw, c.r) : vec4(c.r, p.yzx); + + float d = q.x - min(q.w, q.y); + float e = 1.0e-10; + return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x); +} + +vec3 hsv2rgb(vec3 c) { + vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); + vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www); + return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y); +} + + + +void main() +{ + // first pass: read the "buffer7" into "buffer8" + // apply lag on each pass + if (PASSINDEX == 0) { + if ((lag == false)||(mod(floor(TIME*60.0+5.0),6.0)<=1.0)) { + gl_FragColor = IMG_THIS_NORM_PIXEL(buffer7); + } + else { + gl_FragColor = IMG_THIS_NORM_PIXEL(buffer8); + } + } + else if (PASSINDEX == 1) { + if ((lag == false)||(mod(floor(TIME*60.0+3.0),6.0)<=1.0)) { + gl_FragColor = IMG_THIS_NORM_PIXEL(buffer6); + } + else { + gl_FragColor = IMG_THIS_NORM_PIXEL(buffer7); + } + } + else if (PASSINDEX == 2) { + if ((lag == false)||(mod(floor(TIME*60.0+2.0),6.0)<=1.0)) { + gl_FragColor = IMG_THIS_NORM_PIXEL(buffer5); + } + else { + gl_FragColor = IMG_THIS_NORM_PIXEL(buffer6); + } + } + else if (PASSINDEX == 3) { + if ((lag == false)||(mod(floor(TIME*60.0+5.0),6.0)<=1.0)) { + gl_FragColor = IMG_THIS_NORM_PIXEL(buffer4); + } + else { + gl_FragColor = IMG_THIS_NORM_PIXEL(buffer5); + } + } + else if (PASSINDEX == 4) { + if ((lag == false)||(mod(floor(TIME*60.0+1.0),6.0)<=1.0)) { + gl_FragColor = IMG_THIS_NORM_PIXEL(buffer3); + } + else { + gl_FragColor = IMG_THIS_NORM_PIXEL(buffer4); + } + } + else if (PASSINDEX == 5) { + if ((lag == false)||(mod(floor(TIME*60.0+3.0),6.0)<=1.0)) { + gl_FragColor = IMG_THIS_NORM_PIXEL(buffer2); + } + else { + gl_FragColor = IMG_THIS_NORM_PIXEL(buffer3); + } + } + else if (PASSINDEX == 6) { + if ((lag == false)||(mod(floor(TIME*60.0+5.0),6.0)<=1.0)) { + gl_FragColor = IMG_THIS_NORM_PIXEL(buffer1); + } + else { + gl_FragColor = IMG_THIS_NORM_PIXEL(buffer2); + } + } + else if (PASSINDEX == 7) { + if ((lag == false)||(mod(floor(TIME*60.0+3.0),6.0)<=1.0)) { + gl_FragColor = IMG_THIS_NORM_PIXEL(inputImage); + } + else { + gl_FragColor = IMG_THIS_NORM_PIXEL(buffer1); + } + } + else if (PASSINDEX == 8) { + // Figure out which section I'm in and draw the appropriate buffer there + vec2 tex = isf_FragNormCoord; + vec4 color = vec4(0.0); + // TL – input + if (tex.y > 0.667) { + if (tex.x < 0.333) { + tex.x = tex.x * 3.0; + tex.y = (tex.y - 0.667) * 3.0; + color = IMG_NORM_PIXEL(inputImage, tex); + } + // TM – buffer1 + else if ((tex.x > 0.333) && (tex.x < 0.667)) { + tex.x = (tex.x - 0.333) * 3.0; + tex.y = (tex.y - 0.667) * 3.0; + + color = IMG_NORM_PIXEL(buffer1, tex); + color.rgb = rgb2hsv(color.rgb); + color.r = mod(color.r + 1.0 * hueShift, 1.0); + color.rgb = hsv2rgb(color.rgb); + } + // TL – buffer2 + else { + tex.x = (tex.x - 0.667) * 3.0; + tex.y = (tex.y - 0.667) * 3.0; + + color = IMG_NORM_PIXEL(buffer2, tex); + color.rgb = rgb2hsv(color.rgb); + color.r = mod(color.r + 2.0 * hueShift, 1.0); + color.rgb = hsv2rgb(color.rgb); + } + } + // BL - buffer3 + else if (tex.y > 0.333) { + if (tex.x < 0.333) { + tex.x = tex.x * 3.0; + tex.y = (tex.y - 0.333) * 3.0; + color = IMG_NORM_PIXEL(buffer3, tex); + color.rgb = rgb2hsv(color.rgb); + color.r = mod(color.r + 3.0 * hueShift, 1.0); + color.rgb = hsv2rgb(color.rgb); + } + // TM – buffer1 + else if ((tex.x > 0.333) && (tex.x < 0.667)) { + tex.x = (tex.x - 0.333) * 3.0; + tex.y = (tex.y - 0.333) * 3.0; + + color = IMG_NORM_PIXEL(buffer4, tex); + color.rgb = rgb2hsv(color.rgb); + color.r = mod(color.r + 4.0 * hueShift, 1.0); + color.rgb = hsv2rgb(color.rgb); + } + // TL – buffer2 + else { + tex.x = (tex.x - 0.667) * 3.0; + tex.y = (tex.y - 0.333) * 3.0; + + color = IMG_NORM_PIXEL(buffer5, tex); + color.rgb = rgb2hsv(color.rgb); + color.r = mod(color.r + 5.0 * hueShift, 1.0); + color.rgb = hsv2rgb(color.rgb); + } + } + else { + if (tex.x < 0.333) { + tex.x = tex.x * 3.0; + tex.y = tex.y * 3.0; + color = IMG_NORM_PIXEL(buffer6, tex); + color.rgb = rgb2hsv(color.rgb); + color.r = mod(color.r + 6.0 * hueShift, 1.0); + color.rgb = hsv2rgb(color.rgb); + } + // TM – buffer1 + else if ((tex.x > 0.333) && (tex.x < 0.667)) { + tex.x = (tex.x - 0.333) * 3.0; + tex.y = tex.y * 3.0; + + color = IMG_NORM_PIXEL(buffer7, tex); + color.rgb = rgb2hsv(color.rgb); + color.r = mod(color.r + 7.0 * hueShift, 1.0); + color.rgb = hsv2rgb(color.rgb); + } + // TL – buffer2 + else { + tex.x = (tex.x - 0.667) * 3.0; + tex.y = tex.y * 3.0; + + color = IMG_NORM_PIXEL(buffer8, tex); + color.rgb = rgb2hsv(color.rgb); + color.r = mod(color.r + 8.0 * hueShift, 1.0); + color.rgb = hsv2rgb(color.rgb); + } + } + + gl_FragColor = color; + } +} diff --git a/ISF/Neon.fs b/ISF/Neon.fs new file mode 100644 index 0000000..63e40f6 --- /dev/null +++ b/ISF/Neon.fs @@ -0,0 +1,124 @@ +/*{ + "DESCRIPTION": "", + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "DESCRIPTION": "adapted from https://github.com/neilmendoza/ofxPostProcessing/blob/master/src/GodRaysPass.cpp", + "CATEGORIES": [ + "Stylize" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "intensity", + "TYPE": "float", + "MIN": 0.0, + "MAX": 10.0, + "DEFAULT": 5.0 + }, + { + "NAME": "gain", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 1.0 + }, + { + "NAME": "neonColor", + "TYPE": "color", + "DEFAULT": [ + 1.0, + 0.4, + 0.64, + 1.0 + ] + } + ] +}*/ + + +varying vec2 left_coord; +varying vec2 right_coord; +varying vec2 above_coord; +varying vec2 below_coord; + +varying vec2 lefta_coord; +varying vec2 righta_coord; +varying vec2 leftb_coord; +varying vec2 rightb_coord; + + +float gray(vec4 n) +{ + return (n.r + n.g + n.b)/3.0; +} + + +void main(void) +{ + + // edges // rays // color + vec4 color = IMG_THIS_PIXEL(inputImage); + vec4 colorL = IMG_NORM_PIXEL(inputImage, left_coord); + vec4 colorR = IMG_NORM_PIXEL(inputImage, right_coord); + vec4 colorA = IMG_NORM_PIXEL(inputImage, above_coord); + vec4 colorB = IMG_NORM_PIXEL(inputImage, below_coord); + + vec4 colorLA = IMG_NORM_PIXEL(inputImage, lefta_coord); + vec4 colorRA = IMG_NORM_PIXEL(inputImage, righta_coord); + vec4 colorLB = IMG_NORM_PIXEL(inputImage, leftb_coord); + vec4 colorRB = IMG_NORM_PIXEL(inputImage, rightb_coord); + + float gx = (0.0); + float gy = (0.0); + gx = (-1.0 * gray(colorLA)) + (-1.0 * gray(colorL)) + (-1.0 * gray(colorLB)) + (1.0 * gray(colorRA)) + (1.0 * gray(colorR)) + (1.0 * gray(colorRB)); + gy = (1.0 * gray(colorLA)) + (1.0 * gray(colorA)) + (1.0 * gray(colorRA)) + (-1.0 * gray(colorRB)) + (-1.0 * gray(colorB)) + (-1.0 * gray(colorLB)); + + + + float bright = pow(gx*gx + gy*gy,0.5); + vec4 final = color * bright; + + // if the brightness is below the threshold draw black + if (bright < 0.01) { + final = vec4(0.0); + } + else { + final = final * intensity; + } + + gl_FragColor = final; + + vec4 origColor = final; + vec4 raysColor = color; + int NUM_SAMPLES = 30; + + float exposure = 0.1/float(NUM_SAMPLES); + float decay = 1.0 ; + float density = 0.5; + float weight = 6.0; + float illuminationDecay = 1.0; + vec2 normSrcCoord; + + normSrcCoord.x = isf_FragNormCoord[0]; + normSrcCoord.y = isf_FragNormCoord[1]; + + vec2 deltaTextCoord = vec2(normSrcCoord.st - 0.5); + vec2 textCoo = normSrcCoord; + deltaTextCoord *= 1.0 / float(NUM_SAMPLES) * density; + + for(int i=0; i < NUM_SAMPLES ; i++) { + textCoo -= deltaTextCoord; + vec4 tsample = IMG_NORM_PIXEL(inputImage, textCoo); + tsample *= illuminationDecay * weight; + raysColor += tsample; + illuminationDecay *= decay; + } + raysColor *= exposure * gain; + float p = 0.3 *raysColor.g + 0.59*raysColor.r + 0.11*raysColor.b; + + gl_FragColor = gray(origColor + p) * neonColor; + +} \ No newline at end of file diff --git a/ISF/Neon.vs b/ISF/Neon.vs new file mode 100644 index 0000000..baa2875 --- /dev/null +++ b/ISF/Neon.vs @@ -0,0 +1,28 @@ +varying vec2 left_coord; +varying vec2 right_coord; +varying vec2 above_coord; +varying vec2 below_coord; + +varying vec2 lefta_coord; +varying vec2 righta_coord; +varying vec2 leftb_coord; +varying vec2 rightb_coord; + + +void main() +{ + isf_vertShaderInit(); + vec2 texc = vec2(isf_FragNormCoord[0],isf_FragNormCoord[1]); + vec2 d = 1.0/RENDERSIZE; + + left_coord = clamp(vec2(texc.xy + vec2(-d.x , 0)),0.0,1.0); + right_coord = clamp(vec2(texc.xy + vec2(d.x , 0)),0.0,1.0); + above_coord = clamp(vec2(texc.xy + vec2(0,d.y)),0.0,1.0); + below_coord = clamp(vec2(texc.xy + vec2(0,-d.y)),0.0,1.0); + + d = 1.0/RENDERSIZE; + lefta_coord = clamp(vec2(texc.xy + vec2(-d.x , d.x)),0.0,1.0); + righta_coord = clamp(vec2(texc.xy + vec2(d.x , d.x)),0.0,1.0); + leftb_coord = clamp(vec2(texc.xy + vec2(-d.x , -d.x)),0.0,1.0); + rightb_coord = clamp(vec2(texc.xy + vec2(d.x , -d.x)),0.0,1.0); +} \ No newline at end of file diff --git a/ISF/Night Vision.fs b/ISF/Night Vision.fs new file mode 100644 index 0000000..826cd23 --- /dev/null +++ b/ISF/Night Vision.fs @@ -0,0 +1,78 @@ +/*{ + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Stylize" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "luminanceThreshold", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.2 + }, + { + "NAME": "colorAmplification", + "TYPE": "float", + "MIN": 0.0, + "MAX": 10.0, + "DEFAULT": 4.0 + }, + { + "NAME": "noiseLevel", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.1 + }, + { + "NAME": "visionColor", + "TYPE": "color", + "DEFAULT": [ + 0.1, + 0.95, + 0.2, + 1.0 + ] + } + ], + "IMPORTED": { + "noiseTex": { + "PATH": "noise2d.png" + } + } +}*/ + + + +void main () { + vec2 normSrcCoord; + + normSrcCoord.x = isf_FragNormCoord[0]; + normSrcCoord.y = isf_FragNormCoord[1]; + + vec4 finalColor; + + // Set effectCoverage to 1.0 for normal use. + + vec2 uv; + uv.x = 0.4*sin(TIME*50.0); + uv.y = 0.4*cos(TIME*50.0); + vec3 n = IMG_NORM_PIXEL(noiseTex,mod(normSrcCoord.xy*3.5 + uv,1.0)).rgb; + vec3 c = IMG_THIS_PIXEL(inputImage).rgb + n.rgb * noiseLevel; + + const vec4 lumacoeff = vec4(0.2126, 0.7152, 0.0722, 0.0); + float lum = dot(vec4(c,1.), lumacoeff); + if (lum < luminanceThreshold) { + c *= colorAmplification; + } + finalColor.rgb = (c + (n*0.2)) * visionColor.rgb; + + gl_FragColor.rgb = finalColor.rgb; + gl_FragColor.a = 1.0; +} \ No newline at end of file diff --git a/ISF/Noise Adapt.fs b/ISF/Noise Adapt.fs new file mode 100644 index 0000000..026115d --- /dev/null +++ b/ISF/Noise Adapt.fs @@ -0,0 +1,100 @@ +/* +{ + "CATEGORIES" : [ + "Glitch" + ], + "DESCRIPTION" : "Pixels that change become noise until they match the input again", + "ISFVSN" : "2", + "INPUTS" : [ + { + "NAME" : "inputImage", + "TYPE" : "image" + }, + { + "NAME" : "adaptRate", + "TYPE" : "float", + "MAX" : 1, + "DEFAULT" : 0.5, + "MIN" : 0 + }, + { + "NAME" : "threshold", + "TYPE" : "float", + "MAX" : 1, + "DEFAULT" : 0.05, + "MIN" : 0 + }, + { + "NAME" : "useRGBA", + "TYPE" : "bool", + "DEFAULT" : 1 + } + ], + "PASSES" : [ + { + "TARGET" : "adaptiveBuffer1", + "PERSISTENT" : true + }, + { + + } + ], + "CREDIT" : "by VIDVOX" +} +*/ + + +float minThresh = 3.0/255.0; + + +float rand(vec2 co){ + return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453); +} +float steppedRand(vec2 co){ + return floor(256.0*rand(co))/255.0; +} +vec4 randColor(vec2 co){ + vec4 c = vec4(0.0); + c.r = steppedRand(co+0.234); + c.g = steppedRand(co+0.193); + c.b = steppedRand(co+0.625); + c.a = 1.0; + return c; +} + +float luma(vec4 c) { + return c.a*(c.r+c.g+c.b)/3.0; +} + + +void main() +{ + + vec4 freshPixel = IMG_PIXEL(inputImage,gl_FragCoord.xy); + vec4 stalePixel = IMG_PIXEL(adaptiveBuffer1,gl_FragCoord.xy); + if (useRGBA == false) { + float freshLuma = luma(freshPixel); + float staleLuma = luma(stalePixel); + float thresh = (threshold < minThresh) ? minThresh : threshold; + if (abs(freshLuma-staleLuma)>=thresh) { + stalePixel = randColor(gl_FragCoord.xy+TIME); + } + } + else { + float thresh = (threshold < minThresh) ? minThresh : threshold; + if (abs(freshPixel.r-stalePixel.r)>=thresh) { + stalePixel.r = steppedRand(gl_FragCoord.xy+TIME+1.234); + } + if (abs(freshPixel.g-stalePixel.g)>=thresh) { + stalePixel.g = steppedRand(gl_FragCoord.xy+TIME+2.193); + } + if (abs(freshPixel.b-stalePixel.b)>=thresh) { + stalePixel.b = steppedRand(gl_FragCoord.xy+TIME+3.625); + } + if (abs(freshPixel.a-stalePixel.a)>=thresh) { + stalePixel.a = steppedRand(gl_FragCoord.xy+TIME+4.479); + } + } + gl_FragColor = mix(stalePixel,freshPixel,adaptRate); + +} diff --git a/ISF/Noise Displace.fs b/ISF/Noise Displace.fs new file mode 100644 index 0000000..868b808 --- /dev/null +++ b/ISF/Noise Displace.fs @@ -0,0 +1,77 @@ +/* +{ + "CATEGORIES" : [ + "Distortion Effect" + ], + "DESCRIPTION" : "Displaces image randomly", + "ISFVSN" : "2", + "INPUTS" : [ + { + "NAME" : "inputImage", + "TYPE" : "image" + }, + { + "NAME" : "displaceX", + "TYPE" : "float", + "MAX" : 0.1, + "DEFAULT" : 0.0, + "MIN" : 0.0, + "LABEL" : "Displace X" + }, + { + "NAME" : "displaceY", + "TYPE" : "float", + "MAX" : 0.1, + "DEFAULT" : 0.0, + "MIN" : 0.0, + "LABEL" : "Displace Y" + }, + { + "NAME" : "detailX", + "TYPE" : "float", + "MAX" : 1.0, + "DEFAULT" : 0.1, + "MIN" : 0.0, + "LABEL" : "Detail X" + }, + { + "NAME" : "detailY", + "TYPE" : "float", + "MAX" : 1.0, + "DEFAULT" : 0.1, + "MIN" : 0.0, + "LABEL" : "Detail Y" + }, + { + "NAME" : "updateTime", + "TYPE" : "float", + "MAX" : 0.1, + "DEFAULT" : 0.01, + "MIN" : 0.0, + "LABEL" : "Frequency" + } + ], + "CREDIT" : "VIDVOX" +} +*/ + + +float rand(vec2 co){ + return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453); +} + +void main() { + + vec4 inputPixelColor; + vec2 uv = isf_FragNormCoord.xy; + float wobbleTime = (updateTime == 0.0) ? TIME : floor(TIME/updateTime); + vec2 waveLoc = fract((uv)*vec2(detailX, detailY)); + float val1 = rand(vec2(waveLoc.x, wobbleTime)); + float val2 = rand(vec2(waveLoc.y, wobbleTime+1.0)); + vec2 wave = vec2(val1, val2)-0.5; + wave *= vec2(displaceY, displaceX); + + inputPixelColor = IMG_NORM_PIXEL(inputImage, uv + wave.yx); + + gl_FragColor = inputPixelColor; +} diff --git a/ISF/Noise Pixellate.fs b/ISF/Noise Pixellate.fs new file mode 100644 index 0000000..2b39dc3 --- /dev/null +++ b/ISF/Noise Pixellate.fs @@ -0,0 +1,120 @@ + +/*{ + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Stylize" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "cell_size", + "TYPE": "float", + "MIN": 0.001, + "MAX": 0.5, + "DEFAULT": 0.025 + }, + { + "NAME": "sigGain", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.0 + }, + { + "NAME": "mode", + "VALUES": [ + 0, + 1 + ], + "LABELS": [ + "Multiply", + "Threshold" + ], + "DEFAULT": 1, + "TYPE": "long" + }, + { + "NAME": "shape", + "VALUES": [ + 0, + 1 + ], + "LABELS": [ + "Square", + "Rectangle" + ], + "DEFAULT": 0, + "TYPE": "long" + } + ] +}*/ + +#ifndef GL_ES +float distance (vec2 center, vec2 pt) +{ + float tmp = pow(center.x-pt.x,2.0)+pow(center.y-pt.y,2.0); + return pow(tmp,0.5); +} +#endif + +float rand(vec2 co){ + return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453); +} + +void main() +{ +// CALCULATE EDGES OF CURRENT CELL + // At 0.0 just do a pass-thru + if (cell_size == 0.0) { + gl_FragColor = IMG_THIS_PIXEL(inputImage); + } + else { + // Position of current pixel + vec2 xy; + xy.x = isf_FragNormCoord[0]; + xy.y = isf_FragNormCoord[1]; + + + // Left and right of tile + float CellWidth = cell_size; + float CellHeight = cell_size; + if (shape==0) { + CellHeight = cell_size * RENDERSIZE.x / RENDERSIZE.y; + } + + float x1 = floor(xy.x / CellWidth)*CellWidth; + float x2 = clamp((ceil(xy.x / CellWidth)*CellWidth), 0.0, 1.0); + // Top and bottom of tile + float y1 = floor(xy.y / CellHeight)*CellHeight; + float y2 = clamp((ceil(xy.y / CellHeight)*CellHeight), 0.0, 1.0); + + // GET AVERAGE CELL COLOUR + // Average left and right pixels + vec4 original = IMG_THIS_PIXEL(inputImage); + vec4 avgX = (IMG_NORM_PIXEL(inputImage, vec2(x1, y1))+(IMG_NORM_PIXEL(inputImage, vec2(x2, y1)))) / 2.0; + // Average top and bottom pixels + vec4 avgY = (IMG_NORM_PIXEL(inputImage, vec2(x1, y1))+(IMG_NORM_PIXEL(inputImage, vec2(x1, y2)))) / 2.0; + // Centre pixel + vec4 avgC = IMG_NORM_PIXEL(inputImage, vec2(x1+(CellWidth/2.0), y2+(CellHeight/2.0))); // Average the averages + centre + vec4 avgClr = (avgX+avgY+avgC) / 3.0; + avgClr.a = original.a; + + float thresh = (avgClr.r + avgClr.g + avgClr.b) * avgClr.a / 3.0; + + if (mode == 0) { + float rVal = (1.0 + sigGain) * rand(xy + thresh); + rVal = (rVal > 1.0) ? 1.0 : rVal; + avgClr.rgb *= rVal; + } + else if (mode == 1) { + float rVal = rand(xy + thresh) / (1.0 + sigGain); + rVal = (rVal > 1.0) ? 1.0 : rVal; + avgClr = (thresh > rVal) ? avgClr : vec4(0.0,0.0,0.0,original.a); + } + gl_FragColor = avgClr; + } +} diff --git a/ISF/Noise.fs b/ISF/Noise.fs new file mode 100644 index 0000000..7fa631c --- /dev/null +++ b/ISF/Noise.fs @@ -0,0 +1,172 @@ + +/*{ + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Generator" + ], + "INPUTS": [ + { + "NAME": "seed", + "LABEL": "Random Seed", + "TYPE": "float", + "MIN": 0.01, + "MAX": 1.0, + "DEFAULT": 0.5 + }, + { + "NAME": "cell_size", + "LABEL": "Cell Size", + "TYPE": "float", + "MIN": 0.0, + "MAX": 0.5, + "DEFAULT": 0.125 + }, + { + "NAME": "threshold", + "LABEL": "Threshold", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.0 + }, + { + "NAME": "use_time", + "LABEL": "Animated", + "TYPE": "bool", + "DEFAULT": 1.0 + }, + { + "NAME": "color_mode", + "LABEL": "Color Mode", + "TYPE": "long", + "VALUES": [ + 0, + 1, + 2, + 3 + ], + "LABELS": [ + "B&W", + "Alpha", + "RGB", + "RGBA" + ], + "DEFAULT": 2 + } + ] +}*/ + +float rand(vec2 co){ + return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453); +} + +void main() +{ +// CALCULATE EDGES OF CURRENT CELL + float tmpSeed = seed; + if (use_time) { + tmpSeed = max(mod(tmpSeed * TIME,1.0),0.01); + } + + // if the size is 0.0 do this for every pixel + if (cell_size == 0.0) { + vec4 outColor = vec4(0.0); + float translated = RENDERSIZE.x * isf_FragNormCoord[0] + isf_FragNormCoord[1]; + float val = rand(vec2(translated, tmpSeed)); + if (val >= threshold) { + // b&w + if (color_mode == 0) { + outColor = vec4(1.0); + } + // grayscale, use the alpha + else if (color_mode == 1) { + outColor = vec4(1.0, 1.0, 1.0, val); + } + // RGB + else if (color_mode == 2) { + float rRand = rand(vec2(translated + 0.1542, tmpSeed)); + float gRand = rand(vec2(translated + 0.0835, tmpSeed)); + float bRand = rand(vec2(translated + 0.2547, tmpSeed)); + outColor = vec4(rRand, gRand, bRand, 1.0); + } + // RGBA + else if (color_mode == 3) { + float rRand = rand(vec2(translated + 0.1542, tmpSeed)); + float gRand = rand(vec2(translated + 0.0835, tmpSeed)); + float bRand = rand(vec2(translated + 0.2547, tmpSeed)); + outColor = vec4(rRand, gRand, bRand, val); + } + } + gl_FragColor = outColor; + } + else { + // Position of current pixel + vec2 xy; + xy.x = isf_FragNormCoord[0]; + xy.y = isf_FragNormCoord[1]; + + + // Left and right of tile + float CellWidth = cell_size; + float CellHeight = cell_size; + + + // divide 1 by the cell width and cell height to determine the count + float rows = floor(1.0/CellHeight); + float cols = floor(1.0/CellWidth); + float count = floor(rows * cols); + + // figure out the ID # of the region + float region = cols*floor(xy.x / CellWidth) + floor(xy.y / CellHeight); + + // use this to draw the gradient of the regions as gray colors.. + //gl_FragColor = vec4(vec3(region/count),1.0); + + // now translate this region to another random region using our seed and region + float translated = clamp(rand(vec2(region/count, tmpSeed)),0.0,1.0); + //translated = region/count; + //gl_FragColor = vec4(vec3(translated),1.0); + + // quantize the translated! + translated = floor(count * translated); + //gl_FragColor = vec4(vec3(translated),1.0); + // now convert the translated region back to an xy location + // get the relative position within the original block and then add on the translated amount + xy.x = (xy.x - floor(xy.x / CellWidth)*CellWidth) + CellWidth * floor(translated / rows); + //xy.x = (xy.x - floor(xy.x / CellWidth)*CellWidth); + xy.y = xy.y - floor(xy.y / CellHeight)*CellHeight + CellHeight * floor(mod(translated , cols)); + + float val = rand(vec2(translated, tmpSeed)); + + vec4 outColor = vec4(0.0); + + if (val >= threshold) { + // b&w + if (color_mode == 0) { + outColor = vec4(1.0); + } + // grayscale, use the alpha + else if (color_mode == 1) { + outColor = vec4(1.0, 1.0, 1.0, val); + } + // RGB + else if (color_mode == 2) { + float rRand = rand(vec2(translated + 0.1542, tmpSeed)); + float gRand = rand(vec2(translated + 0.0835, tmpSeed)); + float bRand = rand(vec2(translated + 0.2547, tmpSeed)); + outColor = vec4(rRand, gRand, bRand, 1.0); + } + // RGBA + else if (color_mode == 3) { + float rRand = rand(vec2(translated + 0.1542, tmpSeed)); + float gRand = rand(vec2(translated + 0.0835, tmpSeed)); + float bRand = rand(vec2(translated + 0.2547, tmpSeed)); + outColor = vec4(rRand, gRand, bRand, val); + } + } + + gl_FragColor = outColor; + + } +} \ No newline at end of file diff --git a/ISF/Optical Flow Distort.fs b/ISF/Optical Flow Distort.fs new file mode 100644 index 0000000..28ebba4 --- /dev/null +++ b/ISF/Optical Flow Distort.fs @@ -0,0 +1,182 @@ +/*{ + "DESCRIPTION": "Uses an optical flow mask to create a distortion", + "CREDIT": "by VIDVOX, based on original implementation by Andrew Benson and v002", + "ISFVSN": "2", + "CATEGORIES": [ + "Distortion Effect" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "amt", + "LABEL": "Distortion Amount", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.5 + }, + { + "NAME": "maskHold", + "LABEL": "Flow Persistence", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.98 + }, + { + "NAME": "inputScale", + "LABEL": "Scale", + "TYPE": "float", + "MIN": 0.0, + "MAX": 10.0, + "DEFAULT": 2.0 + }, + { + "NAME": "inputOffset", + "LABEL": "Offset", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.1 + }, + { + "NAME": "inputLambda", + "LABEL": "Noise Removal", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 1.0 + } + ], + "PASSES": [ + { + "TARGET":"maskBuffer", + "PERSISTENT": true + }, + { + "TARGET":"delayBuffer", + "PERSISTENT": true + }, + { + + } + ] + +}*/ + + +varying vec2 left_coord; +varying vec2 right_coord; +varying vec2 above_coord; +varying vec2 below_coord; + +varying vec2 lefta_coord; +varying vec2 righta_coord; +varying vec2 leftb_coord; +varying vec2 rightb_coord; + + +// based on v002 Optical Flow which is itself a port of Andrew Bensons HS Flow implementation on the GPU. +// https://github.com/v002/v002-Optical-Flow + + +const vec4 coeffs = vec4(0.2126, 0.7152, 0.0722, 1.0); + +float gray(vec4 n) +{ + return (n.r + n.g + n.b)/3.0; +} + +void main() +{ + // on the first pass generate the mask using the previous delayBuffer and inputImage + // on the 2nd pass update the delayBuffer to hold inputImage + // on the 3rd pass output the new mask + if (PASSINDEX == 0) { + // convert to grayscale + vec4 a = IMG_THIS_PIXEL(inputImage) * coeffs; + float brightness = gray(a); + a = vec4(brightness); + vec4 b = IMG_THIS_PIXEL(delayBuffer) * coeffs; + brightness = gray(b); + b = vec4(brightness); + + vec2 x1 = vec2(inputOffset * RENDERSIZE.x, 0.0); + vec2 y1 = vec2(0.0,inputOffset * RENDERSIZE.y); + vec2 texcoord0 = isf_FragNormCoord.xy * RENDERSIZE; + vec2 texcoord1 = isf_FragNormCoord.xy * RENDERSIZE; + + //get the difference + vec4 curdif = b-a; + + //calculate the gradient + vec4 gradx = IMG_PIXEL(delayBuffer, texcoord1+x1)-IMG_PIXEL(delayBuffer, texcoord1-x1); + gradx += IMG_PIXEL(inputImage, texcoord0+x1)-IMG_PIXEL(inputImage, texcoord0-x1); + + vec4 grady = IMG_PIXEL(delayBuffer, texcoord1+y1)-IMG_PIXEL(delayBuffer, texcoord1-y1); + grady += IMG_PIXEL(inputImage, texcoord0+y1)-IMG_PIXEL(inputImage, texcoord0-y1); + + vec4 gradmag = sqrt((gradx*gradx)+(grady*grady)+vec4(inputLambda)); + + vec4 vx = curdif*(gradx/gradmag); + float vxd = gray(vx);//assumes greyscale + //format output for flowrepos, out(-x,+x,-y,+y) + vec2 xout = vec2(max(vxd,0.),abs(min(vxd,0.)))*inputScale; + + vec4 vy = curdif*(grady/gradmag); + float vyd = gray(vy);//assumes greyscale + //format output for flowrepos, out(-x,+x,-y,+y) + vec2 yout = vec2(max(vyd,0.),abs(min(vyd,0.)))*inputScale; + + //gl_FragColor = clamp(vec4(xout.xy,yout.xy), 0.0, 1.0); + + vec4 mask = clamp(vec4(xout.xy,yout.xy), 0.0, 1.0); + + vec4 color = IMG_THIS_NORM_PIXEL(maskBuffer); + vec4 colorL = IMG_NORM_PIXEL(maskBuffer, left_coord); + vec4 colorR = IMG_NORM_PIXEL(maskBuffer, right_coord); + vec4 colorA = IMG_NORM_PIXEL(maskBuffer, above_coord); + vec4 colorB = IMG_NORM_PIXEL(maskBuffer, below_coord); + + vec4 colorLA = IMG_NORM_PIXEL(maskBuffer, lefta_coord); + vec4 colorRA = IMG_NORM_PIXEL(maskBuffer, righta_coord); + vec4 colorLB = IMG_NORM_PIXEL(maskBuffer, leftb_coord); + vec4 colorRB = IMG_NORM_PIXEL(maskBuffer, rightb_coord); + + // blur then sharpen the feedback buffer + vec4 blurVector = (color + colorL + colorR + colorA + colorB + colorLA + colorRA + colorLB + colorRB) / 9.0; + gl_FragColor = mask + maskHold * blurVector; + } + else if (PASSINDEX == 1) { + // here we just buffer the current frame for next time + gl_FragColor = IMG_THIS_PIXEL(inputImage); + } + else { + // NOW DO SOMETHING WITH THE MASK - BLUR THE IMAGE AND THE MASK IMAGE + + // blur the mask image + vec2 texcoord0 = isf_FragNormCoord.xy; + + vec4 color = IMG_THIS_NORM_PIXEL(maskBuffer); + vec4 colorL = IMG_NORM_PIXEL(maskBuffer, left_coord); + vec4 colorR = IMG_NORM_PIXEL(maskBuffer, right_coord); + vec4 colorA = IMG_NORM_PIXEL(maskBuffer, above_coord); + vec4 colorB = IMG_NORM_PIXEL(maskBuffer, below_coord); + + vec4 colorLA = IMG_NORM_PIXEL(maskBuffer, lefta_coord); + vec4 colorRA = IMG_NORM_PIXEL(maskBuffer, righta_coord); + vec4 colorLB = IMG_NORM_PIXEL(maskBuffer, leftb_coord); + vec4 colorRB = IMG_NORM_PIXEL(maskBuffer, rightb_coord); + + vec4 blurVector = (color + colorL + colorR + colorA + colorB + colorLA + colorRA + colorLB + colorRB) / 9.0; + //vec4 blurVector = IMG_THIS_PIXEL(maskBuffer); + + vec2 blurAmount = vec2(blurVector.y-blurVector.x, blurVector.w-blurVector.z); + vec4 sample0 = IMG_NORM_PIXEL(inputImage, clamp(texcoord0 + blurAmount * amt,0.0,1.0)); + vec4 sample1 = IMG_NORM_PIXEL(inputImage, clamp(texcoord0 + 1.02 * blurAmount * amt * amt,0.0,1.0)); + gl_FragColor = (sample0 * 3.0 + sample1) / 4.0; + } +} diff --git a/ISF/Optical Flow Distort.vs b/ISF/Optical Flow Distort.vs new file mode 100644 index 0000000..84fb87d --- /dev/null +++ b/ISF/Optical Flow Distort.vs @@ -0,0 +1,27 @@ +varying vec2 left_coord; +varying vec2 right_coord; +varying vec2 above_coord; +varying vec2 below_coord; + +varying vec2 lefta_coord; +varying vec2 righta_coord; +varying vec2 leftb_coord; +varying vec2 rightb_coord; + + +void main() +{ + isf_vertShaderInit(); + vec2 texc = vec2(isf_FragNormCoord[0],isf_FragNormCoord[1]); + vec2 d = 4.0/RENDERSIZE; + + left_coord = clamp(vec2(texc.xy + vec2(-d.x , 0)),0.0,1.0); + right_coord = clamp(vec2(texc.xy + vec2(d.x , 0)),0.0,1.0); + above_coord = clamp(vec2(texc.xy + vec2(0,d.y)),0.0,1.0); + below_coord = clamp(vec2(texc.xy + vec2(0,-d.y)),0.0,1.0); + + lefta_coord = clamp(vec2(texc.xy + vec2(-d.x , d.x)),0.0,1.0); + righta_coord = clamp(vec2(texc.xy + vec2(d.x , d.x)),0.0,1.0); + leftb_coord = clamp(vec2(texc.xy + vec2(-d.x , -d.x)),0.0,1.0); + rightb_coord = clamp(vec2(texc.xy + vec2(d.x , -d.x)),0.0,1.0); +} \ No newline at end of file diff --git a/ISF/Optical Flow Generator.fs b/ISF/Optical Flow Generator.fs new file mode 100644 index 0000000..836c655 --- /dev/null +++ b/ISF/Optical Flow Generator.fs @@ -0,0 +1,117 @@ +/*{ + "DESCRIPTION": "Creates a raw optical flow mask from the input image", + "CREDIT": "by VIDVOX / v002 / Andrew Benson", + "ISFVSN": "2", + "CATEGORIES": [ + "Masking" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "inputScale", + "LABEL": "Scale", + "TYPE": "float", + "MIN": 0.0, + "MAX": 50.0, + "DEFAULT": 10.0 + }, + { + "NAME": "inputOffset", + "LABEL": "Offset", + "TYPE": "float", + "MIN": -0.5, + "MAX": 0.5, + "DEFAULT": 0.01 + }, + { + "NAME": "inputLambda", + "LABEL": "Noise Removal", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.2 + } + ], + "PASSES": [ + { + "TARGET":"maskBuffer" + }, + { + "TARGET":"delayBuffer", + "PERSISTENT": true + }, + { + + } + ] + +}*/ + + +// based on v002 Optical Flow which is itself a port of Andrew Bensons HS Flow implementation on the GPU. +// https://github.com/v002/v002-Optical-Flow + +const vec4 coeffs = vec4(0.2126, 0.7152, 0.0722, 1.0); + +float gray(vec4 n) +{ + return (n.r + n.g + n.b)/3.0; +} + +void main() +{ + // on the first pass generate the mask using the previous delayBuffer and inputImage + // on the 2nd pass update the delayBuffer to hold inputImage + // on the 3rd pass output the new mask + if (PASSINDEX == 0) { + // convert to grayscale + vec4 a = IMG_THIS_PIXEL(inputImage) * coeffs; + float brightness = gray(a); + a = vec4(brightness); + vec4 b = IMG_THIS_PIXEL(delayBuffer) * coeffs; + brightness = gray(b); + b = vec4(brightness); + + vec2 x1 = vec2(inputOffset * RENDERSIZE.x, 0.0); + vec2 y1 = vec2(0.0,inputOffset * RENDERSIZE.y / 2.0); + vec2 texcoord0 = isf_FragNormCoord.xy * RENDERSIZE; + vec2 texcoord1 = isf_FragNormCoord.xy * RENDERSIZE; + + //get the difference + vec4 curdif = b-a; + + //calculate the gradient + vec4 gradx = IMG_PIXEL(delayBuffer, texcoord1+x1)-IMG_PIXEL(delayBuffer, texcoord1-x1); + gradx += IMG_PIXEL(inputImage, texcoord0+x1)-IMG_PIXEL(inputImage, texcoord0-x1); + + vec4 grady = IMG_PIXEL(delayBuffer, texcoord1+y1)-IMG_PIXEL(delayBuffer, texcoord1-y1); + grady += IMG_PIXEL(inputImage, texcoord0+y1)-IMG_PIXEL(inputImage, texcoord0-y1); + + vec4 gradmag = sqrt((gradx*gradx)+(grady*grady)+vec4(inputLambda)); + + vec4 vx = curdif*(gradx/gradmag); + float vxd = gray(vx);//assumes greyscale + //format output for flowrepos, out(-x,+x,-y,+y) + vec2 xout = vec2(max(vxd,0.),abs(min(vxd,0.)))*inputScale; + + vec4 vy = curdif*(grady/gradmag); + float vyd = gray(vy);//assumes greyscale + //format output for flowrepos, out(-x,+x,-y,+y) + vec2 yout = vec2(max(vyd,0.),abs(min(vyd,0.)))*inputScale; + + vec4 mask = clamp(vec4(xout.xy,yout.xy), 0.0, 1.0); + gl_FragColor = mask; + } + else if (PASSINDEX == 1) { + gl_FragColor = IMG_THIS_PIXEL(inputImage); + } + else { + // NOW DO SOMETHING WITH THE MASK + vec4 mask = IMG_THIS_NORM_PIXEL(maskBuffer); + mask.a = 1.0; + gl_FragColor = mask; + } +} diff --git a/ISF/Pixel Shifter.fs b/ISF/Pixel Shifter.fs new file mode 100644 index 0000000..a834c62 --- /dev/null +++ b/ISF/Pixel Shifter.fs @@ -0,0 +1,113 @@ +/*{ + "DESCRIPTION": "Shifts pixels up and down", + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Glitch", "Distortion Effect" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "hPhase", + "LABEL": "Horizontal Phase", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.0 + }, + { + "NAME": "hFrequency", + "LABEL": "Horizontal Frequency", + "TYPE": "float", + "MIN": -16.0, + "MAX": 16.0, + "DEFAULT": 1.0 + }, + { + "NAME": "hRandom", + "LABEL": "Horizontal Random", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.0 + }, + { + "NAME": "vPhase", + "LABEL": "Vertical Phase", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.0 + }, + { + "NAME": "vFrequency", + "LABEL": "Vertical Frequency", + "TYPE": "float", + "MIN": -16.0, + "MAX": 16.0, + "DEFAULT": 0.0 + }, + { + "NAME": "vRandom", + "LABEL": "Vertical Random", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.0 + }, + { + "NAME": "doSin", + "LABEL": "Sinusoidal", + "TYPE": "bool", + "DEFAULT": 1.0 + }, + { + "NAME": "mirror", + "LABEL": "Mirror", + "TYPE": "bool", + "DEFAULT": 1.0 + } + ] +}*/ + + +float PI_CONST = 3.14159265359; + + +float rand(vec2 co){ + return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453); +} + + +void main() +{ + // start with the pixel + vec2 loc = isf_FragNormCoord; + float modVal = 1.0; + + if (mirror) + modVal = 2.0; + + // shift the loc.x by the frequency * loc.y + phase + if (doSin) + loc.x = mod(hRandom * rand(vec2(TIME * 0.127, loc.x)) + loc.x + sign(hFrequency) * 0.5 * (1.0+cos(2.0 * PI_CONST * (hPhase + hFrequency * loc.y))), modVal); + else + loc.x = mod(hRandom * rand(vec2(TIME * 0.129, loc.x)) + loc.x + hFrequency * loc.y + hPhase, modVal); + + // shift the loc.y by the frequency * loc.x + phase + if (doSin) + loc.y = mod(vRandom * rand(vec2(TIME * 0.273, loc.y)) + loc.y + sign(vFrequency) * 0.5 * (1.0+cos(2.0 * PI_CONST * (vPhase + vFrequency * loc.x))), modVal); + else + loc.y = mod(vRandom * rand(vec2(TIME * 0.341, loc.y)) +loc.y + vFrequency * loc.x + vPhase, modVal); + + if (loc.x > 1.0) + loc.x = 2.0 - loc.x; + + if (loc.y > 1.0) + loc.y = 2.0 - loc.y; + + gl_FragColor = IMG_NORM_PIXEL(inputImage,loc); +} diff --git a/ISF/Pixellate.fs b/ISF/Pixellate.fs new file mode 100644 index 0000000..039aed6 --- /dev/null +++ b/ISF/Pixellate.fs @@ -0,0 +1,82 @@ + +/*{ + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Stylize" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "cell_size", + "TYPE": "float", + "MIN": 0.001, + "MAX": 0.5, + "DEFAULT": 0.125 + }, + { + "NAME": "shape", + "VALUES": [ + 0, + 1 + ], + "LABELS": [ + "Square", + "Rectangle" + ], + "DEFAULT": 0, + "TYPE": "long" + } + ] +}*/ + +#ifndef GL_ES +float distance (vec2 center, vec2 pt) +{ + float tmp = pow(center.x-pt.x,2.0)+pow(center.y-pt.y,2.0); + return pow(tmp,0.5); +} +#endif + +void main() +{ +// CALCULATE EDGES OF CURRENT CELL + // At 0.0 just do a pass-thru + if (cell_size == 0.0) { + gl_FragColor = IMG_THIS_PIXEL(inputImage); + } + else { + // Position of current pixel + vec2 xy; + xy.x = isf_FragNormCoord[0]; + xy.y = isf_FragNormCoord[1]; + + + // Left and right of tile + float CellWidth = cell_size; + float CellHeight = cell_size; + if (shape==0) { + CellHeight = cell_size * RENDERSIZE.x / RENDERSIZE.y; + } + + float x1 = floor(xy.x / CellWidth)*CellWidth; + float x2 = clamp((ceil(xy.x / CellWidth)*CellWidth), 0.0, 1.0); + // Top and bottom of tile + float y1 = floor(xy.y / CellHeight)*CellHeight; + float y2 = clamp((ceil(xy.y / CellHeight)*CellHeight), 0.0, 1.0); + + // GET AVERAGE CELL COLOUR + // Average left and right pixels + vec4 avgX = (IMG_NORM_PIXEL(inputImage, vec2(x1, y1))+(IMG_NORM_PIXEL(inputImage, vec2(x2, y1)))) / 2.0; + // Average top and bottom pixels + vec4 avgY = (IMG_NORM_PIXEL(inputImage, vec2(x1, y1))+(IMG_NORM_PIXEL(inputImage, vec2(x1, y2)))) / 2.0; + // Centre pixel + vec4 avgC = IMG_NORM_PIXEL(inputImage, vec2(x1+(CellWidth/2.0), y2+(CellHeight/2.0))); // Average the averages + centre + vec4 avgClr = (avgX+avgY+avgC) / 3.0; + + gl_FragColor = vec4(avgClr); + } +} diff --git a/ISF/Poly Glitch.fs b/ISF/Poly Glitch.fs new file mode 100644 index 0000000..7d6040f --- /dev/null +++ b/ISF/Poly Glitch.fs @@ -0,0 +1,169 @@ +/*{ + "CREDIT": "by VIDVOX", + "CATEGORIES": [ + "Stylize", "Glitch" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "randomSeed", + "LABEL": "Random Seed", + "TYPE": "float", + "MIN": 0.01, + "MAX": 1.0, + "DEFAULT": 0.239 + }, + { + "NAME": "sizeSpread", + "LABEL": "Poly Size", + "TYPE": "float", + "MIN": 0.0, + "MAX": 0.25, + "DEFAULT": 0.025 + }, + { + "NAME": "sizeGain", + "LABEL": "Size Gain", + "TYPE": "float", + "MIN": 1.0, + "MAX": 2.0, + "DEFAULT": 1.0 + }, + { + "NAME": "sampleMode", + "LABEL": "Sample Mode", + "VALUES": [ + 0, + 1 + ], + "LABELS": [ + "Single", + "Double" + ], + "DEFAULT": 0, + "TYPE": "long" + } + ] +}*/ + + +const float MaxPointCount = 5.0; +float divisions = 1.0 / sizeSpread; + + + +float rand(vec2 co){ + return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453); +} + +float sign(vec2 p1, vec2 p2, vec2 p3) { + return (p1.x - p3.x) * (p2.y - p3.y) - (p2.x - p3.x) * (p1.y - p3.y); +} + +bool PointInTriangle(vec2 pt, vec2 v1, vec2 v2, vec2 v3) { + bool b1, b2, b3; + + b1 = sign(pt, v1, v2) < 0.0; + b2 = sign(pt, v2, v3) < 0.0; + b3 = sign(pt, v3, v1) < 0.0; + + return ((b1 == b2) && (b2 == b3)); +} + +vec2 AvgPointForTriangle(vec2 p1, vec2 p2, vec2 p3) { + return (p1 + p2 + p3) / 3.0; +} + +float AreaOfTriangle(vec2 p1, vec2 p2, vec2 p3) { + return abs(p1.x*(p2.y-p3.y)+p2.x*(p3.y-p1.y)+p3.x*(p1.y-p2.y))/2.0; +} + +vec4 ColorForPtIndex(vec2 index1, vec2 index2, float sizeAmount, float theSeed, vec2 pt) { + vec4 returnMe = vec4(0.0); + vec2 pt1, pt2, pt3; + vec2 offset1 = (index1 + divisions / 2.0) * sizeAmount + sizeAmount / 2.0; + vec2 offset2 = (index2 + divisions / 2.0) * sizeAmount + sizeAmount / 2.0; + float adjustedSizeAmount = sizeAmount * sizeGain; + vec2 inPoint = pt + vec2(0.5); + + + pt1 = vec2(rand(vec2(theSeed+index1.x,2.187*theSeed+index1.x)),rand(vec2(theSeed+index1.y,0.823*theSeed+index1.y))); + pt2 = pt1 + vec2(rand(vec2(theSeed+index1.x,5.326*theSeed+index1.x)),rand(vec2(theSeed+index1.y,1.421*theSeed+index1.y))); + pt3 = pt1 - vec2(rand(vec2(theSeed+index2.x,1.935*theSeed+index2.x)),rand(vec2(theSeed+index2.y,3.177*theSeed+index2.y))); + + float area = AreaOfTriangle(pt1,pt2,pt3); + + if (area < 0.5) { + pt1 = 1.0 - pt1; + adjustedSizeAmount = adjustedSizeAmount * (2.5-area); + } + else if (area > 0.5) { + //pt3 = 1.0-pt3; + } + + pt1 = clamp(pt1 * adjustedSizeAmount + offset1 - adjustedSizeAmount / 2.0,0.0,1.0); + pt2 = clamp(pt2 * adjustedSizeAmount + offset1 - adjustedSizeAmount / 2.0,0.0,1.0); + pt3 = clamp(pt3 * adjustedSizeAmount + offset2 - adjustedSizeAmount / 2.0,0.0,1.0); + + if(PointInTriangle(inPoint,pt1,pt2,pt3)) { + vec2 avgPt = AvgPointForTriangle(pt1,pt2,pt3); + returnMe = IMG_NORM_PIXEL(inputImage,avgPt); + if (sampleMode==1) { + returnMe.a = 0.5; + returnMe.rgb = returnMe.rgb * returnMe.a; + } + else { + returnMe.a = 1.0; + } + } + + return returnMe; +} + + + +void main() { + vec4 result = vec4(0.0); + vec2 thisPoint = vv_FragNormCoord - vec2(0.5); + float inSpread = sizeSpread; + vec2 ptIndex = floor(thisPoint / inSpread); + vec4 original = IMG_THIS_NORM_PIXEL(inputImage); + float pointCount = MaxPointCount + float(sampleMode); + + if (sizeSpread > 0.0) { + inSpread = sizeSpread * 1.0; + for (float i=0.0;i0.667) + break; + float tmpSpread = inSpread; + if (result.a<=0.75) + result += ColorForPtIndex(ptIndex,ptIndex+vec2(1.0,0.0),tmpSpread,i+randomSeed,thisPoint); + if (result.a<=0.75) + result += ColorForPtIndex(ptIndex,ptIndex+vec2(-1.0,0.0),tmpSpread,i+randomSeed,thisPoint); + if (result.a<=0.75) + result += ColorForPtIndex(ptIndex,ptIndex+vec2(0.0,1.0),tmpSpread,i+randomSeed,thisPoint); + if (result.a<=0.75) + result += ColorForPtIndex(ptIndex,ptIndex+vec2(0.0,-1.0),tmpSpread,i+randomSeed,thisPoint); + + if (result.a<=0.75) + result += ColorForPtIndex(ptIndex+vec2(-1.0,0.0),ptIndex,tmpSpread,i+randomSeed,thisPoint); + if (result.a<=0.75) + result += ColorForPtIndex(ptIndex+vec2(0.0,1.0),ptIndex,tmpSpread,i+randomSeed,thisPoint); + if (result.a<=0.75) + result += ColorForPtIndex(ptIndex+vec2(0.0,-1.0),ptIndex,tmpSpread,i+randomSeed,thisPoint); + if (result.a<=0.75) + result += ColorForPtIndex(ptIndex+vec2(1.0,0.0),ptIndex,tmpSpread,i+randomSeed,thisPoint); + } + if (result.a<1.0) + result += (2.0 - result.a) * ColorForPtIndex(ptIndex,ptIndex,inSpread,randomSeed,thisPoint); + if (sampleMode==0) + result.a = original.a; + } + else { + result = original; + } + gl_FragColor = result; +} \ No newline at end of file diff --git a/ISF/Poly Star.fs b/ISF/Poly Star.fs new file mode 100644 index 0000000..4205e49 --- /dev/null +++ b/ISF/Poly Star.fs @@ -0,0 +1,96 @@ +/* +{ + "CATEGORIES" : [ + "Generator" + ], + "DESCRIPTION" : "", + "ISFVSN" : "2", + "INPUTS" : [ + { + "NAME" : "pointCount", + "TYPE" : "float", + "MAX" : 20, + "DEFAULT" : 5, + "MIN" : 3, + "LABEL" : "Point Count" + }, + { + "NAME" : "buldge", + "TYPE" : "float", + "MAX" : 10, + "DEFAULT" : 5, + "MIN" : 0, + "LABEL" : "Buldge Amount" + }, + { + "NAME" : "pointRadiusInside", + "TYPE" : "float", + "MAX" : 1, + "DEFAULT" : 0.1, + "LABEL" : "Radius Inside", + "MIN" : 0 + }, + { + "NAME" : "pointRadiusOutside", + "TYPE" : "float", + "MAX" : 1, + "DEFAULT" : 0.1, + "LABEL" : "Radius Outside", + "MIN" : 0 + }, + { + "NAME" : "pointRotation", + "TYPE" : "float", + "MAX" : 1, + "DEFAULT" : 0, + "LABEL" : "Rotation", + "MIN" : 0 + }, + { + "NAME" : "starColor", + "TYPE" : "color", + "DEFAULT" : [ + 1, + 1, + 1, + 1 + ], + "LABEL" : "Star Color" + } + ], + "CREDIT" : "" +} +*/ + + +float rand(vec2 co){ + return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453); +} + +const float pi = 3.14159265359; + +void main() { + vec4 inputPixelColor = vec4(0.0); + float angleInc = 1.0 / pointCount; + + vec2 loc = RENDERSIZE * isf_FragNormCoord; + // 'r' is the radius- the distance in pixels from 'loc' to the center of the rendering space + float r = distance(RENDERSIZE/2.0, loc); + r /= max(RENDERSIZE.x,RENDERSIZE.y); + // 'a' is the angle of the line segment from the center to loc is rotated + float a = atan ((loc.y-RENDERSIZE.y/2.0),(loc.x-RENDERSIZE.x/2.0)); + a += pi; + a /= 2.0*pi; + a += pointRotation; + // 'at' is the angle time + float at = mod(a,angleInc) / angleInc; + // 'rd' is the radius at this angle for the shape + float starness = 10.0 - buldge; + float rd = pointRadiusOutside * pow(at,starness) + pointRadiusInside; + inputPixelColor = (r < rd) ? starColor : vec4(0.0); + at = 1.0 - at; + rd = pointRadiusOutside * pow(at,starness) + pointRadiusInside; + inputPixelColor = (r < rd) ? starColor : inputPixelColor; + + gl_FragColor = inputPixelColor; +} diff --git a/ISF/Posterize.fs b/ISF/Posterize.fs new file mode 100644 index 0000000..1bfca26 --- /dev/null +++ b/ISF/Posterize.fs @@ -0,0 +1,44 @@ +/*{ + "DESCRIPTION": "Posterizes an image", + "CREDIT": "VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Stylize", "Retro" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "gamma", + "LABEL": "Gamma", + "TYPE": "float", + "DEFAULT": 1.25, + "MIN": 0.5, + "MAX": 2.0 + }, + { + "NAME": "numColors", + "LABEL": "Quality", + "TYPE": "float", + "DEFAULT": 6.0, + "MIN": 3.0, + "MAX": 32.0 + } + ] + +}*/ + +void main() { + + vec4 c = IMG_THIS_PIXEL(inputImage); + + c.rgb = pow(c.rgb, vec3(gamma, gamma, gamma)); + c.rgb = c.rgb * numColors; + c.rgb = floor(c.rgb); + c.rgb = c.rgb / numColors; + c.rgb = pow(c.rgb, vec3(1.0/gamma)); + + gl_FragColor = c; +} diff --git a/ISF/Power Warp.fs b/ISF/Power Warp.fs new file mode 100644 index 0000000..377b4c1 --- /dev/null +++ b/ISF/Power Warp.fs @@ -0,0 +1,107 @@ +/*{ + "DESCRIPTION": "Power curves distortions with shifting", + "CREDIT": "", + "CATEGORIES": [ + "Distortion Effect" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "power_x", + "TYPE": "float", + "DEFAULT": 1, + "MIN": 0.25, + "MAX": 4 + }, + { + "NAME": "power_y", + "TYPE": "float", + "DEFAULT": 1, + "MIN": 0.25, + "MAX": 4 + }, + { + "NAME": "shift_x", + "TYPE": "float", + "DEFAULT": 0, + "MIN": 0, + "MAX": 1 + }, + { + "NAME": "shift_y", + "TYPE": "float", + "DEFAULT": 0, + "MIN": 0, + "MAX": 1 + }, + { + "NAME": "mode_x", + "TYPE": "long", + "VALUES": [ + 0, + 1 + ], + "LABELS": [ + "Style 1", + "Style 2" + ], + "DEFAULT": 1 + }, + { + "NAME": "mode_y", + "TYPE": "long", + "VALUES": [ + 0, + 1 + ], + "LABELS": [ + "Style 1", + "Style 2" + ], + "DEFAULT": 1 + } + ] +}*/ + + +const float pi = 3.14159265359; + + + +void main() { + vec4 inputPixelColor; + vec2 pos = isf_FragNormCoord.xy; + + if (mode_x == 0) { + pos.x = pow(pos.x, power_x); + } + else { + if (pos.x > 0.5) + pos.x = 0.5 + pow(2.0*(pos.x - 0.5), power_x) / 2.0; + else { + pos.x = pow(1.0 - 2.0*pos.x, power_x) / 2.0; + pos.x = 0.5 - pos.x; + } + } + pos.x = mod(pos.x + shift_x, 1.0); + + if (mode_y == 0) { + pos.y = pow(pos.y, power_y); + } + else { + if (pos.y > 0.5) + pos.y = 0.5 + pow(2.0*(pos.y - 0.5), power_y) / 2.0; + else { + pos.y = pow(1.0 - 2.0*pos.y, power_y) / 2.0; + pos.y = 0.5 - pos.y; + } + } + pos.y = mod(pos.y + shift_y, 1.0); + + inputPixelColor = IMG_NORM_PIXEL(inputImage, pos); + + gl_FragColor = inputPixelColor; +} diff --git a/ISF/Quad Mask.fs b/ISF/Quad Mask.fs new file mode 100644 index 0000000..d61adec --- /dev/null +++ b/ISF/Quad Mask.fs @@ -0,0 +1,150 @@ +/* +{ + "CATEGORIES" : [ + "Masking" + ], + "DESCRIPTION" : "", + "ISFVSN" : "2", + "INPUTS" : [ + { + "NAME" : "inputImage", + "TYPE" : "image" + }, + { + "NAME" : "pt1", + "TYPE" : "point2D", + "LABEL" : "Bottom left", + "MAX" : [ + 1, + 1 + ], + "DEFAULT" : [ + 0, + 0 + ], + "MIN" : [ + 0, + 0 + ] + }, + { + "NAME" : "pt2", + "TYPE" : "point2D", + "LABEL" : "Top left", + "MAX" : [ + 1, + 1 + ], + "DEFAULT" : [ + 1, + 0 + ], + "MIN" : [ + 0, + 0 + ] + }, + { + "NAME" : "pt3", + "TYPE" : "point2D", + "LABEL" : "Top right", + "MAX" : [ + 1, + 1 + ], + "DEFAULT" : [ + 1, + 1 + ], + "MIN" : [ + 0, + 0 + ] + }, + { + "NAME" : "pt4", + "TYPE" : "point2D", + "LABEL" : "Bottom right", + "MAX" : [ + 1, + 1 + ], + "DEFAULT" : [ + 0, + 1 + ], + "MIN" : [ + 0, + 0 + ] + }, + { + "NAME" : "invertMask", + "TYPE" : "bool", + "DEFAULT" : 0, + "LABEL" : "Invert Mask" + }, + { + "NAME": "maskApplyMode", + "LABEL": "Apply Mask", + "TYPE": "long", + "VALUES": [ + 0, + 1, + 2 + ], + "LABELS": [ + "Apply Mask", + "Set Alpha", + "Show Mask" + ], + "DEFAULT": 0 + } + ], + "CREDIT" : "" +} +*/ + + +float sign(vec2 p1, vec2 p2, vec2 p3) +{ + return (p1.x - p3.x) * (p2.y - p3.y) - (p2.x - p3.x) * (p1.y - p3.y); +} + +bool PointInTriangle(vec2 pt, vec2 v1, vec2 v2, vec2 v3) +{ + bool b1, b2, b3; + + b1 = sign(pt, v1, v2) < 0.0; + b2 = sign(pt, v2, v3) < 0.0; + b3 = sign(pt, v3, v1) < 0.0; + + return ((b1 == b2) && (b2 == b3)); +} + + +void main() { + vec4 inputPixelColor = IMG_THIS_PIXEL(inputImage); + vec2 loc = isf_FragNormCoord; + bool drawPixel = false; + + if ((PointInTriangle(loc,pt1,pt2,pt3))||(PointInTriangle(loc,pt1,pt4,pt3))) { + drawPixel = true; + } + + if (invertMask) + drawPixel = !drawPixel; + + if (maskApplyMode == 0) { + inputPixelColor = (drawPixel) ? inputPixelColor : vec4(0.0); + } + // in this mode only the alpha is changed; the rgb remains intact and may still be visible if another filter adjusts the alpha again + else if (maskApplyMode == 1) { + inputPixelColor.a = (drawPixel) ? inputPixelColor.a : 0.0; + } + else if (maskApplyMode == 2) { + inputPixelColor = (drawPixel) ? vec4(1.0) : vec4(0.0); + } + + gl_FragColor = inputPixelColor; +} diff --git a/ISF/Quad Tile.fs b/ISF/Quad Tile.fs new file mode 100644 index 0000000..1c100ea --- /dev/null +++ b/ISF/Quad Tile.fs @@ -0,0 +1,111 @@ +/*{ + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Tile Effect" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "size", + "TYPE": "float", + "MIN": 0.0, + "MAX": 2.0, + "DEFAULT": 0.5 + }, + { + "NAME": "rotation", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.0 + }, + { + "NAME": "angle", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.0 + }, + { + "NAME": "slide1", + "TYPE": "point2D", + "DEFAULT": [ + 0.0, + 0.0 + ] + }, + { + "NAME": "slide2", + "TYPE": "point2D", + "DEFAULT": [ + 0.0, + 0.0 + ] + }, + { + "NAME": "shift", + "TYPE": "point2D", + "DEFAULT": [ + 0.0, + 0.0 + ] + } + ] +}*/ + + +const float tau = 6.28318530718; + + +vec2 pattern() { + float s = sin(tau * rotation); + float c = cos(tau * rotation); + vec2 tex = isf_FragNormCoord * RENDERSIZE; + float scale = 1.0 / max(size,0.001); + vec2 point = vec2( c * tex.x - s * tex.y, s * tex.x + c * tex.y ) * scale; + point = (point - shift) / RENDERSIZE; + // do this to repeat + point = mod(point,1.0); + if (point.x < 0.5) { + point.y = mod(point.y + slide1.y/RENDERSIZE.y, 1.0); + } + else { + point.y = mod(point.y + slide2.y/RENDERSIZE.y, 1.0); + } + if (point.y < 0.5) { + point.x = mod(point.x + slide1.x/RENDERSIZE.x, 1.0); + } + else { + point.x = mod(point.x + slide2.x/RENDERSIZE.x, 1.0); + } + // do this for relections + point = 1.0-abs(1.0-2.0*point); + + // Now let's do a squish based on angle + // convert to polar coordinates + vec2 center = vec2(0.5,0.5); + float r = distance(center, point); + float a = atan ((point.y-center.y),(point.x-center.x)); + + s = sin(a + tau * angle); + c = cos(a + tau * angle); + + float zoom = RENDERSIZE.x / RENDERSIZE.y; + + point.x = (r * c)/zoom + 0.5; + point.y = (r * s)/zoom + 0.5; + + return point; +} + + +void main() { + + vec2 pat = pattern(); + + gl_FragColor = IMG_NORM_PIXEL(inputImage,pat); +} \ No newline at end of file diff --git a/ISF/RGB EQ.fs b/ISF/RGB EQ.fs new file mode 100644 index 0000000..75c200d --- /dev/null +++ b/ISF/RGB EQ.fs @@ -0,0 +1,61 @@ +/*{ + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Color Effect" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "red", + "TYPE": "float", + "MIN": 0.0, + "MAX": 2.0, + "DEFAULT": 1.0 + }, + { + "NAME": "green", + "TYPE": "float", + "MIN": 0.0, + "MAX": 2.0, + "DEFAULT": 1.0 + }, + { + "NAME": "blue", + "TYPE": "float", + "MIN": 0.0, + "MAX": 2.0, + "DEFAULT": 1.0 + }, + { + "NAME": "gain", + "TYPE": "float", + "MIN": -1.0, + "MAX": 1.0, + "DEFAULT": 0.0 + } + ] +}*/ + + + + +void main() { + vec4 pixel = IMG_THIS_PIXEL(inputImage); + float brightness = (pixel.r * red + pixel.g * green + pixel.b * blue) / 3.0; + + pixel.r = pixel.r * red; + pixel.g = pixel.g * green; + pixel.b = pixel.b * blue; + + if (gain >= 0.0) { + pixel.a = (brightness >= gain) ? pixel.a : 0.0; + } + else { + pixel.a = (brightness <= 1.0-abs(gain)) ? pixel.a : 0.0; + } + gl_FragColor = pixel; +} diff --git a/ISF/RGB Halftone-lookaround.fs b/ISF/RGB Halftone-lookaround.fs new file mode 100644 index 0000000..bb3a7f3 --- /dev/null +++ b/ISF/RGB Halftone-lookaround.fs @@ -0,0 +1,108 @@ +/*{ + "CREDIT": "by zoidberg", + "ISFVSN": "2", + "CATEGORIES": [ + "Halftone Effect" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "gridSize", + "TYPE": "float", + "MIN": 1.0, + "MAX": 256.0, + "DEFAULT": 45.0 + }, + { + "NAME": "smoothing", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.15 + } + ] +}*/ + +vec4 gridRot = vec4(15.0, 45.0, 75.0, 0.0); +//vec4 gridRot = vec4(15.0, 75.0, 0.0, 45.0); +//vec4 gridRot = vec4(0.0, 0.0, 0.0, 0.0); + + + +// during calculation we find the closest dot to a frag, determine its size, and then determine the size of the four dots above/below/right/left of it. this array of offsets move "one left", "one up", "one right", and "one down"... +vec2 originOffsets[4]; + + + +void main() { + // a halftone is an overlapping series of grids of dots + // each grid of dots is rotated by a different amount + // the size of the dots determines the colors. the shape of the dot should never change (always be a dot with regular edges) + originOffsets[0] = vec2(-1.0, 0.0); + originOffsets[1] = vec2(0.0, 1.0); + originOffsets[2] = vec2(1.0, 0.0); + originOffsets[3] = vec2(0.0, -1.0); + + vec3 rgbAmounts = vec3(0.0); + int i; + int j; + // for each of the channels (i) of RGB... + for (i=0; i<3; ++i) { + // figure out the rotation of the grid in radians + float rotRad = radians(gridRot[i]); + // the grids are rotated counter-clockwise- to find the nearest dot, take the fragment pixel loc, + // rotate it clockwise, and split by the grid to find the center of the dot. then rotate this + // coord counter-clockwise to yield the location of the center of the dot in pixel coords local to the render space + mat2 ccTrans = mat2(vec2(cos(rotRad), sin(rotRad)), vec2(-1.0*sin(rotRad), cos(rotRad))); + mat2 cTrans = mat2(vec2(cos(rotRad), -1.0*sin(rotRad)), vec2(sin(rotRad), cos(rotRad))); + + // find the location of the frag in the grid (prior to rotating it) + vec2 gridFragLoc = cTrans * gl_FragCoord.xy; + // find the center of the dot closest to the frag- there's no "round" in GLSL 1.2, so do a "floor" to find the dot to the bottom-left of the frag, then figure out if the frag would be in the top and right halves of that square to find the closest dot to the frag + vec2 gridOriginLoc = vec2(floor(gridFragLoc.x/gridSize), floor(gridFragLoc.y/gridSize)); + + vec2 tmpGridCoords = gridFragLoc/vec2(gridSize); + bool fragAtTopOfGrid = ((tmpGridCoords.y-floor(tmpGridCoords.y)) > (gridSize/2.0)) ? true : false; + bool fragAtRightOfGrid = ((tmpGridCoords.x-floor(tmpGridCoords.x)) > (gridSize/2.0)) ? true : false; + if (fragAtTopOfGrid) + gridOriginLoc.y = gridOriginLoc.y + 1.0; + if (fragAtRightOfGrid) + gridOriginLoc.x = gridOriginLoc.x + 1.0; + // ...at this point, "gridOriginLoc" contains the grid coords of the nearest dot to the fragment being rendered + // convert the location of the center of the dot from grid coords to pixel coords + vec2 gridDotLoc = vec2(gridOriginLoc.x*gridSize, gridOriginLoc.y*gridSize) + vec2(gridSize/2.0); + // rotate the pixel coords of the center of the dot so they become relative to the rendering space + vec2 renderDotLoc = ccTrans * gridDotLoc; + // get the color of the pixel of the input image under this dot (the color will ultimately determine the size of the dot) + vec4 renderDotImageColorRGB = IMG_PIXEL(inputImage, renderDotLoc); + + + // the amount of this channel is taken from the same channel of the color of the pixel of the input image under this halftone dot + float imageChannelAmount = renderDotImageColorRGB[i]; + // the size of the dot is determined by the value of the channel + float dotRadius = imageChannelAmount * (gridSize*1.50/2.0); + float fragDistanceToDotCenter = distance(gl_FragCoord.xy, renderDotLoc); + if (fragDistanceToDotCenter < dotRadius) { + rgbAmounts[i] += smoothstep(dotRadius, dotRadius-(dotRadius*smoothing), fragDistanceToDotCenter); + } + + // calcluate the size of the dots abov/below/to the left/right to see if they're overlapping + for (j=0; j<4; ++j) { + gridDotLoc = vec2((gridOriginLoc.x+originOffsets[j].x)*gridSize, (gridOriginLoc.y+originOffsets[j].y)*gridSize) + vec2(gridSize/2.0); + renderDotLoc = ccTrans * gridDotLoc; + renderDotImageColorRGB = IMG_PIXEL(inputImage, renderDotLoc); + + imageChannelAmount = renderDotImageColorRGB[i]; + dotRadius = imageChannelAmount * (gridSize*1.50/2.0); + fragDistanceToDotCenter = distance(gl_FragCoord.xy, renderDotLoc); + if (fragDistanceToDotCenter < dotRadius) { + rgbAmounts[i] += smoothstep(dotRadius, dotRadius-(dotRadius*smoothing), fragDistanceToDotCenter); + } + } + } + + gl_FragColor = vec4(rgbAmounts[0], rgbAmounts[1], rgbAmounts[2], 1.0); +} \ No newline at end of file diff --git a/ISF/RGB Halftone.fs b/ISF/RGB Halftone.fs new file mode 100644 index 0000000..5db5e06 --- /dev/null +++ b/ISF/RGB Halftone.fs @@ -0,0 +1,65 @@ +/*{ + "CREDIT": "by zoidberg", + "ISFVSN": "2", + "CATEGORIES": [ + "Halftone Effect" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "gridSize", + "TYPE": "float", + "MIN": 1.0, + "MAX": 256.0, + "DEFAULT": 45.0 + }, + { + "NAME": "smoothing", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.15 + } + ] +}*/ + +vec3 gridRot = vec3(15.0, 45.0, 75.0); + +void main() { + // a halftone is an overlapping series of grids of dots + // each grid of dots is rotated by a different amount + // the size of the dots determines the colors. the shape of the dot should never change (always be a dot with regular edges) + + vec4 rgbaAmounts = vec4(0.0); + + // for each of the channels (i) of RGB... + for (int i=0; i<3; ++i) { + // figure out the rotation of the grid in radians + float rotRad = radians(gridRot[i]); + // the grids are rotated counter-clockwise- to find the nearest dot, take the fragment pixel loc, + // rotate it clockwise, and split by the grid to find the center of the dot. then rotate this + // coord counter-clockwise to yield the location of the center of the dot in pixel coords local to the render space + mat2 ccTrans = mat2(vec2(cos(rotRad), sin(rotRad)), vec2(-1.0*sin(rotRad), cos(rotRad))); + mat2 cTrans = mat2(vec2(cos(rotRad), -1.0*sin(rotRad)), vec2(sin(rotRad), cos(rotRad))); + + // render loc -> grid loc -> grid dot loc -> grid dot loc in render coords -> pixel color under grid dot loc + vec2 gridFragLoc = cTrans * gl_FragCoord.xy; + vec2 gridDotLoc = vec2(floor(gridFragLoc.x/gridSize)*gridSize, floor(gridFragLoc.y/gridSize)*gridSize); + gridDotLoc = gridDotLoc + vec2(gridSize/2.0); + vec2 renderDotLoc = ccTrans * gridDotLoc; + vec4 renderDotImageColorRGB = IMG_PIXEL(inputImage, renderDotLoc); + + float channelAmount = renderDotImageColorRGB[i]; + float dotRadius = channelAmount * (gridSize/2.0); + float fragDistanceToGridCenter = distance(gl_FragCoord.xy, renderDotLoc); + // the amount of the channel depends on the distance to the center of the grid, the size of the dot, and smoothing + float smoothDist = smoothing * (gridSize/6.0); + rgbaAmounts[i] += smoothstep(dotRadius, dotRadius-(dotRadius*smoothing), fragDistanceToGridCenter); + } + + rgbaAmounts.a = 1.0; + gl_FragColor = rgbaAmounts; +} \ No newline at end of file diff --git a/ISF/RGB Invert.fs b/ISF/RGB Invert.fs new file mode 100644 index 0000000..7b35b3d --- /dev/null +++ b/ISF/RGB Invert.fs @@ -0,0 +1,46 @@ +/*{ + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Color Effect" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "r", + "TYPE": "bool", + "DEFAULT": 1.0 + }, + { + "NAME": "g", + "TYPE": "bool", + "DEFAULT": 1.0 + }, + { + "NAME": "b", + "TYPE": "bool", + "DEFAULT": 1.0 + }, + { + "NAME": "a", + "TYPE": "bool", + "DEFAULT": 0.0 + } + ] +}*/ + +void main() { + vec4 srcPixel = IMG_THIS_PIXEL(inputImage); + if (r) + srcPixel.r = 1.0-srcPixel.r; + if (g) + srcPixel.g = 1.0-srcPixel.g; + if (b) + srcPixel.b = 1.0-srcPixel.b; + if (a) + srcPixel.a = 1.0-srcPixel.a; + gl_FragColor = srcPixel; +} \ No newline at end of file diff --git a/ISF/RGB Strobe.fs b/ISF/RGB Strobe.fs new file mode 100644 index 0000000..aa54c22 --- /dev/null +++ b/ISF/RGB Strobe.fs @@ -0,0 +1,108 @@ +/*{ + "DESCRIPTION": "", + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Color Effect" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "r", + "TYPE": "bool", + "DEFAULT": 1.0 + }, + { + "NAME": "g", + "TYPE": "bool", + "DEFAULT": 1.0 + }, + { + "NAME": "b", + "TYPE": "bool", + "DEFAULT": 1.0 + }, + { + "NAME": "a", + "TYPE": "bool", + "DEFAULT": 0.0 + }, + { + "NAME": "strobeRates", + "LABEL": "Strobe Rates", + "TYPE": "color", + "DEFAULT": [ + 0.0, + 0.0, + 0.0, + 0.0 + ] + } + ], + "PASSES": [ + { + "TARGET":"lastState", + "WIDTH": "1", + "HEIGHT": "1", + "PERSISTENT": true, + "DESCRIPTION": "Stores the current strobe state of each of the color channels." + }, + { + + } + ] + +}*/ + + + +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 = IMG_PIXEL(lastState,vec2(0.5)); + // i'm only using the X, which is the last render time we reset + if (strobeRates.r == 0.0) { + srcPixel.r = (srcPixel.r == 0.0) ? 1.0 : 0.0; + } + else { + srcPixel.r = (mod(TIME, strobeRates.r) <= strobeRates.r / 2.0) ? 1.0 : 0.0; + } + if (strobeRates.g == 0.0) { + srcPixel.g = (srcPixel.g == 0.0) ? 1.0 : 0.0; + } + else { + srcPixel.g = (mod(TIME, strobeRates.g) <= strobeRates.g / 2.0) ? 1.0 : 0.0; + } + if (strobeRates.b == 0.0) { + srcPixel.b = (srcPixel.b == 0.0) ? 1.0 : 0.0; + } + else { + srcPixel.b = (mod(TIME, strobeRates.b) <= strobeRates.b / 2.0) ? 1.0 : 0.0; + } + if (strobeRates.a == 0.0) { + srcPixel.a = (srcPixel.a == 0.0) ? 1.0 : 0.0; + } + else { + srcPixel.a = (mod(TIME, strobeRates.a) <= strobeRates.a / 2.0) ? 1.0 : 0.0; + } + gl_FragColor = srcPixel; + } + // else this isn't the first pass- read the position value from the buffer which stores it + else { + vec4 lastStateVector = IMG_PIXEL(lastState,vec2(0.5)); + vec4 srcPixel = IMG_THIS_PIXEL(inputImage); + float red = (r == true) ? 1.0 : 0.0; + float green = (g == true) ? 1.0 : 0.0; + float blue = (b == true) ? 1.0 : 0.0; + float alpha = (a == true) ? 1.0 : 0.0; + srcPixel.r = (lastStateVector.r == 0.0) ? srcPixel.r : abs(red-srcPixel.r); + srcPixel.g = (lastStateVector.g == 0.0) ? srcPixel.g : abs(green-srcPixel.g); + srcPixel.b = (lastStateVector.b == 0.0) ? srcPixel.b : abs(blue-srcPixel.b); + srcPixel.a = (lastStateVector.a == 0.0) ? srcPixel.a : abs(alpha-srcPixel.a); + gl_FragColor = srcPixel; + } +} diff --git a/ISF/RGB Trails 3.0.fs b/ISF/RGB Trails 3.0.fs new file mode 100644 index 0000000..ad29751 --- /dev/null +++ b/ISF/RGB Trails 3.0.fs @@ -0,0 +1,53 @@ +/*{ + "CREDIT": "by zoidberg", + "ISFVSN": "2", + "DESCRIPTION": "a persistent buffer is used to maintain an image which is constantly updated. Similar to VVMotionBlur, but each channel has its own weight", + "CATEGORIES": [ + "Color Effect" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "rWeight", + "TYPE": "float" + }, + { + "NAME": "gWeight", + "TYPE": "float" + }, + { + "NAME": "bWeight", + "TYPE": "float" + }, + { + "NAME": "aWeight", + "TYPE": "float", + "DEFAULT": 0.0 + } + ], + "PASSES": [ + { + "TARGET":"accum", + "PERSISTENT": true, + "FLOAT": true + }, + { + + } + ] + +}*/ + +void main() +{ + if (PASSINDEX==0) { + vec4 freshPixel = IMG_THIS_PIXEL(inputImage); + vec4 stalePixel = IMG_THIS_PIXEL(accum); + gl_FragColor = vec4(mix(freshPixel.r,stalePixel.r,rWeight), mix(freshPixel.g,stalePixel.g,gWeight), mix(freshPixel.b,stalePixel.b,bWeight), mix(freshPixel.a,stalePixel.a,aWeight)); + } + else + gl_FragColor = IMG_THIS_PIXEL(accum); +} diff --git a/ISF/RGBA Swap.fs b/ISF/RGBA Swap.fs new file mode 100644 index 0000000..a04f7f1 --- /dev/null +++ b/ISF/RGBA Swap.fs @@ -0,0 +1,166 @@ +/*{ + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Color Adjustment" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "LABEL": "Red", + "NAME": "redInput", + "TYPE": "long", + "VALUES": [ + 0, + 1, + 2, + 3, + 4 + ], + "LABELS": [ + "R", + "G", + "B", + "A", + "Average" + ], + "DEFAULT": 0 + }, + { + "LABEL": "Green", + "NAME": "greenInput", + "TYPE": "long", + "VALUES": [ + 0, + 1, + 2, + 3, + 4 + ], + "LABELS": [ + "R", + "G", + "B", + "A", + "Average" + ], + "DEFAULT": 1 + }, + { + "LABEL": "Blue", + "NAME": "blueInput", + "TYPE": "long", + "VALUES": [ + 0, + 1, + 2, + 3, + 4 + ], + "LABELS": [ + "R", + "G", + "B", + "A", + "Average" + ], + "DEFAULT": 2 + }, + { + "LABEL": "Alpha", + "NAME": "alphaInput", + "TYPE": "long", + "VALUES": [ + 0, + 1, + 2, + 3, + 4 + ], + "LABELS": [ + "R", + "G", + "B", + "A", + "Average" + ], + "DEFAULT": 3 + } + ] +}*/ + +void main() { + vec4 srcPixel = IMG_THIS_PIXEL(inputImage); + vec4 outputPixel = srcPixel; + float avgVal = (srcPixel.r + srcPixel.g + srcPixel.b) * srcPixel.a / 3.0; + + if (redInput == 0) { + outputPixel.r = srcPixel.r; + } + else if (redInput == 1) { + outputPixel.r = srcPixel.g; + } + else if (redInput == 2) { + outputPixel.r = srcPixel.b; + } + else if (redInput == 3) { + outputPixel.r = srcPixel.a; + } + else if (redInput == 4) { + outputPixel.r = avgVal; + } + + if (greenInput == 0) { + outputPixel.g = srcPixel.r; + } + else if (greenInput == 1) { + outputPixel.g = srcPixel.g; + } + else if (greenInput == 2) { + outputPixel.g = srcPixel.b; + } + else if (greenInput == 3) { + outputPixel.g = srcPixel.a; + } + else if (greenInput == 4) { + outputPixel.g = avgVal; + } + + if (blueInput == 0) { + outputPixel.b = srcPixel.r; + } + else if (blueInput == 1) { + outputPixel.b = srcPixel.g; + } + else if (blueInput == 2) { + outputPixel.b = srcPixel.b; + } + else if (blueInput == 3) { + outputPixel.b = srcPixel.a; + } + else if (blueInput == 4) { + outputPixel.b = avgVal; + } + + + if (alphaInput == 0) { + outputPixel.a = srcPixel.r; + } + else if (alphaInput == 1) { + outputPixel.a = srcPixel.g; + } + else if (alphaInput == 2) { + outputPixel.a = srcPixel.b; + } + else if (alphaInput == 3) { + outputPixel.a = srcPixel.a; + } + else if (alphaInput == 4) { + outputPixel.a = avgVal; + } + + gl_FragColor = outputPixel; +} \ No newline at end of file diff --git a/ISF/RGBtoHSV.fs b/ISF/RGBtoHSV.fs new file mode 100644 index 0000000..90525da --- /dev/null +++ b/ISF/RGBtoHSV.fs @@ -0,0 +1,44 @@ +/*{ + "DESCRIPTION": "swizzles RGBA to BGRA and vice versa", + "CREDIT": "by zoidberg", + "ISFVSN": "2", + "CATEGORIES": [ + "Glitch","Color Effect" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + } + ] +}*/ + + + + +vec3 rgb2hsv(vec3 c) { + vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); + //vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g)); + //vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r)); + vec4 p = c.g < c.b ? vec4(c.bg, K.wz) : vec4(c.gb, K.xy); + vec4 q = c.r < p.x ? vec4(p.xyw, c.r) : vec4(c.r, p.yzx); + + float d = q.x - min(q.w, q.y); + float e = 1.0e-10; + return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x); +} + +vec3 hsv2rgb(vec3 c) { + vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); + vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www); + return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y); +} + + + + +void main() +{ + vec4 inColor = IMG_NORM_PIXEL(inputImage, isf_FragNormCoord); + gl_FragColor = vec4(rgb2hsv(inColor.rgb), inColor.a); +} diff --git a/ISF/Radial Gradient.fs b/ISF/Radial Gradient.fs new file mode 100644 index 0000000..6e6f216 --- /dev/null +++ b/ISF/Radial Gradient.fs @@ -0,0 +1,71 @@ +/*{ + "CREDIT": "by Carter Rosenberg", + "ISFVSN": "2", + "CATEGORIES": [ + "Generator" + ], + "INPUTS": [ + { + "NAME": "radius1", + "TYPE": "float", + "DEFAULT": 0.1 + }, + { + "NAME": "radius2", + "TYPE": "float", + "DEFAULT": 0.25 + }, + { + "NAME": "startColor", + "TYPE": "color", + "DEFAULT": [ + 1.0, + 0.75, + 0.0, + 1.0 + ] + }, + { + "NAME": "endColor", + "TYPE": "color", + "DEFAULT": [ + 0.0, + 0.25, + 0.75, + 1.0 + ] + }, + { + "NAME": "location", + "TYPE": "point2D", + "DEFAULT": [ + 0.5, + 0.5 + ] + } + ] +}*/ + +#ifndef GL_ES +float distance (vec2 start, vec2 end) { + return sqrt(pow((start.x-end.x),2.0) + pow((start.y-end.y),2.0)); +} +#endif + +void main() { + vec2 tmpPt = location / RENDERSIZE; + float mixOffset = distance(tmpPt * RENDERSIZE.x / RENDERSIZE.y, isf_FragNormCoord * RENDERSIZE.x / RENDERSIZE.y); + float tmpRadius = radius1 + radius2; + if (mixOffset <= radius1) { + gl_FragColor = startColor; + } + else if (mixOffset > tmpRadius) { + gl_FragColor = endColor; + } + else if (radius1 == tmpRadius) { + gl_FragColor = endColor; + } + else { + gl_FragColor = mix(startColor,endColor,(mixOffset-radius1)/(tmpRadius-radius1)); + } +} \ No newline at end of file diff --git a/ISF/Radial Replicate.fs b/ISF/Radial Replicate.fs new file mode 100644 index 0000000..30b086f --- /dev/null +++ b/ISF/Radial Replicate.fs @@ -0,0 +1,105 @@ +/* +{ + "CATEGORIES" : [ + "Geometry Adjustment", "Tile Effect" + ], + "DESCRIPTION" : "Repllcates a radial slice of an image", + "ISFVSN" : "2", + "INPUTS" : [ + { + "NAME" : "inputImage", + "TYPE" : "image" + }, + { + "NAME" : "postRotateAngle", + "TYPE" : "float", + "MAX" : 360, + "DEFAULT" : 0, + "LABEL" : "Post Rotate Angle", + "MIN" : 0 + }, + { + "NAME" : "numberOfDivisions", + "TYPE" : "float", + "MAX" : 360, + "DEFAULT" : 12, + "MIN" : 1, + "LABEL" : "Number Of Divisions" + }, + { + "NAME" : "preRotateAngle", + "TYPE" : "float", + "MAX" : 180, + "DEFAULT" : 0, + "MIN" : -180, + "LABEL" : "Pre Rotate Angle" + }, + { + "MIN" : 0, + "IDENTITY" : 0, + "DEFAULT" : 0, + "LABEL" : "Radius Start", + "TYPE" : "float", + "MAX" : 1, + "NAME" : "centerRadiusStart" + }, + { + "MIN" : 0, + "IDENTITY" : 0, + "DEFAULT" : 1, + "LABEL" : "Radius End", + "TYPE" : "float", + "MAX" : 2, + "NAME" : "centerRadiusEnd" + } + ], + "CREDIT" : "VIDVOX" +} +*/ + + + +const float pi = 3.14159265359; + + + + +void main() { + + vec4 inputPixelColor = vec4(0.0); + vec2 loc = _inputImage_imgRect.zw * vec2(isf_FragNormCoord.x,isf_FragNormCoord.y); + // 'r' is the radius- the distance in pixels from 'loc' to the center of the rendering space + //float r = distance(IMG_SIZE(inputImage)/2.0, loc); + float r = distance(_inputImage_imgRect.zw/2.0, loc); + // 'a' is the angle of the line segment from the center to loc is rotated + //float a = atan ((loc.y-IMG_SIZE(inputImage).y/2.0),(loc.x-IMG_SIZE(inputImage).x/2.0)); + float a = atan ((loc.y-_inputImage_imgRect.w/2.0),(loc.x-_inputImage_imgRect.z/2.0)); + float modAngle = 2.0 * pi / numberOfDivisions; + float scaledCenterRadiusStart = centerRadiusStart * max(RENDERSIZE.x,RENDERSIZE.y); + float scaledCenterRadiusEnd = centerRadiusEnd * max(RENDERSIZE.x,RENDERSIZE.y); + + if (scaledCenterRadiusStart > scaledCenterRadiusEnd) { + scaledCenterRadiusStart = scaledCenterRadiusEnd; + scaledCenterRadiusEnd = centerRadiusStart * max(RENDERSIZE.x,RENDERSIZE.y); + } + + if ((centerRadiusEnd != centerRadiusStart)&&(r >= scaledCenterRadiusStart)&&(r <= scaledCenterRadiusEnd)) { + r = (r - scaledCenterRadiusStart) / (centerRadiusEnd - centerRadiusStart); + + a = mod(a + pi * postRotateAngle/360.0,modAngle); + + // now modify 'a', and convert the modified polar coords (radius/angle) back to cartesian coords (x/y pixels) + loc.x = r * cos(a + 2.0 * pi * (preRotateAngle) / 360.0); + loc.y = r * sin(a + 2.0 * pi * (preRotateAngle) / 360.0); + + loc = loc / _inputImage_imgRect.zw + vec2(0.5); + + if ((loc.x < 0.0)||(loc.y < 0.0)||(loc.x > 1.0)||(loc.y > 1.0)) { + inputPixelColor = vec4(0.0); + } + else { + inputPixelColor = IMG_NORM_PIXEL(inputImage,loc); + } + } + gl_FragColor = inputPixelColor; +} diff --git a/ISF/Radial Spectrogram.fs b/ISF/Radial Spectrogram.fs new file mode 100644 index 0000000..37a6618 --- /dev/null +++ b/ISF/Radial Spectrogram.fs @@ -0,0 +1,86 @@ +/* +{ + "CATEGORIES" : [ + "icalvin102", "Generator" + ], + "DESCRIPTION" : "Generates a radial audiospectrogram from fft-input", + "ISFVSN" : "2", + "INPUTS" : [ + { + "NAME" : "audioFFT", + "TYPE" : "audioFFT", + "LABEL" : "AudioFFT" + }, + { + "NAME" : "size", + "TYPE" : "float", + "MAX" : 0.05, + "DEFAULT" : 0.001, + "MIN" : 1.0, + "LABEL" : "Size" + }, + { + "NAME" : "feedbackOpacity", + "TYPE" : "float", + "MAX" : 1, + "DEFAULT" : 0.99, + "LABEL" : "Feedback Opacity", + "MIN" : 0.7 + }, + { + "NAME" : "low", + "TYPE" : "float", + "MAX" : 1, + "DEFAULT" : 0, + "LABEL" : "Lowest Frequency", + "MIN" : 0 + }, + { + "NAME" : "high", + "TYPE" : "float", + "MAX" : 1, + "DEFAULT" : 1, + "LABEL" : "Heighest Frequency", + "MIN" : 0 + } + ], + "PASSES" : [ + { + "PERSISTENT" : true, + "WIDTH" : "1", + "HEIGHT" : "1", + "TARGET" : "time", + "FLOAT" : true + }, + { + "TARGET" : "buff", + "PERSISTENT" : true, + "FLOAT" : true + }, + { + + } + ], + "CREDIT" : "icalvin102 (calvin@icalvin.de)" +} +*/ + +void main() { + vec4 inputPixelColor = IMG_THIS_PIXEL(buff); + float t = IMG_PIXEL(time, vec2(0.0,0.0)).r; + if(PASSINDEX == 0){ + gl_FragColor = vec4(t+size); + return; + } + if(PASSINDEX == 1){ + vec2 dir = vec2(sin(t), cos(t)); + vec2 co = (isf_FragNormCoord - vec2(0.5,0.5)) * 2.0; + float radius=length(co); + inputPixelColor *= feedbackOpacity; + if( dot(dir, normalize(co)) >= cos(size) && radius <= 1.0){ + inputPixelColor = IMG_NORM_PIXEL(audioFFT, vec2((1.0-radius) * abs(high - low) + low, .5)); + } + inputPixelColor.a = 1.0; + } + gl_FragColor = inputPixelColor; +} diff --git a/ISF/Random Freeze.fs b/ISF/Random Freeze.fs new file mode 100644 index 0000000..eb49b06 --- /dev/null +++ b/ISF/Random Freeze.fs @@ -0,0 +1,97 @@ +/* +{ + "CATEGORIES" : [ + "Glitch" + ], + "DESCRIPTION" : "Causes only part of an image to update", + "ISFVSN" : "2", + "INPUTS" : [ + { + "NAME" : "inputImage", + "TYPE" : "image" + }, + { + "NAME" : "maxUpdateSize", + "TYPE" : "float", + "MAX" : 1, + "DEFAULT" : 0.5, + "LABEL" : "Size", + "MIN" : 0 + }, + { + "NAME" : "maxBlendAmount", + "TYPE" : "float", + "MAX" : 1, + "DEFAULT" : 0, + "MIN" : 0 + }, + { + "NAME" : "resetImage", + "TYPE" : "event", + "LABEL" : "Reset Image" + } + ], + "PASSES" : [ + { + "TARGET" : "lastState", + "PERSISTENT" : true, + "DESCRIPTION" : "" + } + ], + "CREDIT" : "VIDVOX" +} +*/ + +float rand(vec2 co){ + return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453); +} + +vec4 rand4(vec4 co) { + vec4 returnMe = vec4(0.0); + returnMe.r = rand(co.rg); + returnMe.g = rand(co.gb); + returnMe.b = rand(co.ba); + returnMe.a = rand(co.rb); + return returnMe; +} + +vec3 hsv2rgb(vec3 c) { + vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); + vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www); + return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y); +} + +const float pi = 3.14159265359; + + +bool pointInRect(vec2 pt, vec4 r) +{ + bool returnMe = false; + if ((pt.x >= r.x)&&(pt.y >= r.y)&&(pt.x <= r.x + r.z)&&(pt.y <= r.y + r.w)) + returnMe = true; + return returnMe; +} + +void main() { + vec2 loc = isf_FragNormCoord.xy; + bool doReset = ((resetImage)||(FRAMEINDEX==0)); + vec4 returnMe = (doReset) ? IMG_THIS_PIXEL(inputImage) : IMG_THIS_PIXEL(lastState); + vec4 seeds1 = TIME * vec4(0.2123,0.34517,0.53428,0.7431); + vec4 randCoords = rand4(seeds1); + randCoords.zw *= maxUpdateSize; + if (randCoords.x + randCoords.z > 1.0) + randCoords.z = 1.0 - randCoords.x; + if (randCoords.y + randCoords.w > 1.0) + randCoords.w = 1.0 - randCoords.y; + + bool isInShape = pointInRect(loc,randCoords); + + if (isInShape) { + float mixAmount = maxBlendAmount * rand(vec2(TIME,0.32234)); + vec4 newColor = IMG_THIS_PIXEL(inputImage); + newColor.a = 1.0; + returnMe = mix(newColor,returnMe,mixAmount); + } + + gl_FragColor = returnMe; +} diff --git a/ISF/Random Lines.fs b/ISF/Random Lines.fs new file mode 100644 index 0000000..98e531e --- /dev/null +++ b/ISF/Random Lines.fs @@ -0,0 +1,300 @@ +/*{ + "DESCRIPTION": "", + "CREDIT": "VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Generator" + ], + "INPUTS": [ + { + "NAME": "lineCount", + "LABEL": "Line Count", + "TYPE": "float", + "MIN": 1.0, + "MAX": 60.0, + "DEFAULT": 15.0 + }, + { + "NAME": "lineWidth", + "LABEL": "Max Line Width", + "TYPE": "float", + "MIN": 0.0, + "MAX": 0.25, + "DEFAULT": 0.025 + }, + { + "NAME": "randomSeed", + "LABEL": "Random Seed", + "TYPE": "float", + "MIN": 0.01, + "MAX": 1.0, + "DEFAULT": 0.25 + }, + { + "NAME": "wobbleAmount", + "LABEL": "Wobble Amount", + "TYPE": "float", + "MIN": 0.00, + "MAX": 0.1, + "DEFAULT": 0.0 + }, + { + "NAME": "hueRange", + "LABEL": "Hue Range", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.2 + }, + { + "NAME": "colorSaturation", + "LABEL": "Saturation", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 1.0 + }, + { + "NAME": "randomizeBrightness", + "LABEL": "Randomize Brightness", + "TYPE": "bool", + "DEFAULT": true + }, + { + "NAME": "randomizeWidth", + "LABEL": "Randomize Width", + "TYPE": "bool", + "DEFAULT": false + }, + { + "NAME": "randomizeAllPoints", + "LABEL": "Randomize Points", + "TYPE": "bool", + "DEFAULT": false + }, + { + "NAME": "randomizeAlpha", + "LABEL": "Randomize Alpha", + "TYPE": "bool", + "DEFAULT": false + } + ] + +}*/ + +vec3 rgb2hsv(vec3 c) { + vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); + //vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g)); + //vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r)); + vec4 p = c.g < c.b ? vec4(c.bg, K.wz) : vec4(c.gb, K.xy); + vec4 q = c.r < p.x ? vec4(p.xyw, c.r) : vec4(c.r, p.yzx); + + float d = q.x - min(q.w, q.y); + float e = 1.0e-10; + return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x); +} + +vec3 hsv2rgb(vec3 c) { + vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); + vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www); + return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y); +} + +float rand(vec2 co){ + return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453); +} + +bool is_point_above_line(vec2 pt, float slope, float intercept) { + bool returnMe = false; + float y = slope * pt.x + intercept; + if (y < pt.y) + returnMe = true; + return returnMe; +} + +// returns two values – distrance from the line and the percentage of the way on the line +float distance_from_point_to_line(vec2 pt, vec2 l1, vec2 l2){ + float returnMe = 0.0; + float a = (l2.y - l1.y); + float b = (l2.x - l1.x); + float c = 0.0; + + // if b is zero, this is a vertical line! + // in which case distance is based on x distance alone + if (b == 0.0) { + float minY = min(l1.y, l2.y); + float maxY = max(l1.y, l2.y); + + // if we're between the two points distrance is straight up x diff + if ((pt.y > minY) && (pt.y < maxY)) { + returnMe = abs(pt.x-l1.x); + } + else { + //returnMe = min(distance(pt, l1), distance(pt, l2)); + returnMe = -1.0; + } + } + // if a is zero, this is a horizontal line + else if (a == 0.0) { + float minX = min(l1.x, l2.x); + float maxX = max(l1.x, l2.x); + + // if we're between the two points distrance is straight up y diff + if ((pt.x > minX) && (pt.x < maxX)) { + returnMe = abs(pt.y - l1.y); + } + else { + //returnMe = min(distance(pt, l1), distance(pt, l2)); + returnMe = -1.0; + } + } + // if b isn't 0, solve for c now that we know a, b, and either l1 or l2 + else { + // here's the tricky bit- + // if pt is beyond l1 and l2, we should switch to distance from those points + // in order to determine this we need to use the perpendicular lines to the segment l1|l2 that pass through l1 & l2 + // the slope of the perp line will be -1.0 / slope of original line + float m = a / b; + float perpm = -b / a; + vec2 left_line_pt = l1; + vec2 right_line_pt = l2; + if (l1.x > l2.x) { + left_line_pt = l2; + right_line_pt = l1; + } + + float perp_intercept1 = left_line_pt.y - perpm * left_line_pt.x; + float perp_intercept2 = right_line_pt.y - perpm * right_line_pt.x; + + if (m > 0.0) { + /* + if (is_point_above_line(pt, perpm, perp_intercept1)==false) { + //returnMe = distance(pt, left_line_pt); + returnMe = -1.0; + } + else if (is_point_above_line(pt, perpm, perp_intercept2)==true) { + //returnMe = distance(pt, right_line_pt); + returnMe = -1.0; + } + else { + returnMe = abs(a * pt.x - b * pt.y + l2.x * l1.y - l2.y * l1.x) / sqrt(a*a + b*b); + } + */ + returnMe = abs(a * pt.x - b * pt.y + l2.x * l1.y - l2.y * l1.x) / sqrt(a*a + b*b); + } + else { + /* + if (is_point_above_line(pt, perpm, perp_intercept1)==true) { + //returnMe = distance(pt, left_line_pt); + returnMe = -1.0; + } + else if (is_point_above_line(pt, perpm, perp_intercept2)==false) { + //returnMe = distance(pt, right_line_pt); + returnMe = -1.0; + } + else { + returnMe = abs(a * pt.x - b * pt.y + l2.x * l1.y - l2.y * l1.x) / sqrt(a*a + b*b); + } + */ + returnMe = abs(a * pt.x - b * pt.y + l2.x * l1.y - l2.y * l1.x) / sqrt(a*a + b*b); + } + } + + return returnMe; +} + +void main() { + float maxWidth = lineWidth; + float minWidth = 1.0 / min(RENDERSIZE.x, RENDERSIZE.y); + if (maxWidth < minWidth) + maxWidth = minWidth; + + vec4 result = vec4(0.0); + vec2 thisPoint = isf_FragNormCoord; + vec3 colorHSL; + vec2 pt1, pt2; + float baseHue = rand(vec2(floor(lineCount), 1.0)); + + colorHSL.x = baseHue; + colorHSL.y = colorSaturation; + colorHSL.z = 1.0; + if (randomizeBrightness) { + colorHSL.z = rand(vec2(floor(lineCount)+randomSeed * 3.72, randomSeed + lineCount * 0.649)); + } + + vec2 wobbleVector = vec2(0.0); + + pt1 = vec2(rand(vec2(floor(lineCount)+randomSeed*1.123,randomSeed*1.321)),rand(vec2(randomSeed*2.123,randomSeed*3.325))); + pt2 = vec2(rand(vec2(floor(lineCount)+randomSeed*0.317,randomSeed*2.591)),rand(vec2(randomSeed*1.833,randomSeed*4.916))); + + if (wobbleAmount > 0.0) { + wobbleVector = wobbleAmount * vec2(rand(vec2(TIME*1.123,TIME*3.239)),rand(vec2(TIME*3.321,TIME*2.131))) - vec2(wobbleAmount / 2.0); + pt1 = pt1 + wobbleVector; + + wobbleVector = wobbleAmount * vec2(rand(vec2(TIME*6.423,TIME*1.833)),rand(vec2(TIME*2.436,TIME*7.532))) - vec2(wobbleAmount / 2.0); + pt2 = pt2 + wobbleVector; + } + + float randomWidth = maxWidth; + + if (randomizeWidth) { + randomWidth = clamp(maxWidth * rand(vec2(1.0 + randomSeed * 4.672, randomSeed * lineCount * 2.523)), minWidth, maxWidth); + } + + if (distance_from_point_to_line(thisPoint, pt1, pt2) < randomWidth) { + float newAlpha = 1.0; + + if (randomizeAlpha) { + newAlpha = 0.25 + 0.5 * rand(vec2(1.0 + floor(lineCount)+randomSeed * 1.938, randomSeed * lineCount * 1.541)); + } + + result.rgb = hsv2rgb(colorHSL); + result.a = result.a + newAlpha; + } + + for (float i = 0.0; i < 60.0; ++i) { + if (result.a > 0.75) + break; + if (i >= lineCount - 1.0) + break; + if (randomizeAllPoints) { + pt1 = vec2(rand(vec2(i+randomSeed*1.123,floor(lineCount)+randomSeed*1.321)),rand(vec2((1.0+i)*floor(lineCount)+randomSeed*2.123,i+randomSeed*1.325))); + + if (wobbleAmount > 0.0) { + wobbleVector = wobbleAmount * vec2(rand(vec2(i*floor(lineCount)+TIME*3.123,i*floor(lineCount)+TIME*3.239)),rand(vec2(i*floor(lineCount)+TIME*3.321,i*floor(lineCount)+TIME*2.131))) - vec2(wobbleAmount / 2.0); + pt1 = pt1 + wobbleVector; + } + } + else { + pt1 = pt2; + } + pt2 = vec2(rand(vec2(i*floor(lineCount)+randomSeed*3.573,i+randomSeed*6.273)),rand(vec2(i+randomSeed*9.253,i+randomSeed*7.782))); + + if (wobbleAmount > 0.0) { + wobbleVector = wobbleAmount * vec2(rand(vec2(i*floor(lineCount)+TIME*3.573,i+randomSeed*6.273)),rand(vec2(i+TIME*9.253,i+TIME*7.782))) - vec2(wobbleAmount / 2.0); + pt2 = pt2 + wobbleVector; + } + + if (randomizeWidth) { + randomWidth = clamp(maxWidth * rand(vec2(i + randomSeed * 4.672, 1.673 + i * randomSeed * 2.523)), minWidth, maxWidth); + } + + if (distance_from_point_to_line(thisPoint, pt1, pt2) < randomWidth) { + //result = vec4(1.0); + float newAlpha = 1.0; + + if (randomizeAlpha) { + newAlpha = 0.25 + 0.25 * rand(vec2(i + floor(lineCount)+randomSeed * 1.938, randomSeed * lineCount * 1.541)); + } + + colorHSL.x = mod(baseHue + hueRange * rand(vec2(floor(lineCount)+randomSeed, i)), 1.0); + if (randomizeBrightness) { + colorHSL.z = 0.15 + 0.85 * rand(vec2(i + floor(lineCount)+randomSeed * 2.78, randomSeed + lineCount * 0.249)); + } + result.rgb = result.rgb + hsv2rgb(colorHSL) * newAlpha; + result.a = result.a + newAlpha; + } + } + + gl_FragColor = result; +} diff --git a/ISF/Random Shape Blast.fs b/ISF/Random Shape Blast.fs new file mode 100644 index 0000000..92e9427 --- /dev/null +++ b/ISF/Random Shape Blast.fs @@ -0,0 +1,224 @@ +/* +{ + "CATEGORIES" : [ + "Generator" + ], + "KEYWORDS" : [ + "Abstract", "Geometric" + ], + "DESCRIPTION" : "", + "ISFVSN" : "2", + "INPUTS" : [ + { + "NAME" : "saturation", + "TYPE" : "float", + "MAX" : 1, + "DEFAULT" : 0.5, + "LABEL" : "Saturation", + "MIN" : 0 + }, + { + "NAME" : "brightness", + "TYPE" : "float", + "MAX" : 1, + "DEFAULT" : 1, + "LABEL" : "Brightness", + "MIN" : 0 + }, + { + "NAME" : "mixAmount", + "TYPE" : "float", + "MAX" : 1, + "DEFAULT" : 1, + "LABEL" : "Mix Amount", + "MIN" : 0 + }, + { + "NAME": "maskShapeMode", + "LABEL": "Mask Shape Mode", + "TYPE": "long", + "VALUES": [ + 0, + 1, + 2, + 3, + 4 + ], + "LABELS": [ + "Random", + "Rectangle", + "Triangle", + "Circle", + "Diamond" + ], + "DEFAULT": 0 + }, + { + "NAME" : "anchorToBottom", + "TYPE" : "bool", + "DEFAULT" : 0, + "LABEL" : "Anchor To Bottom" + }, + { + "NAME" : "resetImage", + "TYPE" : "event", + "LABEL" : "Reset" + } + ], + "PASSES" : [ + { + "TARGET" : "lastState", + "PERSISTENT" : true, + "DESCRIPTION" : "Holds the last render state for drawing over" + } + ], + "CREDIT" : "VIDVOX" +} +*/ + +float rand(vec2 co){ + return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453); +} + +vec4 rand4(vec4 co) { + vec4 returnMe = vec4(0.0); + returnMe.r = rand(co.rg); + returnMe.g = rand(co.gb); + returnMe.b = rand(co.ba); + returnMe.a = rand(co.rb); + return returnMe; +} + +vec3 hsv2rgb(vec3 c) { + vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); + vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www); + return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y); +} + +const float pi = 3.14159265359; + + +vec2 rotatePoint(vec2 pt, float angle, vec2 center) +{ + vec2 returnMe; + float s = sin(angle * pi); + float c = cos(angle * pi); + + returnMe = pt; + + // translate point back to origin: + returnMe.x -= center.x; + returnMe.y -= center.y; + + // rotate point + float xnew = returnMe.x * c - returnMe.y * s; + float ynew = returnMe.x * s + returnMe.y * c; + + // translate point back: + returnMe.x = xnew + center.x; + returnMe.y = ynew + center.y; + return returnMe; +} + +float sign(vec2 p1, vec2 p2, vec2 p3) +{ + return (p1.x - p3.x) * (p2.y - p3.y) - (p2.x - p3.x) * (p1.y - p3.y); +} + +bool RotatedPointInTriangle(vec2 pt, vec2 v1, vec2 v2, vec2 v3, vec2 center) +{ + bool b1, b2, b3; + + vec2 v1r = v1; + vec2 v2r = v2; + vec2 v3r = v3; + + b1 = sign(pt, v1r, v2r) < 0.0; + b2 = sign(pt, v2r, v3r) < 0.0; + b3 = sign(pt, v3r, v1r) < 0.0; + + return ((b1 == b2) && (b2 == b3)); +} + + +float isPointInShape(vec2 pt, int shape, vec4 shapeCoordinates) { + float returnMe = 0.0; + + // rectangle + if (shape == 0) { + if (RotatedPointInTriangle(pt, shapeCoordinates.xy, shapeCoordinates.xy + vec2(0.0, shapeCoordinates.w), shapeCoordinates.xy + vec2(shapeCoordinates.z, 0.0), shapeCoordinates.xy + shapeCoordinates.zw / 2.0)) { + returnMe = 1.0; + // soft edge if needed + if ((pt.x > shapeCoordinates.x) && (pt.x < shapeCoordinates.x)) { + returnMe = clamp(((pt.x - shapeCoordinates.x) / RENDERSIZE.x), 0.0, 1.0); + returnMe = pow(returnMe, 0.5); + } + else if ((pt.x > shapeCoordinates.x + shapeCoordinates.z) && (pt.x < shapeCoordinates.x + shapeCoordinates.z)) { + returnMe = clamp(((shapeCoordinates.x + shapeCoordinates.z - pt.x) / RENDERSIZE.x), 0.0, 1.0); + returnMe = pow(returnMe, 0.5); + } + } + else if (RotatedPointInTriangle(pt, shapeCoordinates.xy + shapeCoordinates.zw, shapeCoordinates.xy + vec2(0.0, shapeCoordinates.w), shapeCoordinates.xy + vec2(shapeCoordinates.z, 0.0), shapeCoordinates.xy + shapeCoordinates.zw / 2.0)) { + returnMe = 1.0; + // soft edge if needed + if ((pt.x > shapeCoordinates.x) && (pt.x < shapeCoordinates.x)) { + returnMe = clamp(((pt.x - shapeCoordinates.x) / RENDERSIZE.x), 0.0, 1.0); + returnMe = pow(returnMe, 0.5); + } + else if ((pt.x > shapeCoordinates.x + shapeCoordinates.z) && (pt.x < shapeCoordinates.x + shapeCoordinates.z)) { + returnMe = clamp(((shapeCoordinates.x + shapeCoordinates.z - pt.x) / RENDERSIZE.x), 0.0, 1.0); + returnMe = pow(returnMe, 0.5); + } + } + } + // triangle + else if (shape == 1) { + if (RotatedPointInTriangle(pt, shapeCoordinates.xy, shapeCoordinates.xy + vec2(shapeCoordinates.z / 2.0, shapeCoordinates.w), shapeCoordinates.xy + vec2(shapeCoordinates.z, 0.0), shapeCoordinates.xy + shapeCoordinates.zw / 2.0)) { + returnMe = 1.0; + } + } + // oval + else if (shape == 2) { + returnMe = distance(pt, vec2(shapeCoordinates.xy + shapeCoordinates.zw / 2.0)); + if (returnMe < min(shapeCoordinates.z,shapeCoordinates.w) / 2.0) { + returnMe = 1.0; + } + else { + returnMe = 0.0; + } + } + // diamond + else if (shape == 3) { + if (RotatedPointInTriangle(pt, shapeCoordinates.xy + vec2(0.0, shapeCoordinates.w / 2.0), shapeCoordinates.xy + vec2(shapeCoordinates.z / 2.0, shapeCoordinates.w), shapeCoordinates.xy + vec2(shapeCoordinates.z, shapeCoordinates.w / 2.0), shapeCoordinates.xy + shapeCoordinates.zw / 2.0)) { + returnMe = 1.0; + } + else if (RotatedPointInTriangle(pt, shapeCoordinates.xy + vec2(0.0, shapeCoordinates.w / 2.0), shapeCoordinates.xy + vec2(shapeCoordinates.z / 2.0, 0.0), shapeCoordinates.xy + vec2(shapeCoordinates.z, shapeCoordinates.w / 2.0), shapeCoordinates.xy + shapeCoordinates.zw / 2.0)) { + returnMe = 1.0; + } + } + + return returnMe; +} + + +void main() { + vec2 loc = isf_FragNormCoord.xy; + vec4 returnMe = (resetImage) ? vec4(0.0) : IMG_NORM_PIXEL(lastState,loc); + vec4 seeds1 = TIME * vec4(0.2123,0.34517,0.53428,0.7431); + vec4 randCoords = rand4(seeds1); + if (anchorToBottom == true) { + randCoords.y = 0.0; + } + int shapeMode = (maskShapeMode != 0) ? maskShapeMode - 1 : int(floor(3.99 * rand(vec2(TIME+0.213,0.43*TIME+0.831)))); + float isInShape = isPointInShape(loc,shapeMode,randCoords); + + if (isInShape > 0.0) { + float randHue = rand(vec2(TIME,0.32234)); + vec4 newColor = vec4(0.0); + newColor.rgb = hsv2rgb(vec3(randHue,saturation,brightness)); + newColor.a = 1.0; + returnMe = mix(returnMe,newColor,mixAmount); + } + + gl_FragColor = returnMe; +} diff --git a/ISF/Random Shape.fs b/ISF/Random Shape.fs new file mode 100644 index 0000000..ba6b5ee --- /dev/null +++ b/ISF/Random Shape.fs @@ -0,0 +1,157 @@ +/*{ + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Generator" + ], + "INPUTS": [ + { + "NAME": "pointCount", + "LABEL": "Point Count", + "TYPE": "float", + "MIN": 3.0, + "MAX": 90.0, + "DEFAULT": 5.0 + }, + { + "NAME": "randomSeed", + "LABEL": "Random Seed", + "TYPE": "float", + "MIN": 0.01, + "MAX": 1.0, + "DEFAULT": 0.125 + }, + { + "NAME": "colorSaturation", + "LABEL": "Saturation", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.0 + }, + { + "NAME": "randomizeBrightness", + "LABEL": "Random Shades", + "TYPE": "bool", + "DEFAULT": true + }, + { + "NAME": "randomizeAlpha", + "LABEL": "Random Alpha", + "TYPE": "bool", + "DEFAULT": false + }, + { + "NAME": "randomizeAllPoints", + "LABEL": "Triangle Shapes", + "TYPE": "bool", + "DEFAULT": false + } + ] +}*/ + + + +vec3 rgb2hsv(vec3 c) { + vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); + //vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g)); + //vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r)); + vec4 p = c.g < c.b ? vec4(c.bg, K.wz) : vec4(c.gb, K.xy); + vec4 q = c.r < p.x ? vec4(p.xyw, c.r) : vec4(c.r, p.yzx); + + float d = q.x - min(q.w, q.y); + float e = 1.0e-10; + return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x); +} + +vec3 hsv2rgb(vec3 c) { + vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); + vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www); + return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y); +} + +float rand(vec2 co){ + return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453); +} + + +float sign(vec2 p1, vec2 p2, vec2 p3) { + return (p1.x - p3.x) * (p2.y - p3.y) - (p2.x - p3.x) * (p1.y - p3.y); +} + +bool PointInTriangle(vec2 pt, vec2 v1, vec2 v2, vec2 v3) { + bool b1, b2, b3; + + b1 = sign(pt, v1, v2) < 0.0; + b2 = sign(pt, v2, v3) < 0.0; + b3 = sign(pt, v3, v1) < 0.0; + + return ((b1 == b2) && (b2 == b3)); +} + + +void main() { + vec4 result = vec4(0.0); + vec2 thisPoint = isf_FragNormCoord; + vec3 colorHSL; + vec2 pt1, pt2, pt3; + + colorHSL.x = rand(vec2(floor(pointCount)+randomSeed, 1.0)); + colorHSL.y = colorSaturation; + colorHSL.z = 1.0; + if (randomizeBrightness) { + colorHSL.z = rand(vec2(floor(pointCount)+randomSeed * 3.72, randomSeed + pointCount * 0.649)); + } + + pt1 = vec2(rand(vec2(floor(pointCount)+randomSeed*1.123,randomSeed*1.321)),rand(vec2(randomSeed*2.123,randomSeed*3.325))); + pt2 = vec2(rand(vec2(floor(pointCount)+randomSeed*5.317,randomSeed*2.591)),rand(vec2(randomSeed*1.833,randomSeed*4.916))); + pt3 = vec2(rand(vec2(floor(pointCount)+randomSeed*3.573,randomSeed*6.273)),rand(vec2(randomSeed*9.253,randomSeed*7.782))); + + if (PointInTriangle(thisPoint,pt1,pt2,pt3)) { + float newAlpha = 1.0; + + if (randomizeAlpha) { + newAlpha = 0.5 + 0.5 * rand(vec2(1.0 + floor(pointCount)+randomSeed * 1.938, randomSeed * pointCount * 1.541)); + } + + result.rgb = hsv2rgb(colorHSL); + result.a = result.a + newAlpha; + } + + for (float i = 0.0; i < 60.0; ++i) { + if (result.a > 0.75) + break; + if (i > pointCount - 3.0) + break; + if (randomizeAllPoints) { + pt1 = vec2(rand(vec2(i+randomSeed*1.123,i*floor(pointCount)+randomSeed*1.321)),rand(vec2(i*floor(pointCount)+randomSeed*2.123,i+randomSeed*1.325))); + pt2 = vec2(rand(vec2(i*floor(pointCount)+randomSeed*5.317,randomSeed*2.591)),rand(vec2(i+randomSeed*1.833,i*floor(pointCount)+randomSeed*4.916))); + } + else { + pt1 = pt2; + pt2 = pt3; + } + pt3 = vec2(rand(vec2(i*floor(pointCount)+randomSeed*3.573,i+randomSeed*6.273)),rand(vec2(i+randomSeed*9.253,i+randomSeed*7.782))); + if (PointInTriangle(thisPoint,pt1,pt2,pt3)) { + //result = vec4(1.0); + float newAlpha = 1.0; + + if (randomizeAlpha) { + newAlpha = 0.1 + 0.25 * rand(vec2(i + floor(pointCount)+randomSeed * 1.938, randomSeed * pointCount * 1.541)); + } + + colorHSL.x = rand(vec2(floor(pointCount)+randomSeed, i)); + if (randomizeBrightness) { + colorHSL.z = 0.15 + 0.85 * rand(vec2(i + floor(pointCount)+randomSeed * 2.78, randomSeed + pointCount * 0.249)); + } + result.rgb = hsv2rgb(colorHSL); + result.a = result.a + newAlpha; + } + } + + //result.rgb = result.rgb * hsv2rgb(colorHSL); + + gl_FragColor = result; +} + + \ No newline at end of file diff --git a/ISF/Replicate Random.fs b/ISF/Replicate Random.fs new file mode 100644 index 0000000..efed4f6 --- /dev/null +++ b/ISF/Replicate Random.fs @@ -0,0 +1,96 @@ +/* +{ + "CATEGORIES" : [ + "Glitch", + "Stylize" + ], + "DESCRIPTION" : "", + "ISFVSN" : "2", + "INPUTS" : [ + { + "NAME" : "inputImage", + "TYPE" : "image" + }, + { + "NAME" : "randomSeed", + "TYPE" : "float" + }, + { + "NAME" : "repetitions", + "TYPE" : "float", + "MAX" : 15, + "DEFAULT" : 5, + "MIN" : 1 + }, + { + "NAME" : "randomizeOpacity", + "TYPE" : "bool" + } + ], + "CREDIT" : "" +} +*/ + + +float rand(vec2 co){ + return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453); +} + + +vec2 paddedZoomedPosition(vec2 loc, float zl, vec2 c, float p) { + vec2 returnMe = loc; + float zoomMult = (1.0/zl); + vec2 modifiedCenter = 2.0*(1.0+p)*c/RENDERSIZE-(1.0+p); + float modifiedPadding = p; + + returnMe.x = (returnMe.x)*zoomMult + p/2.0 - modifiedCenter.x; + returnMe.y = (returnMe.y)*zoomMult + p/2.0 - modifiedCenter.y; + returnMe.x = mod(returnMe.x,1.0+modifiedPadding) - p/2.0; + returnMe.y = mod(returnMe.y,1.0+modifiedPadding) - p/2.0; + + return returnMe; +} + +vec2 randomPaddedZoomedPositionWithSeed(vec2 loc, vec2 seed) { + float minZoomLevel = (4.0/RENDERSIZE.x); + vec2 zSeed = seed * vec2(0.128,9.21) + vec2(1.42,2.17); + vec2 cSeed1 = seed * vec2(0.436,0.931) + vec2(2.76,3.779); + vec2 cSeed2 = seed * vec2(2.831,2.173) + vec2(1.73,6.256); + float modZoom = 0.9*rand(zSeed); + vec2 modCenter = RENDERSIZE*vec2(rand(cSeed1),rand(cSeed2)); + float modPad = 0.5*rand(seed); + modZoom = (modZoom < minZoomLevel) ? minZoomLevel : modZoom; + + vec2 returnMe = paddedZoomedPosition(loc,modZoom,modCenter,modPad); + + return returnMe; +} + + + + +void main() { + vec4 inputPixelColor = vec4(0.0); + + int depth = int(repetitions); + vec2 loc = isf_FragNormCoord; + + for (int i = 0;i < depth;++i) { + vec2 tmpSeed = vec2((1.12+float(i))*randomSeed+1.37,(1.92+float(i))*randomSeed+1.37); + float modOpacity = (randomizeOpacity) ? 0.25+0.75*rand(tmpSeed) : 1.0; + loc = randomPaddedZoomedPositionWithSeed(isf_FragNormCoord,tmpSeed); + if ((loc.x < 0.0)||(loc.y < 0.0)||(loc.x > 1.0)||(loc.y > 1.0)) { + //inputPixelColor = vec4(0.0); + } + else { + vec4 tmpColor = IMG_NORM_PIXEL(inputImage,loc); + inputPixelColor.rgb = inputPixelColor.rgb + tmpColor.rgb * tmpColor.a * modOpacity; + inputPixelColor.a += (tmpColor.a * modOpacity); + if (inputPixelColor.a > 0.99) { + break; + } + } + } + + gl_FragColor = inputPixelColor; +} diff --git a/ISF/Replicate.fs b/ISF/Replicate.fs new file mode 100644 index 0000000..87bc520 --- /dev/null +++ b/ISF/Replicate.fs @@ -0,0 +1,127 @@ +/* +{ + "CATEGORIES" : [ + "Geometry Adjustment", + "Stylize", "Tile Effect" + ], + "DESCRIPTION" : "", + "ISFVSN" : "2", + "INPUTS" : [ + { + "NAME" : "inputImage", + "TYPE" : "image" + }, + { + "NAME" : "startSize", + "TYPE" : "float", + "MAX" : 2, + "DEFAULT" : 0.5, + "MIN" : 0, + "IDENTITY" : 1 + }, + { + "NAME" : "startOpacity", + "TYPE" : "float", + "MAX" : 1, + "DEFAULT" : 1, + "MIN" : 0 + }, + { + "NAME" : "startCenter", + "TYPE" : "point2D" + }, + { + "NAME" : "startPadding", + "TYPE" : "float", + "MAX" : 1, + "DEFAULT" : 0.25, + "MIN" : 0 + }, + { + "NAME" : "endSize", + "TYPE" : "float", + "MAX" : 2, + "DEFAULT" : 0.25, + "MIN" : 0 + }, + { + "NAME" : "endOpacity", + "TYPE" : "float", + "MAX" : 1, + "DEFAULT" : 1, + "MIN" : 0 + }, + { + "NAME" : "endCenter", + "TYPE" : "point2D" + }, + { + "NAME" : "endPadding", + "TYPE" : "float", + "MAX" : 1, + "DEFAULT" : 0.1, + "MIN" : 0 + }, + { + "NAME" : "repetitions", + "TYPE" : "float", + "MAX" : 15, + "DEFAULT" : 5, + "MIN" : 1 + } + ], + "CREDIT" : "" +} +*/ + + +vec2 paddedZoomedPosition(vec2 loc, float zl, vec2 c, float p) { + vec2 returnMe = loc; + float zoomMult = (1.0/zl); + vec2 modifiedCenter = 2.0*(1.0+p)*c/RENDERSIZE-(1.0+p); + float modifiedPadding = p; + + returnMe.x = (returnMe.x)*zoomMult + p/2.0 - modifiedCenter.x; + returnMe.y = (returnMe.y)*zoomMult + p/2.0 - modifiedCenter.y; + returnMe.x = mod(returnMe.x,1.0+modifiedPadding) - p/2.0; + returnMe.y = mod(returnMe.y,1.0+modifiedPadding) - p/2.0; + + return returnMe; +} + + +void main() { + vec4 inputPixelColor = vec4(0.0); + + int depth = int(repetitions); + vec2 loc = isf_FragNormCoord; + float minZoomLevel = (1.0/RENDERSIZE.x); + float startZoomLevel = (startSize < minZoomLevel) ? minZoomLevel : startSize; + float endZoomLevel = (endSize < minZoomLevel) ? minZoomLevel : endSize; + float zoomIncrement = (depth < 2) ? 0.0 : (endZoomLevel - startZoomLevel)/float(depth-1); + vec2 centerIncrement = (depth < 2) ? vec2(0.0) : (endCenter - startCenter)/float(depth-1); + float paddingIncrement = (depth < 2) ? 0.0 : (endPadding - startPadding)/float(depth-1); + float opacityIncrement = (depth < 2) ? 0.0 : (endOpacity - startOpacity)/float(depth-1); + + for (int i = 0;i < depth;++i) { + float modZoom = startZoomLevel + zoomIncrement * float(i); + vec2 modCenter = startCenter + centerIncrement * float(i); + float modPad = startPadding + paddingIncrement * float(i); + float modOpacity = startOpacity + opacityIncrement * float(i); + modOpacity = clamp(modOpacity,0.0,1.0); + loc = paddedZoomedPosition(isf_FragNormCoord,modZoom,modCenter,modPad); + if ((loc.x < 0.0)||(loc.y < 0.0)||(loc.x > 1.0)||(loc.y > 1.0)) { + //inputPixelColor = vec4(0.0); + } + else { + vec4 tmpColor = IMG_NORM_PIXEL(inputImage,loc); + inputPixelColor.rgb = inputPixelColor.rgb + tmpColor.rgb * tmpColor.a * modOpacity; + inputPixelColor.a += (tmpColor.a * modOpacity); + if (inputPixelColor.a > 0.99) { + break; + } + } + } + + gl_FragColor = inputPixelColor; +} diff --git a/ISF/Resize Glitch.fs b/ISF/Resize Glitch.fs new file mode 100644 index 0000000..be63c4c --- /dev/null +++ b/ISF/Resize Glitch.fs @@ -0,0 +1,116 @@ +/* +{ + "CATEGORIES" : [ + "Glitch", + "Geometry Adjustment" + ], + "ISFVSN" : "2", + "INPUTS" : [ + { + "NAME" : "inputImage", + "TYPE" : "image" + }, + { + "NAME" : "randomFrequency", + "TYPE" : "float", + "MAX" : 1, + "DEFAULT" : 0, + "MIN" : 0 + }, + { + "NAME" : "glitchNow", + "TYPE" : "event" + }, + { + "NAME" : "levelX", + "TYPE" : "float", + "MAX" : 10, + "DEFAULT" : 2, + "MIN" : 0.01 + }, + { + "NAME" : "levelY", + "TYPE" : "float", + "MAX" : 10, + "DEFAULT" : 2, + "MIN" : 0.01 + }, + { + "NAME" : "center", + "TYPE" : "point2D", + "MAX" : [ + 1, + 1 + ], + "DEFAULT" : [ + 0.5, + 0.5 + ], + "MIN" : [ + 0, + 0 + ] + }, + { + "NAME" : "randomizeWidth", + "TYPE" : "bool", + "DEFAULT" : true + }, + { + "NAME" : "randomizeHeight", + "TYPE" : "bool", + "DEFAULT" : true + }, + { + "NAME" : "randomizeCenter", + "TYPE" : "bool", + "DEFAULT" : true + } + ], + "CREDIT" : "by VIDVOX" +} +*/ + +float random (vec2 st) { + return fract(sin(dot(st.xy,vec2(12.9898,78.233)))*43758.5453123); +} + +void main() { + vec2 loc; + vec2 modifiedCenter; + + loc = isf_FragNormCoord; + modifiedCenter = (randomizeCenter) ? vec2(random(vec2(TIME*1.24,0.234)),random(vec2(TIME*2.93,1.234))) : center; + + float newWidth = 1.0; + float newHeight = 1.0; + + bool doGlitch = false; + + if (glitchNow) { + doGlitch = true; + } + else if (randomFrequency == 1.0) { + doGlitch = true; + } + else { + float val = random(vec2(TIME,0.2321)); + if (val <= randomFrequency) { + doGlitch = true; + } + } + + if (doGlitch == true) { + newWidth = (randomizeWidth == false) ? levelX : levelX * random(vec2(TIME+0.315,FRAMEINDEX+32)); + newHeight = (randomizeHeight == false) ? levelY : levelY * random(vec2(TIME+0.942,FRAMEINDEX+43)); + } + + loc.x = (loc.x - modifiedCenter.x)*(1.0/newWidth) + modifiedCenter.x; + loc.y = (loc.y - modifiedCenter.y)*(1.0/newHeight) + modifiedCenter.y; + if ((loc.x < 0.0)||(loc.y < 0.0)||(loc.x > 1.0)||(loc.y > 1.0)) { + gl_FragColor = vec4(0.0); + } + else { + gl_FragColor = IMG_NORM_PIXEL(inputImage,loc); + } +} diff --git a/ISF/Ripples.fs b/ISF/Ripples.fs new file mode 100644 index 0000000..0b407f7 --- /dev/null +++ b/ISF/Ripples.fs @@ -0,0 +1,109 @@ +/*{ + "CREDIT": "by carter rosenberg", + "ISFVSN": "2", + "CATEGORIES": [ + "Distortion Effect" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "level", + "TYPE": "float", + "MIN": 0.1, + "MAX": 32.0, + "DEFAULT": 1.0 + }, + { + "NAME": "offset", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.0 + }, + { + "NAME": "x_smear", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.0 + }, + { + "NAME": "y_smear", + "TYPE": "float", + "MIN": 0.01, + "MAX": 1.0, + "DEFAULT": 0.0 + }, + { + "NAME": "center", + "TYPE": "point2D", + "DEFAULT": [ + 0.5, + 0.5 + ] + }, + { + "NAME": "mode", + "VALUES": [ + 0, + 1 + ], + "LABELS": [ + "Single", + "Double" + ], + "DEFAULT": 0, + "TYPE": "long" + } + ] +}*/ + +const float pi = 3.14159265359; + +#ifndef GL_ES +float distance (vec2 center, vec2 pt) +{ + float tmp = pow(center.x-pt.x,2.0)+pow(center.y-pt.y,2.0); + return pow(tmp,0.5); +} +#endif + +void main() { + vec2 uv = vec2(isf_FragNormCoord[0],isf_FragNormCoord[1]); + vec2 texSize = RENDERSIZE; + vec2 tc = uv * texSize; + vec2 modifiedCenter = center; + float r = distance(modifiedCenter, tc); + float a = atan ((tc.y-modifiedCenter.y),(tc.x-modifiedCenter.x)); + float radius = 1.0; + float radius_sized = radius * length(RENDERSIZE); + + tc -= modifiedCenter; + + if (r < radius_sized) { + float percent = 1.0-(radius_sized - r) / radius_sized; + float adjustedOffset = offset * 2.0 * pi; + if (mode == 0) { + tc.x = r*(1.0+sin(percent * level * 2.0 * pi + adjustedOffset))/2.0 * cos(a); + tc.y = r*(1.0+sin(percent * level * 2.0 * pi + adjustedOffset))/2.0 * sin(a); + } + else if (mode == 1) { + tc.x = r*(1.0+sin(percent * level * 2.0 * pi * cos(adjustedOffset + percent * percent * level * 2.0 * pi)))/2.0 * cos(a); + tc.y = r*(1.0+sin(percent * level * 2.0 * pi * cos(adjustedOffset + percent * percent * level * 2.0 * pi)))/2.0 * sin(a); + } + tc.x = mix(uv.x, tc.x, max(1.0-x_smear,0.001)); + tc.y = mix(uv.y, tc.y, max(1.0-y_smear,0.001)); + } + tc += modifiedCenter; + vec2 loc = tc / texSize; + + if ((loc.x < 0.0)||(loc.y < 0.0)||(loc.x > 1.0)||(loc.y > 1.0)) { + gl_FragColor = vec4(0.0); + } + else { + gl_FragColor = IMG_NORM_PIXEL(inputImage, loc); + } +} diff --git a/ISF/Rotate.fs b/ISF/Rotate.fs new file mode 100644 index 0000000..eb31a8a --- /dev/null +++ b/ISF/Rotate.fs @@ -0,0 +1,34 @@ +/*{ + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Geometry Adjustment" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "angle", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.0 + } + ] +}*/ + + +varying vec2 translated_coord; + +void main() { + vec2 loc = translated_coord; + // if out of range draw black + if ((loc.x < 0.0)||(loc.y < 0.0)||(loc.x > 1.0)||(loc.y > 1.0)) { + gl_FragColor = vec4(0.0); + } + else { + gl_FragColor = IMG_NORM_PIXEL(inputImage,loc); + } +} diff --git a/ISF/Rotate.vs b/ISF/Rotate.vs new file mode 100644 index 0000000..7de2586 --- /dev/null +++ b/ISF/Rotate.vs @@ -0,0 +1,23 @@ +varying vec2 translated_coord; + +const float pi = 3.14159265359; + +void main() { + isf_vertShaderInit(); + + // 'loc' is the location in pixels of this vertex. we're going to convert this to polar coordinates (radius/angle) + //vec2 loc = IMG_SIZE(inputImage) * vec2(isf_FragNormCoord[0],isf_FragNormCoord[1]); + vec2 loc = _inputImage_imgRect.zw * vec2(isf_FragNormCoord[0],isf_FragNormCoord[1]); + // 'r' is the radius- the distance in pixels from 'loc' to the center of the rendering space + //float r = distance(IMG_SIZE(inputImage)/2.0, loc); + float r = distance(_inputImage_imgRect.zw/2.0, loc); + // 'a' is the angle of the line segment from the center to loc is rotated + //float a = atan ((loc.y-IMG_SIZE(inputImage).y/2.0),(loc.x-IMG_SIZE(inputImage).x/2.0)); + float a = atan ((loc.y-_inputImage_imgRect.w/2.0),(loc.x-_inputImage_imgRect.z/2.0)); + + // now modify 'a', and convert the modified polar coords (radius/angle) back to cartesian coords (x/y pixels) + loc.x = r * cos(a + 2.0 * pi * angle); + loc.y = r * sin(a + 2.0 * pi * angle); + + translated_coord = loc / _inputImage_imgRect.zw + vec2(0.5); +} \ No newline at end of file diff --git a/ISF/Sepia Tone.fs b/ISF/Sepia Tone.fs new file mode 100644 index 0000000..eb3e4cd --- /dev/null +++ b/ISF/Sepia Tone.fs @@ -0,0 +1,42 @@ +/*{ + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Color Effect" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "contrast", + "TYPE": "float", + "MIN": 0.8, + "MAX": 1.2, + "DEFAULT": 0.8 + } + ] +}*/ + + +// Adapted from https://www.omniref.com/ruby/gems/essytas/0.0.1/files/lib/glsl/sepia.frag + +void main() { + + vec4 color = IMG_THIS_PIXEL(inputImage); + + vec4 sepia1 = vec4( 0.2, 0.05, 0.0, 1.0 ); + vec4 sepia2 = vec4( 1.0, 0.9, 0.5, 1.0 ); + float sepiaMix = dot(vec3(0.3, 0.59, 0.11), color.rgb); + color = mix(color, vec4(sepiaMix), 0.5); + vec4 sepia = mix(sepia1, sepia2, sepiaMix); + sepia = vec4( min( vec3( 1.0 ), sepia.rgb ), color.a ); + + float bright = 0.05; + sepia = sepia + vec4(bright, bright, bright, 0.0); + sepia.rgb = ((vec3(2.0) * (sepia.rgb - vec3(0.5))) * vec3(contrast) / vec3(2.0)) + vec3(0.5); + + gl_FragColor = sepia; + +} diff --git a/ISF/Set Alpha.fs b/ISF/Set Alpha.fs new file mode 100644 index 0000000..5f8802c --- /dev/null +++ b/ISF/Set Alpha.fs @@ -0,0 +1,30 @@ +/*{ + "DESCRIPTION": "Sets the alpha channel of the image", + "CREDIT": "VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Color Adjustment" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "newAlpha", + "LABEL": "New Alpha", + "TYPE": "float", + "DEFAULT": 0.5, + "MIN": 0.0, + "MAX": 1.0 + } + ] +}*/ + +void main() { + vec4 inputPixelColor = IMG_THIS_NORM_PIXEL(inputImage); + + inputPixelColor.a = newAlpha; + + gl_FragColor = inputPixelColor; +} diff --git a/ISF/Shake.fs b/ISF/Shake.fs new file mode 100644 index 0000000..b608b32 --- /dev/null +++ b/ISF/Shake.fs @@ -0,0 +1,54 @@ +/* +{ + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Geometry Adjustment", "Stylize" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "magnitude", + "TYPE": "float", + "MIN": 0.0, + "MAX": 2.0, + "DEFAULT": 0.0 + }, + { + "NAME": "intensity", + "TYPE": "float", + "MIN": 0.0, + "MAX": 10.0, + "DEFAULT": 1.0 + } + ] +} +*/ + + +const float pi = 3.14159265359; + + +float rand(vec2 co) { + return fract(sin(dot(co.xy, vec2(12.9898,78.233))) * 43758.5453); +} + +void main(void) { + float offset = 0.1 * magnitude; + vec2 uv = gl_FragCoord.xy / RENDERSIZE.xy; + float rotation = intensity * 2.0 * pi * rand(vec2(magnitude, TIME)); + float yOffset = offset * sin(TIME * 1.0 * cos(TIME * intensity) + rotation) * rand(vec2(magnitude, TIME)); + float xOffset = offset * cos(TIME * 1.0 * cos(TIME * intensity) + rotation) * rand(vec2(1.0-magnitude, TIME));; + + float zoom = 1.0 + offset; + + uv = (uv - 0.5) / zoom + 0.5; + + uv.y += yOffset; + uv.x += xOffset; + + gl_FragColor = IMG_NORM_PIXEL(inputImage, uv); +} \ No newline at end of file diff --git a/ISF/Shape Mask.fs b/ISF/Shape Mask.fs new file mode 100644 index 0000000..91890ba --- /dev/null +++ b/ISF/Shape Mask.fs @@ -0,0 +1,295 @@ +/*{ + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Masking" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "maskShapeMode", + "LABEL": "Mask Shape Mode", + "TYPE": "long", + "VALUES": [ + 0, + 1, + 2, + 3 + ], + "LABELS": [ + "Rectangle", + "Triangle", + "Circle", + "Diamond" + ], + "DEFAULT": 1 + }, + { + "NAME": "shapeWidth", + "LABEL": "Shape Width", + "TYPE": "float", + "MIN": 0.0, + "MAX": 2.0, + "DEFAULT": 0.5 + }, + { + "NAME": "shapeHeight", + "LABEL": "Shape Height", + "TYPE": "float", + "MIN": 0.0, + "MAX": 2.0, + "DEFAULT": 0.5 + }, + { + "NAME": "center", + "TYPE": "point2D", + "DEFAULT": [ + 0.5, + 0.5 + ] + }, + { + "NAME": "invertMask", + "LABEL": "Invert Mask", + "TYPE": "bool", + "DEFAULT": false + }, + { + "NAME": "horizontalRepeat", + "LABEL": "Horizontal Repeat", + "TYPE": "long", + "VALUES": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9 + ], + "LABELS": [ + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9" + ], + "DEFAULT": 1 + }, + { + "NAME": "verticalRepeat", + "LABEL": "Vertical Repeat", + "TYPE": "long", + "VALUES": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9 + ], + "LABELS": [ + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9" + ], + "DEFAULT": 1 + }, + { + "NAME": "maskApplyMode", + "LABEL": "Apply Mask", + "TYPE": "long", + "VALUES": [ + 0, + 1, + 2 + ], + "LABELS": [ + "Apply Mask", + "Set Alpha", + "Show Mask" + ], + "DEFAULT": 0 + } + ] +}*/ + + + +const float pi = 3.14159265359; + + +vec2 rotatePoint(vec2 pt, float angle, vec2 center) +{ + vec2 returnMe; + float s = sin(angle * pi); + float c = cos(angle * pi); + + returnMe = pt; + + // translate point back to origin: + returnMe.x -= center.x; + returnMe.y -= center.y; + + // rotate point + float xnew = returnMe.x * c - returnMe.y * s; + float ynew = returnMe.x * s + returnMe.y * c; + + // translate point back: + returnMe.x = xnew + center.x; + returnMe.y = ynew + center.y; + return returnMe; +} + +float sign(vec2 p1, vec2 p2, vec2 p3) +{ + return (p1.x - p3.x) * (p2.y - p3.y) - (p2.x - p3.x) * (p1.y - p3.y); +} + +bool PointInTriangle(vec2 pt, vec2 v1, vec2 v2, vec2 v3) +{ + bool b1, b2, b3; + + b1 = sign(pt, v1, v2) < 0.0; + b2 = sign(pt, v2, v3) < 0.0; + b3 = sign(pt, v3, v1) < 0.0; + + return ((b1 == b2) && (b2 == b3)); +} + +bool RotatedPointInTriangle(vec2 pt, vec2 v1, vec2 v2, vec2 v3, vec2 center) +{ + bool b1, b2, b3; + + vec2 v1r = v1; + vec2 v2r = v2; + vec2 v3r = v3; + + b1 = sign(pt, v1r, v2r) < 0.0; + b2 = sign(pt, v2r, v3r) < 0.0; + b3 = sign(pt, v3r, v1r) < 0.0; + + return ((b1 == b2) && (b2 == b3)); +} + + +float isPointInShape(vec2 pt, int shape, vec4 shapeCoordinates) { + float returnMe = 0.0; + + // rectangle + if (shape == 0) { + if (RotatedPointInTriangle(pt, shapeCoordinates.xy, shapeCoordinates.xy + vec2(0.0, shapeCoordinates.w), shapeCoordinates.xy + vec2(shapeCoordinates.z, 0.0), shapeCoordinates.xy + shapeCoordinates.zw / 2.0)) { + returnMe = 1.0; + // soft edge if needed + if ((pt.x > shapeCoordinates.x) && (pt.x < shapeCoordinates.x)) { + returnMe = clamp(((pt.x - shapeCoordinates.x) / RENDERSIZE.x), 0.0, 1.0); + returnMe = pow(returnMe, 0.5); + } + else if ((pt.x > shapeCoordinates.x + shapeCoordinates.z) && (pt.x < shapeCoordinates.x + shapeCoordinates.z)) { + returnMe = clamp(((shapeCoordinates.x + shapeCoordinates.z - pt.x) / RENDERSIZE.x), 0.0, 1.0); + returnMe = pow(returnMe, 0.5); + } + } + else if (RotatedPointInTriangle(pt, shapeCoordinates.xy + shapeCoordinates.zw, shapeCoordinates.xy + vec2(0.0, shapeCoordinates.w), shapeCoordinates.xy + vec2(shapeCoordinates.z, 0.0), shapeCoordinates.xy + shapeCoordinates.zw / 2.0)) { + returnMe = 1.0; + // soft edge if needed + if ((pt.x > shapeCoordinates.x) && (pt.x < shapeCoordinates.x)) { + returnMe = clamp(((pt.x - shapeCoordinates.x) / RENDERSIZE.x), 0.0, 1.0); + returnMe = pow(returnMe, 0.5); + } + else if ((pt.x > shapeCoordinates.x + shapeCoordinates.z) && (pt.x < shapeCoordinates.x + shapeCoordinates.z)) { + returnMe = clamp(((shapeCoordinates.x + shapeCoordinates.z - pt.x) / RENDERSIZE.x), 0.0, 1.0); + returnMe = pow(returnMe, 0.5); + } + } + } + // triangle + else if (shape == 1) { + if (RotatedPointInTriangle(pt, shapeCoordinates.xy, shapeCoordinates.xy + vec2(shapeCoordinates.z / 2.0, shapeCoordinates.w), shapeCoordinates.xy + vec2(shapeCoordinates.z, 0.0), shapeCoordinates.xy + shapeCoordinates.zw / 2.0)) { + returnMe = 1.0; + } + } + // oval + else if (shape == 2) { + returnMe = distance(pt, vec2(shapeCoordinates.xy + shapeCoordinates.zw / 2.0)); + if (returnMe < min(shapeCoordinates.z,shapeCoordinates.w) / 2.0) { + returnMe = 1.0; + } + else { + returnMe = 0.0; + } + } + // diamond + else if (shape == 3) { + if (RotatedPointInTriangle(pt, shapeCoordinates.xy + vec2(0.0, shapeCoordinates.w / 2.0), shapeCoordinates.xy + vec2(shapeCoordinates.z / 2.0, shapeCoordinates.w), shapeCoordinates.xy + vec2(shapeCoordinates.z, shapeCoordinates.w / 2.0), shapeCoordinates.xy + shapeCoordinates.zw / 2.0)) { + returnMe = 1.0; + } + else if (RotatedPointInTriangle(pt, shapeCoordinates.xy + vec2(0.0, shapeCoordinates.w / 2.0), shapeCoordinates.xy + vec2(shapeCoordinates.z / 2.0, 0.0), shapeCoordinates.xy + vec2(shapeCoordinates.z, shapeCoordinates.w / 2.0), shapeCoordinates.xy + shapeCoordinates.zw / 2.0)) { + returnMe = 1.0; + } + } + + return returnMe; +} + + + +void main() { + vec4 srcPixel = IMG_THIS_PIXEL(inputImage); + vec2 centerPt = center; + vec2 tmpVec = RENDERSIZE * vec2(shapeWidth,shapeHeight) / 2.0; + vec4 patternRect = vec4(vec2(centerPt - tmpVec),tmpVec * 2.0); + vec2 thisPoint = RENDERSIZE * isf_FragNormCoord; + + if ((thisPoint.x >= patternRect.x) && (thisPoint.x <= patternRect.x + abs(patternRect.z))) { + patternRect.z = patternRect.z / float(horizontalRepeat); + patternRect.x = patternRect.x + abs(patternRect.z) * floor((thisPoint.x - patternRect.x) / abs(patternRect.z)); + } + else { + patternRect.z = patternRect.z / float(horizontalRepeat); + } + + if ((thisPoint.y >= patternRect.y) && (thisPoint.y <= patternRect.y + abs(patternRect.w))) { + patternRect.w = patternRect.w / float(verticalRepeat); + patternRect.y = patternRect.y + abs(patternRect.w) * floor((thisPoint.y - patternRect.y) / abs(patternRect.w)); + } + else { + patternRect.w = patternRect.w / float(verticalRepeat); + } + + float luminance = isPointInShape(thisPoint.xy, maskShapeMode, patternRect); + + if (invertMask) + luminance = 1.0 - luminance; + + if (maskApplyMode == 0) { + srcPixel = srcPixel * luminance; + } + else if (maskApplyMode == 1) { + srcPixel.a = srcPixel.a * luminance; + } + else if (maskApplyMode == 2) { + srcPixel.rgb = vec3(luminance); + } + + gl_FragColor = srcPixel; +} + diff --git a/ISF/Sharpen Luminance.fs b/ISF/Sharpen Luminance.fs new file mode 100644 index 0000000..1745ecc --- /dev/null +++ b/ISF/Sharpen Luminance.fs @@ -0,0 +1,55 @@ +/*{ + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Sharpen" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "intensity", + "TYPE": "float", + "MIN": 0.0, + "MAX": 2.0, + "DEFAULT": 1.0 + } + ] +}*/ + + +varying vec2 left_coord; +varying vec2 right_coord; +varying vec2 above_coord; +varying vec2 below_coord; + +varying vec2 lefta_coord; +varying vec2 righta_coord; +varying vec2 leftb_coord; +varying vec2 rightb_coord; + +float gray(vec4 n) +{ + return (n.r + n.g + n.b)/3.0; +} + +void main() +{ + + vec4 color = IMG_THIS_PIXEL(inputImage); + float colorL = gray(IMG_NORM_PIXEL(inputImage, left_coord)); + float colorR = gray(IMG_NORM_PIXEL(inputImage, right_coord)); + float colorA = gray(IMG_NORM_PIXEL(inputImage, above_coord)); + float colorB = gray(IMG_NORM_PIXEL(inputImage, below_coord)); + + float colorLA = gray(IMG_NORM_PIXEL(inputImage, lefta_coord)); + float colorRA = gray(IMG_NORM_PIXEL(inputImage, righta_coord)); + float colorLB = gray(IMG_NORM_PIXEL(inputImage, leftb_coord)); + float colorRB = gray(IMG_NORM_PIXEL(inputImage, rightb_coord)); + + vec4 final = color + color * intensity * (8.0*gray(color) - colorL - colorR - colorA - colorB - colorLA - colorRA - colorLB - colorRB); + + gl_FragColor = final; +} \ No newline at end of file diff --git a/ISF/Sharpen Luminance.vs b/ISF/Sharpen Luminance.vs new file mode 100644 index 0000000..c8b60f7 --- /dev/null +++ b/ISF/Sharpen Luminance.vs @@ -0,0 +1,27 @@ +varying vec2 left_coord; +varying vec2 right_coord; +varying vec2 above_coord; +varying vec2 below_coord; + +varying vec2 lefta_coord; +varying vec2 righta_coord; +varying vec2 leftb_coord; +varying vec2 rightb_coord; + + +void main() +{ + isf_vertShaderInit(); + vec2 texc = vec2(isf_FragNormCoord[0],isf_FragNormCoord[1]); + vec2 d = 1.0/RENDERSIZE; + + left_coord = clamp(vec2(texc.xy + vec2(-d.x , 0)),0.0,1.0); + right_coord = clamp(vec2(texc.xy + vec2(d.x , 0)),0.0,1.0); + above_coord = clamp(vec2(texc.xy + vec2(0,d.y)),0.0,1.0); + below_coord = clamp(vec2(texc.xy + vec2(0,-d.y)),0.0,1.0); + + lefta_coord = clamp(vec2(texc.xy + vec2(-d.x , d.x)),0.0,1.0); + righta_coord = clamp(vec2(texc.xy + vec2(d.x , d.x)),0.0,1.0); + leftb_coord = clamp(vec2(texc.xy + vec2(-d.x , -d.x)),0.0,1.0); + rightb_coord = clamp(vec2(texc.xy + vec2(d.x , -d.x)),0.0,1.0); +} \ No newline at end of file diff --git a/ISF/Sharpen RGB.fs b/ISF/Sharpen RGB.fs new file mode 100644 index 0000000..23fbed6 --- /dev/null +++ b/ISF/Sharpen RGB.fs @@ -0,0 +1,72 @@ +/*{ + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Sharpen" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "intensityR", + "TYPE": "float", + "MIN": 0.0, + "MAX": 10.0, + "DEFAULT": 1.0 + }, + { + "NAME": "intensityG", + "TYPE": "float", + "MIN": 0.0, + "MAX": 10.0, + "DEFAULT": 1.0 + }, + { + "NAME": "intensityB", + "TYPE": "float", + "MIN": 0.0, + "MAX": 10.0, + "DEFAULT": 1.0 + } + ] +}*/ + + +varying vec2 left_coord; +varying vec2 right_coord; +varying vec2 above_coord; +varying vec2 below_coord; + +varying vec2 lefta_coord; +varying vec2 righta_coord; +varying vec2 leftb_coord; +varying vec2 rightb_coord; + +float gray(vec4 n) +{ + return (n.r + n.g + n.b)/3.0; +} + +void main() +{ + + vec4 color = IMG_THIS_PIXEL(inputImage); + vec4 colorL = IMG_NORM_PIXEL(inputImage, left_coord); + vec4 colorR = IMG_NORM_PIXEL(inputImage, right_coord); + vec4 colorA = IMG_NORM_PIXEL(inputImage, above_coord); + vec4 colorB = IMG_NORM_PIXEL(inputImage, below_coord); + + vec4 colorLA = IMG_NORM_PIXEL(inputImage, lefta_coord); + vec4 colorRA = IMG_NORM_PIXEL(inputImage, righta_coord); + vec4 colorLB = IMG_NORM_PIXEL(inputImage, leftb_coord); + vec4 colorRB = IMG_NORM_PIXEL(inputImage, rightb_coord); + + vec4 final = color; + final.r = color.r + intensityR * (8.0*color.r - colorL.r - colorR.r - colorA.r - colorB.r - colorLA.r - colorRA.r - colorLB.r - colorRB.r); + final.g = color.g + intensityG * (8.0*color.g - colorL.g - colorR.g - colorA.g - colorB.g - colorLA.g - colorRA.g - colorLB.g - colorRB.g); + final.b = color.b + intensityB * (8.0*color.b - colorL.b - colorR.b - colorA.b - colorB.b - colorLA.b - colorRA.b - colorLB.b - colorRB.b); + + gl_FragColor = final; +} \ No newline at end of file diff --git a/ISF/Sharpen RGB.vs b/ISF/Sharpen RGB.vs new file mode 100644 index 0000000..c8b60f7 --- /dev/null +++ b/ISF/Sharpen RGB.vs @@ -0,0 +1,27 @@ +varying vec2 left_coord; +varying vec2 right_coord; +varying vec2 above_coord; +varying vec2 below_coord; + +varying vec2 lefta_coord; +varying vec2 righta_coord; +varying vec2 leftb_coord; +varying vec2 rightb_coord; + + +void main() +{ + isf_vertShaderInit(); + vec2 texc = vec2(isf_FragNormCoord[0],isf_FragNormCoord[1]); + vec2 d = 1.0/RENDERSIZE; + + left_coord = clamp(vec2(texc.xy + vec2(-d.x , 0)),0.0,1.0); + right_coord = clamp(vec2(texc.xy + vec2(d.x , 0)),0.0,1.0); + above_coord = clamp(vec2(texc.xy + vec2(0,d.y)),0.0,1.0); + below_coord = clamp(vec2(texc.xy + vec2(0,-d.y)),0.0,1.0); + + lefta_coord = clamp(vec2(texc.xy + vec2(-d.x , d.x)),0.0,1.0); + righta_coord = clamp(vec2(texc.xy + vec2(d.x , d.x)),0.0,1.0); + leftb_coord = clamp(vec2(texc.xy + vec2(-d.x , -d.x)),0.0,1.0); + rightb_coord = clamp(vec2(texc.xy + vec2(d.x , -d.x)),0.0,1.0); +} \ No newline at end of file diff --git a/ISF/Shockwave Pulse.fs b/ISF/Shockwave Pulse.fs new file mode 100644 index 0000000..9dae042 --- /dev/null +++ b/ISF/Shockwave Pulse.fs @@ -0,0 +1,96 @@ +/*{ + "DESCRIPTION": "", + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Distortion Effect" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "pulse", + "TYPE": "event" + }, + { + "NAME": "rate", + "LABEL": "rate", + "TYPE": "float", + "MIN": 0.0, + "MAX": 4.0, + "DEFAULT": 1.0 + }, + { + "NAME": "magnitude", + "LABEL": "magnitude", + "TYPE": "float", + "MIN": 0.0, + "MAX": 0.2, + "DEFAULT": 0.08 + }, + { + "NAME": "distortion", + "LABEL": "distortion", + "TYPE": "float", + "MIN": 0.0, + "MAX": 20.0, + "DEFAULT": 10.0 + }, + { + "NAME": "center", + "TYPE": "point2D", + "DEFAULT": [ + 0.0, + 0.0 + ] + } + ], + "PASSES": [ + { + "TARGET":"lastTime", + "WIDTH": "1", + "HEIGHT": "1", + "FLOAT": true, + "PERSISTENT": true, + "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..." + }, + { + + } + ] + +}*/ + + + +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 = IMG_PIXEL(lastTime,vec2(0.5)); + // i'm only using the X, which is the last render time we reset + srcPixel.r = (pulse) ? 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 = isf_FragNormCoord.xy; + vec2 texCoord = uv; + vec2 mod_center = center / RENDERSIZE; + float distance = distance(uv, mod_center); + vec4 lastPosVector = IMG_PIXEL(lastTime,vec2(0.5)); + 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 = IMG_NORM_PIXEL(inputImage, texCoord); + } +} diff --git a/ISF/Shockwave.fs b/ISF/Shockwave.fs new file mode 100644 index 0000000..2ec9b34 --- /dev/null +++ b/ISF/Shockwave.fs @@ -0,0 +1,76 @@ +/*{ + "DESCRIPTION": "", + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Distortion Effect" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "position", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.0 + }, + { + "NAME": "distortion", + "TYPE": "float", + "MIN": 1.0, + "MAX": 20.0, + "DEFAULT": 10.0 + }, + { + "NAME": "magnitude", + "TYPE": "float", + "MIN": 0.00, + "MAX": 0.2, + "DEFAULT": 0.08 + }, + { + "NAME": "center", + "TYPE": "point2D", + "DEFAULT": [ + 0.0, + 0.0 + ] + }, + { + "NAME": "background", + "TYPE": "bool", + "DEFAULT": 1.0 + } + ] + +}*/ + + + +void main() +{ + // do this junk so that the ripple starts from nothing + vec2 uv = isf_FragNormCoord.xy; + vec2 texCoord = uv; + vec2 mod_center = center / RENDERSIZE; + vec4 color = vec4(0.0); + float distance = distance(uv, mod_center); + float adjustedTime = (position * RENDERSIZE.x/RENDERSIZE.y - magnitude)/(1.0 - magnitude); + + if ( (distance <= (adjustedTime + magnitude)) && (distance >= (adjustedTime - magnitude)) ) { + float diff = (distance - adjustedTime); + float powDiff = 1.0 - pow(abs(diff*distortion), + 0.8); + float diffTime = diff * powDiff; + vec2 diffUV = normalize(uv - mod_center); + texCoord = uv + (diffUV * diffTime); + color = IMG_NORM_PIXEL(inputImage, texCoord); + } + else if (background) { + color = IMG_NORM_PIXEL(inputImage, texCoord); + } + gl_FragColor = color; +} diff --git a/ISF/Side Scroller And Flip.fs b/ISF/Side Scroller And Flip.fs new file mode 100644 index 0000000..6a24a47 --- /dev/null +++ b/ISF/Side Scroller And Flip.fs @@ -0,0 +1,58 @@ +/*{ + "CREDIT": "BrianChasalow", + "ISFVSN": "2", + "CATEGORIES": [ + "Geometry Adjustment" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "slide", + "TYPE": "float", + "MIN": 0.0, + "MAX": 2.0, + "DEFAULT": 0.0 + }, + { + "NAME": "shift", + "TYPE": "float", + "MIN": 0.0, + "MAX": 2.0, + "DEFAULT": 0.0 + }, + { + "NAME": "mirrorHorizontal", + "TYPE": "bool", + "MIN": false, + "MAX": true, + "DEFAULT": true + }, + { + "NAME": "mirrorVertical", + "TYPE": "bool", + "MIN": false, + "MAX": true, + "DEFAULT": true + } + + ] + }*/ + +void main(void) +{ + vec2 retard = isf_FragNormCoord; + retard.x += slide; + retard.y += shift; + vec2 moddedRetard = mod(retard,1.0); + + if(mirrorHorizontal && retard.x >= 1.0 && retard.x <= 2.0) + moddedRetard = vec2(1.0-moddedRetard.x, moddedRetard.y); + if(mirrorVertical && retard.y >= 1.0 && retard.y <= 2.0) + moddedRetard = vec2(moddedRetard.x, 1.0-moddedRetard.y); + + vec4 pixel = IMG_NORM_PIXEL(inputImage, moddedRetard); + gl_FragColor = pixel; +} \ No newline at end of file diff --git a/ISF/Sine Warp Gradient.fs b/ISF/Sine Warp Gradient.fs new file mode 100644 index 0000000..77b4bba --- /dev/null +++ b/ISF/Sine Warp Gradient.fs @@ -0,0 +1,110 @@ +/*{ + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Generator" + ], + "INPUTS": [ + { + "NAME": "size", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.5 + }, + { + "NAME": "rotation", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.0 + }, + { + "NAME": "angle", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.0 + }, + { + "NAME": "shift", + "TYPE": "point2D", + "DEFAULT": [ + 0.5, + 0.5 + ] + }, + { + "NAME": "xcolor", + "TYPE": "color", + "DEFAULT": [ + 1.0, + 0.5, + 0.0, + 1.0 + ] + }, + { + "NAME": "ycolor", + "TYPE": "color", + "DEFAULT": [ + 0.0, + 0.5, + 1.0, + 1.0 + ] + }, + { + "NAME": "background", + "TYPE": "color", + "DEFAULT": [ + 0.0, + 0.0, + 0.0, + 0.0 + ] + } + ] +}*/ + + + +// Basically just uses the same gradient as the Sine Warp Tile but uses the x/y values as the mix amounts for our colors + + +const float tau = 6.28318530718; + + +vec2 pattern() { + float s = sin(tau * rotation * 0.5); + float c = cos(tau * rotation * 0.5); + vec2 tex = isf_FragNormCoord; + float scale = 1.0 / max(size,0.001); + vec2 point = vec2( c * tex.x - s * tex.y, s * tex.x + c * tex.y ) * scale; + point = point - scale * shift / RENDERSIZE; + // do the sine distort + point = 0.5 + 0.5 * vec2( sin(scale * point.x), sin(scale * point.y)); + + // now do a rotation + vec2 center = vec2(0.5,0.5); + float r = distance(center, point); + float a = atan ((point.y-center.y),(point.x-center.x)); + + s = sin(a + tau * angle); + c = cos(a + tau * angle); + + float zoom = max(abs(s),abs(c))*RENDERSIZE.x / RENDERSIZE.y; + + point.x = (r * c)/zoom + 0.5; + point.y = (r * s)/zoom + 0.5; + + return point; +} + + +void main() { + + vec2 pat = pattern(); + + gl_FragColor = background + pat.x * xcolor + pat.y * ycolor; +} \ No newline at end of file diff --git a/ISF/Sine Warp Tile.fs b/ISF/Sine Warp Tile.fs new file mode 100644 index 0000000..53ec86a --- /dev/null +++ b/ISF/Sine Warp Tile.fs @@ -0,0 +1,80 @@ +/*{ + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Tile Effect" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "size", + "TYPE": "float", + "MIN": 0.0, + "MAX": 0.5, + "DEFAULT": 0.5 + }, + { + "NAME": "rotation", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.0 + }, + { + "NAME": "angle", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.0 + }, + { + "NAME": "shift", + "TYPE": "point2D", + "DEFAULT": [ + 0.5, + 0.5 + ] + } + ] +}*/ + + +const float tau = 6.28318530718; + + +vec2 pattern() { + float s = sin(tau * rotation * 0.5); + float c = cos(tau * rotation * 0.5); + vec2 tex = isf_FragNormCoord; + float scale = 1.0 / max(size,0.001); + vec2 point = vec2( c * tex.x - s * tex.y, s * tex.x + c * tex.y ) * scale; + point = point - scale * shift / RENDERSIZE; + // do the sine distort + point = 0.5 + 0.5 * vec2( sin(scale * point.x), sin(scale * point.y)); + + // now do a rotation + vec2 center = vec2(0.5,0.5); + float r = distance(center, point); + float a = atan ((point.y-center.y),(point.x-center.x)); + + s = sin(a + tau * angle); + c = cos(a + tau * angle); + + float zoom = max(abs(s),abs(c))*RENDERSIZE.x / RENDERSIZE.y; + + point.x = (r * c)/zoom + 0.5; + point.y = (r * s)/zoom + 0.5; + + return point; +} + + +void main() { + + vec2 pat = pattern(); + + gl_FragColor = IMG_NORM_PIXEL(inputImage,pat); +} \ No newline at end of file diff --git a/ISF/Sketch.fs b/ISF/Sketch.fs new file mode 100644 index 0000000..e78674b --- /dev/null +++ b/ISF/Sketch.fs @@ -0,0 +1,61 @@ +/*{ + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Stylize" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "intensity", + "TYPE": "float", + "MIN": 0.0, + "MAX": 10.0, + "DEFAULT": 1.0 + } + ] +}*/ + + +varying vec2 left_coord; +varying vec2 right_coord; +varying vec2 above_coord; +varying vec2 below_coord; + +varying vec2 lefta_coord; +varying vec2 righta_coord; +varying vec2 leftb_coord; +varying vec2 rightb_coord; + +float gray(vec4 n) +{ + return (n.r + n.g + n.b)/3.0; +} + +void main() +{ + + vec4 color = IMG_THIS_PIXEL(inputImage); + vec4 colorL = IMG_NORM_PIXEL(inputImage, left_coord); + vec4 colorR = IMG_NORM_PIXEL(inputImage, right_coord); + vec4 colorA = IMG_NORM_PIXEL(inputImage, above_coord); + vec4 colorB = IMG_NORM_PIXEL(inputImage, below_coord); + + vec4 colorLA = IMG_NORM_PIXEL(inputImage, lefta_coord); + vec4 colorRA = IMG_NORM_PIXEL(inputImage, righta_coord); + vec4 colorLB = IMG_NORM_PIXEL(inputImage, leftb_coord); + vec4 colorRB = IMG_NORM_PIXEL(inputImage, rightb_coord); + + // blur, do edges, then use the edge as a mask on the blurred + + float gx = (-1.0 * gray(colorLA)) + (-2.0 * gray(colorL)) + (-1.0 * gray(colorLB)) + (1.0 * gray(colorRA)) + (2.0 * gray(colorR)) + (1.0 * gray(colorRB)); + float gy = (1.0 * gray(colorLA)) + (2.0 * gray(colorA)) + (1.0 * gray(colorRA)) + (-1.0 * gray(colorRB)) + (-2.0 * gray(colorB)) + (-1.0 * gray(colorLB)); + + float edge = clamp(pow(gx*gx + gy*gy,0.5) * intensity,0.0,1.0); + vec4 blurred = (color + colorL + colorR + colorA + colorB + colorLA + colorRA + colorLB + colorRB) / 9.0; + //gl_FragColor = vec4(edge,edge,edge,1.0); + gl_FragColor = blurred * (1.0-edge); +} \ No newline at end of file diff --git a/ISF/Sketch.vs b/ISF/Sketch.vs new file mode 100644 index 0000000..c8b60f7 --- /dev/null +++ b/ISF/Sketch.vs @@ -0,0 +1,27 @@ +varying vec2 left_coord; +varying vec2 right_coord; +varying vec2 above_coord; +varying vec2 below_coord; + +varying vec2 lefta_coord; +varying vec2 righta_coord; +varying vec2 leftb_coord; +varying vec2 rightb_coord; + + +void main() +{ + isf_vertShaderInit(); + vec2 texc = vec2(isf_FragNormCoord[0],isf_FragNormCoord[1]); + vec2 d = 1.0/RENDERSIZE; + + left_coord = clamp(vec2(texc.xy + vec2(-d.x , 0)),0.0,1.0); + right_coord = clamp(vec2(texc.xy + vec2(d.x , 0)),0.0,1.0); + above_coord = clamp(vec2(texc.xy + vec2(0,d.y)),0.0,1.0); + below_coord = clamp(vec2(texc.xy + vec2(0,-d.y)),0.0,1.0); + + lefta_coord = clamp(vec2(texc.xy + vec2(-d.x , d.x)),0.0,1.0); + righta_coord = clamp(vec2(texc.xy + vec2(d.x , d.x)),0.0,1.0); + leftb_coord = clamp(vec2(texc.xy + vec2(-d.x , -d.x)),0.0,1.0); + rightb_coord = clamp(vec2(texc.xy + vec2(d.x , -d.x)),0.0,1.0); +} \ No newline at end of file diff --git a/ISF/Sliding Strips.fs b/ISF/Sliding Strips.fs new file mode 100644 index 0000000..56d2cd6 --- /dev/null +++ b/ISF/Sliding Strips.fs @@ -0,0 +1,76 @@ +/* +{ + "CATEGORIES" : [ + "Geometry Adjustment" + ], + "DESCRIPTION" : "", + "ISFVSN" : "2", + "INPUTS" : [ + { + "NAME" : "inputImage", + "TYPE" : "image" + }, + { + "NAME" : "xShiftAmount", + "TYPE" : "float", + "MAX" : 1, + "DEFAULT" : 0, + "MIN" : 0 + }, + { + "NAME" : "yShiftAmount", + "TYPE" : "float", + "MAX" : 1, + "DEFAULT" : 0, + "MIN" : 0 + }, + { + "NAME" : "xTileSize", + "TYPE" : "float", + "MAX" : 1, + "DEFAULT" : 0.25, + "MIN" : 0 + }, + { + "NAME" : "yTileSize", + "TYPE" : "float", + "MAX" : 1, + "DEFAULT" : 0.25, + "MIN" : 0 + } + ], + "CREDIT" : "" +} +*/ + +void main() { + vec2 loc = isf_FragNormCoord.xy; + vec2 coords = vec2(0.0); + coords.x = (xTileSize == 0.0) ? gl_FragCoord.x : floor(loc.x / yTileSize); + coords.y = (yTileSize == 0.0) ? gl_FragCoord.y : floor(loc.y / xTileSize); + + vec2 maxCoords = vec2(0.0); + maxCoords.x = (xTileSize == 0.0) ? RENDERSIZE.x : (1.0 / yTileSize); + maxCoords.y = (yTileSize == 0.0) ? RENDERSIZE.y : (1.0 / xTileSize); + vec2 shiftAmount = vec2(xShiftAmount, yShiftAmount); + + shiftAmount.x = shiftAmount.x + shiftAmount.x * coords.y / maxCoords.y; + + if (shiftAmount.x < 0.0) + shiftAmount.x = 0.0; + else if (shiftAmount.x > 1.0) + shiftAmount.x = 1.0; + + loc.x = mod(loc.x + shiftAmount.x, 1.0); + + shiftAmount.y = shiftAmount.y + shiftAmount.y * coords.x / maxCoords.x; + + if (shiftAmount.y < 0.0) + shiftAmount.y = 0.0; + else if (shiftAmount.y > 1.0) + shiftAmount.y = 1.0; + + loc.y = mod(loc.y + shiftAmount.y, 1.0); + + gl_FragColor = IMG_NORM_PIXEL(inputImage, loc); +} diff --git a/ISF/Slit Scan.fs b/ISF/Slit Scan.fs new file mode 100644 index 0000000..fef1ba3 --- /dev/null +++ b/ISF/Slit Scan.fs @@ -0,0 +1,87 @@ +/*{ + "DESCRIPTION": "Pixels update only if within range of the specified lines to create a slit scan style", + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Glitch" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "spacing", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.5, + "DEFAULT": 1.0 + }, + { + "NAME": "line_width", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.33 + }, + { + "NAME": "angle", + "TYPE": "float", + "MIN": -1.0, + "MAX": 1.0, + "DEFAULT": 0.25 + }, + { + "NAME": "shift", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.5 + } + ], + "PASSES": [ + { + "TARGET":"bufferVariableNameA", + "PERSISTENT": true + } + ] + +}*/ + + +const float pi = 3.14159265359; + + +float pattern() { + float s = sin(angle * pi); + float c = cos(angle * pi); + vec2 tex = isf_FragNormCoord * RENDERSIZE; + float spaced = length(RENDERSIZE) * spacing; + vec2 point = vec2( c * tex.x - s * tex.y, s * tex.x + c * tex.y ) * max(1.0/spaced,0.001); + float d = point.y; + float w = line_width; + if (w > spacing) { + w = 0.99*spacing; + } + return ( mod(d + shift*spacing + w * 0.5,spacing) ); +} + +void main() +{ + vec4 freshPixel = IMG_PIXEL(inputImage,gl_FragCoord.xy); + // If we're on the line, update, otherwise use the stale pixel + vec4 result = IMG_PIXEL(bufferVariableNameA,gl_FragCoord.xy); + float pat = pattern(); + float w = line_width; + if (w > spacing) { + w = 0.99*spacing; + } + + if ((pat > 0.0)&&(pat <= w)) { + float percent = (1.0-abs(w-2.0*pat)/w); + percent = clamp(percent,0.0,1.0); + result = mix(result, freshPixel, percent); + //result = vec4(percent,percent,percent,1.0); + } + gl_FragColor = result; +} diff --git a/ISF/Smoke Screen.fs b/ISF/Smoke Screen.fs new file mode 100644 index 0000000..78d91db --- /dev/null +++ b/ISF/Smoke Screen.fs @@ -0,0 +1,105 @@ +/* +{ + "CATEGORIES" : [ + "Stylize" + ], + "DESCRIPTION" : "A smoke screen overlay effect", + "ISFVSN" : "2", + "INPUTS" : [ + { + "NAME" : "inputImage", + "TYPE" : "image" + }, + { + "NAME" : "smokeColor", + "TYPE" : "color", + "DEFAULT" : [ + 0.75, + 0.75, + 0.75, + 0.75 + ] + }, + { + "NAME" : "smokeIntensity", + "TYPE" : "float", + "MAX" : 10, + "DEFAULT" : 1, + "MIN" : 0 + }, + { + "NAME" : "smokeDirection", + "TYPE" : "point2D", + "MAX" : [ + 1, + 1 + ], + "DEFAULT" : [ + 0.5, + 0.75 + ], + "MIN" : [ + 0, + 0 + ] + } + ], + "CREDIT" : "jackdavenport" +} +*/ + + + +// Converted from https://www.shadertoy.com/view/4t2SRz by jackdavenport + + + +float random(vec2 co){ + return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453); +} + +float noise(vec2 p) { + + return random(vec2(p.x + p.y * 10000.0,p.y + p.x * 10000.0)); + +} + +vec2 sw(vec2 p) { return vec2(floor(p.x), floor(p.y)); } +vec2 se(vec2 p) { return vec2(ceil(p.x), floor(p.y)); } +vec2 nw(vec2 p) { return vec2(floor(p.x), ceil(p.y)); } +vec2 ne(vec2 p) { return vec2(ceil(p.x), ceil(p.y)); } + +float smoothNoise(vec2 p) { + + vec2 interp = smoothstep(0., 1., fract(p)); + float s = mix(noise(sw(p)), noise(se(p)), interp.x); + float n = mix(noise(nw(p)), noise(ne(p)), interp.x); + return mix(s, n, interp.y); + +} + +float fractalNoise(vec2 p) { + + float n = 0.; + n += smoothNoise(p); + n += smoothNoise(p * 2.) / 2.; + n += smoothNoise(p * 4.) / 4.; + n += smoothNoise(p * 8.) / 8.; + n += smoothNoise(p * 16.) / 16.; + n /= 1. + 1./2. + 1./4. + 1./8. + 1./16.; + return n; + +} + +void main() { + vec2 uv = isf_FragNormCoord; + vec2 sd = (smokeDirection - vec2(0.5)); + vec2 nuv = vec2(uv.x - sd.x * TIME / 3.0, uv.y - sd.y * TIME / 3.0); + + float x = fractalNoise(nuv * 6.0); + vec4 inputPixel = IMG_NORM_PIXEL(inputImage,uv); + vec4 final = mix(vec4(x * smokeColor.rgb,max(x,inputPixel.a)), inputPixel, pow(abs(uv.y),pow(smokeColor.a*smokeIntensity*x,2.0))); + + gl_FragColor = final; +} + diff --git a/ISF/Soft Blur.fs b/ISF/Soft Blur.fs new file mode 100644 index 0000000..4a5cd9f --- /dev/null +++ b/ISF/Soft Blur.fs @@ -0,0 +1,85 @@ +/*{ + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Blur" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "softness", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.9 + }, + { + "NAME": "depth", + "TYPE": "float", + "MIN": 1.0, + "MAX": 10.0, + "DEFAULT": 10.0 + } + ], + "PASSES": [ + { + "TARGET": "smaller", + "WIDTH": "max(floor($WIDTH*0.02),1.0)", + "HEIGHT": "max(floor($HEIGHT*0.02),1.0)" + }, + { + "TARGET": "small", + "WIDTH": "max(floor($WIDTH*0.25),1.0)", + "HEIGHT": "max(floor($HEIGHT*0.25),1.0)" + }, + { + + } + ] +}*/ + + +// A simple three pass blur – first reduce the size, then do a weighted blur, then do the same thing + + +varying vec2 left_coord; +varying vec2 right_coord; +varying vec2 above_coord; +varying vec2 below_coord; + +varying vec2 lefta_coord; +varying vec2 righta_coord; +varying vec2 leftb_coord; +varying vec2 rightb_coord; + + + +void main() +{ + + vec4 color = IMG_THIS_NORM_PIXEL(inputImage); + vec4 colorL = IMG_NORM_PIXEL(inputImage, left_coord); + vec4 colorR = IMG_NORM_PIXEL(inputImage, right_coord); + vec4 colorA = IMG_NORM_PIXEL(inputImage, above_coord); + vec4 colorB = IMG_NORM_PIXEL(inputImage, below_coord); + + vec4 colorLA = IMG_NORM_PIXEL(inputImage, lefta_coord); + vec4 colorRA = IMG_NORM_PIXEL(inputImage, righta_coord); + vec4 colorLB = IMG_NORM_PIXEL(inputImage, leftb_coord); + vec4 colorRB = IMG_NORM_PIXEL(inputImage, rightb_coord); + + vec4 avg = (color + colorL + colorR + colorA + colorB + colorLA + colorRA + colorLB + colorRB) / 9.0; + + if (PASSINDEX == 1) { + vec4 blur = IMG_THIS_NORM_PIXEL(smaller); + avg = mix(color, (avg + depth*blur)/(1.0+depth), softness); + } + else if (PASSINDEX == 2) { + vec4 blur = IMG_THIS_NORM_PIXEL(small); + avg = mix(color, (avg + depth*blur)/(1.0+depth), softness); + } + gl_FragColor = avg; +} \ No newline at end of file diff --git a/ISF/Soft Blur.vs b/ISF/Soft Blur.vs new file mode 100644 index 0000000..da454ce --- /dev/null +++ b/ISF/Soft Blur.vs @@ -0,0 +1,27 @@ +varying vec2 left_coord; +varying vec2 right_coord; +varying vec2 above_coord; +varying vec2 below_coord; + +varying vec2 lefta_coord; +varying vec2 righta_coord; +varying vec2 leftb_coord; +varying vec2 rightb_coord; + + +void main() +{ + isf_vertShaderInit(); + vec2 texc = vec2(isf_FragNormCoord[0],isf_FragNormCoord[1]); + vec2 d = 1.0/RENDERSIZE; + + left_coord = clamp(vec2(texc.xy + vec2(-d.x , 0)),0.0,1.0); + right_coord = clamp(vec2(texc.xy + vec2(d.x , 0)),0.0,1.0); + above_coord = clamp(vec2(texc.xy + vec2(0,d.y)),0.0,1.0); + below_coord = clamp(vec2(texc.xy + vec2(0,-d.y)),0.0,1.0); + + lefta_coord = clamp(vec2(texc.xy + vec2(-d.x , d.x)),0.0,1.0); + righta_coord = clamp(vec2(texc.xy + vec2(d.x , d.x)),0.0,1.0); + leftb_coord = clamp(vec2(texc.xy + vec2(-d.x , -d.x)),0.0,1.0); + rightb_coord = clamp(vec2(texc.xy + vec2(d.x , -d.x)),0.0,1.0); +} \ No newline at end of file diff --git a/ISF/Solarize.fs b/ISF/Solarize.fs new file mode 100644 index 0000000..4665018 --- /dev/null +++ b/ISF/Solarize.fs @@ -0,0 +1,91 @@ +/*{ + "DESCRIPTION": "Solarizes an image", + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Glitch" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "centerBrightness", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.5 + }, + { + "NAME": "powerCurve", + "TYPE": "float", + "MIN": 0.0, + "MAX": 4.0, + "DEFAULT": 1.0 + }, + { + "NAME": "colorize", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.0 + }, + { + "NAME": "inverse", + "TYPE": "bool", + "DEFAULT": 1.0 + } + ] +}*/ + + + + +vec3 rgb2hsv(vec3 c) { + vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); + //vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g)); + //vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r)); + vec4 p = c.g < c.b ? vec4(c.bg, K.wz) : vec4(c.gb, K.xy); + vec4 q = c.r < p.x ? vec4(p.xyw, c.r) : vec4(c.r, p.yzx); + + float d = q.x - min(q.w, q.y); + float e = 1.0e-10; + return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x); +} + +vec3 hsv2rgb(vec3 c) { + vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); + vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www); + return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y); +} + + + + +void main() +{ + vec4 inColor = IMG_NORM_PIXEL(inputImage, isf_FragNormCoord); + vec4 hslColor; + vec4 outColor; + + // convert to HSV + hslColor.rgb = rgb2hsv(inColor.rgb); + outColor.rgb = hslColor.rgb; + outColor.a = inColor.a; + + // drop the saturation + //outColor.g = 0.0; + + // adjust the brightness curve + outColor.b = (outColor.b < centerBrightness) ? (1.0 - outColor.b / centerBrightness) : (outColor.b - centerBrightness) / centerBrightness; + outColor.b = pow(outColor.b, powerCurve); + outColor.b = (inverse) ? 1.0 - outColor.b : outColor.b; + + outColor.g = (inverse) ? outColor.g * (1.0-hslColor.b) * colorize : outColor.g * hslColor.b * colorize; + + // convert back to rgb + outColor.rgb = hsv2rgb(outColor.rgb); + + gl_FragColor = outColor; +} diff --git a/ISF/Solid Color.fs b/ISF/Solid Color.fs new file mode 100644 index 0000000..cf08030 --- /dev/null +++ b/ISF/Solid Color.fs @@ -0,0 +1,25 @@ +/*{ + "DESCRIPTION": "demonstrates the use of color-type image inputs", + "CREDIT": "by Carter Rosenberg", + "ISFVSN": "2", + "CATEGORIES": [ + "Generator" + ], + "INPUTS": [ + { + "NAME": "Color", + "TYPE": "color", + "DEFAULT": [ + 1.0, + 0.0, + 0.0, + 1.0 + ] + } + ] +}*/ + +void main() +{ + gl_FragColor = Color; +} diff --git a/ISF/Sphere Map.fs b/ISF/Sphere Map.fs new file mode 100644 index 0000000..baeb7db --- /dev/null +++ b/ISF/Sphere Map.fs @@ -0,0 +1,68 @@ +/*{ + "DESCRIPTION": "Maps video onto a sphere", + "CREDIT": "VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Geometry Adjustment" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "LABEL": "Image Scale", + "NAME": "imageScale", + "TYPE": "float", + "DEFAULT": 0.5, + "MIN": 0.125, + "MAX": 1.0 + }, + { + "LABEL": "Radius Scale", + "NAME": "radiusScale", + "TYPE": "float", + "DEFAULT": 1.0, + "MIN": 0.0, + "MAX": 1.999 + }, + { + "LABEL": "Rotate", + "NAME": "pointInput", + "TYPE": "point2D", + "DEFAULT": [ + 0, + 0 + ] + } + ] + +}*/ + + + +const float pi = 3.14159265359; + + +void main() { + vec4 inputPixelColor = vec4(0.0); + vec2 rotate = pointInput / RENDERSIZE; + vec2 p = 2.0 * isf_FragNormCoord.xy - 1.0; + float aspect = RENDERSIZE.x / RENDERSIZE.y; + p.x = p.x * aspect; + + float r = sqrt(dot(p,p)) * (2.0-radiusScale); + if (r < 1.0) { + vec2 uv; + float f = imageScale * (1.0-sqrt(1.0-r))/(r); + uv.x = mod(p.x*f + rotate.x,1.0); + uv.y = mod(p.y*f + rotate.y,1.0); + inputPixelColor = IMG_NORM_PIXEL(inputImage, uv); + } + + + // both of these are also the same + //inputPixelColor = IMG_NORM_PIXEL(inputImage, loc); + + gl_FragColor = inputPixelColor; +} diff --git a/ISF/Spiral.fs b/ISF/Spiral.fs new file mode 100644 index 0000000..e8aa455 --- /dev/null +++ b/ISF/Spiral.fs @@ -0,0 +1,106 @@ +/*{ + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Generator" + ], + "INPUTS": [ + { + "NAME": "rotation", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.0 + }, + { + "NAME": "count", + "TYPE": "float", + "MIN": 0.1, + "MAX": 50.0, + "DEFAULT": 2.0 + }, + { + "NAME": "width", + "TYPE": "float", + "MIN": 0.0, + "MAX": 0.25, + "DEFAULT": 0.125 + }, + { + "NAME": "softness", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.25 + }, + { + "NAME": "color1", + "TYPE": "color", + "DEFAULT": [ + 0.0, + 0.0, + 0.0, + 0.0 + ] + }, + { + "NAME": "color2", + "TYPE": "color", + "DEFAULT": [ + 1.0, + 1.0, + 1.0, + 1.0 + ] + } + ] +}*/ + + +const float pi = 3.14159265359; + + +void main() { + // determine if we are on an even or odd line + // math goes like.. + // r = a + b*theta + // Changing the parameter 'a' will turn the spiral, while 'b' controls the distance between successive turnings. + + + vec4 out_color = color1; + + // convert to polar coordinates + vec2 loc = vec2(isf_FragNormCoord[0],isf_FragNormCoord[1]); + loc.y = (loc.y - 0.5) * RENDERSIZE.y / RENDERSIZE.x + 0.5; + float r = 2.0 * count * distance(vec2(0.5,0.5), loc) + width; + float theta = atan ((loc.y-0.5),(loc.x-0.5)); + + loc.y = r * sin(theta + 2.0 * pi * rotation) + 0.5; + + if (loc.y < 0.5) { + theta = theta + 2.0 * pi; + theta = mod(theta + rotation * 2.0 * pi, 2.0 * pi); + theta = (theta + 2.0 * pi * floor(r - width)); + } + else { + theta = mod(theta + rotation * 2.0 * pi, 2.0 * pi); + theta = (theta + 2.0 * pi * floor(r + width)); + } + + if (width == 0.0) { + out_color = color1; + } + else { + float dist = abs(r - theta/(2.0*pi)); + if (dist < width) { + if (dist > width * (1.0-softness)) { + out_color = mix(color2, color1, (dist - width * (1.0-softness))/(width - width * (1.0-softness))); + } + else { + out_color = color2; + } + } + } + + gl_FragColor = out_color; +} \ No newline at end of file diff --git a/ISF/Star.fs b/ISF/Star.fs new file mode 100644 index 0000000..d477c8b --- /dev/null +++ b/ISF/Star.fs @@ -0,0 +1,108 @@ +/*{ + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Generator" + ], + "INPUTS": [ + { + "NAME": "size", + "LABEL": "Size", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.25 + }, + { + "NAME": "bordersize", + "LABEL": "Stroke Width", + "TYPE": "float", + "MIN": 0.0, + "MAX": 0.1, + "DEFAULT": 0.01 + }, + { + "NAME": "color1", + "LABEL": "Fill Color", + "TYPE": "color", + "DEFAULT": [ + 1.0, + 0.6, + 0.75, + 1.0 + ] + }, + { + "NAME": "color2", + "LABEL": "Stroke Color", + "TYPE": "color", + "DEFAULT": [ + 0.0, + 0.0, + 0.0, + 1.0 + ] + } + ] +}*/ + + +// Adapted from https://glsl.io/transition/d1f891c5585fc40b55ea + + +vec2 circlePoint( float ang ) +{ + ang += 6.28318 * 0.15; + return vec2( cos(ang), sin(ang) ); +} + +float cross2d( vec2 a, vec2 b ) +{ + return ( a.x * b.y - a.y * b.x ); +} + +// quickly knocked together with some math from http://www.pixeleuphoria.com/node/30 +float star( vec2 p, float size ) +{ + if( size <= 0.0 ) + { + return 0.0; + } + p /= size; + + vec2 p0 = circlePoint( 0.0 ); + vec2 p1 = circlePoint( 6.28318 * 1.0 / 5.0 ); + vec2 p2 = circlePoint( 6.28318 * 2.0 / 5.0 ); + vec2 p3 = circlePoint( 6.28318 * 3.0 / 5.0 ); + vec2 p4 = circlePoint( 6.28318 * 4.0 / 5.0 ); + + // are we on this side of the line + float s0 = ( cross2d( p1 - p0, p - p0 ) ); + float s1 = ( cross2d( p2 - p1, p - p1 ) ); + float s2 = ( cross2d( p3 - p2, p - p2 ) ); + float s3 = ( cross2d( p4 - p3, p - p3 ) ); + float s4 = ( cross2d( p0 - p4, p - p4 ) ); + + // some trial and error math to get the star shape. I'm sure there's some elegance I'm missing. + float s5 = min( min( min( s0, s1 ), min( s2, s3 ) ), s4 ); + float s = max( 1.0 - sign( s0 * s1 * s2 * s3 * s4 ) + sign(s5), 0.0 ); + s = sign( 2.6 - length(p) ) * s; + + return max( s, 0.0 ); +} + +void main() +{ + vec2 p = isf_FragNormCoord; + vec2 o = p * 2.0 - 1.0; + + float t = size * 1.4; + + float c1 = star( o, t ); + float c2 = star( o, t - bordersize ); + + float border = max( c1 - c2, 0.0 ); + + gl_FragColor = mix(mix(vec4(0.0), color1, c1), color2, border); +} + diff --git a/ISF/Stripes.fs b/ISF/Stripes.fs new file mode 100644 index 0000000..5e0c0cf --- /dev/null +++ b/ISF/Stripes.fs @@ -0,0 +1,68 @@ +/*{ + "CREDIT": "by Carter Rosenberg", + "ISFVSN": "2", + "CATEGORIES": [ + "Generator" + ], + "INPUTS": [ + { + "NAME": "width", + "TYPE": "float", + "DEFAULT": 0.25 + }, + { + "NAME": "offset", + "TYPE": "float", + "DEFAULT": 0.0 + }, + { + "NAME": "vertical", + "TYPE": "bool", + "DEFAULT": 0.0 + }, + { + "NAME": "color1", + "TYPE": "color", + "DEFAULT": [ + 1.0, + 1.0, + 1.0, + 1.0 + ] + }, + { + "NAME": "color2", + "TYPE": "color", + "DEFAULT": [ + 0.0, + 0.0, + 0.0, + 1.0 + ] + } + ] +}*/ + + + +void main() { + // determine if we are on an even or odd line + // math goes like.. + // mod(((coord+offset) / width),2) + + + vec4 out_color = color2; + float coord = isf_FragNormCoord[0]; + + if (vertical) { + coord = isf_FragNormCoord[1]; + } + if (width == 0.0) { + out_color = color1; + } + else if(mod(((coord+offset) / width),2.0) < 1.0) { + out_color = color1; + } + + gl_FragColor = out_color; +} \ No newline at end of file diff --git a/ISF/Strobe.fs b/ISF/Strobe.fs new file mode 100644 index 0000000..b0a1541 --- /dev/null +++ b/ISF/Strobe.fs @@ -0,0 +1,91 @@ +/* +{ + "CATEGORIES" : [ + "Color Effect" + ], + "DESCRIPTION" : "", + "ISFVSN" : "2", + "INPUTS" : [ + { + "NAME" : "inputImage", + "TYPE" : "image" + }, + { + "NAME" : "strobeRate", + "TYPE" : "float", + "MAX" : 1, + "DEFAULT" : 0, + "LABEL" : "Strobe Rate", + "MIN" : 0 + }, + { + "LABELS" : [ + "Invert", + "Color" + ], + "NAME" : "strobeMode", + "TYPE" : "long", + "LABEL" : "Strobe Mode", + "VALUES" : [ + 0, + 1 + ] + }, + { + "NAME" : "strobeColor", + "TYPE" : "color", + "DEFAULT" : [ + 1, + 1, + 1, + 1 + ], + "LABEL" : "Strobe Color" + } + ], + "PASSES" : [ + { + "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" : "lastState", + "PERSISTENT" : 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 = IMG_PIXEL(lastState,vec2(0.5)); + // i'm only using the X, which is the last render time we reset + if (strobeRate == 0.0) { + srcPixel.r = (srcPixel.r == 0.0) ? 1.0 : 0.0; + } + else { + srcPixel.r = (mod(TIME, strobeRate) <= strobeRate / 2.0) ? 1.0 : 0.0; + } + gl_FragColor = srcPixel; + } + // else this isn't the first pass- read the position value from the buffer which stores it + else { + vec4 lastStateVector = IMG_PIXEL(lastState,vec2(0.5)); + vec4 srcPixel = IMG_THIS_PIXEL(inputImage); + // invert or flash a color? + if (strobeMode == 0) { + srcPixel = (lastStateVector.r == 0.0) ? srcPixel : vec4(1.0-srcPixel.r, 1.0-srcPixel.g, 1.0-srcPixel.b, srcPixel.a); + } + else if (strobeMode == 1) { + srcPixel = (lastStateVector.r == 0.0) ? srcPixel : strobeColor; + } + gl_FragColor = srcPixel; + } +} diff --git a/ISF/Thermal Camera.fs b/ISF/Thermal Camera.fs new file mode 100644 index 0000000..3e6856e --- /dev/null +++ b/ISF/Thermal Camera.fs @@ -0,0 +1,98 @@ +/*{ + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Stylize" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + } + ] +}*/ + + +// partly adapted from http://coding-experiments.blogspot.com/2010/10/thermal-vision-pixel-shader.html + +varying vec2 left_coord; +varying vec2 right_coord; +varying vec2 above_coord; +varying vec2 below_coord; + +varying vec2 lefta_coord; +varying vec2 righta_coord; +varying vec2 leftb_coord; +varying vec2 rightb_coord; + + +void main () { + //vec4 pixcol = IMG_THIS_PIXEL(inputImage); + vec4 colors[9]; + // 8 color stages with variable ranges to get this to look right + // black, purple, blue, cyan, green, yellow, orange, red, red + colors[0] = vec4(0.0,0.0,0.0,1.0); + colors[1] = vec4(0.272,0.0,0.4,1.0); // dark deep purple, (RGB: 139, 0, 204) + colors[2] = vec4(0.0,0.0,1.0,1.0); // full blue + colors[3] = vec4(0.0,1.0,1.0,1.0); // cyan + colors[4] = vec4(0.0,1.0,0.0,1.0); // green + colors[5] = vec4(0.0,1.0,0.0,1.0); // green + colors[6] = vec4(1.0,1.0,0.0,1.0); // yellow + colors[7] = vec4(1.0,0.5,0.0,1.0); // orange + colors[8] = vec4(1.0,0.0,0.0,1.0); // red + + vec4 color = IMG_THIS_NORM_PIXEL(inputImage); + vec4 colorL = IMG_NORM_PIXEL(inputImage, left_coord); + vec4 colorR = IMG_NORM_PIXEL(inputImage, right_coord); + vec4 colorA = IMG_NORM_PIXEL(inputImage, above_coord); + vec4 colorB = IMG_NORM_PIXEL(inputImage, below_coord); + + vec4 colorLA = IMG_NORM_PIXEL(inputImage, lefta_coord); + vec4 colorRA = IMG_NORM_PIXEL(inputImage, righta_coord); + vec4 colorLB = IMG_NORM_PIXEL(inputImage, leftb_coord); + vec4 colorRB = IMG_NORM_PIXEL(inputImage, rightb_coord); + + vec4 avg = (color + colorL + colorR + colorA + colorB + colorLA + colorRA + colorLB + colorRB) / 9.0; + + const vec4 lumacoeff = vec4(0.2126, 0.7152, 0.0722, 0.0); + float lum = dot(avg, lumacoeff); + //float lum = (avg.r+avg.g+avg.b)/3.0; + //float lum = dot(vec3(0.30, 0.59, 0.11), avg.rgb); + lum = pow(lum,1.4); + + int ix = 0; + float range = 1.0 / 8.0; + + // orange to red + if (lum > range * 7.0) { + ix = 7; + } + // yellow to orange + else if (lum > range * 6.0) { + ix = 6; + } + // green to yellow + else if (lum > range * 5.0) { + ix = 5; + } + // green to green + else if (lum > range * 4.0) { + ix = 4; + } + // cyan to green + else if (lum > range * 3.0) { + ix = 3; + } + // blue to cyan + else if (lum > range * 2.0) { + ix = 2; + } + // purple to blue + else if (lum > range) { + ix = 1; + } + + vec4 thermal = mix(colors[ix],colors[ix+1],(lum-float(ix)*range)/range); + gl_FragColor = thermal; + +} \ No newline at end of file diff --git a/ISF/Thermal Camera.vs b/ISF/Thermal Camera.vs new file mode 100644 index 0000000..da454ce --- /dev/null +++ b/ISF/Thermal Camera.vs @@ -0,0 +1,27 @@ +varying vec2 left_coord; +varying vec2 right_coord; +varying vec2 above_coord; +varying vec2 below_coord; + +varying vec2 lefta_coord; +varying vec2 righta_coord; +varying vec2 leftb_coord; +varying vec2 rightb_coord; + + +void main() +{ + isf_vertShaderInit(); + vec2 texc = vec2(isf_FragNormCoord[0],isf_FragNormCoord[1]); + vec2 d = 1.0/RENDERSIZE; + + left_coord = clamp(vec2(texc.xy + vec2(-d.x , 0)),0.0,1.0); + right_coord = clamp(vec2(texc.xy + vec2(d.x , 0)),0.0,1.0); + above_coord = clamp(vec2(texc.xy + vec2(0,d.y)),0.0,1.0); + below_coord = clamp(vec2(texc.xy + vec2(0,-d.y)),0.0,1.0); + + lefta_coord = clamp(vec2(texc.xy + vec2(-d.x , d.x)),0.0,1.0); + righta_coord = clamp(vec2(texc.xy + vec2(d.x , d.x)),0.0,1.0); + leftb_coord = clamp(vec2(texc.xy + vec2(-d.x , -d.x)),0.0,1.0); + rightb_coord = clamp(vec2(texc.xy + vec2(d.x , -d.x)),0.0,1.0); +} \ No newline at end of file diff --git a/ISF/Time Glitch RGB.fs b/ISF/Time Glitch RGB.fs new file mode 100644 index 0000000..cbb1be1 --- /dev/null +++ b/ISF/Time Glitch RGB.fs @@ -0,0 +1,461 @@ +/*{ + "DESCRIPTION": "Buffers 8 recent frames", + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Glitch" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "inputDelay", + "LABEL": "Buffer", + "TYPE": "color", + "DEFAULT": [ + 0.25, + 0.5, + 0.75, + 0.5 + ] + }, + { + "NAME": "inputRate", + "LABEL": "Buffer Lag", + "TYPE": "float", + "MIN": 1.0, + "MAX": 20.0, + "DEFAULT": 4.0 + }, + { + "NAME": "glitch_size", + "LABEL": "Size", + "TYPE": "float", + "MIN": 0.0, + "MAX": 0.5, + "DEFAULT": 0.1 + }, + { + "NAME": "glitch_horizontal", + "LABEL": "Horizontal Amount", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.2 + }, + { + "NAME": "glitch_vertical", + "LABEL": "Vertical Amount", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.0 + }, + { + "NAME": "randomize_size", + "LABEL": "Randomize Size", + "TYPE": "bool", + "DEFAULT": 1.0 + }, + { + "NAME": "randomize_position", + "LABEL": "Randomize Position", + "TYPE": "bool", + "DEFAULT": 0.0 + }, + { + "NAME": "randomize_zoom", + "LABEL": "Randomize Zoom", + "TYPE": "bool", + "DEFAULT": 0.0 + } + ], + "PASSES": [ + { + "TARGET":"lastRow", + "WIDTH": "1", + "HEIGHT": "1", + "PERSISTENT": true, + "DESCRIPTION": "this buffer stores the last frame's odd / even state" + }, + { + "TARGET":"buffer8", + "PERSISTENT": true + }, + { + "TARGET":"buffer7", + "PERSISTENT": true + }, + { + "TARGET":"buffer6", + "PERSISTENT": true + }, + { + "TARGET":"buffer5", + "PERSISTENT": true + }, + { + "TARGET":"buffer4", + "PERSISTENT": true + }, + { + "TARGET":"buffer3", + "PERSISTENT": true + }, + { + "TARGET":"buffer2", + "PERSISTENT": true + }, + { + "TARGET":"buffer1", + "PERSISTENT": true + }, + { + + } + ] + +}*/ + + +float rand(vec2 co){ + return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453); +} + + +void main() +{ + // first pass: read the "buffer7" into "buffer8" + // apply lag on each pass + // if this is the first pass, i'm going to read the position from the "lastRow" image, and write a new position based on this and the hold variables + if (PASSINDEX == 0) { + vec4 srcPixel = IMG_PIXEL(lastRow,vec2(0.5)); + // i'm only using the X and Y components, which are the X and Y offset (normalized) for the frame + if (inputRate == 0.0) { + srcPixel.x = 0.0; + srcPixel.y = 0.0; + } + else if (inputRate <= 1.0) { + srcPixel.x = (srcPixel.x) > 0.5 ? 0.0 : 1.0; + srcPixel.y = 0.0; + } + else { + srcPixel.x = srcPixel.x + 1.0 / inputRate + srcPixel.y; + if (srcPixel.x > 1.0) { + srcPixel.y = mod(srcPixel.x, 1.0); + srcPixel.x = 0.0; + } + } + gl_FragColor = srcPixel; + } + if (PASSINDEX == 1) { + vec4 lastRow = IMG_PIXEL(lastRow,vec2(0.5)); + if (lastRow.x == 0.0) { + gl_FragColor = IMG_THIS_NORM_PIXEL(buffer7); + } + else { + gl_FragColor = IMG_THIS_NORM_PIXEL(buffer8); + } + } + else if (PASSINDEX == 2) { + vec4 lastRow = IMG_PIXEL(lastRow,vec2(0.5)); + if (lastRow.x == 0.0) { + gl_FragColor = IMG_THIS_NORM_PIXEL(buffer6); + } + else { + gl_FragColor = IMG_THIS_NORM_PIXEL(buffer7); + } + } + else if (PASSINDEX == 3) { + vec4 lastRow = IMG_PIXEL(lastRow,vec2(0.5)); + if (lastRow.x == 0.0) { + gl_FragColor = IMG_THIS_NORM_PIXEL(buffer5); + } + else { + gl_FragColor = IMG_THIS_NORM_PIXEL(buffer6); + } + } + else if (PASSINDEX == 4) { + vec4 lastRow = IMG_PIXEL(lastRow,vec2(0.5)); + if (lastRow.x == 0.0) { + gl_FragColor = IMG_THIS_NORM_PIXEL(buffer4); + } + else { + gl_FragColor = IMG_THIS_NORM_PIXEL(buffer5); + } + } + else if (PASSINDEX == 5) { + vec4 lastRow = IMG_PIXEL(lastRow,vec2(0.5)); + if (lastRow.x == 0.0) { + gl_FragColor = IMG_THIS_NORM_PIXEL(buffer3); + } + else { + gl_FragColor = IMG_THIS_NORM_PIXEL(buffer4); + } + } + else if (PASSINDEX == 6) { + vec4 lastRow = IMG_PIXEL(lastRow,vec2(0.5)); + if (lastRow.x == 0.0) { + gl_FragColor = IMG_THIS_NORM_PIXEL(buffer2); + } + else { + gl_FragColor = IMG_THIS_NORM_PIXEL(buffer3); + } + } + else if (PASSINDEX == 7) { + vec4 lastRow = IMG_PIXEL(lastRow,vec2(0.5)); + if (lastRow.x == 0.0) { + gl_FragColor = IMG_THIS_NORM_PIXEL(buffer1); + } + else { + gl_FragColor = IMG_THIS_NORM_PIXEL(buffer2); + } + } + else if (PASSINDEX == 8) { + vec4 lastRow = IMG_PIXEL(lastRow,vec2(0.5)); + if (lastRow.x == 0.0) { + gl_FragColor = IMG_THIS_NORM_PIXEL(inputImage); + } + else { + gl_FragColor = IMG_THIS_NORM_PIXEL(buffer1); + } + } + else if (PASSINDEX == 9) { + // Figure out which section I'm in and draw the appropriate buffer there + vec2 tex = isf_FragNormCoord; + vec4 color = vec4(0.0); + // figure out the "input delay shift" for this pixel... + float randomDelayShift = 0.0; + + vec2 xy; + xy.x = isf_FragNormCoord[0]; + xy.y = isf_FragNormCoord[1]; + + // quantize the xy to the glitch_amount size + //xy = floor(xy / glitch_size) * glitch_size; + vec2 random; + + float local_glitch_size = glitch_size; + float random_offset = 0.0; + + if (randomize_size) { + random_offset = mod(rand(vec2(TIME,TIME)), 1.0); + local_glitch_size = random_offset * glitch_size; + } + + if (local_glitch_size > 0.0) { + random.x = rand(vec2(floor(random_offset + xy.y / local_glitch_size) * local_glitch_size, TIME)); + random.y = rand(vec2(floor(random_offset + xy.x / local_glitch_size) * local_glitch_size, TIME)); + } + else { + random.x = rand(vec2(xy.x, TIME)); + random.y = rand(vec2(xy.y, TIME)); + } + + // if doing a horizontal glitch do a random shift + if ((random.x < glitch_horizontal)&&(random.y < glitch_vertical)) { + randomDelayShift = clamp(random.x + random.y, 0.0, 2.0); + } + else if (random.x < glitch_horizontal) { + randomDelayShift = clamp(random.x + random.y, 0.0, 2.0); + } + else if (random.y < glitch_vertical) { + randomDelayShift = clamp(random.x + random.y, 0.0, 2.0); + } + + vec4 pixelBuffer = randomDelayShift * inputDelay * 9.0; + + if (randomize_zoom) { + if ((random.x < glitch_horizontal)&&(random.y < glitch_vertical)) { + float level = (random.x + random.y) / 3.0 + 0.90; + tex = (tex - vec2(0.5))*(1.0/level) + vec2(0.5); + } + else if (random.x < glitch_horizontal) { + float level = (random.x) / 2.0 + 0.95; + tex = (tex - vec2(0.5))*(1.0/level) + vec2(0.5); + } + else if (random.y < glitch_vertical) { + float level = (random.y) / 2.0 + 0.95; + tex = (tex - vec2(0.5))*(1.0/level) + vec2(0.5); + } + } + + if (randomize_position) { + if ((random.x < glitch_horizontal)&&(random.y < glitch_vertical)) { + tex.x = mod(tex.x + inputDelay.r * random.x, 1.0); + tex.y = mod(tex.y + inputDelay.r * random.y, 1.0); + } + else if (random.x < glitch_horizontal) { + tex.y = mod(tex.y + inputDelay.r * random.x, 1.0); + } + else if (random.y < glitch_vertical) { + tex.x = mod(tex.x + inputDelay.r * random.y, 1.0); + } + // apply small random zoom too + } + + if (pixelBuffer.r < 1.0) { + color.r = IMG_NORM_PIXEL(inputImage, tex).r; + } + else if (pixelBuffer.r < 2.0) { + color.r = IMG_NORM_PIXEL(buffer1, tex).r; + } + else if (pixelBuffer.r < 3.0) { + color.r = IMG_NORM_PIXEL(buffer2, tex).r; + } + else if (pixelBuffer.r < 4.0) { + color.r = IMG_NORM_PIXEL(buffer3, tex).r; + } + else if (pixelBuffer.r < 5.0) { + color.r = IMG_NORM_PIXEL(buffer4, tex).r; + } + else if (pixelBuffer.r < 6.0) { + color.r = IMG_NORM_PIXEL(buffer5, tex).r; + } + else if (pixelBuffer.r < 7.0) { + color.r = IMG_NORM_PIXEL(buffer6, tex).r; + } + else if (pixelBuffer.r < 8.0) { + color.r = IMG_NORM_PIXEL(buffer7, tex).r; + } + else { + color.r = IMG_NORM_PIXEL(buffer8, tex).r; + } + + if (randomize_position) { + if ((random.x < glitch_horizontal)&&(random.y < glitch_vertical)) { + tex.x = mod(tex.x + random.x * inputDelay.g, 1.0); + tex.y = mod(tex.y + random.y * inputDelay.g, 1.0); + } + else if (random.x < glitch_horizontal) { + tex.y = mod(tex.y + random.x * inputDelay.g, 1.0); + } + else if (random.y < glitch_vertical) { + tex.x = mod(tex.x + random.y * inputDelay.g, 1.0); + } + // apply small random zoom too + //float level = inputDelay.g * random.x / 5.0 + 0.9; + //tex = (tex - vec2(0.5))*(1.0/level) + vec2(0.5); + } + + if (pixelBuffer.g < 1.0) { + color.g = IMG_NORM_PIXEL(inputImage, tex).g; + } + else if (pixelBuffer.g < 2.0) { + color.g = IMG_NORM_PIXEL(buffer1, tex).g; + } + else if (pixelBuffer.g < 3.0) { + color.g = IMG_NORM_PIXEL(buffer2, tex).g; + } + else if (pixelBuffer.g < 4.0) { + color.g = IMG_NORM_PIXEL(buffer3, tex).g; + } + else if (pixelBuffer.g < 5.0) { + color.g = IMG_NORM_PIXEL(buffer4, tex).g; + } + else if (pixelBuffer.g < 6.0) { + color.g = IMG_NORM_PIXEL(buffer5, tex).g; + } + else if (pixelBuffer.g < 7.0) { + color.g = IMG_NORM_PIXEL(buffer6, tex).g; + } + else if (pixelBuffer.g < 8.0) { + color.g = IMG_NORM_PIXEL(buffer7, tex).g; + } + else { + color.g = IMG_NORM_PIXEL(buffer8, tex).g; + } + + if (randomize_position) { + if ((random.x < glitch_horizontal)&&(random.y < glitch_vertical)) { + tex.x = mod(tex.x + random.x * inputDelay.b, 1.0); + tex.y = mod(tex.y + random.y * inputDelay.b, 1.0); + } + else if (random.x < glitch_horizontal) { + tex.y = mod(tex.y + random.x * inputDelay.b, 1.0); + } + else if (random.y < glitch_vertical) { + tex.x = mod(tex.x + random.y * inputDelay.b, 1.0); + } + // apply small random zoom too + //float level = inputDelay.b * random.x / 5.0 + 0.9; + //tex = (tex - vec2(0.5))*(1.0/level) + vec2(0.5); + } + + if (pixelBuffer.b < 1.0) { + color.b = IMG_NORM_PIXEL(inputImage, tex).b; + } + else if (pixelBuffer.b < 2.0) { + color.b = IMG_NORM_PIXEL(buffer1, tex).b; + } + else if (pixelBuffer.b < 3.0) { + color.b = IMG_NORM_PIXEL(buffer2, tex).b; + } + else if (pixelBuffer.b < 4.0) { + color.b = IMG_NORM_PIXEL(buffer3, tex).b; + } + else if (pixelBuffer.b < 5.0) { + color.b = IMG_NORM_PIXEL(buffer4, tex).b; + } + else if (pixelBuffer.b < 6.0) { + color.b = IMG_NORM_PIXEL(buffer5, tex).b; + } + else if (pixelBuffer.b < 7.0) { + color.b = IMG_NORM_PIXEL(buffer6, tex).b; + } + else if (pixelBuffer.b < 8.0) { + color.b = IMG_NORM_PIXEL(buffer7, tex).b; + } + else { + color.b = IMG_NORM_PIXEL(buffer8, tex).b; + } + + if (randomize_position) { + if ((random.x < glitch_horizontal)&&(random.y < glitch_vertical)) { + tex.x = mod(tex.x + random.x * inputDelay.a, 1.0); + tex.y = mod(tex.y + random.y * inputDelay.a, 1.0); + } + else if (random.x < glitch_horizontal) { + tex.y = mod(tex.y + random.x * inputDelay.a, 1.0); + } + else if (random.y < glitch_vertical) { + tex.x = mod(tex.x + random.y * inputDelay.a, 1.0); + } + // apply small random zoom too + //float level = inputDelay.a * random.x / 5.0 + 0.9; + //tex = (tex - vec2(0.5))*(1.0/level) + vec2(0.5); + } + + if (pixelBuffer.a < 1.0) { + color.a = IMG_NORM_PIXEL(inputImage, tex).a; + } + else if (pixelBuffer.a < 2.0) { + color.a = IMG_NORM_PIXEL(buffer1, tex).a; + } + else if (pixelBuffer.a < 3.0) { + color.a = IMG_NORM_PIXEL(buffer2, tex).a; + } + else if (pixelBuffer.a < 4.0) { + color.a = IMG_NORM_PIXEL(buffer3, tex).a; + } + else if (pixelBuffer.a < 5.0) { + color.a = IMG_NORM_PIXEL(buffer4, tex).a; + } + else if (pixelBuffer.a < 6.0) { + color.a = IMG_NORM_PIXEL(buffer5, tex).a; + } + else if (pixelBuffer.a < 7.0) { + color.a = IMG_NORM_PIXEL(buffer6, tex).a; + } + else if (pixelBuffer.a < 8.0) { + color.a = IMG_NORM_PIXEL(buffer7, tex).a; + } + else { + color.a = IMG_NORM_PIXEL(buffer8, tex).a; + } + + gl_FragColor = color; + } +} diff --git a/ISF/Toon.fs b/ISF/Toon.fs new file mode 100644 index 0000000..bb43664 --- /dev/null +++ b/ISF/Toon.fs @@ -0,0 +1,77 @@ + +/*{ + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Stylize" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "normalEdgeThreshold", + "TYPE": "float", + "MIN": 0.0, + "MAX": 0.1, + "DEFAULT": 0.03 + }, + { + "NAME": "qLevel", + "TYPE": "float", + "MIN": 2.0, + "MAX": 64.0, + "DEFAULT": 32.0 + } + ] +}*/ + +// with help from https://github.com/neilmendoza/ofxPostProcessing/blob/master/src/ToonPass.cpp + + +vec3 getNormal(vec2 st){ + vec2 texcoord = clamp(st, 0.001, 0.999); + return IMG_NORM_PIXEL(inputImage,texcoord).rgb; +} + +void main(void){ + float dxtex = 1.0 / RENDERSIZE.x; + float dytex = 1.0 / RENDERSIZE.y; + + vec2 st = vec2(isf_FragNormCoord[0],isf_FragNormCoord[1]); + // access center pixel and 4 surrounded pixel + vec3 center = getNormal(st).rgb; + vec3 left = getNormal(st + vec2(dxtex, 0.0)).rgb; + vec3 right = getNormal(st + vec2(-dxtex, 0.0)).rgb; + vec3 up = getNormal(st + vec2(0.0, -dytex)).rgb; + vec3 down = getNormal(st + vec2(0.0, dytex)).rgb; + + // discrete Laplace operator + vec3 laplace = abs(-4.0*center + left + right + up + down); + // if one rgb-component of convolution result is over threshold => edge + vec4 line = IMG_NORM_PIXEL(inputImage, st); + if(laplace.r > normalEdgeThreshold + || laplace.g > normalEdgeThreshold + || laplace.b > normalEdgeThreshold){ + line = vec4(0.0, 0.0, 0.0, 1.0); // => color the pixel green + } else { + line = vec4(1.0, 1.0, 1.0, 1.0); // black + } + + //end Line; + //gl_FragColor = line; + + vec4 color = IMG_THIS_PIXEL(inputImage); + + // store previous alpha value + float alpha = color.a; + // quantize process: multiply by factor, round and divde by factor + color = floor((qLevel * color)) / qLevel; + // set fragment/pixel color + color.a = alpha; + + gl_FragColor = color * line; + +} + diff --git a/ISF/Trail Mask.fs b/ISF/Trail Mask.fs new file mode 100644 index 0000000..20cb87a --- /dev/null +++ b/ISF/Trail Mask.fs @@ -0,0 +1,173 @@ +/*{ + "DESCRIPTION": "Pixels update only based on the masking image", + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Glitch","Masking" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "maskImage", + "TYPE": "image", + "LABEL": "mask image" + }, + { + "NAME": "maskSizingMode", + "LABEL": "mask size mode", + "TYPE": "long", + "VALUES": [ + 0, + 1, + 2, + 3 + ], + "LABELS": [ + "Fit", + "Fill", + "Stretch", + "Copy" + ], + "DEFAULT": 0 + }, + { + "NAME": "bright", + "TYPE": "float", + "MIN": -1.0, + "MAX": 1.0, + "DEFAULT": 0.0 + }, + { + "NAME": "contrast", + "TYPE": "float", + "MIN": -4.0, + "MAX": 4.0, + "DEFAULT": 1.0 + }, + { + "NAME": "RGB_mode", + "TYPE": "bool", + "DEFAULT": 1.0 + } + ], + "PASSES": [ + { + "TARGET":"bufferVariableNameA", + "PERSISTENT": true + } + ] + +}*/ + + + +//const vec4 lumcoeff = vec4(0.299, 0.587, 0.114, 0.0); +const vec4 lumcoeff = vec4(0.2126, 0.7152, 0.0722, 0.0); + +// 'a' and 'b' are rects (x and y are the originx, z and w are the width and height) +// 'm' is the sizing mode as described above (fit/fill/stretch/copy) +vec4 RectThatFitsRectInRect(vec4 a, vec4 b, int m); + + +void main() +{ + vec4 freshPixel = IMG_PIXEL(inputImage,gl_FragCoord.xy); + // If we're on the line, update, otherwise use the stale pixel + vec4 stalePixel = IMG_PIXEL(bufferVariableNameA,gl_FragCoord.xy); + + + // get the rect of the mask image after it's been resized according to the passed sizing mode. this is in pixel coords relative to the rendering space! + vec4 rectOfResizedMaskImage = RectThatFitsRectInRect(vec4(0.0, 0.0, _maskImage_imgRect.z, _maskImage_imgRect.w), vec4(0,0,RENDERSIZE.x,RENDERSIZE.y), maskSizingMode); + //vec4 rectOfResizedMaskImage = RectThatFitsRectInRect(vec4(0.0, 0.0, IMG_SIZE(maskImage).x, IMG_SIZE(maskImage).y), vec4(0,0,RENDERSIZE.x,RENDERSIZE.y), maskSizingMode); + // i know the pixel coords of this frag in the render space- convert this to NORMALIZED texture coords for the resized mask image + vec2 normMaskSrcCoord; + normMaskSrcCoord.x = (gl_FragCoord.x-rectOfResizedMaskImage.x)/rectOfResizedMaskImage.z; + normMaskSrcCoord.y = (gl_FragCoord.y-rectOfResizedMaskImage.y)/rectOfResizedMaskImage.w; + + // get the color of the pixel from the mask image for these normalized coords + vec4 tmpColorA = IMG_NORM_PIXEL(maskImage, normMaskSrcCoord); + + // apply bright/contrast to this pixel value + vec4 tmpColorB = tmpColorA + vec4(bright, bright, bright, 0.0); + tmpColorA.rgb = ((vec3(2.0) * (tmpColorB.rgb - vec3(0.5))) * vec3(contrast) / vec3(2.0)) + vec3(0.5); + tmpColorA.a = ((2.0 * (tmpColorB.a - 0.5)) * abs(contrast) / 2.0) + 0.5; + + + vec4 result; + if (RGB_mode) { + result.a = freshPixel.a; + result.rgb = mix(freshPixel.rgb, stalePixel.rgb, clamp(tmpColorA.rgb,0.0,1.0)); + } + // get the luminance of this pixel value: this will be the new alpha for the source pixel + // use the luminance to mix between the fresh pixel and the stale one + else { + float luminance = dot(tmpColorA,lumcoeff); + result = mix(freshPixel, stalePixel, clamp(luminance,0.0,1.0)); + } + + gl_FragColor = result; +} + + +// rect that fits 'a' in 'b' using sizing mode 'm' +vec4 RectThatFitsRectInRect(vec4 a, vec4 b, int m) { + float bAspect = b.z/b.w; + float aAspect = a.z/a.w; + if (aAspect==bAspect) { + return b; + } + vec4 returnMe = vec4(0.0); + // fit + if (m==0) { + // if the rect i'm trying to fit stuff *into* is wider than the rect i'm resizing + if (bAspect > aAspect) { + returnMe.w = b.w; + returnMe.z = returnMe.w * aAspect; + } + // else if the rect i'm resizing is wider than the rect it's going into + else if (bAspect < aAspect) { + returnMe.z = b.z; + returnMe.w = returnMe.z / aAspect; + } + else { + returnMe.z = b.z; + returnMe.w = b.w; + } + returnMe.x = (b.z-returnMe.z)/2.0+b.x; + returnMe.y = (b.w-returnMe.w)/2.0+b.y; + } + // fill + else if (m==1) { + // if the rect i'm trying to fit stuff *into* is wider than the rect i'm resizing + if (bAspect > aAspect) { + returnMe.z = b.z; + returnMe.w = returnMe.z / aAspect; + } + // else if the rect i'm resizing is wider than the rect it's going into + else if (bAspect < aAspect) { + returnMe.w = b.w; + returnMe.z = returnMe.w * aAspect; + } + else { + returnMe.z = b.z; + returnMe.w = b.w; + } + returnMe.x = (b.z-returnMe.z)/2.0+b.x; + returnMe.y = (b.w-returnMe.w)/2.0+b.y; + } + // stretch + else if (m==2) { + returnMe = vec4(b.x, b.y, b.z, b.w); + } + // copy + else if (m==3) { + returnMe.z = float(int(a.z)); + returnMe.w = float(int(a.w)); + returnMe.x = float(int((b.z-returnMe.z)/2.0+b.x)); + returnMe.y = float(int((b.w-returnMe.w)/2.0+b.y)); + } + return returnMe; +} diff --git a/ISF/Trapezoid Distortion.fs b/ISF/Trapezoid Distortion.fs new file mode 100644 index 0000000..dd3d2c9 --- /dev/null +++ b/ISF/Trapezoid Distortion.fs @@ -0,0 +1,58 @@ +/*{ + "DESCRIPTION": "Warps the video into a trapezoid shape", + "CREDIT": "VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Distortion Effect" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "LABEL": "Top Width", + "NAME": "topWidth", + "TYPE": "float", + "DEFAULT": 1.0, + "MIN": 0.0, + "MAX": 1.0 + }, + { + "LABEL": "Bottom Width", + "NAME": "bottomWidth", + "TYPE": "float", + "DEFAULT": 1.0, + "MIN": 0.0, + "MAX": 1.0 + }, + { + "LABEL": "Height", + "NAME": "heightScale", + "TYPE": "float", + "DEFAULT": 1.0, + "MIN": 0.0, + "MAX": 1.0 + } + ] + +}*/ + +void main() { + vec4 inputPixelColor = vec4(0.0); + vec2 loc = isf_FragNormCoord.xy; + if (heightScale > 0.0) { + float heightDivisor = 1.0 / heightScale; + loc.y = loc.y * heightDivisor + (1.0 - heightDivisor) / 2.0; + float currentLineWidth = mix(bottomWidth,topWidth,loc.y); + if (currentLineWidth > 0.0) { + float lwDivisor = 1.0 / currentLineWidth; + loc.x = loc.x * lwDivisor + (1.0 - lwDivisor) / 2.0; + + if ((loc.x >= 0.0)&&(loc.x <= 1.0)&&(loc.y >= 0.0)&&(loc.y <= 1.0)) { + inputPixelColor = IMG_NORM_PIXEL(inputImage,loc); + } + } + } + gl_FragColor = inputPixelColor; +} diff --git a/ISF/Triangle.fs b/ISF/Triangle.fs new file mode 100644 index 0000000..cb736e5 --- /dev/null +++ b/ISF/Triangle.fs @@ -0,0 +1,85 @@ +/*{ + "CREDIT": "by Carter Rosenberg", + "ISFVSN": "2", + "CATEGORIES": [ + "Generator" + ], + "INPUTS": [ + { + "NAME": "pt1", + "TYPE": "point2D", + "DEFAULT": [ + 0.0, + 0.0 + ] + }, + { + "NAME": "pt2", + "TYPE": "point2D", + "DEFAULT": [ + 0.5, + 1.0 + ] + }, + { + "NAME": "pt3", + "TYPE": "point2D", + "DEFAULT": [ + 1.0, + 0.0 + ] + }, + { + "NAME": "fillColor", + "TYPE": "color", + "DEFAULT": [ + 1.0, + 1.0, + 1.0, + 1.0 + ] + }, + { + "NAME": "bgColor", + "TYPE": "color", + "DEFAULT": [ + 0.0, + 0.0, + 0.0, + 0.0 + ] + } + ] +}*/ + + +// functions via http://stackoverflow.com/questions/2049582/how-to-determine-a-point-in-a-triangle + +float sign(vec2 p1, vec2 p2, vec2 p3) +{ + return (p1.x - p3.x) * (p2.y - p3.y) - (p2.x - p3.x) * (p1.y - p3.y); +} + +bool PointInTriangle(vec2 pt, vec2 v1, vec2 v2, vec2 v3) +{ + bool b1, b2, b3; + + b1 = sign(pt, v1, v2) < 0.0; + b2 = sign(pt, v2, v3) < 0.0; + b3 = sign(pt, v3, v1) < 0.0; + + return ((b1 == b2) && (b2 == b3)); +} + + +void main() { + vec2 loc = isf_FragNormCoord; + vec4 outColor = vec4(0.0); + vec2 point1 = pt1 / RENDERSIZE; + vec2 point2 = pt2 / RENDERSIZE; + vec2 point3 = pt3 / RENDERSIZE; + + // determine if we are inside or outside of the triangle + + gl_FragColor = mix(bgColor, fillColor, float(PointInTriangle(loc, point1,point2,point3)));; +} \ No newline at end of file diff --git a/ISF/Triangles.fs b/ISF/Triangles.fs new file mode 100644 index 0000000..0f0bd10 --- /dev/null +++ b/ISF/Triangles.fs @@ -0,0 +1,130 @@ + +/*{ + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Stylize" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "cell_size", + "TYPE": "float", + "MIN": 0.001, + "MAX": 0.5, + "DEFAULT": 0.125 + }, + { + "NAME": "style", + "VALUES": [ + 0, + 1 + ], + "LABELS": [ + "Squared", + "Diamond" + ], + "DEFAULT": 0, + "TYPE": "long" + } + ] +}*/ + +#ifndef GL_ES +float distance (vec2 center, vec2 pt) +{ + float tmp = pow(center.x-pt.x,2.0)+pow(center.y-pt.y,2.0); + return pow(tmp,0.5); +} +#endif + +void main() +{ +// CALCULATE EDGES OF CURRENT CELL + // At 0.0 just do a pass-thru + if (cell_size == 0.0) { + gl_FragColor = IMG_THIS_PIXEL(inputImage); + } + else { + // Position of current pixel + vec2 xy; + xy.x = isf_FragNormCoord[0]; + xy.y = isf_FragNormCoord[1]; + + + // Left and right of tile + float CellWidth = cell_size; + float CellHeight = cell_size; + + CellHeight = cell_size * RENDERSIZE.x / RENDERSIZE.y; + + float x1 = floor(xy.x / CellWidth)*CellWidth; + float x2 = clamp((ceil(xy.x / CellWidth)*CellWidth), 0.0, 1.0); + // Top and bottom of tile + float y1 = floor(xy.y / CellHeight)*CellHeight; + float y2 = clamp((ceil(xy.y / CellHeight)*CellHeight), 0.0, 1.0); + + // get the normalized local coords in the cell + float x = (xy.x-x1) / CellWidth; + float y = (xy.y-y1) / CellHeight; + vec4 avgClr = vec4(0.0); + + // style 0, two right triangles making a square + if (style == 0) { + // if above the center line... + if (x < y) { + // Average bottom left, top left, center and top right pixels + vec4 avgL = (IMG_NORM_PIXEL(inputImage, vec2(x1, y1))+(IMG_NORM_PIXEL(inputImage, vec2(x1, y2)))) / 2.0; + vec4 avgR = IMG_NORM_PIXEL(inputImage, vec2(x2, y2)); + vec4 avgC = IMG_NORM_PIXEL(inputImage, vec2(x1+(CellWidth/2.0), y2+(CellHeight/2.0))); // Average the averages + centre + avgClr = (avgL+avgR+avgC) / 3.0; + } + else { + // Average bottom right, bottom left, center and top right pixels + vec4 avgR = (IMG_NORM_PIXEL(inputImage, vec2(x2, y1))+(IMG_NORM_PIXEL(inputImage, vec2(x2, y2)))) / 2.0; + vec4 avgL = IMG_NORM_PIXEL(inputImage, vec2(x1, y1)); + vec4 avgC = IMG_NORM_PIXEL(inputImage, vec2(x1+(CellWidth/2.0), y2+(CellHeight/2.0))); // Average the averages + centre + avgClr = (avgL+avgR+avgC) / 3.0; + } + } + // style 1, four triangles making a square + else { + // if above the B2T center line and below the T2B center line... + if ((x > y)&&(x < 1.0 - y)) { + // Average bottom left, bottom right, center + vec4 avgL = IMG_NORM_PIXEL(inputImage, vec2(x1, y1)); + vec4 avgR = IMG_NORM_PIXEL(inputImage, vec2(x2, y1)); + vec4 avgC = IMG_NORM_PIXEL(inputImage, vec2(x1+(CellWidth/2.0), y2+(CellHeight/2.0))); // Average the averages + centre + avgClr = (avgL+avgR+avgC) / 3.0; + } + else if ((x < y)&&(x < 1.0 - y)) { + // Average bottom left, top left, center + vec4 avgL = IMG_NORM_PIXEL(inputImage, vec2(x1, y1)); + vec4 avgR = IMG_NORM_PIXEL(inputImage, vec2(x1, y2)); + vec4 avgC = IMG_NORM_PIXEL(inputImage, vec2(x1+(CellWidth/2.0), y2+(CellHeight/2.0))); // Average the averages + centre + avgClr = (avgL+avgR+avgC) / 3.0; + } + else if ((x > 1.0 - y)&&(x < y)) { + // Average top left, top right, center + vec4 avgL = IMG_NORM_PIXEL(inputImage, vec2(x1, y2)); + vec4 avgR = IMG_NORM_PIXEL(inputImage, vec2(x2, y2)); + vec4 avgC = IMG_NORM_PIXEL(inputImage, vec2(x1+(CellWidth/2.0), y2+(CellHeight/2.0))); // Average the averages + centre + avgClr = (avgL+avgR+avgC) / 3.0; + //avgClr = vec4(0.0,1.0,0.0,1.0); + } + else { + // Average top right, bottom right, center + vec4 avgL = IMG_NORM_PIXEL(inputImage, vec2(x2, y1)); + vec4 avgR = IMG_NORM_PIXEL(inputImage, vec2(x2, y2)); + vec4 avgC = IMG_NORM_PIXEL(inputImage, vec2(x1+(CellWidth/2.0), y2+(CellHeight/2.0))); // Average the averages + centre + avgClr = (avgL+avgR+avgC) / 3.0; + //avgClr = vec4(0.0,0.0,1.0,1.0); + } + } + + gl_FragColor = avgClr; + } +} diff --git a/ISF/Trio Tone.fs b/ISF/Trio Tone.fs new file mode 100644 index 0000000..bd76965 --- /dev/null +++ b/ISF/Trio Tone.fs @@ -0,0 +1,72 @@ +/*{ + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Color Effect" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "darkColor", + "TYPE": "color", + "DEFAULT": [ + 0.00, + 0.164, + 1.0, + 1.0 + ] + }, + { + "NAME": "midColor", + "TYPE": "color", + "DEFAULT": [ + 0.00, + 1.00, + 0.00, + 1.0 + ] + }, + { + "NAME": "brightColor", + "TYPE": "color", + "DEFAULT": [ + 1.0, + 0.00, + 0.00, + 1.0 + ] + } + ] +}*/ + + +// partly adapted from http://coding-experiments.blogspot.com/2010/10/thermal-vision-pixel-shader.html + + +void main () { + vec4 pixcol = IMG_THIS_PIXEL(inputImage); + + vec4 colors[4]; + colors[0] = vec4(0.0,0.0,0.0,1.0); + colors[1] = darkColor; + colors[2] = midColor; + colors[3] = brightColor; + const vec4 lumacoeff = vec4(0.2126, 0.7152, 0.0722, 0.0); + float lum = dot(pixcol, lumacoeff); + //float lum = (pixcol.r+pixcol.g+pixcol.b)/3.; + int ix = 0; + + if (lum > 0.66) { + ix = 2; + } + else if (lum > 0.33) { + ix = 1; + } + + vec4 thermal = mix(colors[ix],colors[ix+1],(lum-float(ix)*0.33)/0.33); + gl_FragColor = vec4(thermal.rgb, pixcol.a); + +} \ No newline at end of file diff --git a/ISF/Twirl.fs b/ISF/Twirl.fs new file mode 100644 index 0000000..cdf942c --- /dev/null +++ b/ISF/Twirl.fs @@ -0,0 +1,66 @@ +/*{ + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Distortion Effect" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "radius", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 5.0 + }, + { + "NAME": "amount", + "TYPE": "float", + "MIN": -10.0, + "MAX": 10.0, + "DEFAULT": 0.0 + }, + { + "NAME": "center", + "TYPE": "point2D", + "DEFAULT": [ + 0.5, + 0.5 + ] + } + ] +}*/ + + +const float pi = 3.14159265359; + + +void main (void) +{ + vec2 uv = vec2(isf_FragNormCoord[0],isf_FragNormCoord[1]); + vec2 texSize = RENDERSIZE; + vec2 tc = uv * texSize; + float radius_sized = radius * max(RENDERSIZE.x,RENDERSIZE.y); + tc -= center; + float dist = length(tc); + if (dist < radius_sized) { + float percent = (radius_sized - dist) / radius_sized; + float theta = percent * percent * amount * 2.0 * pi; + float s = sin(theta); + float c = cos(theta); + tc = vec2(dot(tc, vec2(c, -s)), dot(tc, vec2(s, c))); + } + tc += center; + vec2 loc = tc / texSize; + vec4 color = IMG_NORM_PIXEL(inputImage, loc); + + if ((loc.x < 0.0)||(loc.y < 0.0)||(loc.x > 1.0)||(loc.y > 1.0)) { + gl_FragColor = vec4(0.0); + } + else { + gl_FragColor = color; + } +} \ No newline at end of file diff --git a/ISF/Unsharp Mask.fs b/ISF/Unsharp Mask.fs new file mode 100644 index 0000000..5473b75 --- /dev/null +++ b/ISF/Unsharp Mask.fs @@ -0,0 +1,55 @@ +/*{ + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Sharpen" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "intensity", + "TYPE": "float", + "MIN": 0.0, + "MAX": 10.0, + "DEFAULT": 1.0 + } + ] +}*/ + + +varying vec2 left_coord; +varying vec2 right_coord; +varying vec2 above_coord; +varying vec2 below_coord; + +varying vec2 lefta_coord; +varying vec2 righta_coord; +varying vec2 leftb_coord; +varying vec2 rightb_coord; + +float gray(vec4 n) +{ + return (n.r + n.g + n.b)/3.0; +} + +void main() +{ + + vec4 color = IMG_THIS_PIXEL(inputImage); + vec4 colorL = IMG_NORM_PIXEL(inputImage, left_coord); + vec4 colorR = IMG_NORM_PIXEL(inputImage, right_coord); + vec4 colorA = IMG_NORM_PIXEL(inputImage, above_coord); + vec4 colorB = IMG_NORM_PIXEL(inputImage, below_coord); + + vec4 colorLA = IMG_NORM_PIXEL(inputImage, lefta_coord); + vec4 colorRA = IMG_NORM_PIXEL(inputImage, righta_coord); + vec4 colorLB = IMG_NORM_PIXEL(inputImage, leftb_coord); + vec4 colorRB = IMG_NORM_PIXEL(inputImage, rightb_coord); + + vec4 final = color + intensity * (8.0*color - colorL - colorR - colorA - colorB - colorLA - colorRA - colorLB - colorRB); + + gl_FragColor = final; +} \ No newline at end of file diff --git a/ISF/Unsharp Mask.vs b/ISF/Unsharp Mask.vs new file mode 100644 index 0000000..c8b60f7 --- /dev/null +++ b/ISF/Unsharp Mask.vs @@ -0,0 +1,27 @@ +varying vec2 left_coord; +varying vec2 right_coord; +varying vec2 above_coord; +varying vec2 below_coord; + +varying vec2 lefta_coord; +varying vec2 righta_coord; +varying vec2 leftb_coord; +varying vec2 rightb_coord; + + +void main() +{ + isf_vertShaderInit(); + vec2 texc = vec2(isf_FragNormCoord[0],isf_FragNormCoord[1]); + vec2 d = 1.0/RENDERSIZE; + + left_coord = clamp(vec2(texc.xy + vec2(-d.x , 0)),0.0,1.0); + right_coord = clamp(vec2(texc.xy + vec2(d.x , 0)),0.0,1.0); + above_coord = clamp(vec2(texc.xy + vec2(0,d.y)),0.0,1.0); + below_coord = clamp(vec2(texc.xy + vec2(0,-d.y)),0.0,1.0); + + lefta_coord = clamp(vec2(texc.xy + vec2(-d.x , d.x)),0.0,1.0); + righta_coord = clamp(vec2(texc.xy + vec2(d.x , d.x)),0.0,1.0); + leftb_coord = clamp(vec2(texc.xy + vec2(-d.x , -d.x)),0.0,1.0); + rightb_coord = clamp(vec2(texc.xy + vec2(d.x , -d.x)),0.0,1.0); +} \ No newline at end of file diff --git a/ISF/VHS Glitch.fs b/ISF/VHS Glitch.fs new file mode 100644 index 0000000..d80f060 --- /dev/null +++ b/ISF/VHS Glitch.fs @@ -0,0 +1,213 @@ +/*{ + "DESCRIPTION": "VHS Glitch Style", + "CREDIT": "David Lublin, original by Staffan Widegarn Åhlvik", + "ISFVSN": "2", + "CATEGORIES": [ + "Stylize", "Glitch", "Retro" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "autoScan", + "TYPE": "bool", + "DEFAULT": 1.0 + }, + { + "NAME": "xScanline", + "TYPE": "float", + "DEFAULT": 0.5, + "MIN": 0.0, + "MAX": 1.0 + }, + { + "NAME": "xScanline2", + "TYPE": "float", + "DEFAULT": 0.5, + "MIN": 0.0, + "MAX": 1.0 + }, + { + "NAME": "yScanline", + "TYPE": "float", + "DEFAULT": 0.0, + "MIN": 0.0, + "MAX": 1.0 + }, + { + "NAME": "xScanlineSize", + "TYPE": "float", + "DEFAULT": 0.5, + "MIN": 0.0, + "MAX": 1.0 + }, + { + "NAME": "xScanlineSize2", + "TYPE": "float", + "DEFAULT": 0.25, + "MIN": 0.0, + "MAX": 1.0 + }, + { + "NAME": "yScanlineAmount", + "TYPE": "float", + "DEFAULT": 0.25, + "MIN": -1.0, + "MAX": 1.0 + }, + { + "NAME": "grainLevel", + "TYPE": "float", + "DEFAULT": 0.0, + "MIN": 0.0, + "MAX": 3.0 + }, + { + "NAME": "scanFollow", + "TYPE": "bool", + "DEFAULT": 1.0 + }, + { + "NAME": "analogDistort", + "TYPE": "float", + "DEFAULT": 1.0, + "MIN": 0.0, + "MAX": 10.0 + }, + { + "NAME": "bleedAmount", + "TYPE": "float", + "DEFAULT": 1.0, + "MIN": 0.0, + "MAX": 3.0 + }, + { + "NAME": "bleedDistort", + "TYPE": "float", + "DEFAULT": 0.5, + "MIN": 0.0, + "MAX": 1.0 + }, + { + "NAME": "bleedRange", + "TYPE": "float", + "DEFAULT": 1.0, + "MIN": 0.0, + "MAX": 2.0 + }, + { + "NAME": "colorBleedL", + "TYPE": "color", + "DEFAULT": [ + 0.8, + 0.0, + 0.4, + 1.0 + ] + }, + { + "NAME": "colorBleedC", + "TYPE": "color", + "DEFAULT": [ + 0.0, + 0.5, + 0.75, + 1.0 + ] + }, + { + "NAME": "colorBleedR", + "TYPE": "color", + "DEFAULT": [ + 0.8, + 0.0, + 0.4, + 1.0 + ] + } + ] + +}*/ + + + + +// Based on https://github.com/staffantan/unity-vhsglitch +// Converted by David Lublin / VIDVOX + + +const float tau = 6.28318530718; + + +float rand(vec3 co){ + return abs(mod(sin( dot(co.xyz ,vec3(12.9898,78.233,45.5432) )) * 43758.5453, 1.0)); +} + +void main() { + float actualXLine = (!autoScan) ? xScanline : mod(xScanline + ((1.0+sin(0.34*TIME))/2.0 + (1.0+sin(TIME))/3.0 + (1.0+cos(2.1*TIME))/3.0 + (1.0+cos(0.027*TIME))/2.0)/3.5,1.0); + float actualXLineWidth = (!autoScan) ? xScanlineSize : xScanlineSize + ((1.0+sin(1.2*TIME))/2.0 + (1.0+cos(3.91*TIME))/3.0 + (1.0+cos(0.014*TIME))/2.0)/3.5; + vec2 loc = isf_FragNormCoord; + vec4 vhs = IMG_NORM_PIXEL(inputImage, loc); + float dx = 1.0+actualXLineWidth/25.0-abs(distance(loc.y, actualXLine)); + float dx2 = 1.0+xScanlineSize2/10.0-abs(distance(loc.y, xScanline2)); + float dy = (1.0-abs(distance(loc.y, yScanline))); + if (autoScan) + dy = (1.0-abs(distance(loc.y, mod(yScanline+TIME,1.0)))); + + dy = (dy > 0.5) ? 2.0 * dy : 2.0 * (1.0 - dy); + + float rX = (scanFollow) ? rand(vec3(dy,actualXLine,analogDistort)) : rand(vec3(dy,bleedAmount,analogDistort)); + float xTime = (actualXLine > 0.5) ? 2.0 * actualXLine : 2.0 * (1.0 - actualXLine); + + loc.x += yScanlineAmount * dy * 0.025 + analogDistort * rX/(RENDERSIZE.x/2.0); + + if(dx2 > 1.0 - xScanlineSize2 / 10.0) { + float rX2 = (dy * rand(vec3(dy,dx2,dx+TIME)) + dx2) / 4.0; + float distortAmount = analogDistort * (sin(rX * tau / dx2) + cos(rX * tau * 0.78 / dx2)) / 10.0; + //loc.y = xScanline2; + //loc.x += (1.0 + distortAmount * sin(tau * (loc.x) / rX2 ) - 1.0) / 15.0; + loc.x += (1.0 + distortAmount * sin(tau * (loc.x) / rX2 ) - 1.0) / 15.0; + } + if(dx > 1.0 - actualXLineWidth / 25.0) + loc.y = actualXLine; + + loc.x = mod(loc.x,1.0); + loc.y = mod(loc.y,1.0); + + vec4 c = IMG_NORM_PIXEL(inputImage, loc); + float x = (loc.x*320.0)/320.0; + float y = (loc.y*240.0)/240.0; + float bleed = 0.0; + + if (scanFollow) + c -= rand(vec3(x, y, xTime)) * xTime / (5.0-grainLevel); + else + c -= rand(vec3(x, y, bleedAmount)) * (bleedAmount/20.0) / (5.0-grainLevel); + + if (bleedAmount > 0.0) { + IMG_NORM_PIXEL(inputImage, loc + vec2(0.01, 0)).r; + bleed += IMG_NORM_PIXEL(inputImage, loc + bleedRange * vec2(0.02, 0)).r; + bleed += IMG_NORM_PIXEL(inputImage, loc + bleedRange * vec2(0.01, 0.01)).r; + bleed += IMG_NORM_PIXEL(inputImage, loc + bleedRange * vec2(-0.02, 0.02)).r; + bleed += IMG_NORM_PIXEL(inputImage, loc + bleedRange * vec2(0.0, -0.03)).r; + bleed /= 6.0; + bleed *= bleedAmount; + } + + if (bleed > 0.1){ + float bleedFreq = 1.0; + float bleedX = 0.0; + if (autoScan) + bleedX = x + bleedDistort * (yScanlineAmount + (1.5 + cos(TIME / 13.0 + tau*(bleedDistort+(1.0-loc.y))))/2.0) * sin((TIME / 9.0 + bleedDistort) * tau + loc.y * loc.y * tau * bleedFreq) / 8.0; + else + bleedX = x + (yScanlineAmount + (1.0 + sin(tau*(bleedDistort+loc.y)))/2.0) * sin(bleedDistort * tau + loc.y * loc.y * tau * bleedFreq) / 10.0; + vec4 colorBleed = (bleedX < 0.5) ? mix(colorBleedL, colorBleedC, 2.0 * bleedX) : mix(colorBleedR, colorBleedC, 2.0 - 2.0 * bleedX); + if (scanFollow) + c += bleed * max(xScanlineSize,xTime) * colorBleed; + else + c += bleed * colorBleed; + } + gl_FragColor = c; +} diff --git a/ISF/VVMotionBlur 3.0.fs b/ISF/VVMotionBlur 3.0.fs new file mode 100644 index 0000000..489b7d7 --- /dev/null +++ b/ISF/VVMotionBlur 3.0.fs @@ -0,0 +1,37 @@ +/*{ + "DESCRIPTION": "this is basically identical to the demonstration of a persistent buffer", + "CREDIT": "by zoidberg", + "ISFVSN": "2", + "CATEGORIES": [ + "Blur" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "blurAmount", + "TYPE": "float", + "DEFAULT": 0.0 + } + ], + "PASSES": [ + { + "TARGET":"bufferVariableNameA", + "PERSISTENT": true, + "FLOAT": true + }, + { + + } + ] + +}*/ + +void main() +{ + vec4 freshPixel = IMG_PIXEL(inputImage,gl_FragCoord.xy); + vec4 stalePixel = IMG_PIXEL(bufferVariableNameA,gl_FragCoord.xy); + gl_FragColor = mix(freshPixel,stalePixel,blurAmount); +} diff --git a/ISF/Vertex Manipulator.fs b/ISF/Vertex Manipulator.fs new file mode 100644 index 0000000..e8490b7 --- /dev/null +++ b/ISF/Vertex Manipulator.fs @@ -0,0 +1,58 @@ +/*{ + "DESCRIPTION": "Moves the vertex points to the specified locations without correction", + "CREDIT": "VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Glitch","Geometry Adjustment" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "topleft", + "LABEL": "Top Left", + "TYPE": "point2D", + "DEFAULT": [ + 0.0, + 1.0 + ] + }, + { + "NAME": "bottomleft", + "LABEL": "Bottom Left", + "TYPE": "point2D", + "DEFAULT": [ + 0.0, + 0.0 + ] + }, + { + "NAME": "topright", + "LABEL": "Top Right", + "TYPE": "point2D", + "DEFAULT": [ + 1.0, + 1.0 + ] + }, + + { + "NAME": "bottomright", + "LABEL": "Bottom Right", + "TYPE": "point2D", + "DEFAULT": [ + 1.0, + 0.0 + ] + } + ] +}*/ + + +void main() +{ + vec4 test = IMG_THIS_PIXEL(inputImage); + gl_FragColor = test; +} diff --git a/ISF/Vertex Manipulator.vs b/ISF/Vertex Manipulator.vs new file mode 100644 index 0000000..599fdfc --- /dev/null +++ b/ISF/Vertex Manipulator.vs @@ -0,0 +1,31 @@ + + +void main() +{ + isf_vertShaderInit(); + + vec4 position = gl_Position; + vec4 coord; + if ((position.x<0.0)&&(position.y<0.0)) { + coord.xy = bottomleft / RENDERSIZE; + coord.x = coord.x * 2.0; + coord.y = coord.y * 2.0; + } + else if ((position.x>0.0)&&(position.y<0.0)) { + coord.xy = bottomright / RENDERSIZE; + coord.x = (1.0-coord.x) * -2.0; + coord.y = coord.y * 2.0; + } + else if (position.x<0.0) { + coord.xy = topleft / RENDERSIZE; + coord.x = coord.x * 2.0; + coord.y = (1.0-coord.y) * -2.0; + } + else { + coord.xy = topright / RENDERSIZE; + coord.x = (1.0-coord.x) * -2.0; + coord.y = (1.0-coord.y) * -2.0; + } + gl_Position.xy = position.xy + coord.xy; + +} diff --git a/ISF/Vertical Tearing.fs b/ISF/Vertical Tearing.fs new file mode 100644 index 0000000..954e864 --- /dev/null +++ b/ISF/Vertical Tearing.fs @@ -0,0 +1,51 @@ +/* +{ + "CATEGORIES" : [ + "Glitch" + ], + "DESCRIPTION" : "This introduces a vertical tearing effect similar to when GL VBL sync is off.", + "ISFVSN" : "2", + "INPUTS" : [ + { + "NAME" : "inputImage", + "TYPE" : "image" + }, + { + "NAME" : "tearPosition", + "TYPE" : "float", + "MAX" : 1, + "DEFAULT" : 0.5, + "MIN" : 0 + } + ], + "PASSES" : [ + { + "TARGET" : "oldImage" + }, + { + "TARGET" : "newImage", + "PERSISTENT" : true + }, + { + + } + ], + "CREDIT" : "by VIDVOX" +} +*/ + +void main() +{ + // write the previous buffer into here + if (PASSINDEX == 0) { + gl_FragColor = IMG_NORM_PIXEL(newImage,isf_FragNormCoord.xy); + } + else if (PASSINDEX == 1) { + gl_FragColor = IMG_NORM_PIXEL(inputImage,isf_FragNormCoord.xy); + } + else if (PASSINDEX == 2) { + vec4 freshPixel = IMG_NORM_PIXEL(inputImage,isf_FragNormCoord.xy); + vec4 stalePixel = IMG_NORM_PIXEL(oldImage,isf_FragNormCoord.xy); + gl_FragColor = (isf_FragNormCoord.y > tearPosition) ? freshPixel : stalePixel; + } +} diff --git a/ISF/Vibrance.fs b/ISF/Vibrance.fs new file mode 100644 index 0000000..ed8788c --- /dev/null +++ b/ISF/Vibrance.fs @@ -0,0 +1,54 @@ +/*{ + "CREDIT": "by zoidberg", + "ISFVSN": "2", + "CATEGORIES": [ + "Color Adjustment" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "vibrance", + "TYPE": "float", + "MIN": -0.25, + "MAX": 0.6, + "DEFAULT": 0.0 + } + ] +}*/ + + +vec3 rgb2hsv(vec3 c); +vec3 hsv2rgb(vec3 c); + +void main() { + vec4 tmpColorA = IMG_THIS_PIXEL(inputImage); + vec3 tmpColorB = rgb2hsv(tmpColorA.rgb); + float maxDelta = sqrt(tmpColorB.y) - tmpColorB.y; + tmpColorB.y = (maxDelta * vibrance) + tmpColorB.y; + tmpColorA.rgb = hsv2rgb(tmpColorB.rgb); + gl_FragColor = tmpColorA; +} + + + + +vec3 rgb2hsv(vec3 c) { + vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); + //vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g)); + //vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r)); + vec4 p = c.g < c.b ? vec4(c.bg, K.wz) : vec4(c.gb, K.xy); + vec4 q = c.r < p.x ? vec4(p.xyw, c.r) : vec4(c.r, p.yzx); + + float d = q.x - min(q.w, q.y); + float e = 1.0e-10; + return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x); +} + +vec3 hsv2rgb(vec3 c) { + vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); + vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www); + return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y); +} \ No newline at end of file diff --git a/ISF/Waveform Displace.fs b/ISF/Waveform Displace.fs new file mode 100644 index 0000000..29e7bac --- /dev/null +++ b/ISF/Waveform Displace.fs @@ -0,0 +1,72 @@ +/* +{ + "CATEGORIES" : [ + "Distortion Effect", "Audio Reactive" + ], + "DESCRIPTION" : "Displaces image with audio waveform", + "ISFVSN" : "2", + "INPUTS" : [ + { + "NAME" : "inputImage", + "TYPE" : "image" + }, + { + "NAME" : "audio", + "TYPE" : "image", + "LABEL" : "Audio Waveform" + }, + { + "NAME" : "displaceX", + "TYPE" : "float", + "MAX" : 1, + "DEFAULT" : 0.1, + "MIN" : 0, + "LABEL" : "Displace X" + }, + { + "NAME" : "displaceY", + "TYPE" : "float", + "MAX" : 1, + "DEFAULT" : 0.1, + "MIN" : 0, + "LABEL" : "Displace Y" + }, + { + "NAME" : "detailX", + "TYPE" : "float", + "MAX" : 1, + "DEFAULT" : 0.5, + "MIN" : 0, + "LABEL" : "Detail X" + }, + { + "NAME" : "detailY", + "TYPE" : "float", + "MAX" : 1, + "DEFAULT" : 0.5, + "MIN" : 0, + "LABEL" : "Detail Y" + } + ], + "PASSES" : [ + { + "DESCRIPTION" : "Renderpass 0" + } + ], + "CREDIT" : "icalvin102 (calvin@icalvin.de)" +} +*/ + +void main() { + + vec4 inputPixelColor; + vec2 uv = isf_FragNormCoord.xy; + vec2 waveLoc = fract((uv)*vec2(detailX, detailY)); + + vec2 wave = vec2(IMG_NORM_PIXEL(audio, vec2(waveLoc.x, 0.0)).r, IMG_NORM_PIXEL(audio, vec2(waveLoc.y, 1.0)).r)-.5; + wave *= vec2(displaceY, displaceX); + + inputPixelColor = IMG_NORM_PIXEL(inputImage, uv + wave.yx); + + gl_FragColor = inputPixelColor; +} diff --git a/ISF/White Point Adjust.fs b/ISF/White Point Adjust.fs new file mode 100644 index 0000000..ffdd564 --- /dev/null +++ b/ISF/White Point Adjust.fs @@ -0,0 +1,31 @@ +/*{ + "CREDIT": "by zoidberg", + "ISFVSN": "2", + "DESCRIPTION": "Modifies the white point by multiplying the src pixel by the color value", + "CATEGORIES": [ + "Color Adjustment" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "newWhite", + "TYPE": "color", + "DEFAULT": [ + 1.0, + 1.0, + 1.0, + 1.0 + ] + } + ] +}*/ + + + +void main() { + vec4 tmpColorA = IMG_THIS_PIXEL(inputImage); + gl_FragColor = tmpColorA * newWhite; +} \ No newline at end of file diff --git a/ISF/XYZoom.fs b/ISF/XYZoom.fs new file mode 100644 index 0000000..9c63019 --- /dev/null +++ b/ISF/XYZoom.fs @@ -0,0 +1,51 @@ +/*{ + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Distortion Effect", "Geometry Adjustment" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "levelX", + "TYPE": "float", + "MIN": 0.01, + "MAX": 10.0, + "DEFAULT": 1.0 + }, + { + "NAME": "levelY", + "TYPE": "float", + "MIN": 0.01, + "MAX": 10.0, + "DEFAULT": 1.0 + }, + { + "NAME": "center", + "TYPE": "point2D", + "DEFAULT": [ + 0.5, + 0.5 + ] + } + ] +}*/ + +void main() { + vec2 loc; + vec2 modifiedCenter; + + loc = isf_FragNormCoord; + modifiedCenter = center / RENDERSIZE; + loc.x = (loc.x - modifiedCenter.x)*(1.0/levelX) + modifiedCenter.x; + loc.y = (loc.y - modifiedCenter.y)*(1.0/levelY) + modifiedCenter.y; + if ((loc.x < 0.0)||(loc.y < 0.0)||(loc.x > 1.0)||(loc.y > 1.0)) { + gl_FragColor = vec4(0.0); + } + else { + gl_FragColor = IMG_NORM_PIXEL(inputImage,loc); + } +} diff --git a/ISF/Zoom.fs b/ISF/Zoom.fs new file mode 100644 index 0000000..473dd19 --- /dev/null +++ b/ISF/Zoom.fs @@ -0,0 +1,44 @@ +/*{ + "CREDIT": "by VIDVOX", + "ISFVSN": "2", + "CATEGORIES": [ + "Distortion Effect", "Geometry Adjustment" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "level", + "TYPE": "float", + "MIN": 0.01, + "MAX": 10.0, + "DEFAULT": 1.0 + }, + { + "NAME": "center", + "TYPE": "point2D", + "DEFAULT": [ + 0.5, + 0.5 + ] + } + ] +}*/ + +void main() { + vec2 loc; + vec2 modifiedCenter; + + loc = isf_FragNormCoord; + modifiedCenter = center / RENDERSIZE; + loc.x = (loc.x - modifiedCenter.x)*(1.0/level) + modifiedCenter.x; + loc.y = (loc.y - modifiedCenter.y)*(1.0/level) + modifiedCenter.y; + if ((loc.x < 0.0)||(loc.y < 0.0)||(loc.x > 1.0)||(loc.y > 1.0)) { + gl_FragColor = vec4(0.0); + } + else { + gl_FragColor = IMG_NORM_PIXEL(inputImage,loc); + } +} diff --git a/ISF/Zooming Feedback.fs b/ISF/Zooming Feedback.fs new file mode 100644 index 0000000..d099bbc --- /dev/null +++ b/ISF/Zooming Feedback.fs @@ -0,0 +1,205 @@ +/*{ + "DESCRIPTION": "Creates a simple zooming feedback loop", + "CREDIT": "", + "ISFVSN": "2", + "CATEGORIES": [ + "Stylize", "Retro" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "preShift", + "TYPE": "point2D", + "DEFAULT": [ + 0, + 0 + ] + }, + { + "NAME": "feedbackLevel", + "TYPE": "float", + "DEFAULT": 0.9, + "MIN": 0.0, + "MAX": 1.0 + }, + { + "NAME": "rotateAngle", + "TYPE": "float", + "DEFAULT": 0.5, + "MIN": 0.0, + "MAX": 1.0 + }, + { + "NAME": "zoomLevel", + "TYPE": "float", + "DEFAULT": 1.2, + "MIN": 0.25, + "MAX": 2.0 + }, + { + "NAME": "zoomCenter", + "TYPE": "point2D", + "DEFAULT": [ + 0, + 0 + ] + }, + { + "NAME": "feedbackShift", + "TYPE": "point2D", + "DEFAULT": [ + 0, + 0 + ] + }, + { + "NAME": "invert", + "TYPE": "bool", + "DEFAULT": 0.0 + }, + { + "NAME": "blendMode", + "TYPE": "long", + "VALUES": [ + 0, + 1, + 2, + 3, + 4, + 5 + ], + "LABELS": [ + "Add", + "Over Black", + "Over Alpha", + "Max", + "Under Black", + "Under Alpha" + ], + "DEFAULT": 3 + }, + { + "NAME": "blackThresh", + "TYPE": "float", + "DEFAULT": 0.1, + "MIN": 0.0, + "MAX": 1.0 + }, + { + "NAME": "satLevel", + "TYPE": "float", + "DEFAULT": 1.0, + "MIN": 0.0, + "MAX": 2.0 + }, + { + "NAME": "colorShift", + "TYPE": "float", + "DEFAULT": 0.0, + "MIN": 0.0, + "MAX": 1.0 + } + ], + "PASSES": [ + { + "TARGET":"feedbackBuffer", + "PERSISTENT": true + } + ] + +}*/ + + +const float pi = 3.14159265359; + + +vec3 rgb2hsv(vec3 c) { + vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); + //vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g)); + //vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r)); + vec4 p = c.g < c.b ? vec4(c.bg, K.wz) : vec4(c.gb, K.xy); + vec4 q = c.r < p.x ? vec4(p.xyw, c.r) : vec4(c.r, p.yzx); + + float d = q.x - min(q.w, q.y); + float e = 1.0e-10; + return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x); +} + +vec3 hsv2rgb(vec3 c) { + vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); + vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www); + return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y); +} + + + +void main() { + vec2 loc = isf_FragNormCoord; + vec4 inputPixelColor = IMG_NORM_PIXEL(inputImage,loc + (0.5 - (preShift / RENDERSIZE))); + + vec4 feedbackPixelColor = vec4(0.0); + + // rotate here if needed + loc = loc * RENDERSIZE; + float r = distance(RENDERSIZE/2.0, loc); + float a = atan ((loc.y-RENDERSIZE.y/2.0),(loc.x-RENDERSIZE.x/2.0)); + + loc.x = r * cos(a + 2.0 * pi * rotateAngle - pi) + 0.5; + loc.y = r * sin(a + 2.0 * pi * rotateAngle - pi) + 0.5; + + loc = loc / RENDERSIZE + vec2(0.5); + + vec2 modifiedCenter = zoomCenter / RENDERSIZE; + loc.x = (loc.x - modifiedCenter.x)*(1.0/zoomLevel) + modifiedCenter.x; + loc.y = (loc.y - modifiedCenter.y)*(1.0/zoomLevel) + modifiedCenter.y; + loc += (0.5 - (feedbackShift / RENDERSIZE)); + + if ((loc.x < 0.0)||(loc.y < 0.0)||(loc.x > 1.0)||(loc.y > 1.0)) { + feedbackPixelColor = vec4(0.0); + } + else { + feedbackPixelColor = IMG_NORM_PIXEL(feedbackBuffer,loc); + } + + feedbackPixelColor.rgb = rgb2hsv(feedbackPixelColor.rgb); + feedbackPixelColor.r = mod(feedbackPixelColor.r+colorShift,1.0); + feedbackPixelColor.g *= satLevel; + + feedbackPixelColor.rgb = hsv2rgb(feedbackPixelColor.rgb); + + if (invert) + feedbackPixelColor.rgb = 1.0 - feedbackPixelColor.rgb; + + if (blendMode == 0) { + inputPixelColor = inputPixelColor + feedbackLevel * feedbackPixelColor; + } + else if (blendMode == 1) { + float val = inputPixelColor.a * (inputPixelColor.r + inputPixelColor.g + inputPixelColor.b) / 3.0; + inputPixelColor = (val >= blackThresh) ? inputPixelColor : feedbackLevel * feedbackPixelColor; + inputPixelColor.a = inputPixelColor.a + feedbackPixelColor.a * feedbackLevel; + } + else if (blendMode == 2) { + // apply the alpha to the input pixel as this happens + inputPixelColor.rgb = inputPixelColor.a * inputPixelColor.rgb + (1.0 - inputPixelColor.a) * feedbackLevel * feedbackPixelColor.rgb; + inputPixelColor.a = inputPixelColor.a + feedbackPixelColor.a * feedbackLevel; + } + else if (blendMode == 3) { + inputPixelColor.rgb = max(inputPixelColor.a * inputPixelColor.rgb, feedbackLevel * feedbackPixelColor.rgb); + inputPixelColor.a = inputPixelColor.a + feedbackPixelColor.a * feedbackLevel; + } + else if (blendMode == 4) { + float val = feedbackPixelColor.a * (feedbackPixelColor.r + feedbackPixelColor.g + feedbackPixelColor.b) / 3.0; + inputPixelColor = (val < blackThresh) ? inputPixelColor.a * inputPixelColor : feedbackLevel * feedbackPixelColor; + inputPixelColor.a = inputPixelColor.a + feedbackPixelColor.a * feedbackLevel; + } + else if (blendMode == 5) { + // apply the alpha to the input pixel as this happens + inputPixelColor.rgb = (1.0-feedbackPixelColor.a) * inputPixelColor.a * inputPixelColor.rgb + feedbackLevel * feedbackPixelColor.rgb; + inputPixelColor.a = inputPixelColor.a + feedbackPixelColor.a * feedbackLevel; + } + + gl_FragColor = inputPixelColor; +} diff --git a/ISF/noise2d.png b/ISF/noise2d.png new file mode 100644 index 0000000..79168c9 Binary files /dev/null and b/ISF/noise2d.png differ diff --git a/ISF/v002 Bleach Bypass.fs b/ISF/v002 Bleach Bypass.fs new file mode 100644 index 0000000..d96be25 --- /dev/null +++ b/ISF/v002 Bleach Bypass.fs @@ -0,0 +1,52 @@ +/*{ + "CREDIT": "by v002", + "ISFVSN": "2", + "CATEGORIES": [ + "Film", "v002" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "amount", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.0 + } + ] +}*/ + +// Based on v002 bleach bypass – https://github.com/v002/v002-Film-Effects/ + +//constant variables. +const vec4 one = vec4(1.0); +const vec4 two = vec4(2.0); +//const vec4 lumcoeff = vec4(0.2125,0.7154,0.0721,0.0); +const vec4 lumcoeff = vec4(0.2126, 0.7152, 0.0722, 0.0); + + +vec4 overlay(vec4 myInput, vec4 previousmix, vec4 amount) +{ + float luminance = dot(previousmix,lumcoeff); + float mixamount = clamp((luminance - 0.45) * 10., 0., 1.); + + vec4 branch1 = two * previousmix * myInput; + vec4 branch2 = one - (two * (one - previousmix) * (one - myInput)); + + vec4 result = mix(branch1, branch2, vec4(mixamount) ); + + return mix(previousmix, result, amount); +} + +void main (void) +{ + vec4 input0 = IMG_THIS_PIXEL(inputImage); + + vec4 luma = vec4(dot(input0,lumcoeff)); + + gl_FragColor = overlay(luma, input0, vec4(amount)); + +} \ No newline at end of file diff --git a/ISF/v002 Crosshatch.fs b/ISF/v002 Crosshatch.fs new file mode 100644 index 0000000..46909ab --- /dev/null +++ b/ISF/v002 Crosshatch.fs @@ -0,0 +1,114 @@ +/*{ + "CREDIT": "by v002", + "ISFVSN": "2", + "CATEGORIES": [ + "Halftone Effect", "v002" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "invert", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.0 + }, + { + "NAME": "separation", + "TYPE": "float", + "MIN": 0.0, + "MAX": 0.5, + "DEFAULT": 0.25 + }, + { + "NAME": "greyscale", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.75 + }, + { + "NAME": "thickness", + "TYPE": "float", + "MIN": 0.5, + "MAX": 1.0, + "DEFAULT": 0.75 + }, + { + "NAME": "front", + "TYPE": "color", + "DEFAULT": [ + 0.5, + 0.0, + 0.25, + 1.0 + ] + }, + { + "NAME": "back", + "TYPE": "color", + "DEFAULT": [ + 0.2, + 0.75, + 0.5, + 1.0 + ] + } + ] +}*/ + + +//Original Source +//http://learningwebgl.com/blog/?p=2858 + +// Based on https://github.com/v002/v002-Half-Tones/ + + + + +const vec4 lumacoeff = vec4(0.2126, 0.7152, 0.0722, 0.0); + + +void main() +{ + vec4 color = IMG_THIS_PIXEL(inputImage); + float lum = dot(color, lumacoeff); + vec2 coord = gl_FragCoord.xy; + + vec4 colora = mix(front, back, invert); + vec4 colorb = mix(back, front, invert); + + colora.a *= color.a; + colorb.a *= color.a; + + vec4 cout = mix(color,colora, greyscale); + + gl_FragColor = colorb; + + if (lum > 1.00) + { + if (mod(coord.x + coord.y, thickness) >= separation) + gl_FragColor = cout; + } + + if (lum > 0.75) + { + if (mod(coord.x - coord.y, thickness) >= separation ) + gl_FragColor = cout; + } + + if (lum > 0.50) + { + if (mod(coord.x + coord.y - (thickness * 0.5), thickness) >= separation) + gl_FragColor = cout; + } + + if (lum > 0.3) + { + if (mod(coord.x - coord.y - (thickness * 0.5), thickness) >= separation) + gl_FragColor = cout; + } +} \ No newline at end of file diff --git a/ISF/v002 Dilate.fs b/ISF/v002 Dilate.fs new file mode 100644 index 0000000..dd071e0 --- /dev/null +++ b/ISF/v002 Dilate.fs @@ -0,0 +1,48 @@ +/*{ + "DESCRIPTION": "messed up version of v002 dilate", + "CREDIT": "by carter rosenberg", + "ISFVSN": "2", + "CATEGORIES": [ + "Blur", "v002" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "amount", + "TYPE": "float", + "MIN": 0.0, + "MAX": 0.1, + "DEFAULT": 0.01 + } + ] +}*/ + + +varying vec2 texcoord0; +varying vec2 texcoord1; +varying vec2 texcoord2; +varying vec2 texcoord3; +varying vec2 texcoord4; +varying vec2 texcoord5; +varying vec2 texcoord6; +varying vec2 texcoord7; + +void main() +{ + + vec4 dilate = IMG_NORM_PIXEL(inputImage, 0.5 * (texcoord3 + texcoord4)); + + dilate = max(dilate, IMG_NORM_PIXEL(inputImage, texcoord0)); + dilate = max(dilate, IMG_NORM_PIXEL(inputImage, texcoord1)); + dilate = max(dilate, IMG_NORM_PIXEL(inputImage, texcoord2)); + dilate = max(dilate, IMG_NORM_PIXEL(inputImage, texcoord3)); + dilate = max(dilate, IMG_NORM_PIXEL(inputImage, texcoord4)); + dilate = max(dilate, IMG_NORM_PIXEL(inputImage, texcoord5)); + dilate = max(dilate, IMG_NORM_PIXEL(inputImage, texcoord6)); + dilate = max(dilate, IMG_NORM_PIXEL(inputImage, texcoord7)); + + gl_FragColor = dilate; +} \ No newline at end of file diff --git a/ISF/v002 Dilate.vs b/ISF/v002 Dilate.vs new file mode 100644 index 0000000..ae18584 --- /dev/null +++ b/ISF/v002 Dilate.vs @@ -0,0 +1,29 @@ + +varying vec2 texcoord0; +varying vec2 texcoord1; +varying vec2 texcoord2; +varying vec2 texcoord3; +varying vec2 texcoord4; +varying vec2 texcoord5; +varying vec2 texcoord6; +varying vec2 texcoord7; + +void main() +{ + isf_vertShaderInit(); + // perform standard transform on vertex + //gl_Position = ftransform(); + + // transform texcoord + vec2 texcoord = vec2(isf_FragNormCoord[0],isf_FragNormCoord[1]); + + // get sample positions + texcoord0 = texcoord + vec2(-amount, -amount); + texcoord1 = texcoord + vec2( 0, -amount); + texcoord2 = texcoord + vec2( amount, -amount); + texcoord3 = texcoord + vec2(-amount, 0); + texcoord4 = texcoord + vec2( amount, 0); + texcoord5 = texcoord + vec2(-amount, amount); + texcoord6 = texcoord + vec2( 0, amount); + texcoord7 = texcoord + vec2( amount, amount); +} diff --git a/ISF/v002 Erode.fs b/ISF/v002 Erode.fs new file mode 100644 index 0000000..9878ae7 --- /dev/null +++ b/ISF/v002 Erode.fs @@ -0,0 +1,48 @@ +/*{ + "DESCRIPTION": "messed up version of v002 erode", + "CREDIT": "by carter rosenberg", + "ISFVSN": "2", + "CATEGORIES": [ + "Blur", "v002" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "amount", + "TYPE": "float", + "MIN": 0.0, + "MAX": 0.1, + "DEFAULT": 0.01 + } + ] +}*/ + + +varying vec2 texcoord0; +varying vec2 texcoord1; +varying vec2 texcoord2; +varying vec2 texcoord3; +varying vec2 texcoord4; +varying vec2 texcoord5; +varying vec2 texcoord6; +varying vec2 texcoord7; + +void main() +{ + + vec4 erode = IMG_NORM_PIXEL(inputImage, 0.5 * (texcoord3 + texcoord4)); + + erode = min(erode, IMG_NORM_PIXEL(inputImage, texcoord0)); + erode = min(erode, IMG_NORM_PIXEL(inputImage, texcoord1)); + erode = min(erode, IMG_NORM_PIXEL(inputImage, texcoord2)); + erode = min(erode, IMG_NORM_PIXEL(inputImage, texcoord3)); + erode = min(erode, IMG_NORM_PIXEL(inputImage, texcoord4)); + erode = min(erode, IMG_NORM_PIXEL(inputImage, texcoord5)); + erode = min(erode, IMG_NORM_PIXEL(inputImage, texcoord6)); + erode = min(erode, IMG_NORM_PIXEL(inputImage, texcoord7)); + + gl_FragColor = erode; +} \ No newline at end of file diff --git a/ISF/v002 Erode.vs b/ISF/v002 Erode.vs new file mode 100644 index 0000000..ae18584 --- /dev/null +++ b/ISF/v002 Erode.vs @@ -0,0 +1,29 @@ + +varying vec2 texcoord0; +varying vec2 texcoord1; +varying vec2 texcoord2; +varying vec2 texcoord3; +varying vec2 texcoord4; +varying vec2 texcoord5; +varying vec2 texcoord6; +varying vec2 texcoord7; + +void main() +{ + isf_vertShaderInit(); + // perform standard transform on vertex + //gl_Position = ftransform(); + + // transform texcoord + vec2 texcoord = vec2(isf_FragNormCoord[0],isf_FragNormCoord[1]); + + // get sample positions + texcoord0 = texcoord + vec2(-amount, -amount); + texcoord1 = texcoord + vec2( 0, -amount); + texcoord2 = texcoord + vec2( amount, -amount); + texcoord3 = texcoord + vec2(-amount, 0); + texcoord4 = texcoord + vec2( amount, 0); + texcoord5 = texcoord + vec2(-amount, amount); + texcoord6 = texcoord + vec2( 0, amount); + texcoord7 = texcoord + vec2( amount, amount); +} diff --git a/ISF/v002 Light Leak.fs b/ISF/v002 Light Leak.fs new file mode 100644 index 0000000..015f9da --- /dev/null +++ b/ISF/v002 Light Leak.fs @@ -0,0 +1,77 @@ +/*{ + "CREDIT": "by v002", + "ISFVSN": "2", + "CATEGORIES": [ + "Film", "v002" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "leakImage", + "TYPE": "image" + }, + { + "NAME": "amount", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.5, + "DEFAULT": 0.5 + }, + { + "NAME": "length", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.5 + }, + { + "NAME": "angle", + "TYPE": "float", + "MIN": 0.0, + "MAX": 360.0, + "DEFAULT": 0.0 + } + ] +}*/ + + +// rotation matrix +varying mat2 rotmat; + + + +void main (void) +{ + + // normalized point 0 - 1 texcoords + vec2 point = isf_FragNormCoord; + // our normal image. + vec4 input0 = IMG_NORM_PIXEL(inputImage, point); + // rotate sampling point + point = ((point - 0.5) * rotmat) + 0.5; + //point = clamp(point, 0.0, 1.0); + + // this adjusts the length of the leak + float leakIntensity = pow(point.y, 1.0 + ((1.0 - length) * 19.0)); + + // this adjusts the gamma/brightness of the overall effect. + leakIntensity = pow(leakIntensity, 1.0 / amount); + + // sample the leak // how do we want to handle edge texcoords during rotation? + if (point.x < 0.0) { + point.x = abs(point.x); + } + if (point.x > 1.0) { + point.x = 2.0 - point.x; + } + + vec4 leak = IMG_NORM_PIXEL(leakImage, vec2(mod(point.x,1.0),0.0)); + + leak = pow(leak * leakIntensity, vec4(1.0/(leakIntensity))); // - vec2(0.5, 0.0); + leak += input0; + + gl_FragColor = mix(input0, leak, amount); +} \ No newline at end of file diff --git a/ISF/v002 Light Leak.vs b/ISF/v002 Light Leak.vs new file mode 100644 index 0000000..37790ab --- /dev/null +++ b/ISF/v002 Light Leak.vs @@ -0,0 +1,16 @@ + +varying mat2 rotmat; + +void main() +{ + isf_vertShaderInit(); + // setup basic rotation matrix here + float theta = radians(angle); + + // dont need to compute this more than once.. + float c = cos(theta); + float s = sin(theta); + + // rotation matrix + rotmat = mat2(c,s,-s,c); +} \ No newline at end of file diff --git a/ISF/v002 Technicolor.fs b/ISF/v002 Technicolor.fs new file mode 100644 index 0000000..fd88712 --- /dev/null +++ b/ISF/v002 Technicolor.fs @@ -0,0 +1,105 @@ +/*{ + "CREDIT": "by v002", + "ISFVSN": "2", + "CATEGORIES": [ + "v002", "Film" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "amount", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.5 + }, + { + "NAME": "style", + "VALUES": [ + 0, + 1, + 2 + ], + "LABELS": [ + "Strip additive", + "Strip subtractive", + "Strip matte" + ], + "DEFAULT": 0, + "TYPE": "long" + } + ] +}*/ + + +// Based on v002 technicolor – https://github.com/v002/v002-Film-Effects/ + +const vec4 redfilter1 = vec4(1.0, 0.0, 0.0, 1.0); +const vec4 bluegreenfilter1 = vec4(0.0, 1.0, 0.7, 1.0); + +const vec4 redfilter2 = vec4(1.0, 0.0, 0.0, 0.0); +const vec4 bluegreenfilter2 = vec4(0.0, 1.0, 1.0, 0.0); + +const vec4 cyanfilter = vec4(0.0, 1.0, 0.5, 0.0); +const vec4 magentafilter = vec4(1.0, 0.0, 0.25, 0.0); + + + +void main (void) +{ + vec4 input0 = IMG_THIS_PIXEL(inputImage); + vec4 result; + + if (style == 0) { + vec4 redrecord = input0 * redfilter1; + vec4 bluegreenrecord = input0 * bluegreenfilter1; + vec4 rednegative = vec4(redrecord.r); + vec4 bluegreennegative = vec4((bluegreenrecord.g + bluegreenrecord.b)/2.0); + + vec4 redoutput = rednegative * redfilter1; + vec4 bluegreenoutput = bluegreennegative * bluegreenfilter1; + + // additive 'projection" + result = redoutput + bluegreenoutput; + + result = mix(input0, result, amount); + result.a = input0.a; + } + else if (style == 1) { + vec4 redrecord = input0 * redfilter2; + vec4 bluegreenrecord = input0 * bluegreenfilter2; + + vec4 rednegative = vec4(redrecord.r); + vec4 bluegreennegative = vec4((bluegreenrecord.g + bluegreenrecord.b)/2.0); + + vec4 redoutput = rednegative + cyanfilter; + vec4 bluegreenoutput = bluegreennegative + magentafilter; + + result = redoutput * bluegreenoutput; + + result = mix(input0, result, amount); + result.a = input0.a; + } + else if (style == 2) { + vec3 redmatte = vec3(input0.r - ((input0.g + input0.b)/2.0)); + vec3 greenmatte = vec3(input0.g - ((input0.r + input0.b)/2.0)); + vec3 bluematte = vec3(input0.b - ((input0.r + input0.g)/2.0)); + + redmatte = 1.0 - redmatte; + greenmatte = 1.0 - greenmatte; + bluematte = 1.0 - bluematte; + + vec3 red = greenmatte * bluematte * input0.r; + vec3 green = redmatte * bluematte * input0.g; + vec3 blue = redmatte * greenmatte * input0.b; + + result = vec4(red.r, green.g, blue.b, input0.a); + + result = mix(input0, result, amount); + result.a = input0.a; + } + gl_FragColor = result; +} \ No newline at end of file diff --git a/ISF/v002 Vignette.fs b/ISF/v002 Vignette.fs new file mode 100644 index 0000000..ae2f6b9 --- /dev/null +++ b/ISF/v002 Vignette.fs @@ -0,0 +1,64 @@ +/*{ + "CREDIT": "by v002", + "ISFVSN": "2", + "CATEGORIES": [ + "v002", "Film" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "vignette", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.5 + }, + { + "NAME": "vignetteEdge", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.0 + }, + { + "NAME": "vignetteMix", + "TYPE": "float", + "MIN": 0.0, + "MAX": 1.0, + "DEFAULT": 0.0 + } + ] +}*/ + + +// Based on v002 vignette – https://github.com/v002/v002-Film-Effects/ + + + +// create a black and white oval about the center of our image for our vignette +vec4 vignetteFucntion(vec2 normalizedTexcoord, float vignetteedge, float vignetteMix) +{ + normalizedTexcoord = 2.0 * normalizedTexcoord - 1.0; // - 1.0 to 1.0 + float r = length(normalizedTexcoord); + vec4 vignette = (vec4(smoothstep(0.0, 1.0, pow(clamp(r - vignetteMix, 0.0, 1.0), 1.0 + vignetteedge * 10.0)))); + return clamp(1.0 - vignette, 0.0, 1.0); +} + + + +void main (void) +{ + vec2 normcoord = vec2(isf_FragNormCoord[0],isf_FragNormCoord[1]); + + + // make a vignette around our borders. + vec4 vignetteResult = vignetteFucntion(normcoord, vignetteEdge, vignetteMix); + + // sharpen via unsharp mask (subtract image from blured image) + vec4 input0 = IMG_THIS_PIXEL(inputImage); + + gl_FragColor = mix(input0,vignetteResult * input0, vignette); +} \ No newline at end of file diff --git a/ISF/v002-CRT-Displacement.fs b/ISF/v002-CRT-Displacement.fs new file mode 100755 index 0000000..280ca8b --- /dev/null +++ b/ISF/v002-CRT-Displacement.fs @@ -0,0 +1,52 @@ +/*{ + "DESCRIPTION": "CRT Displacement, emulating the look of curved CRT Displays", + "CREDIT": "by vade", + "ISFVSN": "2", + "CATEGORIES": [ + "v002", "Retro" + ], + "INPUTS": [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "Amount", + "TYPE": "float", + "DEFAULT": 0.5, + "MIN": 0.0, + "MAX": 1.0 + } + ] +}*/ + +void main (void) +{ + vec2 t1, t2; + vec2 ctr = RENDERSIZE / 2.0; + + t1 = gl_FragCoord.xy; + + float a = -0.0; + float b = -.1 * Amount; + float c = -.0; + float d = 1.0 - 1.1 * ( a + b + c ); + float r1, r2; + float unit = length(ctr) / 2.0; + + r1 = distance( t1, ctr )/unit; + r2 = r1 *( r1*( r1 * (a*r1 + b) + c) + d ); + float sc = step( 0.0 , r1) * ( r1/(r2 + .000001)) + (1.0 - step( 0.0 , r1)); + + t2 = ctr + ( t1 - ctr) * sc; + + gl_FragColor = IMG_PIXEL(inputImage, t2); + + if ((t2.x < 0.0) + ||(t2.y < 0.0) + ||(t2.x > RENDERSIZE.x) + ||(t2.y > RENDERSIZE.y)) + { + gl_FragColor = vec4(0.0); + } +} \ No newline at end of file diff --git a/ISF/v002-CRT-Mask-RGB-Shadow.png b/ISF/v002-CRT-Mask-RGB-Shadow.png new file mode 100755 index 0000000..5dbf30c Binary files /dev/null and b/ISF/v002-CRT-Mask-RGB-Shadow.png differ diff --git a/ISF/v002-CRT-Mask-RGB-Staggered.png b/ISF/v002-CRT-Mask-RGB-Staggered.png new file mode 100755 index 0000000..c2b42d0 Binary files /dev/null and b/ISF/v002-CRT-Mask-RGB-Staggered.png differ diff --git a/ISF/v002-CRT-Mask-RGB-Straight.png b/ISF/v002-CRT-Mask-RGB-Straight.png new file mode 100755 index 0000000..230fd84 Binary files /dev/null and b/ISF/v002-CRT-Mask-RGB-Straight.png differ diff --git a/ISF/v002-CRT-Mask-Scanline-Staggered.png b/ISF/v002-CRT-Mask-Scanline-Staggered.png new file mode 100755 index 0000000..2e9c4a3 Binary files /dev/null and b/ISF/v002-CRT-Mask-Scanline-Staggered.png differ diff --git a/ISF/v002-CRT-Mask.fs b/ISF/v002-CRT-Mask.fs new file mode 100755 index 0000000..c4f2d10 --- /dev/null +++ b/ISF/v002-CRT-Mask.fs @@ -0,0 +1,78 @@ +/*{ + "DESCRIPTION": "CRT Mask, emulating the look of curved CRT Displays", + "CREDIT": "by vade", + "ISFVSN": "2", + "CATEGORIES": + [ + "v002", "Retro" + ], + "INPUTS": + [ + { + "NAME": "inputImage", + "TYPE": "image" + }, + { + "NAME": "Amount", + "TYPE": "float", + "DEFAULT": 0.5, + "MIN": 0.0, + "MAX": 1.0 + }, + { + "LABEL": "Style", + "NAME": "style", + "TYPE": "long", + "VALUES": [ + 0, + 1, + 2, + 3 + ], + "LABELS": [ + "Staggered", + "Shadow", + "Straight", + "Scanline Staggered" + ], + "DEFAULT": 0 + } + ], + "IMPORTED": + { + "CRTMask0": { + "PATH": "v002-CRT-Mask-RGB-Staggered.png" + }, + "CRTMask1": { + "PATH": "v002-CRT-Mask-RGB-Shadow.png" + }, + "CRTMask2": { + "PATH": "v002-CRT-Mask-RGB-Straight.png" + }, + "CRTMask3": { + "PATH": "v002-CRT-Mask-Scanline-Staggered.png" + } + } +}*/ + +void main (void) +{ + vec2 crtcoord = mod(gl_FragCoord.xy, 12.0); + vec4 crt; + + if (style == 0) + crt = IMG_PIXEL(CRTMask0, crtcoord); + else if (style == 1) + crt = IMG_PIXEL(CRTMask1, crtcoord); + else if (style == 2) + crt = IMG_PIXEL(CRTMask2, crtcoord); + else if (style == 3) + crt = IMG_PIXEL(CRTMask3, crtcoord); + + vec4 image = IMG_THIS_PIXEL(inputImage); + vec4 result = mix(image, image * crt, Amount); + + result.a = image.a; + + gl_FragColor = result; +} \ No newline at end of file diff --git a/ISF_light.png b/ISF_light.png new file mode 100644 index 0000000..eaffa8e Binary files /dev/null and b/ISF_light.png differ diff --git a/README.md b/README.md index 29d20bd..e0ac1ab 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,14 @@ +

+ +

+ # ISF-Files -ISF generators and filters + +ISF (Interactive Shader Format) is a file format that describes a GLSL fragment shader, as well as how to execute and interact with it. More information about the ISF specification- including a test app that can use these files- [can be found here](https://www.github.com/mrRay/ISF_Spec). + +This repository is home to our collection of ISF generators and filters. There are just over two hundred generators and filters in this collection, and everything conforms to ISF 2.0. + +Installation Instructions: +* **Mac OS X**- ISF files should be installed in `/Library/Graphics/ISF` (if you want them to be available for all users on your system) or `~/Library/Graphics/ISF` (if you only want them to be available to your user account). ISF files installed in either of these locations will be available to all applications: application-specific ISFs should be installed in `/Library/Application Support/` or `/Library/Application Support/`. +* **Windows**- Please consult the instructions for your software package. +* **.nix**- Haven't targeted this platform yet, interested parties please get in touch!