/*{ "CATEGORIES": [ "Feedback" ], "CREDIT": "VIDVOX", "DESCRIPTION": "", "INPUTS": [ { "NAME": "inputImage", "TYPE": "image" }, { "DEFAULT": 0.25, "MAX": 1, "MIN": 0, "NAME": "maskRadius", "TYPE": "float" }, { "DEFAULT": 1, "MAX": 16, "MIN": 0, "NAME": "feedbackRate", "TYPE": "float" }, { "DEFAULT": 0.5, "MAX": 1, "MIN": 0, "NAME": "mixPoint", "TYPE": "float" }, { "DEFAULT": 0, "LABELS": [ "Circle", "Triangle", "Rect", "Pentagram", "Hexagon", "Star1", "Star2", "Heart", "Rays" ], "NAME": "shape1", "TYPE": "long", "VALUES": [ 0, 1, 2, 3, 4, 5, 6, 7, 8 ] }, { "DEFAULT": 1, "LABELS": [ "Circle", "Triangle", "Rect", "Pentagram", "Hexagon", "Star1", "Star2", "Heart", "Rays" ], "NAME": "shape2", "TYPE": "long", "VALUES": [ 0, 1, 2, 3, 4, 5, 6, 7, 8 ] }, { "DEFAULT": 0, "MAX": 2, "MIN": 0, "NAME": "shapeWobble", "TYPE": "float" }, { "DEFAULT": 0, "MAX": 0.25, "MIN": -0.25, "NAME": "twirlAmount", "TYPE": "float" }, { "DEFAULT": 0, "MAX": 1, "MIN": 0, "NAME": "fadeRate", "TYPE": "float" }, { "DEFAULT": 0.1, "MAX": 1, "MIN": 0, "NAME": "centerFeedback", "TYPE": "float" }, { "DEFAULT": [ 0.5, 0.5 ], "MAX": [ 1, 1 ], "MIN": [ 0, 0 ], "NAME": "feedbackCenter", "TYPE": "point2D" }, { "DEFAULT": 2, "LABELS": [ "Mask", "CenteredMask", "Scaled", "Wrap", "MirrorWrap", "InvertedMask" ], "NAME": "styleMode", "TYPE": "long", "VALUES": [ 0, 1, 2, 3, 4, 5 ] }, { "NAME": "clearBuffer", "TYPE": "event" } ], "ISFVSN": "2", "PASSES": [ { "PERSISTENT": true, "TARGET": "feedbackBuffer" } ] } */ const float pi = 3.1415926535897932384626433832795; const float tau = 6.2831853071795864769252867665590; // borrowed from pixel spirit deck! // https://github.com/patriciogonzalezvivo/PixelSpiritDeck/tree/master/lib float triSDF(vec2 st) { st = (st*2.-1.)*2.; return max(abs(st.x) * 0.866025 + st.y * 0.5, -st.y * 0.5); } float circleSDF(vec2 st) { return length(st-.5)*2.; } float polySDF(vec2 st, int V) { st = st*2.-1.; float a = atan(st.x,st.y)+pi; float r = length(st); float v = tau/float(V); return cos(floor(.5+a/v)*v-a)*r; } float pentSDF(vec2 st) { vec2 pt = st; pt.y /= 0.89217; return polySDF(pt, 5); } float hexSDF(vec2 st) { st = abs(st*2.-1.); return max(abs(st.y), st.x * 0.866025 + st.y * 0.5); } float flowerSDF(vec2 st, int N) { st = st*2.-1.; float r = length(st)*2.; float a = atan(st.y,st.x); float v = float(N)*.5; return 1.-(abs(cos(a*v))*.5+.5)/r; } float heartSDF(vec2 st) { st -= vec2(.5,.8); float r = length(st)*5.5; st = normalize(st); return r - ((st.y*pow(abs(st.x),0.67))/ (st.y+1.5)-(2.)*st.y+1.26); } float starSDF(vec2 st, int V, float s) { st = st*4.-2.; float a = atan(st.y, st.x)/tau; float seg = a * float(V); a = ((floor(seg) + 0.5)/float(V) + mix(s,-s,step(.5,fract(seg)))) * tau; return abs(dot(vec2(cos(a),sin(a)), st)); } float raysSDF(vec2 st, int N) { st -= .5; return fract(atan(st.y,st.x)/tau*float(N)); } float shapeForType(vec2 st, int shape) { if (shape == 0) return circleSDF(st); else if (shape == 1) return triSDF(st); else if (shape == 2) return polySDF(st,4); else if (shape == 3) return pentSDF(st); else if (shape == 4) return hexSDF(st); else if (shape == 5) return starSDF(st,5,0.07); else if (shape == 6) return starSDF(st,12,0.12); else if (shape == 7) return heartSDF(st); else if (shape == 8) return raysSDF(st,6); } void main() { vec4 inputPixelColor = vec4(0.0); vec2 loc = isf_FragNormCoord.xy; loc -= (feedbackCenter - vec2(0.5)); loc = mix(vec2((loc.x*RENDERSIZE.x/RENDERSIZE.y)-(RENDERSIZE.x*.5-RENDERSIZE.y*.5)/RENDERSIZE.y,loc.y), vec2(loc.x,loc.y*(RENDERSIZE.y/RENDERSIZE.x)-(RENDERSIZE.y*.5-RENDERSIZE.x*.5)/RENDERSIZE.x), step(RENDERSIZE.x,RENDERSIZE.y)); float val1 = shapeForType(loc,shape1); float val2 = shapeForType(loc,shape2); vec2 locCenter = feedbackCenter * RENDERSIZE; loc = gl_FragCoord.xy; float val = mix(val1,val2,mixPoint); float a1 = (atan(locCenter.y-loc.y,locCenter.x-loc.x) + pi) / (tau); val += (shapeWobble == 0.0) ? 0.0 : shapeWobble * ((sin(TIME+10.0*tau*(a1)))/13.0 + (sin(-TIME*2.1+17.0*tau*(a1)))/17.0 + (sin(19.0*tau*(a1)))/19.0); float scaledRadius = maskRadius * min(RENDERSIZE.x,RENDERSIZE.y); float dist = val * min(RENDERSIZE.x,RENDERSIZE.y); bool invertMask = (styleMode == 5); float feedbackLevel = 1.0; // if within the shape, just do the shape if (((dist>scaledRadius)&&(invertMask))||((dist 0.0)&&(clearBuffer == false)) { inputPixelColor = mix(inputPixelColor,IMG_THIS_PIXEL(feedbackBuffer),centerFeedback); } */ //inputPixelColor = vec4(loc.x,loc.y,0.0,1.0); } if ((clearBuffer == false)&&(feedbackLevel > 0.0)) { //float r = distance(RENDERSIZE/2.0,loc); float a = atan((loc.y-locCenter.y),(loc.x-locCenter.x)); //a = tau * (floor(a * 5.0 / tau) / 5.0); float shiftAmount = -1.0 * feedbackRate; vec2 shift = shiftAmount * vec2(cos(a + twirlAmount * tau), sin(a + twirlAmount * tau)); loc = (invertMask) ? loc - shift : loc + shift; inputPixelColor = mix(inputPixelColor,IMG_PIXEL(feedbackBuffer,loc),feedbackLevel); inputPixelColor.a -= fadeRate / 50.0; //inputPixelColor = vec4((a+pi)/(2.0*pi),2.0*r/RENDERSIZE.x,0.0,1.0); //inputPixelColor = vec4(shift.x*2.0-1.0,shift.y*2.0-1.0,0.0,1.0); } gl_FragColor = inputPixelColor; }