compositor for 2d glitch effects
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

effects.pde 145KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876
  1. /*
  2. ASDFPIXELSORT
  3. by Kim Asendorf
  4. */
  5. class ASDFPIXELSORT extends Shader {
  6. ASDFPIXELSORT() {
  7. name = "fxASDFPixelSort";
  8. params.add(new Param("black", INTVAL, -17000000, -2000000, new int[]{SINE, SAWTOOTH, RAMPUPDOWN, TAN, TANINVERSE, TRIANG}));
  9. params.add(new Param("target", INTVAL, 0, 2, new int[]{RANDOM}));
  10. params.add(new Param("direction", INTVAL, 0, 3, new int[]{RANDOM}));
  11. directionParamIndex = 2;
  12. }
  13. int previousMode;
  14. void apply() {
  15. if (previousMode != int(params.get(1).value)) {
  16. if (params.get(1).value == 0) changeParam(0, new Param("black", INTVAL, -17000000, -2000000, new int[]{SINE, SAWTOOTH, RAMPUPDOWN, TAN, TANINVERSE, TRIANG}));
  17. if (params.get(1).value == 1) changeParam(0, new Param("brightness", INTVAL, 0, 200, new int[]{SINE, SAWTOOTH, RAMPUPDOWN, TAN, TANINVERSE, TRIANG}));
  18. if (params.get(1).value == 2) changeParam(0, new Param("white", INTVAL, -15000000, -700000, new int[]{SINE, SAWTOOTH, RAMPUPDOWN, TAN, TANINVERSE, TRIANG}));
  19. }
  20. previousMode = (int)params.get(1).value;
  21. row = 0;
  22. column = 0;
  23. colorMode(RGB);
  24. canvas.beginDraw();
  25. while (column < canvas.width-1) {
  26. canvas.loadPixels();
  27. sortColumn();
  28. column++;
  29. canvas.updatePixels();
  30. }
  31. while (row < canvas.height-1) {
  32. canvas.loadPixels();
  33. sortRow();
  34. row++;
  35. canvas.updatePixels();
  36. }
  37. canvas.endDraw();
  38. }
  39. int row = 0;
  40. int column = 0;
  41. void sortRow() {
  42. int x = 0;
  43. int y = row;
  44. int xend = 0;
  45. while (xend < canvas.width-1) {
  46. switch((int)params.get(1).value) {
  47. case 0:
  48. x = getFirstNotBlackX(x, y);
  49. xend = getNextBlackX(x, y);
  50. break;
  51. case 1:
  52. x = getFirstBrightX(x, y);
  53. xend = getNextDarkX(x, y);
  54. break;
  55. case 2:
  56. x = getFirstNotWhiteX(x, y);
  57. xend = getNextWhiteX(x, y);
  58. break;
  59. default:
  60. break;
  61. }
  62. if (x < 0) break;
  63. int sortLength = xend-x;
  64. color[] unsorted = new color[sortLength];
  65. color[] sorted = new color[sortLength];
  66. for (int i=0; i<sortLength; i++) {
  67. unsorted[i] = canvas.pixels[x + i + y * canvas.width];
  68. }
  69. sorted = sort(unsorted);
  70. for (int i=0; i<sortLength; i++) {
  71. canvas.pixels[x + i + y * canvas.width] = sorted[i];
  72. }
  73. x = xend+1;
  74. }
  75. }
  76. void sortColumn() {
  77. int x = column;
  78. int y = 0;
  79. int yend = 0;
  80. while (yend < canvas.height-1) {
  81. switch((int)params.get(1).value) {
  82. case 0:
  83. y = getFirstNotBlackY(x, y);
  84. yend = getNextBlackY(x, y);
  85. break;
  86. case 1:
  87. y = getFirstBrightY(x, y);
  88. yend = getNextDarkY(x, y);
  89. break;
  90. case 2:
  91. y = getFirstNotWhiteY(x, y);
  92. yend = getNextWhiteY(x, y);
  93. break;
  94. default:
  95. break;
  96. }
  97. if (y < 0) break;
  98. int sortLength = yend-y;
  99. color[] unsorted = new color[sortLength];
  100. color[] sorted = new color[sortLength];
  101. for (int i=0; i<sortLength; i++) {
  102. unsorted[i] = canvas.pixels[x + (y+i) * canvas.width];
  103. }
  104. sorted = sort(unsorted);
  105. for (int i=0; i<sortLength; i++) {
  106. canvas.pixels[x + (y+i) * canvas.width] = sorted[i];
  107. }
  108. y = yend+1;
  109. }
  110. }
  111. //BLACK
  112. int getFirstNotBlackX(int _x, int _y) {
  113. int x = _x;
  114. int y = _y;
  115. color c;
  116. while ( (c = canvas.pixels[x + y * canvas.width]) < params.get(0).value) {
  117. x++;
  118. if (x >= canvas.width) return -1;
  119. }
  120. return x;
  121. }
  122. int getNextBlackX(int _x, int _y) {
  123. int x = _x+1;
  124. int y = _y;
  125. color c;
  126. while ( (c = canvas.pixels[x + y * canvas.width]) > params.get(0).value) {
  127. x++;
  128. if (x >= canvas.width) return canvas.width-1;
  129. }
  130. return x-1;
  131. }
  132. //BRIGHTNESS
  133. int getFirstBrightX(int _x, int _y) {
  134. int x = _x;
  135. int y = _y;
  136. color c;
  137. while (brightness (c = canvas.pixels[x + y * canvas.width]) < params.get(0).value) {
  138. x++;
  139. if (x >= canvas.width) return -1;
  140. }
  141. return x;
  142. }
  143. int getNextDarkX(int _x, int _y) {
  144. int x = _x+1;
  145. int y = _y;
  146. color c;
  147. while (brightness (c = canvas.pixels[x + y * canvas.width]) > params.get(0).value) {
  148. x++;
  149. if (x >= canvas.width) return canvas.width-1;
  150. }
  151. return x-1;
  152. }
  153. //WHITE
  154. int getFirstNotWhiteX(int _x, int _y) {
  155. int x = _x;
  156. int y = _y;
  157. color c;
  158. while ( (c = canvas.pixels[x + y * canvas.width]) > params.get(0).value) {
  159. x++;
  160. if (x >= canvas.width) return -1;
  161. }
  162. return x;
  163. }
  164. int getNextWhiteX(int _x, int _y) {
  165. int x = _x+1;
  166. int y = _y;
  167. color c;
  168. while ( (c = canvas.pixels[x + y * canvas.width]) < params.get(0).value) {
  169. x++;
  170. if (x >= canvas.width) return canvas.width-1;
  171. }
  172. return x-1;
  173. }
  174. //BLACK
  175. int getFirstNotBlackY(int _x, int _y) {
  176. int x = _x;
  177. int y = _y;
  178. color c;
  179. if (y < canvas.height) {
  180. while ( (c = canvas.pixels[x + y * canvas.width]) < params.get(0).value) {
  181. y++;
  182. if (y >= canvas.height) return -1;
  183. }
  184. }
  185. return y;
  186. }
  187. int getNextBlackY(int _x, int _y) {
  188. int x = _x;
  189. int y = _y+1;
  190. color c;
  191. if (y < canvas.height) {
  192. while ( (c = canvas.pixels[x + y * canvas.width]) > params.get(0).value) {
  193. y++;
  194. if (y >= canvas.height) return canvas.height-1;
  195. }
  196. }
  197. return y-1;
  198. }
  199. //BRIGHTNESS
  200. int getFirstBrightY(int _x, int _y) {
  201. int x = _x;
  202. int y = _y;
  203. color c;
  204. if (y < canvas.height) {
  205. while (brightness (c = canvas.pixels[x + y * canvas.width]) < params.get(0).value) {
  206. y++;
  207. if (y >= canvas.height) return -1;
  208. }
  209. }
  210. return y;
  211. }
  212. int getNextDarkY(int _x, int _y) {
  213. int x = _x;
  214. int y = _y+1;
  215. color c;
  216. if (y < canvas.height) {
  217. while (brightness (c = canvas.pixels[x + y * canvas.width]) > params.get(0).value) {
  218. y++;
  219. if (y >= canvas.height) return canvas.height-1;
  220. }
  221. }
  222. return y-1;
  223. }
  224. //WHITE
  225. int getFirstNotWhiteY(int _x, int _y) {
  226. int x = _x;
  227. int y = _y;
  228. color c;
  229. if (y < canvas.height) {
  230. while ( (c = canvas.pixels[x + y * canvas.width]) > params.get(0).value) {
  231. y++;
  232. if (y >= canvas.height) return -1;
  233. }
  234. }
  235. return y;
  236. }
  237. int getNextWhiteY(int _x, int _y) {
  238. int x = _x;
  239. int y = _y+1;
  240. color c;
  241. if (y < canvas.height) {
  242. while ( (c = canvas.pixels[x + y * canvas.width]) < params.get(0).value) {
  243. y++;
  244. if (y >= canvas.height) return canvas.height-1;
  245. }
  246. }
  247. return y-1;
  248. }
  249. }
  250. /*
  251. DISTORTER
  252. by Tomasz Sulej
  253. */
  254. class DISTORTER extends Shader {
  255. boolean do_blend = false; // blend image after process
  256. int blend_mode = OVERLAY; // blend type
  257. int channel = BRIGHTNESS; // channel used in processing (R,G,B) or (H,S,B)
  258. float scalex = 0.05; // from 0.01 to 1
  259. float scaley = 0.1; // from 0.01 to 1
  260. boolean shift_hue = true;
  261. float shift_amt = 0.1; // from 0 to 1
  262. PImage buffer;
  263. final static int distortionMatrixSize = 512; //doesnt really make a difference, it's more or less "noise variety".. only kinda different if real low, like 2 or so
  264. int[][] distort = new int[2][distortionMatrixSize];
  265. final static float tick = 1.0/distortionMatrixSize;
  266. int mode = 0;
  267. int initBufferW, initBufferH;
  268. DISTORTER() {
  269. buffer = createImage(canvas.width, canvas.height, ARGB);
  270. initBufferW = buffer.width;
  271. initBufferH = buffer.height;
  272. name = "fxDistorter";
  273. params.add(new Param("width", FLOATVAL, 2, buffer.width/4-1, new int[]{SINE, SAWTOOTH, RAMPUPDOWN, TAN, TANINVERSE, TRIANG}));
  274. params.add(new Param("height", FLOATVAL, 2, buffer.height/4-1, new int[]{SINE, SAWTOOTH, RAMPUPDOWN, TAN, TANINVERSE, TRIANG}));
  275. params.add(new Param("do blend", INTVAL, 0, 1, new int[]{RANDOM, SQUAR}));
  276. params.add(new Param("shift hue amount", FLOATVAL, 0, 1, new int[]{SAWTOOTH, SAWTOOTHINVERSE, TAN, TANINVERSE, RAMP, RAMPINVERSE}));
  277. params.add(new Param("scale x", FLOATVAL, 0.01, 1, new int[]{SINE, SAWTOOTH, RAMPUPDOWN, TAN, TANINVERSE, TRIANG}));
  278. params.add(new Param("scale y", FLOATVAL, 0.01, 1, new int[]{SINE, SAWTOOTH, RAMPUPDOWN, TAN, TANINVERSE, TRIANG}));
  279. params.add(new Param("blend mode", INTVAL, 0, blends.length-1, new int[]{SINE, SAWTOOTH, RAMPUPDOWN, TAN, TANINVERSE, TRIANG}));
  280. params.add(new Param("channel", INTVAL, 0, 12, new int[]{SINE, SAWTOOTH, RAMPUPDOWN, TAN, TANINVERSE, TRIANG}));
  281. params.add(new Param("direction", INTVAL, 0, 3, new int[]{RANDOM}));
  282. directionParamIndex = 8;
  283. //params.add(new Param(DIRECTION));
  284. // channel, blend_mode
  285. //params.add(new Param("height", FLOATVAL, 1, buffer.height/4-1, new int[]{SINE, SAWTOOTH, RAMPUPDOWN, TAN, TANINVERSE, TRIANG}));
  286. // prepare distortion pattern
  287. for (int i=0; i<distortionMatrixSize; i++) {
  288. distort[0][i] = (int)random(-128, 128);
  289. distort[1][i] = (int)random(-128, 128);
  290. }
  291. }
  292. // ALL Channels, Nxxx stand for negative (255-value)
  293. // channels to work with
  294. final static int RED = 0;
  295. final static int GREEN = 1;
  296. final static int BLUE = 2;
  297. final static int HUE = 3;
  298. final static int SATURATION = 4;
  299. final static int BRIGHTNESS = 5;
  300. final static int NRED = 6;
  301. final static int NGREEN = 7;
  302. final static int NBLUE = 8;
  303. final static int NHUE = 9;
  304. final static int NSATURATION = 10;
  305. final static int NBRIGHTNESS = 11;
  306. void apply() {
  307. buffer = canvas.get();
  308. buffer.resize(canvas.width, canvas.height);
  309. float neww = map(params.get(0).value, 2, initBufferW-2, 2, buffer.width/4-2);
  310. float newh = map(params.get(1).value, 2, initBufferH-2, 2, buffer.height/4-2);
  311. do_blend = boolean(int(params.get(2).value));
  312. shift_amt = params.get(3).value;
  313. scalex = params.get(4).value;
  314. scaley = params.get(5).value;
  315. blend_mode = blends[(int)params.get(6).value];
  316. channel = (int)params.get(7).value;
  317. float totalnum = neww+newh;
  318. float times = (totalnum/floor(totalnum/neww));
  319. float offx = (totalnum%neww)/times;
  320. float ratiox = neww/buffer.width;
  321. //println(ratiox);
  322. canvas.beginDraw();
  323. canvas.noStroke();
  324. for (int y=0; y<buffer.height; y++) {
  325. float yy = y/(float)buffer.height;
  326. for (int x=0; x<buffer.width; x++) {
  327. float xx = x/(float)buffer.width;
  328. float offy = floor(newh*yy);
  329. float fx = xx*ratiox+offx*offy;
  330. float shift = fx%1.0;
  331. float st = shift/tick;
  332. int no1 = floor(st)%distortionMatrixSize;
  333. int no2 = ceil(st)%distortionMatrixSize ;
  334. float l = st-(float)no1;
  335. float cx = lerp(distort[0][no1], distort[0][no2], l);
  336. float cy = lerp(distort[1][no1], distort[1][no2], l);
  337. float rx =getChannel(buffer.get(x, y), channel);
  338. int sx = (int)((buffer.width+x+cx*rx*scalex*0.1)%buffer.width);
  339. int sy = (int)((buffer.height+y+cy*scaley)%buffer.height);
  340. color c=buffer.get(sx, sy);
  341. if (shift_hue) {
  342. colorMode(HSB, 255);
  343. c = color((hue(c)+shift_amt*255*noise(newh+y))%255.0, constrain(saturation(c)*1.2, 0, 255), constrain(brightness(c), 0, 255));
  344. colorMode(RGB, 255);
  345. }
  346. // buffer.fill(lerpColor(c,img.get(x,y),0.2));
  347. canvas.fill(c); //wärs nich effizienter die pixelmatrix zu ändern ?
  348. canvas.rect(x, y, 1, 1);
  349. }
  350. }
  351. if (do_blend)
  352. canvas.blend(buffer, 0, 0, buffer.width, buffer.height, 0, 0, canvas.width, canvas.height, blend_mode);
  353. canvas.endDraw();
  354. }
  355. float getChannel(color c, int channel) {
  356. int ch = channel>5?channel-6:channel;
  357. float cc;
  358. switch(ch) {
  359. case RED:
  360. cc = red(c);
  361. break;
  362. case GREEN:
  363. cc = green(c);
  364. break;
  365. case BLUE:
  366. cc = blue(c);
  367. break;
  368. case HUE:
  369. cc = hue(c);
  370. break;
  371. case SATURATION:
  372. cc = saturation(c);
  373. break;
  374. default:
  375. cc= brightness(c);
  376. break;
  377. }
  378. return channel>5?255-cc:cc;
  379. }
  380. }
  381. /*
  382. FM
  383. */
  384. class FM extends Shader {
  385. // configuration
  386. int colorspace = RGB;
  387. int quantval = 30; // 0 - off, less - more glitch, more - more precision
  388. boolean do_blend = true; // blend image after process
  389. int blend_mode = OVERLAY; // blend type
  390. //unused parameters (giers):
  391. final static boolean first_channel_only = false; // for L.. or Y.. colorspaces set true to modulate only luma;
  392. final static boolean lowpass1_on = true; // on/off of first low pass filter
  393. final static boolean lowpass2_on = true; // on/off of second low pass filter
  394. final static boolean lowpass3_on = true; // on/off of third low pass filter
  395. // better don't touch it, lowpass filters are run in cascade
  396. float lowpass1_cutoff = 0.25; // percentage of rate
  397. float lowpass2_cutoff = 0.1;
  398. float lowpass3_cutoff = 0.05;
  399. // working buffer
  400. PGraphics buffer;
  401. // local variables
  402. float min_omega, max_omega;
  403. float min_phase_mult=0.05;
  404. float max_phase_mult=50.0;
  405. LowpassFilter lpf1, lpf2, lpf3;
  406. int[][] pxls;
  407. boolean negate = false;
  408. FM() {
  409. name = "fxFM";
  410. params.add(new Param ("do blend", INTVAL, 0, 1, new int[]{RANDOM, SQUAR}));
  411. params.add(new Param ("blend_mode", INTVAL, 0, blends.length-1, new int[]{RANDOM}));
  412. params.add(new Param ("omega", FLOATVAL, 0, 1, new int[]{SINE, SAWTOOTH, TRIANG}));
  413. params.add(new Param ("phase", FLOATVAL, 0, 1, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  414. params.add(new Param ("colorspace", INTVAL, 0, 16, new int[]{RANDOM}));
  415. params.add(new Param ("quant", INTVAL, 0, 40, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  416. params.add(new Param("direction", INTVAL, 0, 3, new int[]{RANDOM}));
  417. directionParamIndex = 6;
  418. buffer = createGraphics(canvas.width, canvas.height);
  419. buffer.beginDraw();
  420. buffer.noStroke();
  421. //buffer.smooth(8);
  422. //buffer.background(0);
  423. // buffer.image(canvas, 0, 0);
  424. buffer.endDraw();
  425. float rate = 100000.0;
  426. lpf1 = new LowpassFilter(rate, lowpass1_cutoff*rate);
  427. lpf2 = new LowpassFilter(rate, lowpass2_cutoff*rate);
  428. lpf3 = new LowpassFilter(rate, lowpass3_cutoff*rate);
  429. //img.loadPixels();
  430. }
  431. void prepareData() {
  432. pxls = new int[3][canvas.pixels.length];
  433. for (int i=0; i<canvas.pixels.length; i++) {
  434. int cl = toColorspace(canvas.pixels[i], colorspace);
  435. pxls[0][i] = (cl >> 16) & 0xff;
  436. pxls[1][i] = (cl >> 8) & 0xff;
  437. pxls[2][i] = (cl) & 0xff;
  438. }
  439. }
  440. float omega, min_phase, max_phase;
  441. int rw, rh;
  442. void apply() {
  443. buffer.setSize(canvas.width, canvas.height);
  444. min_omega = TWO_PI/(0.05*canvas.width);
  445. max_omega = TWO_PI/(300.0*canvas.width);
  446. rw = canvas.width;
  447. do_blend = boolean(int(params.get(0).value));
  448. blend_mode = blends[(int)params.get(1).value];
  449. omega = map(sqrt(params.get(2).value), 0, 1, min_omega, max_omega);
  450. float phase = map(sq(params.get(3).value), 0, 1, min_phase_mult, max_phase_mult);
  451. colorspace = (int)params.get(4).value;
  452. quantval = (int) params.get(5).value;
  453. if (rw != canvas.width || rh != canvas.height) {
  454. rw = canvas.width;
  455. rh = canvas.height;
  456. min_omega = TWO_PI/(0.05*canvas.width);
  457. max_omega = TWO_PI/(300.0*canvas.width);
  458. }
  459. prepareData();
  460. //buffer = canvas.get(0, 0, canvas.width, canvas.height);
  461. max_phase = phase * omega;
  462. min_phase = -max_phase;
  463. processImage();
  464. }
  465. void processImage() {
  466. buffer.beginDraw();
  467. buffer.loadPixels();
  468. int [][] dest_pxls = new int[3][canvas.pixels.length];
  469. if (first_channel_only) {
  470. arrayCopy(pxls[1], dest_pxls[1]);
  471. arrayCopy(pxls[2], dest_pxls[2]);
  472. }
  473. for (int i=0; i< (first_channel_only?1:3); i++) {
  474. for (int y=0; y<canvas.height; y++) {
  475. int off = y * canvas.width;
  476. //reset filters each line
  477. lpf1.resetFilter(map(pxls[i][off], 0, 255, min_phase, max_phase));
  478. lpf2.resetFilter(map(pxls[i][off], 0, 255, min_phase, max_phase));
  479. lpf3.resetFilter(map(pxls[i][off], 0, 255, min_phase, max_phase));
  480. float sig_int = 0; // integral of the signal
  481. float pre_m = 0; // previous value of modulated signal
  482. for (int x=0; x<canvas.width; x++) {
  483. /////////////////////////
  484. // FM part starts here
  485. /////////////////////////
  486. float sig = map(pxls[i][x+off], 0, 255, min_phase, max_phase); // current signal value
  487. sig_int += sig; // current value of signal integral
  488. float m = cos(omega * x + sig_int); // modulate signal
  489. if ( quantval > 0) {
  490. m = map((int)map(m, -1, 1, 0, quantval), 0, quantval, -1, 1); // quantize
  491. }
  492. float dem = abs(m-pre_m); // demodulate signal, derivative
  493. pre_m = m; // remember current value
  494. // lowpass filter chain
  495. if (lowpass1_on) dem = lpf1.lowpass(dem);
  496. if (lowpass2_on) dem = lpf2.lowpass(dem);
  497. if (lowpass3_on) dem = lpf3.lowpass(dem);
  498. // remap signal back to channel value
  499. int v = constrain( (int)map(2*(dem-omega), min_phase, max_phase, 0, 255), 0, 255);
  500. //////////////////////
  501. // FM part ends here
  502. //////////////////////
  503. dest_pxls[i][x+off] = negate?255-v:v;
  504. }
  505. }
  506. }
  507. for (int i=0; i<buffer.pixels.length; i++) {
  508. buffer.pixels[i] = fromColorspace(0xff000000 | (dest_pxls[0][i] << 16) | (dest_pxls[1][i] << 8) | (dest_pxls[2][i]), colorspace);
  509. }
  510. buffer.updatePixels();
  511. if (do_blend)
  512. buffer.blend(canvas, 0, 0, canvas.width, canvas.height, 0, 0, buffer.width, buffer.height, blend_mode);
  513. buffer.endDraw();
  514. canvas.beginDraw();
  515. canvas.image(buffer, canvas.width/2, canvas.height/2, canvas.width, canvas.height);
  516. canvas.endDraw();
  517. }
  518. class LowpassFilter {
  519. float alpha;
  520. float prev;
  521. public LowpassFilter(float rate, float hz) {
  522. alpha = 0.0;
  523. prev = 0.0;
  524. setFilter(rate, hz);
  525. }
  526. void setFilter(float rate, float hz) {
  527. float timeInterval = 1.0/rate;
  528. float tau = 1.0 / (hz * TWO_PI);
  529. alpha = timeInterval / (tau + timeInterval);
  530. }
  531. void resetFilter(float val) {
  532. prev = val;
  533. }
  534. void resetFilter() {
  535. resetFilter(0);
  536. }
  537. float lowpass(float sample) {
  538. float stage1 = sample * alpha;
  539. float stage2 = prev - (prev * alpha);
  540. prev = (stage1 + stage2);
  541. return prev;
  542. }
  543. float highpass(float sample) {
  544. return sample - lowpass(sample);
  545. }
  546. }
  547. }
  548. /*
  549. WZIP
  550. */
  551. class WZIP extends Shader {
  552. final float sqrt05 = sqrt(0.5);
  553. float[] raw, raw1, raw2, raw3;
  554. float[] in, w, out;
  555. float[] in1, in2, in3, out1, out2, out3;
  556. int n, n2, s;
  557. float scalingfactorin, scalingfactorout;
  558. PImage img;
  559. String sessionid;
  560. WZIP() {
  561. name = "fxWZIP";
  562. params.add(new Param ("scale", FLOATVAL, 0.1, 1000, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  563. params.add(new Param ("factor in", FLOATVAL, 0.01, 1, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  564. params.add(new Param ("factor out", FLOATVAL, 0.01, 1, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  565. params.add(new Param("hsb/rgb", INTVAL, 0, 1, new int[]{RANDOM, SQUAR}));
  566. params.add(new Param("mode", INTVAL, 0, 1, new int[]{RANDOM, SQUAR}));
  567. params.add(new Param("direction", INTVAL, 0, 3, new int[]{RANDOM}));
  568. directionParamIndex = 5;
  569. sessionid = hex((int)random(0xffff), 4);
  570. img = createImage(canvas.width, canvas.height, ARGB);
  571. img = canvas.get(0, 0, canvas.width, canvas.height);
  572. }
  573. void apply() {
  574. // img = createImage(canvas.width, canvas.height, ARGB);
  575. img.resize(canvas.width, canvas.height);
  576. img = canvas.get(0, 0, canvas.width, canvas.height);
  577. s = img.width*img.height;
  578. raw = new float[s*3];
  579. raw1 = new float[s];
  580. raw2 = new float[s];
  581. raw3 = new float[s];
  582. canvas.beginDraw();
  583. canvas.background(0);
  584. canvas.noStroke();
  585. if (boolean((int)params.get(3).value)) { /////////////////////
  586. canvas.colorMode(HSB, 255);
  587. colorMode(HSB, 255);
  588. } else {
  589. canvas.colorMode(RGB, 255);
  590. colorMode(RGB, 255);
  591. }
  592. scalingfactorin = map(params.get(1).value, 0, 1, 0, params.get(0).value); /////////////////////
  593. scalingfactorout = map(params.get(2).value, 0, 1, 0, params.get(0).value); /////////////////////
  594. int iter=0;
  595. int iter2 = 0;
  596. for (int y=0; y<img.height; y++) {
  597. for (int x=0; x<img.width; x++) {
  598. color c = img.get(x, y);
  599. float r, g, b;
  600. if (boolean((int)params.get(3).value)) { /////////////////////
  601. r = hue(c)>127?hue(c)-256:hue(c);
  602. g = saturation(c)>127?saturation(c)-256:saturation(c);
  603. b = brightness(c)>127?brightness(c)-256:brightness(c);
  604. } else {
  605. r = red(c)>127?red(c)-256:red(c);
  606. g = green(c)>127?green(c)-256:green(c);
  607. b = blue(c)>127?blue(c)-256:blue(c);
  608. }
  609. raw[iter++] = r;
  610. raw[iter++] = g;
  611. raw[iter++] = b;
  612. raw1[iter2] = r;
  613. raw2[iter2] = g;
  614. raw3[iter2] = b;
  615. iter2++;
  616. }
  617. }
  618. n = (int)pow(2, ceil(log(s*3)/log(2)));
  619. n2 = (int)pow(2, ceil(log(s)/log(2)));
  620. in = new float[n];
  621. w = new float[n];
  622. out = new float[n];
  623. out1 = new float[n2];
  624. out2 = new float[n2];
  625. out3 = new float[n2];
  626. in1 = new float[n2];
  627. in2 = new float[n2];
  628. in3 = new float[n2];
  629. arrayCopy(raw, 0, in, 0, raw.length);
  630. for (int i=raw.length; i<n; i++) in[i] = raw[raw.length-1];
  631. arrayCopy(raw1, 0, in1, 0, s);
  632. arrayCopy(raw2, 0, in2, 0, s);
  633. arrayCopy(raw3, 0, in3, 0, s);
  634. for (int i=s; i<n2; i++) {
  635. in1[i] = raw1[s-1];
  636. in2[i] = raw2[s-1];
  637. in3[i] = raw3[s-1];
  638. }
  639. if (boolean((int)params.get(4).value)) option1(); /////////////////////
  640. else option2();
  641. canvas.colorMode(RGB);
  642. colorMode(RGB);
  643. canvas.endDraw();
  644. }
  645. float clamp(float c) {
  646. return(abs(c<0?256+c:c)%255.0);
  647. }
  648. void option2() {
  649. wtrafo(in1, n2);
  650. wbtrafo(out1, n2);
  651. wtrafo(in2, n2);
  652. wbtrafo(out2, n2);
  653. wtrafo(in3, n2);
  654. wbtrafo(out3, n2);
  655. for (int i=0; i<s; i++) {
  656. float r = clamp(out1[i]);
  657. float g = clamp(out2[i]);
  658. float b = clamp(out3[i]);
  659. canvas.fill(r, g, b);
  660. canvas.rect(i%canvas.width, i/canvas.width, 1, 1);
  661. }
  662. }
  663. void option1() {
  664. wtrafo(in, n);
  665. wbtrafo(out, n);
  666. float r=0, g=0, b=0;
  667. int state = 0;
  668. for (int i=0; i<raw.length; i++) {
  669. float c = clamp(out[i]);
  670. switch(state) {
  671. case 0:
  672. r = c;
  673. break;
  674. case 1:
  675. g = c;
  676. break;
  677. case 2:
  678. b = c;
  679. break;
  680. default:
  681. {
  682. r = c;
  683. canvas.fill(r, g, b);
  684. canvas.rect(floor(i/3.0)%canvas.width, floor(i/3.0)/canvas.width, 1, 1);
  685. state = 0;
  686. }
  687. }
  688. state++;
  689. }
  690. }
  691. void wbtrafo(float[] y, int n) {
  692. float[] d = new float[n];
  693. d[n-2] = w[n-1];
  694. int b1 = n-4;
  695. int b2 = n-2;
  696. int a=1;
  697. while (a<n/2) {
  698. for (int i=0; i<a; i++) {
  699. d[2*i+b1]=(d[i+b2]+w[i+b2])*sqrt05;
  700. d[2*i+1+b1]=(d[i+b2]-w[i+b2])*sqrt05;
  701. }
  702. b2=b1;
  703. b1=b1-4*a;
  704. a*=2;
  705. }
  706. for (int i=0; i<a; i++) {
  707. y[2*i]=(d[i]+w[i])*sqrt05;
  708. y[2*i+1]=(d[i]-w[i])*sqrt05;
  709. }
  710. for (int i=0; i<n; i++) y[i] *= scalingfactorout;
  711. }
  712. void wtrafo(float[] y, int n) {
  713. float[] d = new float[n];
  714. int a = n/2;
  715. for (int i=0; i<a; i++) {
  716. w[i] = (y[2*i]-y[2*i+1])*sqrt05;
  717. d[i] = (y[2*i]+y[2*i+1])*sqrt05;
  718. }
  719. int b1 = 0;
  720. int b2 = a;
  721. a/=2;
  722. while (a>0) {
  723. for (int i=0; i<a; i++) {
  724. w[i+b2]=(d[2*i+b1]-d[2*i+1+b1])*sqrt05;
  725. d[i+b2]=(d[2*i+b1]+d[2*i+1+b1])*sqrt05;
  726. }
  727. b1=b2;
  728. b2=b2+a;
  729. a/=2;
  730. }
  731. w[b2] = d[b1];
  732. for (int i=0; i<n-1; i++) w[i] = (int)(w[i]/scalingfactorin);
  733. if (w[n-1]>0) w[n-1] = (int)(w[n-1]/scalingfactorin+0.5);
  734. else w[n-1] = (int)(w[n-1]/scalingfactorin-0.5);
  735. }
  736. }
  737. /*
  738. AUECHO
  739. */
  740. class AUECHO extends Shader {
  741. final int[] blends = {BLEND, ADD, SUBTRACT, DARKEST, LIGHTEST, DIFFERENCE, EXCLUSION, MULTIPLY, SCREEN, OVERLAY, HARD_LIGHT, SOFT_LIGHT, DODGE, BURN};
  742. AUECHO() {
  743. name = "fxAUecho";
  744. params.add(new Param("mode", INTVAL, 0, 1, new int[]{RANDOM, SQUAR}));
  745. params.add(new Param ("echo", FLOATVAL, 0.001, 1, new int[]{TRIANG, SINE, RAMPUPDOWN, }));
  746. params.add(new Param ("decay", FLOATVAL, 0.001, 1, new int[]{TRIANG, SINE, RAMPUPDOWN }));
  747. params.add(new Param ("blend mode", INTVAL, 0, this.blends.length-1, new int[]{RANDOM }));
  748. params.add(new Param("direction", INTVAL, 0, 3, new int[]{RANDOM}));
  749. directionParamIndex = 4;
  750. }
  751. void apply() {
  752. canvas.beginDraw();
  753. if (boolean((int)params.get(0).value)) {
  754. canvas.colorMode(HSB);
  755. colorMode(HSB);
  756. } else {
  757. canvas.colorMode(RGB);
  758. colorMode(RGB);
  759. }
  760. canvas.loadPixels();
  761. float _delay = params.get(1).value;
  762. float decay = params.get(2).value;
  763. int delay = (int)(canvas.pixels.length * _delay);
  764. color[] history = new color[canvas.pixels.length];
  765. int blendMode =this.blends[(int)params.get(3).value];
  766. for ( int i = 0, l = canvas.pixels.length; i<l; i++) {
  767. history[i] = canvas.pixels[i];
  768. }
  769. for ( int i = 0, l = canvas.pixels.length; i<l; i++) {
  770. int fromPos = i-delay < 0 ? l-abs(i-delay) : i-delay;
  771. color fromColor = history[fromPos];
  772. float r = red(fromColor) * decay;
  773. float g = green(fromColor) * decay;
  774. float b = blue(fromColor) * decay;
  775. color origColor = history[i];
  776. color toColor = color(
  777. r = r + red(origColor) > 255 ? r + red(origColor) - 255 : r + red(origColor), // simulate overflow ;)
  778. g = g + green(origColor) > 255 ? g + green(origColor) - 255 : g + green(origColor),
  779. b = b + blue(origColor) > 255 ? b + blue(origColor) - 255 : b + blue(origColor) );
  780. //canvas.pixels[i] = history[i] = toColor;
  781. canvas.pixels[i] = history[i] = blendColor(origColor, toColor, blendMode);
  782. }
  783. canvas.updatePixels();
  784. if (boolean((int)params.get(0).value)) {
  785. canvas.colorMode(RGB);
  786. colorMode(RGB);
  787. }
  788. canvas.endDraw();
  789. }
  790. }
  791. /*
  792. SLITSCAN
  793. */
  794. class SLITSCAN extends Shader {
  795. int[] fx;
  796. int[] fy;
  797. float[] phx;
  798. float[] phy;
  799. int[] sx, sy;
  800. boolean[] skipfx;
  801. boolean[] skipfy;
  802. boolean dox, doy;
  803. PImage buffer;
  804. float[][] ft = new float[2][32];
  805. //int depth; // number of octaves
  806. int fxnum;
  807. int fynum;
  808. SLITSCAN() {
  809. name = "fxSlitSscan";
  810. buffer = createImage(canvas.width, canvas.height, ARGB);
  811. params.add(new Param("direction", INTVAL, 0, 3, new int[]{RANDOM}));
  812. directionParamIndex = 0;
  813. int s = (int)(log(min(buffer.width, buffer.height))/log(2));
  814. olds = s;
  815. params.add(new Param("x num", INTVAL, 1, s, new int[]{RANDOM}));
  816. params.add(new Param("y num", INTVAL, 1, s, new int[]{RANDOM}));
  817. for (int i=0; i<32; i++) {
  818. ft[0][i] = pow(2.0, i);
  819. ft[1][i] = 0.5*1.0/ft[0][i];
  820. }
  821. }
  822. int olds, oldfxnum, oldfynum;
  823. void apply() {
  824. canvas.beginDraw();
  825. canvas.colorMode(RGB);
  826. canvas.noStroke();
  827. colorMode(RGB);
  828. canvas.fill(255);
  829. buffer.resize(canvas.width, canvas.height);
  830. buffer = canvas.get(0, 0, canvas.width, canvas.height);
  831. //int s = buffer.width>buffer.height?buffer.height:buffer.width;
  832. //int s = min(buffer.width, buffer.height);
  833. //depth = (int)(log(s)/log(2));
  834. int s = (int)(log(min(buffer.width, buffer.height))/log(2));
  835. if (olds != s) {
  836. olds = s;
  837. changeParam(1, new Param("x num", INTVAL, 1, s, new int[]{RANDOM}));
  838. changeParam(2, new Param("y num", INTVAL, 1, s, new int[]{RANDOM}));
  839. }
  840. //depth = (int)params.get(1).value;
  841. //println(depth);
  842. fxnum = (int)random(params.get(1).value);
  843. fynum = (int)random(params.get(2).value);
  844. fx = new int[fxnum+1];
  845. fy = new int[fynum+1];
  846. sx = new int[fxnum+1];
  847. sy = new int[fynum+1];
  848. phx = new float[fxnum+1];
  849. phy = new float[fynum+1];
  850. skipfx = new boolean[fxnum+1];
  851. skipfy = new boolean[fynum+1];
  852. for (int i=0; i<fxnum; i++) {
  853. fx[i]=(int)random(6);
  854. phx[i] = random(1);
  855. skipfx[i] = random(1)<0.2;
  856. sx[i] = random(1)<0.2?-1:1;
  857. }
  858. for (int i=0; i<fynum; i++) {
  859. fy[i]=(int)random(6);
  860. phy[i] = random(1);
  861. skipfy[i] = random(1)<0.2;
  862. sy[i] = random(1)<0.2?-1:1;
  863. }
  864. //dox = random(1)<0.8;
  865. //doy = dox?random(1)<0.8:true;
  866. dox = true;
  867. doy = true;
  868. float v=0;
  869. for (int y=0; y<buffer.height; y++)
  870. for (int x=0; x<buffer.width; x++) {
  871. float iy = map(y, 0, buffer.height, 0, 1);
  872. v=0;
  873. if (doy) for (int i=0; i<fy.length; i++)
  874. if (!skipfy[i]) v+=sy[i]*getValue(fy[i], iy, i, phy[i]);
  875. float ry = 2*iy+v;
  876. float y2 = (3*buffer.height+ry * buffer.height/2)%buffer.height;
  877. float ix = map(x, 0, buffer.width, 0, 1);
  878. v=0;
  879. if (dox) for (int i=0; i<fx.length; i++)
  880. if (!skipfx[i]) v+=sx[i]*getValue(fx[i], ix, i, phx[i]);
  881. float rx = 2*ix+v;
  882. float x2 = (3*buffer.width+rx * buffer.width/2)%buffer.width;
  883. canvas.fill(buffer.get((int)x2, (int)y2));
  884. canvas.rect(x, y, 1, 1);
  885. }
  886. canvas.endDraw();
  887. }
  888. float getValue(int fun, float idx, int freq, float phase) {
  889. switch(fun) {
  890. case 0:
  891. return getSin(idx, freq, phase);
  892. case 1:
  893. return getSaw(idx, freq, phase);
  894. case 2:
  895. return getTriangle(idx, freq, phase);
  896. case 3:
  897. return getCutTriangle(idx, freq, phase);
  898. case 4:
  899. return getSquare(idx, freq, phase);
  900. case 5:
  901. return getNoise(idx, freq, phase);
  902. default:
  903. return getSin(idx, freq, phase);
  904. }
  905. }
  906. float getNoise(float idx, int freq, float phase) {
  907. return 2*ft[1][freq]*(noise((idx+phase)*ft[0][freq])-0.5);
  908. }
  909. float getSin(float idx, int freq, float phase) {
  910. float p = ft[0][freq];
  911. return ft[1][freq] * sin(idx*TWO_PI*p+phase*TWO_PI);
  912. }
  913. float getSaw(float idx, int freq, float phase) {
  914. float p = ft[0][freq];
  915. float rp = 2.0*ft[1][freq];
  916. float p2 = p*((idx+phase+ft[1][freq])%1.0);
  917. return rp*(p2-floor(p2)-0.5);
  918. }
  919. float getSquare(float idx, int freq, float phase) {
  920. float p = ft[0][freq];
  921. float rp = ft[1][freq];
  922. return (((idx*p)+phase)%1.0)<0.5?rp:-rp;
  923. }
  924. float getTriangle(float idx, int freq, float phase) {
  925. return 2*abs(getSaw(idx, freq, phase+0.5*ft[1][freq]))-ft[1][freq];
  926. }
  927. float getCutTriangle(float idx, int freq, float phase) {
  928. return constrain(getTriangle(idx, freq, phase), -ft[1][freq+1], ft[1][freq+1]);
  929. }
  930. }
  931. /*
  932. WAHWAH
  933. */
  934. class WAHWAH extends Shader {
  935. float sequence, lfoskip, xn1, xn2, yn1, yn2, b0, b1, b2, a0, a1, a2, freqofs, freq, freqoff, startsequence, res, depth;
  936. float mCurRate = 0.4, skipcount = 0;
  937. int lfoskipsamples = 0;
  938. float frequency, omega, sn, cs, alpha;
  939. float in, out;
  940. float val;
  941. WAHWAH() {
  942. name = "fxWahWah";
  943. //params.add(new Param("mode", INTVAL, 0, 1, new int[]{RANDOM, SQUAR}));
  944. params.add(new Param ("resolution", FLOATVAL, 1, 100, new int[]{TRIANG, SINE, RAMPUPDOWN, }));
  945. params.add(new Param ("depth", FLOATVAL, 0.0001, 1, new int[]{TRIANG, SINE, RAMPUPDOWN }));
  946. params.add(new Param ("frequency offset", FLOATVAL, 0, 0.9, new int[]{TRIANG, SINE, RAMPUPDOWN }));
  947. params.add(new Param ("mCurRate", FLOATVAL, 0, 1, new int[]{TRIANG, SINE, RAMPUPDOWN }));
  948. params.add(new Param ("direction", INTVAL, 0, 3, new int[]{RANDOM}));
  949. directionParamIndex = 4;
  950. // params.add(new Param ("blend mode", INTVAL, 0, this.blends.length-1, new int[]{RANDOM }));
  951. }
  952. void apply() {
  953. res = params.get(0).value;
  954. depth = params.get(1).value;
  955. freqofs = params.get(2).value;
  956. //res = 12.5
  957. //depth = 0.8;
  958. //freqofs = 0.9;
  959. freq = 1.5;
  960. startsequence = 0.2;
  961. lfoskip = freq * 2 * PI / mCurRate;
  962. skipcount = xn1 = xn2 = yn1 = yn2 = b0 = b1 = b2 = a0 = a1 = a2 = 0;
  963. sequence = startsequence;
  964. canvas.beginDraw();
  965. canvas.colorMode(RGB);
  966. canvas.loadPixels();
  967. float[] rgb = new float[3];
  968. for ( int i = 0, len = canvas.pixels.length; i < len; i++) {
  969. rgb[0] = red(canvas.pixels[i]);
  970. rgb[1] = green(canvas.pixels[i]);
  971. rgb[2] = blue(canvas.pixels[i]);
  972. for ( int ri = 0; ri < 3; ri++ ) {
  973. in = map(rgb[ri], 0, 255, 0, 1);
  974. frequency = (1+cos(skipcount * lfoskip + sequence ))/2;
  975. frequency = frequency * depth * (1-freqofs) + freqofs;
  976. frequency = exp((frequency - 1) * 6 );
  977. omega = PI * frequency;
  978. sn = sin(omega);
  979. cs = cos(omega);
  980. alpha = sn/(2*res);
  981. b0 = (1-cs) /2;
  982. b1 = 1 - cs;
  983. b2 = (1-cs)/2;
  984. a0 = 1 + alpha;
  985. a1 = -2 * cs;
  986. a2 = 1 - alpha;
  987. out = ( b0 * in + b1 * xn1 + b2 * xn2 - a1 * yn1 - a2 * yn2 ) / a0;
  988. xn2 = xn1;
  989. xn1 = in;
  990. yn2 = yn1;
  991. yn1 = out;
  992. rgb[ri] = map(out, 0, 1, 0, 255);
  993. }
  994. canvas.pixels[i] = color(rgb[0], rgb[1], rgb[2]);
  995. }
  996. canvas.updatePixels();
  997. canvas.endDraw();
  998. }
  999. }
  1000. /*
  1001. PHASER
  1002. */
  1003. class PHASER extends Shader {
  1004. //float samplerate = 92230.0; // try setting this to 44100.0 or 2048.5 for kicks
  1005. float samplerate = 44100; // try setting this to 44100.0 or 2048.5 for kicks
  1006. int mode;
  1007. PHASER() {
  1008. name ="fxPhaser";
  1009. params.add(new Param("mode", INTVAL, 0, 1, new int[]{RANDOM, SQUAR}));
  1010. params.add(new Param ("frequency", FLOATVAL, 0.1, 40.0, new int[]{TRIANG, SINE, RAMPUPDOWN }));
  1011. params.add(new Param ("depth", INTVAL, 1, 255, new int[]{TRIANG, SINE, RAMPUPDOWN }));
  1012. params.add(new Param ("feedback", INTVAL, -100, 100, new int[]{TRIANG, SINE, RAMPUPDOWN }));
  1013. params.add(new Param ("phase", FLOATVAL, 0, TWO_PI, new int[]{TRIANG, SINE, RAMPUPDOWN }));
  1014. params.add(new Param ("stages", INTVAL, 1, 24, new int[]{TRIANG, SINE, RAMPUPDOWN }));
  1015. params.add(new Param ("sample rate", FLOATVAL, 512, 92230, new int[]{TRIANG, SINE, RAMPUPDOWN }));
  1016. params.add(new Param("direction", INTVAL, 0, 3, new int[]{RANDOM}));
  1017. directionParamIndex = 7;
  1018. //params.add(new Param ("frequency offset", FLOATVAL, 0, 1, new int[]{TRIANG, SINE, RAMPUPDOWN }));
  1019. }
  1020. /*
  1021. mDepth = (int) map(knobZero, 0, 255, 255, 0);
  1022. mFeedback = (int) map(knobOne, 0, 255, -100, 100);
  1023. // enable these for some more fun :)
  1024. if (mode == 1) {
  1025. mSampleRate = map(knobTwo, 0, 255, 1, 512);
  1026. mStages = (int) ( 2*map(knobThree, 0, 255, 1, 12));
  1027. }
  1028. */
  1029. void apply() {
  1030. mode = (int)params.get(0).value;
  1031. float mFreq = params.get(1).value;
  1032. int mDryWet = 255;
  1033. int mDepth = (int)params.get(2).value;
  1034. int mFeedback = (int)params.get(3).value;
  1035. float mPhase = params.get(4).value;
  1036. //these two are only changed if mode = 1
  1037. int mStages = 2;
  1038. float mSampleRate = samplerate;
  1039. canvas.beginDraw();
  1040. canvas.loadPixels();
  1041. //constants
  1042. float phaserlfoshape = 4.0;
  1043. int lfoskipsamples = 20; //how many samples are processed before recomputing lfo
  1044. int numStages = 24;
  1045. //getParams
  1046. /*
  1047. Phaser Parameters
  1048. mFreq - Phaser's LFO frequency
  1049. mPhase - Phaser's LFO startsequence (radians), needed for stereo Phasers
  1050. mDepth - Phaser depth (0 - no depth, 255 - max depth)
  1051. mStages - Phaser stages (recomanded from 2 to 16-24, and EVEN NUMBER)
  1052. mDryWet - Dry/wet mix, (0 - dry, 128 - dry=wet, 255 - wet)
  1053. mFeedback - Phaser FeedBack (0 - no feedback, 100 = 100% Feedback,
  1054. -100 = -100% FeedBack)
  1055. */
  1056. // enable these for some more fun :)
  1057. if (mode == 1) {
  1058. mStages = (int)params.get(5).value;
  1059. mSampleRate = params.get(6).value;
  1060. }
  1061. //init
  1062. float gain = 0, fbout = 0;
  1063. float lfoskip = mFreq * 2 * PI / mSampleRate;
  1064. float sequence = mPhase * PI / 180;
  1065. float[] old = new float[mStages];
  1066. for ( int j = 0; j < mStages; j++) {
  1067. old[j] = 0.0;
  1068. }
  1069. /* EffectPhaser::ProcessBlock */
  1070. int skipcount = 0;
  1071. float[] rgb = new float[3];
  1072. for ( int i = 0, l = canvas.pixels.length; i<l; i++ ) {
  1073. color c = canvas.pixels[i];
  1074. rgb[0] = map(red(c), 0, 255, 0, 1);
  1075. rgb[1] = map(green(c), 0, 255, 0, 1);
  1076. rgb[2] = map(blue(c), 0, 255, 0, 1);
  1077. for ( int ci = 0; ci < 3; ci++) {
  1078. float in = rgb[ci];
  1079. float m = in + fbout * mFeedback / 100;
  1080. if ( (( skipcount++) % lfoskipsamples ) == 0 ) { //recomopute lfo
  1081. gain = (1.0 + cos(skipcount * lfoskip + sequence)) / 2.0; //compute sine between 0 and 1
  1082. gain = exp(gain * phaserlfoshape) / exp(phaserlfoshape); // change lfo shape
  1083. gain = 1.0 - gain / 255.0 * mDepth; // attenuate the lfo
  1084. }
  1085. //phasing routine
  1086. for ( int j = 0; j<mStages; j++) {
  1087. float tmp = old[j];
  1088. old[j] = gain * tmp + m;
  1089. m = tmp - gain * old[j];
  1090. }
  1091. fbout = m;
  1092. rgb[ci] = (float) (( m * mDryWet + in * (255-mDryWet)) / 255);
  1093. }
  1094. color rc = color(
  1095. map(rgb[0], 0, 1, 0, 255),
  1096. map(rgb[1], 0, 1, 0, 255),
  1097. map(rgb[2], 0, 1, 0, 255));
  1098. canvas.pixels[i] = rc;
  1099. }
  1100. canvas.updatePixels();
  1101. canvas.endDraw();
  1102. }
  1103. }
  1104. /*
  1105. ECHO
  1106. */
  1107. class ECHO extends Shader {
  1108. int mode = 0;
  1109. PImage result;
  1110. ECHO() {
  1111. name = "fxEcho";
  1112. params.add(new Param("mode", INTVAL, 0, 1, new int[]{RANDOM, SQUAR}));
  1113. params.add(new Param ("xp", INTVAL, 0, 100, new int[]{TRIANG, SINE, RAMPUPDOWN }));
  1114. params.add(new Param ("yp", INTVAL, 0, 100, new int[]{TRIANG, SINE, RAMPUPDOWN }));
  1115. params.add(new Param("direction", INTVAL, 0, 3, new int[]{RANDOM}));
  1116. directionParamIndex = 3;
  1117. result = createImage(canvas.width, canvas.height, RGB);
  1118. }
  1119. void apply() {
  1120. mode = (int)params.get(0).value;
  1121. int xp = (int)params.get(1).value;
  1122. int yp = (int)params.get(2).value;
  1123. canvas.beginDraw();
  1124. canvas.colorMode(RGB);
  1125. colorMode(RGB);
  1126. canvas.imageMode(CORNER);
  1127. if (mode == 0) {
  1128. canvas.image(auEcho(canvas, xp, yp), 0, 0);
  1129. } else if (mode == 1) {
  1130. canvas.image(auEchoWTF(canvas, xp, yp), 0, 0);
  1131. }
  1132. canvas.endDraw();
  1133. }
  1134. PImage auEcho(PImage img, int xp, int yp) {
  1135. result.resize(img.width, img.height);
  1136. float _delay = map(xp, 0, 100, 0.001, 1.0);
  1137. float decay = map(yp, 0, 100, 0.0, 1.0);
  1138. int delay = (int)(img.pixels.length * _delay);
  1139. color[] history = new color[img.pixels.length];
  1140. int blendMode = BLEND;
  1141. img.loadPixels();
  1142. result.loadPixels();
  1143. for ( int i = 0, l = img.pixels.length; i<l; i++) {
  1144. history[i] = img.pixels[i];
  1145. }
  1146. for ( int i = 0, l = img.pixels.length; i<l; i++) {
  1147. int fromPos = i-delay < 0 ? l-abs(i-delay) : i-delay;
  1148. color fromColor = history[fromPos];
  1149. float r = red(fromColor) * decay;
  1150. float g = green(fromColor) * decay;
  1151. float b = blue(fromColor) * decay;
  1152. color origColor = history[i];
  1153. color toColor = color(
  1154. r + red(origColor),
  1155. g + green(origColor),
  1156. b + blue(origColor) );
  1157. result.pixels[i] = history[i] = blendColor(origColor, toColor, blendMode);
  1158. }
  1159. return result;
  1160. }
  1161. PImage auEchoWTF(PImage img, int xp, int yp) {
  1162. result.resize(img.width, img.height);
  1163. float delay = map(xp, 0, 100, 0.001, 5);
  1164. float decay = map(yp, 0, 100, 0.0, 5.0);
  1165. int histPos = 0;
  1166. int histLen = img.pixels.length*3;
  1167. float[] history = new float[histLen*3];
  1168. img.loadPixels();
  1169. result.loadPixels();
  1170. float ibuf = 0.0, obuf = 0.0;
  1171. float[] rgb = new float[3];
  1172. for ( int i = 0, l = img.pixels.length; i<l; i++, histPos++) {
  1173. color c = img.pixels[i];
  1174. rgb[0] = map(red(c), 0, 255, 0, 1);
  1175. rgb[1] = map(green(c), 0, 255, 0, 1);
  1176. rgb[2] = map(blue(c), 0, 255, 0, 1);
  1177. history[i] = rgb[0];
  1178. history[i+1] = rgb[1];
  1179. history[i+2] = rgb[2];
  1180. }
  1181. for ( int i = 0, l = img.pixels.length; i<l; i++, histPos++) {
  1182. color c = img.pixels[i];
  1183. rgb[0] = map(red(c), 0, 255, 0, 1);
  1184. rgb[1] = map(green(c), 0, 255, 0, 1);
  1185. rgb[2] = map(blue(c), 0, 255, 0, 1);
  1186. if ( histPos == histLen ) histPos = 0;
  1187. for ( int ri = 0; ri < 3; ri++ ) {
  1188. history[histPos+ri] = rgb[ri] = rgb[ri] + history[histPos+ri] * decay;
  1189. }
  1190. color out = color(
  1191. (int)map(rgb[0], 0, 1, 0, 255),
  1192. (int)map(rgb[1], 0, 1, 0, 255),
  1193. (int)map(rgb[2], 0, 1, 0, 255));
  1194. result.pixels[i] = out;
  1195. }
  1196. return result;
  1197. }
  1198. }
  1199. /*
  1200. DARKER
  1201. */
  1202. class DARKER extends Shader {
  1203. float thresh = 127;
  1204. float darken = 150;
  1205. int mode = 1;
  1206. int bangCount = 0;
  1207. DARKER() {
  1208. name = "fxDarker";
  1209. params.add(new Param("count", INTVAL, 1, 4, new int[]{TRIANG, SINE, RAMPUPDOWN, TAN, TANINVERSE}));
  1210. params.add(new Param("threshold", INTVAL, 60, 180, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  1211. params.add(new Param("darken", INTVAL, 140, 220, new int[]{TRIANG, SINE, RAMPUPDOWN }));
  1212. params.add(new Param("mode", INTVAL, 0, 1, new int[]{SQUAR, RANDOM}));
  1213. //thresh = int(random(60, 180));
  1214. //darken = int(random(140, 220));
  1215. }
  1216. void apply() {
  1217. // bright = knobZero;
  1218. int count = int(params.get(0).value);
  1219. darken = int(params.get(1).value);
  1220. thresh = int(params.get(2).value);
  1221. mode = int(params.get(3).value);
  1222. canvas.beginDraw();
  1223. canvas.colorMode(HSB);
  1224. colorMode(HSB);
  1225. canvas.loadPixels();
  1226. if (mode == 0) {
  1227. for (int h = 1; h < count+1; h++) {
  1228. for (int i = 0; i < canvas.width*canvas.height; i++) {
  1229. float hue = hue(canvas.pixels[i]);
  1230. float sat = saturation(canvas.pixels[i]);
  1231. float bright = brightness(canvas.pixels[i]);
  1232. if (bright > thresh/h) {
  1233. bright -= darken/h;
  1234. constrain(bright, 0, 255);
  1235. }
  1236. color c = color(hue, sat, bright);
  1237. canvas.pixels[i] = c;
  1238. }
  1239. }
  1240. } else if (mode == 1) {
  1241. for (int h = 1; h < count+1; h++) {
  1242. for (int i = 0; i < canvas.width*canvas.height; i++) {
  1243. float hue = hue(canvas.pixels[i]);
  1244. float sat = saturation(canvas.pixels[i]);
  1245. float bright = brightness(canvas.pixels[i]);
  1246. if (bright < thresh/h) {
  1247. bright -= darken/h;
  1248. constrain(bright, 0, 255);
  1249. }
  1250. color c = color(hue, sat, bright);
  1251. canvas.pixels[i] = c;
  1252. }
  1253. }
  1254. }
  1255. canvas.updatePixels();
  1256. canvas.endDraw();
  1257. colorMode(RGB);
  1258. }
  1259. }
  1260. /*
  1261. BRIGHTER
  1262. */
  1263. class BRIGHTER extends Shader {
  1264. float thresh = 120;
  1265. float thresh2 = 150;
  1266. float brighten = 180;
  1267. float speed;
  1268. BRIGHTER() {
  1269. name = "fxBrighter";
  1270. params.add(new Param("threshold", INTVAL, 0, 255, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  1271. params.add(new Param("threshold 2", INTVAL, 0, 255, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  1272. params.add(new Param("brighten", INTVAL, 0, 255, new int[]{TRIANG, SINE, RAMPUPDOWN }));
  1273. }
  1274. void apply() {
  1275. brighten = int(params.get(2).value);
  1276. thresh2 = int(params.get(1).value);
  1277. thresh = int(params.get(0).value);
  1278. canvas.beginDraw();
  1279. canvas.colorMode(HSB);
  1280. colorMode(HSB);
  1281. canvas.loadPixels();
  1282. for (int i = 0; i < canvas.width*canvas.height; i++) {
  1283. float hue = hue(canvas.pixels[i]);
  1284. float sat = saturation(canvas.pixels[i]);
  1285. float bright = brightness(canvas.pixels[i]);
  1286. if (bright < thresh && bright > thresh2) {
  1287. bright += brighten;
  1288. constrain(bright, 0, 255);
  1289. }
  1290. color c = color(hue, sat, bright);
  1291. canvas.pixels[i] = c;
  1292. }
  1293. canvas.colorMode(RGB);
  1294. canvas.updatePixels();
  1295. canvas.endDraw();
  1296. colorMode(RGB);
  1297. }
  1298. }
  1299. /*
  1300. AMPLIFY
  1301. */
  1302. //13
  1303. class AMPLIFY extends Shader {
  1304. int spawnT;
  1305. float h, s, b;
  1306. AMPLIFY() {
  1307. name = "fxAmplify";
  1308. params.add(new Param("hue / red", FLOATVAL, -255, 255, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  1309. params.add(new Param("saturation / green", FLOATVAL, -255, 255, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  1310. params.add(new Param("brightness / blue", FLOATVAL, -255, 255, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  1311. params.add(new Param("RGB / HSB", INTVAL, 0, 1, new int[]{SQUAR, RANDOM}));
  1312. }
  1313. void apply() {
  1314. canvas.beginDraw();
  1315. if (params.get(3).value > 0) colorMode(HSB);
  1316. else {
  1317. colorMode(RGB);
  1318. }
  1319. canvas.loadPixels();
  1320. for (int i = 0; i < canvas.width*canvas.height; i++) {
  1321. float h = hue(canvas.pixels[i]);
  1322. float s = saturation(canvas.pixels[i]);
  1323. float b = brightness(canvas.pixels[i]);
  1324. canvas.pixels[i] = color(h+params.get(0).value, s+params.get(1).value, b+params.get(2).value);
  1325. }
  1326. canvas.updatePixels();
  1327. canvas.endDraw();
  1328. colorMode(RGB);
  1329. }
  1330. }
  1331. /*
  1332. BROKENCOLORROT
  1333. */
  1334. class BROKENCOLORROT extends Shader {
  1335. int spawnT;
  1336. float h, s, b;
  1337. BROKENCOLORROT() {
  1338. name = "fxBrokenColorRot";
  1339. params.add(new Param("hue", INTVAL, 0, 255, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  1340. params.add(new Param("saturation", INTVAL, 0, 255, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  1341. params.add(new Param("brightness", INTVAL, 0, 255, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  1342. params.add(new Param("mode", INTVAL, 0, 1, new int[]{SQUAR, RANDOM}));
  1343. params.add(new Param("direction", INTVAL, 0, 3, new int[]{RANDOM}));
  1344. directionParamIndex = 4;
  1345. }
  1346. void apply() {
  1347. canvas.beginDraw();
  1348. if (params.get(3).value > 0) colorMode(HSB);
  1349. else {
  1350. colorMode(RGB);
  1351. }
  1352. canvas.loadPixels();
  1353. float h = params.get(0).value;
  1354. float s = params.get(1).value;
  1355. float b = params.get(2).value;
  1356. for (int i = 0; i < canvas.width*canvas.height; i++) {
  1357. h = hue(canvas.pixels[i])+h;
  1358. if (h > 255) h -= 255;
  1359. s = saturation(canvas.pixels[i])+s;
  1360. if (s > 255) s -= 255;
  1361. b = brightness(canvas.pixels[i])+b;
  1362. if (b > 255) b -= 255;
  1363. canvas.pixels[i] = color(h, s, b);
  1364. }
  1365. canvas.updatePixels();
  1366. canvas.endDraw();
  1367. colorMode(RGB);
  1368. }
  1369. }
  1370. /*
  1371. POSTERIZE
  1372. */
  1373. class POSTER extends Shader {
  1374. int levels = 2;
  1375. POSTER() {
  1376. name = "fxPosterize";
  1377. params.add(new Param("levels", INTVAL, 2, 10, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  1378. }
  1379. void apply() {
  1380. levels = (int)params.get(0).value;
  1381. canvas.beginDraw();
  1382. canvas.filter(POSTERIZE, levels);
  1383. canvas.endDraw();
  1384. }
  1385. }
  1386. /*
  1387. DUAL
  1388. */
  1389. class DUAL extends Shader {
  1390. PImage buffer;
  1391. int dualColor;
  1392. int dirx = 1;
  1393. int diry = 1;
  1394. DUAL() {
  1395. name = "fxDual";
  1396. params.add(new Param("dual color", INTVAL, 2000000, 15000000, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  1397. params.add(new Param("flip direction", INTVAL, 0, 3, new int[]{RANDOM}));
  1398. params.add(new Param("mode", INTVAL, 0, 1, new int[]{SQUAR, RANDOM}));
  1399. params.add(new Param("direction", INTVAL, 0, 3, new int[]{RANDOM}));
  1400. directionParamIndex = 3;
  1401. buffer = createImage(canvas.width, canvas.height, ARGB);
  1402. }
  1403. void apply() {
  1404. switch((int)params.get(1).value) {
  1405. case(0):
  1406. dirx = 1;
  1407. diry = 1;
  1408. break;
  1409. case(1):
  1410. dirx = -1;
  1411. diry = 1;
  1412. break;
  1413. case(2):
  1414. dirx = 1;
  1415. diry = -1;
  1416. break;
  1417. case(3):
  1418. dirx = -1;
  1419. diry = -1;
  1420. break;
  1421. }
  1422. dualColor = (int)params.get(0).value;
  1423. buffer.resize(canvas.width, canvas.height);
  1424. canvas.beginDraw();
  1425. canvas.imageMode(CORNER);
  1426. canvas.loadPixels();
  1427. buffer.loadPixels();
  1428. if ((int)params.get(2).value > 0) {
  1429. for (int i = 0; i < canvas.width*canvas.height; i++) {
  1430. buffer.pixels[i] = canvas.pixels[i]+dualColor;
  1431. }
  1432. } else {
  1433. for (int i = 0; i < canvas.width*canvas.height; i++) {
  1434. buffer.pixels[i] = canvas.pixels[i]+dualColor;
  1435. buffer.pixels[i] = buffer.pixels[i]+i/10;
  1436. }
  1437. }
  1438. buffer.updatePixels();
  1439. canvas.updatePixels();
  1440. canvas.pushMatrix();
  1441. canvas.scale(dirx, diry);
  1442. canvas.image(buffer, 0, 0, dirx * canvas.width, diry * canvas.height);
  1443. canvas.popMatrix();
  1444. canvas.endDraw();
  1445. }
  1446. }
  1447. /*
  1448. GRAUZONE
  1449. */
  1450. class GRAUZONE extends Shader {
  1451. int nFrames = 20;
  1452. int iWrite = 0, iRead = 1;
  1453. PImage[] buffer;
  1454. PGraphics grauz;
  1455. GRAUZONE() {
  1456. name = "fxGrauzone";
  1457. params.add(new Param("delay (in frames)", INTVAL, 3, 100, new int[]{RANDOM}));
  1458. nFrames = (int)params.get(0).value;
  1459. buffer = new PImage[nFrames];
  1460. }
  1461. int nFramesPrev;
  1462. void apply() {
  1463. nFramesPrev = nFrames;
  1464. if (nFramesPrev != (int)params.get(0).value) {
  1465. iWrite = 0;
  1466. iRead = 1;
  1467. int nFramesOld = nFrames;
  1468. nFrames = (int)params.get(0).value;
  1469. if (nFrames > nFramesOld) {
  1470. buffer = new PImage[nFrames];
  1471. }
  1472. }
  1473. buffer[iWrite] = canvas.get();
  1474. grauz = createGraphics(canvas.width, canvas.height);
  1475. grauz.beginDraw();
  1476. // grauz.resize(canvas.width, canvas.height);
  1477. buffer[iWrite] = canvas.get();
  1478. if (buffer[iRead] != null) {
  1479. grauz.tint(255, 127);
  1480. buffer[iRead].filter(INVERT);
  1481. grauz.image(buffer[iRead], 0, 0, canvas.width, canvas.height);
  1482. grauz.tint(255, 255);
  1483. }
  1484. grauz.endDraw();
  1485. canvas.beginDraw();
  1486. canvas.imageMode(CORNER);
  1487. canvas.image(grauz, 0, 0, canvas.width, canvas.height);
  1488. canvas.endDraw();
  1489. iWrite++;
  1490. iRead++;
  1491. if (iRead >= nFrames-1) {
  1492. iRead = 0;
  1493. }
  1494. if (iWrite >= nFrames-1) {
  1495. iWrite = 0;
  1496. }
  1497. }
  1498. }
  1499. /*
  1500. COPYZOOM
  1501. */
  1502. class COPYZOOM extends Shader {
  1503. int coprx, copry, coprw, coprh;
  1504. PImage buffer;
  1505. COPYZOOM() {
  1506. name = "fxCopyZoom";
  1507. params.add(new Param("w", FLOATVAL, 0, 1, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  1508. params.add(new Param("h", FLOATVAL, 0, 1, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  1509. params.add(new Param("x", FLOATVAL, 0, 1, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  1510. params.add(new Param("y", FLOATVAL, 0, 1, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  1511. buffer = createImage(canvas.width, canvas.height, ARGB);
  1512. }
  1513. void apply() {
  1514. canvas.imageMode(CORNER);
  1515. if (buffer.width != canvas.width || buffer.height != canvas.height) buffer.resize(canvas.width, canvas.height);
  1516. buffer = canvas.get();
  1517. coprw = int(map(params.get(0).value, 0, 1, 1, canvas.width));
  1518. coprh = int(map(params.get(1).value, 0, 1, 1, canvas.height));
  1519. coprx = int(map(params.get(2).value, 0, 1, 0, canvas.width-coprw));
  1520. copry = int(map(params.get(3).value, 0, 1, 0, canvas.height-coprh));
  1521. canvas.beginDraw();
  1522. buffer.copy(coprx, copry, coprw, coprh, 0, 0, canvas.width, canvas.height);
  1523. canvas.image(buffer, 0, 0, canvas.width, canvas.height);
  1524. canvas.endDraw();
  1525. }
  1526. }
  1527. /*
  1528. SUBTLESORT
  1529. */
  1530. class SUBTLESORT extends Shader {
  1531. int direction = 0;
  1532. int mode = 0;
  1533. int c;
  1534. //int count = int(random(777));
  1535. color col;
  1536. final static int RED = 0;
  1537. final static int GREEN = 1;
  1538. final static int BLUE = 2;
  1539. final static int HUE = 3;
  1540. final static int SATURATION = 4;
  1541. final static int BRIGHTNESS = 5;
  1542. final static int NRED = 6;
  1543. final static int NGREEN = 7;
  1544. final static int NBLUE = 8;
  1545. final static int NHUE = 9;
  1546. final static int NSATURATION = 10;
  1547. final static int NBRIGHTNESS = 11;
  1548. // channels for depth: RED, GREEN, BLUE, HUE, SATURATION, BRIGHTNESS, NRED, NGREEN, NBLUE, NHUE, NSATURATION, NBRIGHTNESS.
  1549. int channel = BRIGHTNESS;
  1550. // channel weight.
  1551. float channel_weight = .2;
  1552. //
  1553. SUBTLESORT() {
  1554. name ="fxSubtleSort";
  1555. params.add(new Param ("channel weight", FLOATVAL, 0.001, 20, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  1556. params.add(new Param ("channel", INTVAL, 0, 6, new int[]{RANDOM}));
  1557. //params.add(new Param("direction", INTVAL, 0, 3, new int[]{RANDOM}));
  1558. params.add(new Param("mode", INTVAL, 0, 1, new int[]{SQUARE, RANDOM}));
  1559. params.add(new Param("direction", INTVAL, 0, 3, new int[]{RANDOM}));
  1560. directionParamIndex = 3;
  1561. }
  1562. void apply() {
  1563. channel_weight = map(renderSize, 4, 15000, 0, 1.5)*params.get(0).value;
  1564. channel = (int)params.get(1).value;
  1565. direction = (int)params.get(2).value;
  1566. mode = (int)params.get(3).value;
  1567. canvas.beginDraw();
  1568. canvas.noStroke();
  1569. //if (direction == 0) {
  1570. for (int i = 0; i < canvas.width; i++) {
  1571. for (int j = 0; j < canvas.height; j++) {
  1572. c = i+(j*canvas.width);
  1573. col = canvas.pixels[c];
  1574. canvas.fill(col);
  1575. canvas.rect(i, j+(getChannel(col)), 1, getChannel(col));
  1576. }
  1577. }
  1578. //}
  1579. /*else if (direction == 1) {
  1580. for (int i = 0; i < canvas.width; i++) {
  1581. for (int j = 0; j < canvas.height; j++) {
  1582. c = i+(j*canvas.width);
  1583. col = canvas.pixels[c];
  1584. canvas.fill(col);
  1585. canvas.rect(i, j-(getChannel(col)*mode), 1, -getChannel(col));
  1586. }
  1587. }
  1588. } else if (direction == 2) {
  1589. for (int i = 0; i < canvas.width; i++) {
  1590. for (int j = 0; j < canvas.height; j++) {
  1591. c = i+(j*canvas.width);
  1592. col = canvas.pixels[c];
  1593. canvas.fill(col);
  1594. canvas.rect(i-(getChannel(col)*mode), j, -getChannel(col), 1);
  1595. }
  1596. }
  1597. } else if (direction == 3) {
  1598. for (int i = 0; i < canvas.width; i++) {
  1599. for (int j = 0; j < canvas.height; j++) {
  1600. c = i+(j*canvas.width);
  1601. col = canvas.pixels[c];
  1602. canvas.fill(col);
  1603. canvas.rect(i+(getChannel(col)), j, getChannel(col), 1);
  1604. }
  1605. }
  1606. }*/
  1607. canvas.endDraw();
  1608. }
  1609. float getChannel(color c) {
  1610. int ch = channel;
  1611. float cc;
  1612. switch(ch) {
  1613. case RED:
  1614. cc = red(c);
  1615. break;
  1616. case GREEN:
  1617. cc = green(c);
  1618. break;
  1619. case BLUE:
  1620. cc = blue(c);
  1621. break;
  1622. case HUE:
  1623. cc = hue(c);
  1624. break;
  1625. case SATURATION:
  1626. cc = saturation(c);
  1627. break;
  1628. default:
  1629. cc= brightness(c);
  1630. break;
  1631. }
  1632. return channel_weight * (channel>5?255-cc:cc);
  1633. }
  1634. }
  1635. /*
  1636. SCANKER
  1637. */
  1638. class SCANKER extends Shader {
  1639. int mode;
  1640. SCANKER() {
  1641. name = "fxScanker";
  1642. params.add(new Param ("detail level 1", FLOATVAL, 0.001, 1000, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  1643. params.add(new Param ("detail level 2", FLOATVAL, -50, 50, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  1644. params.add(new Param ("detail level 3", FLOATVAL, -5, 5, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  1645. params.add(new Param ("mode", INTVAL, 0, 1, new int[]{RANDOM, SQUAR}));
  1646. params.add(new Param("direction", INTVAL, 0, 3, new int[]{RANDOM}));
  1647. directionParamIndex = 4;
  1648. }
  1649. void apply() {
  1650. mode = (int)params.get(3).value;
  1651. canvas.beginDraw();
  1652. canvas.loadPixels();
  1653. float factor = params.get(0).value + params.get(1).value + params.get(2).value;
  1654. if (mode == 0) {
  1655. for (int i = 0; i < canvas.width*canvas.height; i++) {
  1656. // canvas.pixels[i] = canvas.pixels[i]+((i/1000)*scankMulti);
  1657. canvas.pixels[i] = canvas.pixels[i]-int(map(i, 0, canvas.width*canvas.height, 0, source.width*source.height)/10*factor);
  1658. }
  1659. } else if (mode == 1) {
  1660. for (int i = 0; i < canvas.width*canvas.height; i++) {
  1661. // canvas.pixels[i] = canvas.pixels[i]+((i/1000)*scankMulti);
  1662. canvas.pixels[i] = canvas.pixels[i]+int(map(i, 0, canvas.width*canvas.height, 0, source.width*source.height)/10*factor);
  1663. }
  1664. }
  1665. canvas.updatePixels();
  1666. canvas.endDraw();
  1667. }
  1668. }
  1669. /*
  1670. MASK
  1671. */
  1672. class MASK extends Shader {
  1673. int backgroundLayer, maskLayer, bandwidth, val, chan, shaderListLength, invert, blend_mode;
  1674. boolean do_blend;
  1675. PImage mask;
  1676. PImage background;
  1677. PImage foreground;
  1678. MASK() {
  1679. name = "mask";
  1680. shaderListLength = gui.shaderList.size();
  1681. params.add(new Param("target layer", INTVAL, 0, shaderListLength-2, new int[]{RANDOM}));
  1682. params.add(new Param("mask layer", INTVAL, 0, shaderListLength-1, new int[]{RANDOM}));
  1683. params.add(new Param("invert", INTVAL, 0, 1, new int[]{RANDOM, SQUAR}));
  1684. params.add(new Param("bandwidth", INTVAL, 0, 255, new int[]{TRIANG, SINE}));
  1685. params.add(new Param("value", INTVAL, 1, 255, new int[]{TRIANG, SINE}));
  1686. params.add(new Param("channel (R/G/B/H/S/V", INTVAL, 0, 5, new int[]{RANDOM}));
  1687. params.add(new Param("do blend", INTVAL, 0, 1, new int[]{RANDOM}));
  1688. params.add(new Param("blend mode", INTVAL, 0, blends.length-1, new int[]{RANDOM}));
  1689. background = createImage(canvas.width, canvas.height, ARGB);
  1690. mask = createImage(canvas.width, canvas.height, ARGB);
  1691. foreground = createImage(canvas.width, canvas.height, ARGB);
  1692. }
  1693. void apply() {
  1694. if (shaderListLength != gui.shaderList.size()) {
  1695. shaderListLength = gui.shaderList.size();
  1696. changeParam(0, new Param("target layer", INTVAL, 0, shaderListLength-2, new int[]{RANDOM}));
  1697. changeParam(1, new Param("mask layer", INTVAL, 0, shaderListLength-1, new int[]{RANDOM}));
  1698. }
  1699. if (mask.width != canvas.width || mask.height != canvas.height) mask.resize(canvas.width, canvas.height);
  1700. if (background.width != canvas.width || background.height != canvas.height) background.resize(canvas.width, canvas.height);
  1701. if (foreground.width != canvas.width || foreground.height != canvas.height) foreground.resize(canvas.width, canvas.height);
  1702. backgroundLayer = (int)params.get(0).value;
  1703. maskLayer = (int)params.get(1).value;
  1704. invert = (int)params.get(2).value;
  1705. bandwidth = (int)params.get(3).value;
  1706. val = (int)params.get(4).value;
  1707. chan = (int)params.get(5).value;
  1708. do_blend = boolean((int)params.get(6).value);
  1709. blend_mode = blends[(int)params.get(7).value];
  1710. if (backgroundLayer <= 0) {
  1711. background.resize(source.width, source.height);
  1712. background = source.get();
  1713. background.resize(canvas.width, canvas.height);
  1714. } else background = gui.shaderList.get(backgroundLayer-1).result.get();
  1715. if (maskLayer <= 0) {
  1716. mask.resize(source.width, source.height);
  1717. mask = source.get();
  1718. mask.resize(canvas.width, canvas.height);
  1719. } else mask = gui.shaderList.get(maskLayer-1).result.get();
  1720. canvas.beginDraw();
  1721. canvas.imageMode(CORNER);
  1722. mask.loadPixels();
  1723. foreground.loadPixels();
  1724. canvas.loadPixels();
  1725. if (boolean(invert)) {
  1726. for (int i = 0; i < canvas.width * canvas.height; i++) {
  1727. if (!thresh(color(mask.pixels[i])))
  1728. foreground.pixels[i] = canvas.pixels[i];
  1729. else
  1730. foreground.pixels[i] = background.pixels[i];
  1731. }
  1732. } else {
  1733. for (int i = 0; i < canvas.width * canvas.height; i++) {
  1734. if (thresh(color(mask.pixels[i])))
  1735. foreground.pixels[i] = canvas.pixels[i];
  1736. else
  1737. foreground.pixels[i] = background.pixels[i];
  1738. }
  1739. }
  1740. canvas.updatePixels();
  1741. foreground.updatePixels();
  1742. mask.updatePixels();
  1743. if (do_blend)
  1744. canvas.blend(foreground, 0, 0, foreground.width, foreground.height, 0, 0, canvas.width, canvas.height, blend_mode);
  1745. else
  1746. canvas.image(foreground, 0, 0, canvas.width, canvas.height);
  1747. canvas.endDraw();
  1748. }
  1749. boolean thresh(color c) {
  1750. switch(chan) {
  1751. case(0):
  1752. if (red(c) > val - bandwidth && red(c) < val + bandwidth)
  1753. return(true);
  1754. else
  1755. return(false);
  1756. case(1):
  1757. if (green(c) > val - bandwidth && green(c) < val + bandwidth)
  1758. return(true);
  1759. else
  1760. return(false);
  1761. case(2):
  1762. if (blue(c) > val - bandwidth && blue(c) < val + bandwidth)
  1763. return(true);
  1764. else
  1765. return(false);
  1766. case(3):
  1767. if (hue(c) > val - bandwidth && hue(c) < val + bandwidth)
  1768. return(true);
  1769. else
  1770. return(false);
  1771. case(4):
  1772. if (saturation(c) > val - bandwidth && saturation(c) < val + bandwidth)
  1773. return(true);
  1774. else
  1775. return(false);
  1776. case(5):
  1777. if (brightness(c) > val - bandwidth && brightness(c) < val + bandwidth)
  1778. return(true);
  1779. else
  1780. return(false);
  1781. }
  1782. return(false);
  1783. }
  1784. }
  1785. class DRAWSTROKES extends Shader {
  1786. int stat_type = ABSDIST2; // type of diff calculation: fast: ABSDIST, DIST, slow: HUE, SATURATION, BRIGHTNESS
  1787. int stroke_len = 3; // length of the stroke, values: 1 and above
  1788. int angles_no = 30; // number of directions stroke can be drew, 2 and above
  1789. int segments = 500; // number of segments of single thread
  1790. float stroke_width = 1; // width of the stroke, 0.5 - 3
  1791. int stroke_alpha = 100; // alpha channel of the stroke: 30 - 200
  1792. color background_color = color(255, 255, 255); // RGB
  1793. boolean interactive = false;
  1794. int max_display_size = 800; // viewing window size (regardless image size)
  1795. int len;
  1796. // working buffer
  1797. PGraphics buffer;
  1798. int currx, curry;
  1799. int[] sintab, costab;
  1800. int sqwidth;
  1801. int iterations;
  1802. int calcDiff(PImage img1, PImage img2) {
  1803. int err = 0;
  1804. for (int i=0; i<img1.pixels.length; i++)
  1805. err += getStat(img1.pixels[i], img2.pixels[i]);
  1806. return err;
  1807. }
  1808. DRAWSTROKES() {
  1809. name = "fxDrawStrokes";
  1810. params.add(new Param ("stat type", INTVAL, 0, 5, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE})); // 4 und 5 sind mit abstand die schnellsten
  1811. params.add(new Param ("stroke length", INTVAL, 1, 10, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  1812. params.add(new Param ("amount of angles", INTVAL, 2, 30, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  1813. params.add(new Param ("amount of segments", INTVAL, 50, 1500, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  1814. params.add(new Param ("stroke width", FLOATVAL, 0.5, 5, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  1815. params.add(new Param ("stroke transparency", INTVAL, 30, 220, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  1816. params.add(new Param ("iterations", INTVAL, 1, 500, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  1817. len = (renderer.width<renderer.height?renderer.width:renderer.height)/3;
  1818. buffer = createGraphics(renderer.width, renderer.height);
  1819. buffer.smooth(2);
  1820. buffer.beginDraw();
  1821. buffer.strokeWeight(stroke_width);
  1822. buffer.noFill();
  1823. buffer.endDraw();
  1824. rw = renderer.width;
  1825. rh = renderer.height;
  1826. }
  1827. int rw, rh;
  1828. void apply() {
  1829. stat_type = (int)params.get(0).value;
  1830. stroke_len = (int)params.get(1).value;
  1831. angles_no = (int)params.get(2).value;
  1832. segments = (int)params.get(3).value;
  1833. stroke_width = params.get(4).value;
  1834. stroke_alpha = (int)params.get(5).value;
  1835. iterations = (int)params.get(6).value;
  1836. if (rw != canvas.width || rh != canvas.height) { //doesnt account image swap
  1837. len = (canvas.width<canvas.height?canvas.width:canvas.height)/3;
  1838. rw = canvas.width;
  1839. rh = canvas.height;
  1840. PGraphics save = createGraphics(canvas.width, canvas.height);
  1841. save.beginDraw();
  1842. save.image(buffer, 0, 0, save.width, save.height);
  1843. save.endDraw();
  1844. buffer.setSize(canvas.width, canvas.height);
  1845. buffer.beginDraw();
  1846. buffer.image(save, 0, 0, buffer.width, buffer.height); // ????
  1847. buffer.endDraw();
  1848. }
  1849. for (int j = 0; j < iterations; j++) {
  1850. currx = (int)random(canvas.width);
  1851. curry = (int)random(canvas.height);
  1852. sintab = new int[angles_no];
  1853. costab = new int[angles_no];
  1854. for (int i=0; i<angles_no; i++) {
  1855. sintab[i] = (int)(stroke_len * sin(TWO_PI*i/(float)angles_no));
  1856. costab[i] = (int)(stroke_len * cos(TWO_PI*i/(float)angles_no));
  1857. }
  1858. sqwidth = stroke_len * 2 + 4;
  1859. buffer.beginDraw();
  1860. buffer.strokeWeight(stroke_width);
  1861. //draw whole segment using current color
  1862. buffer.stroke(canvas.get(currx, curry), stroke_alpha);
  1863. for (int iter=0; iter<segments; iter++) {
  1864. // corners of square containing new strokes
  1865. int corx = currx-stroke_len-2;
  1866. int cory = curry-stroke_len-2;
  1867. // take square from image and current screen
  1868. PImage imgpart = canvas.get(corx, cory, sqwidth, sqwidth);
  1869. PImage mypart = buffer.get(corx, cory, sqwidth, sqwidth);
  1870. imgpart.loadPixels();
  1871. mypart.loadPixels();
  1872. // calc current diff
  1873. float localerr = calcDiff(imgpart, mypart);
  1874. // chosen stroke will be here
  1875. PImage destpart = null;
  1876. int _nx=currx, _ny=curry;
  1877. // start with random angle
  1878. int i = (int)random(angles_no);
  1879. int iterangles = angles_no;
  1880. while (iterangles-- > 0) {
  1881. // take end points
  1882. int nx = currx + costab[i];
  1883. int ny = curry + sintab[i];
  1884. // if not out of the screen
  1885. if (nx>=0 && nx<canvas.width-1 && ny>=0 && ny<canvas.height-1) {
  1886. // clean region and draw line
  1887. buffer.image(mypart, corx, cory);
  1888. buffer.line(currx, curry, nx, ny);
  1889. // take region with line and calc diff
  1890. PImage curr = buffer.get(corx, cory, sqwidth, sqwidth);
  1891. curr.loadPixels();
  1892. int currerr = calcDiff(imgpart, curr);
  1893. // if better, remember this region and line endpoint
  1894. if (currerr < localerr) {
  1895. destpart = curr;
  1896. _nx = nx;
  1897. _ny = ny;
  1898. localerr = currerr;
  1899. }
  1900. }
  1901. // next angle
  1902. i = (i+1)%angles_no;
  1903. }
  1904. // if we have new stroke, draw it
  1905. if (destpart != null) {
  1906. buffer.image(destpart, corx, cory);
  1907. currx = _nx;
  1908. curry = _ny;
  1909. } else {
  1910. break; // skip
  1911. }
  1912. }
  1913. buffer.endDraw();
  1914. }
  1915. canvas.beginDraw();
  1916. canvas.image(buffer, canvas.width/2, canvas.height/2);
  1917. canvas.endDraw();
  1918. }
  1919. final static int DIST = 0;
  1920. final static int HUE = 1;
  1921. final static int BRIGHTNESS = 2;
  1922. final static int SATURATION = 3;
  1923. final static int ABSDIST = 4;
  1924. final static int ABSDIST2 = 5;
  1925. final float getStat(color c1, color c2) {
  1926. switch(stat_type) {
  1927. case HUE:
  1928. abs(hue(c1)-hue(c2));
  1929. case BRIGHTNESS:
  1930. abs(brightness(c1)-brightness(c2));
  1931. case SATURATION:
  1932. abs(saturation(c1)-saturation(c2));
  1933. case ABSDIST:
  1934. return abs(red(c1)-red(c2))+abs(green(c1)-green(c2))+abs(blue(c1)-blue(c2));
  1935. case ABSDIST2:
  1936. return abs( (red(c1)+blue(c1)+green(c1)) - (red(c2)+blue(c2)+green(c2)) );
  1937. default:
  1938. return sq(red(c1)-red(c2)) + sq(green(c1)-green(c2)) + sq(blue(c1)-blue(c2));
  1939. }
  1940. }
  1941. }
  1942. /*
  1943. DRAWGENERATIVE
  1944. */
  1945. class DRAWGENERATIVE extends Shader {
  1946. // choose channel
  1947. int channel = HUE;
  1948. // run, after 30 iterations result will be saved automatically
  1949. // or press SPACE
  1950. // channels to work with
  1951. final static int RED = 0;
  1952. final static int GREEN = 1;
  1953. final static int BLUE = 2;
  1954. final static int HUE = 3;
  1955. final static int SATURATION = 4;
  1956. final static int BRIGHTNESS = 5;
  1957. final static int NRED = 6;
  1958. final static int NGREEN = 7;
  1959. final static int NBLUE = 8;
  1960. final static int NHUE = 9;
  1961. final static int NSATURATION = 10;
  1962. final static int NBRIGHTNESS = 11;
  1963. int n=2000;
  1964. float [] cx=new float[n];
  1965. float [] cy=new float[n];
  1966. int len;
  1967. // working buffer
  1968. PGraphics buffer;
  1969. int tick = 0;
  1970. DRAWGENERATIVE() {
  1971. name = "fxDrawGenerative";
  1972. params.add(new Param ("stroke width", FLOATVAL, 0.3, 5, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE})); // 4 und 5 sind mit abstand die schnellsten
  1973. buffer = createGraphics(renderer.width, renderer.height);
  1974. buffer.noFill();
  1975. buffer.beginDraw();
  1976. //buffer.background(0); //ENABLE THIS TO DRAW FROM BLANK
  1977. buffer.endDraw();
  1978. rw = canvas.width;
  1979. rh = canvas.height;
  1980. len = (canvas.width<canvas.height?canvas.width:canvas.height)/6;
  1981. for (int i=0; i<n; i++) {
  1982. cx[i]=random(canvas.width);
  1983. cy[i]=random(canvas.height);
  1984. }
  1985. }
  1986. int rw, rh;
  1987. void apply() {
  1988. if (rw != canvas.width || rh != canvas.height) {
  1989. rw = canvas.width;
  1990. rh = canvas.height;
  1991. PGraphics save = createGraphics(canvas.width, canvas.height);
  1992. save.beginDraw();
  1993. save.image(buffer, 0, 0, save.width, save.height);
  1994. save.endDraw();
  1995. buffer.setSize(canvas.width, canvas.height);
  1996. buffer.beginDraw();
  1997. buffer.image(save, 0, 0, buffer.width, buffer.height);
  1998. buffer.endDraw();
  1999. }
  2000. buffer.beginDraw();
  2001. buffer.strokeWeight(params.get(0).value);
  2002. for (int i=1; i<n; i++) {
  2003. color c = canvas.get((int)cx[i], (int)cy[i]);
  2004. buffer.stroke(c);
  2005. buffer.point(cx[i], cy[i]);
  2006. // you can choose channels: red(c), blue(c), green(c), hue(c), saturation(c) or brightness(c)
  2007. cy[i]+=sin(map(getChannel(c), 0, 255, 0, TWO_PI));
  2008. cx[i]+=cos(map(getChannel(c), 0, 255, 0, TWO_PI));
  2009. }
  2010. if (frameCount>len) {
  2011. frameCount=0;
  2012. //println("iteration: " + tick++);
  2013. for (int i=0; i<n; i++) {
  2014. cx[i]=random(canvas.width); //same problem as in slitscan here
  2015. cy[i]=random(canvas.height);
  2016. }
  2017. }
  2018. buffer.endDraw();
  2019. canvas.beginDraw();
  2020. canvas.image(buffer, canvas.width/2, canvas.height/2);
  2021. canvas.endDraw();
  2022. }
  2023. float getChannel(color c) {
  2024. int ch = channel>5?channel-6:channel;
  2025. float cc;
  2026. switch(ch) {
  2027. case RED:
  2028. cc = red(c);
  2029. break;
  2030. case GREEN:
  2031. cc = green(c);
  2032. break;
  2033. case BLUE:
  2034. cc = blue(c);
  2035. break;
  2036. case HUE:
  2037. cc = hue(c);
  2038. break;
  2039. case SATURATION:
  2040. cc = saturation(c);
  2041. break;
  2042. default:
  2043. cc= brightness(c);
  2044. break;
  2045. }
  2046. return channel>5?255-cc:cc;
  2047. }
  2048. }
  2049. /*
  2050. PIXELDRIFTER
  2051. */
  2052. class PIXELDRIFTER extends Shader {
  2053. int channel = HUE; // channel data used for shift
  2054. float channel_off = 60; // channel value offset
  2055. int iteration_no = 50; // number of iterations 1-100
  2056. int max_iter = iteration_no;
  2057. int direction = UP; // UP, DOWN, LEFT, RIGHT
  2058. boolean automate_channel_offset = false; // if true, change channel_offset every iteration
  2059. float scale = 0.03; // 0.01 - 0.1, step size (0.01: 2px, 0.1:25px)
  2060. float feedback = 0.9; // 0.9 - 0.999 ; blend ratio with original image
  2061. boolean do_blend = false; // blend image after process
  2062. int blend_mode = OVERLAY; // blend type
  2063. // working buffer
  2064. PGraphics buffer;
  2065. // image
  2066. PImage imgb;
  2067. PImage img;
  2068. String sessionid;
  2069. float acho_step;
  2070. int rw, rh;
  2071. PIXELDRIFTER() {
  2072. name = "fxPixelDrifter";
  2073. params.add(new Param ("channel offset", FLOATVAL, 0, 1, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  2074. params.add(new Param ("iterations", INTVAL, 1, 100, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  2075. params.add(new Param ("step size", FLOATVAL, 0.01, 0.1, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  2076. params.add(new Param ("feedback", FLOATVAL, 0.1, 1, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  2077. params.add(new Param ("direction", INTVAL, 37, 40, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  2078. params.add(new Param ("do blend", INTVAL, 0, 1, new int[]{RANDOM, SQUAR}));
  2079. params.add(new Param ("blend mode", INTVAL, 0, blends.length-1, new int[]{RANDOM}));
  2080. params.add(new Param ("channel", INTVAL, 0, 1, new int[]{SQUAR, RANDOM}));
  2081. params.add(new Param ("automate channel offset", INTVAL, 0, 1, new int[]{SQUAR, RANDOM}));
  2082. rw = canvas.width;
  2083. rh = canvas.height;
  2084. img = createImage(rw, rh, ARGB);
  2085. buffer = createGraphics(rw, rh);
  2086. buffer.beginDraw();
  2087. buffer.noStroke();
  2088. buffer.smooth(8);
  2089. buffer.background(0);
  2090. buffer.image(img, 0, 0);
  2091. buffer.endDraw();
  2092. scale = abs(scale);
  2093. }
  2094. void apply() {
  2095. if (rw != canvas.width || rh != canvas.height) {
  2096. rw = canvas.width;
  2097. rh = canvas.height;
  2098. img.resize(rw, rh);
  2099. buffer = createGraphics(rw, rh);
  2100. }
  2101. channel_off = map(params.get(0).value, 0, 1, 10, max(rw, rh));
  2102. iteration_no = (int)params.get(1).value;
  2103. scale = params.get(2).value;
  2104. feedback = params.get(3).value;
  2105. direction = (int)params.get(4).value;
  2106. do_blend = boolean((int)params.get(5).value);
  2107. blend_mode = blends[(int)params.get(6).value];
  2108. channel = (int)params.get(7).value == 1 ? HUE : RGB;
  2109. automate_channel_offset = boolean((int)params.get(8).value);
  2110. acho_step = 256.0 / iteration_no;
  2111. img = canvas.get();
  2112. // if (iteration_no>0) {
  2113. for (int i = 0; i < iteration_no; i++) {
  2114. processImage();
  2115. }
  2116. //iteration_no--;
  2117. //iteration_no=(iteration_no==0)?max_iter:iteration_no;
  2118. // if (iteration_no == 0)
  2119. // iteration_no = 50;
  2120. // }
  2121. // } else {
  2122. canvas.beginDraw();
  2123. if (do_blend) {
  2124. canvas.blend(img, 0, 0, img.width, img.height, 0, 0, canvas.width, canvas.height, blend_mode);
  2125. } else {
  2126. canvas.image(buffer, canvas.width/2, canvas.height/2, canvas.width, canvas.height);
  2127. }
  2128. canvas.endDraw();
  2129. // canvas.image(img, 0, 0, renderer.width, renderer.height);
  2130. // noLoop();
  2131. // }
  2132. }
  2133. void processImage() {
  2134. buffer.beginDraw();
  2135. for (int x=0; x<img.width; x++) {
  2136. for (int y=0; y<img.height; y++) {
  2137. color c = img.get(x, y);
  2138. color c2;
  2139. if (direction == UP || direction == DOWN) {
  2140. c2 = img.get(x, ((int)(y+img.height+( (channel_off+getChannel(c, channel))%255 )*(direction==DOWN?-1.0:1.0)*scale))%img.height);
  2141. } else {
  2142. c2 = img.get(((int)(x+img.width+( (channel_off+getChannel(c, channel))%255)*(direction==RIGHT?-1.0:1.0)*scale))%img.width, y);
  2143. }
  2144. buffer.set(x, y, lerpColor(c, c2, feedback) );
  2145. }
  2146. }
  2147. buffer.endDraw();
  2148. //canvas.image(buffer, 0, 0, width, height);
  2149. img = buffer.get();
  2150. if (automate_channel_offset) channel_off += acho_step;
  2151. }
  2152. // ALL Channels, Nxxx stand for negative (255-value)
  2153. // channels to work with
  2154. final static int RED = 0;
  2155. final static int GREEN = 1;
  2156. final static int BLUE = 2;
  2157. final static int HUE = 3;
  2158. final static int SATURATION = 4;
  2159. final static int BRIGHTNESS = 5;
  2160. final static int NRED = 6;
  2161. final static int NGREEN = 7;
  2162. final static int NBLUE = 8;
  2163. final static int NHUE = 9;
  2164. final static int NSATURATION = 10;
  2165. final static int NBRIGHTNESS = 11;
  2166. float getChannel(color c, int channel) {
  2167. int ch = channel>5?channel-6:channel;
  2168. float cc;
  2169. switch(ch) {
  2170. case RED:
  2171. cc = red(c);
  2172. break;
  2173. case GREEN:
  2174. cc = green(c);
  2175. break;
  2176. case BLUE:
  2177. cc = blue(c);
  2178. break;
  2179. case HUE:
  2180. cc = hue(c);
  2181. break;
  2182. case SATURATION:
  2183. cc = saturation(c);
  2184. break;
  2185. default:
  2186. cc= brightness(c);
  2187. break;
  2188. }
  2189. return channel>5?255-cc:cc;
  2190. }
  2191. }
  2192. /*
  2193. DRIPDRIP
  2194. */
  2195. class DRIPDRIP extends Shader {
  2196. int maxsteps = 50; //maximum fade length in px
  2197. int minsteps = 2; //minimum fade length in px
  2198. Boolean brightmode = false; //if enabled will fade light over dark
  2199. Boolean autotoggle = true; //switch brightmode at pivot point
  2200. float autoPivot = 0.58; //where on the y axis (0-1) to switch
  2201. int steps[];
  2202. int rw, rh;
  2203. DRIPDRIP() {
  2204. name = "fxDripDrip";
  2205. params.add(new Param ("max steps", FLOATVAL, 0, 1, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  2206. params.add(new Param ("min steps", FLOATVAL, 0, 1, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  2207. params.add(new Param ("bright breakpoint", FLOATVAL, 0, 1, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  2208. //params.add(new Param ("auto toggle", INTVAL, 0, 1, new int[]{SQUAR, RANDOM}));
  2209. params.add(new Param("direction", INTVAL, 0, 3, new int[]{RANDOM}));
  2210. directionParamIndex = 3;
  2211. rw = canvas.width;
  2212. rh = canvas.height;
  2213. steps = new int[canvas.width*canvas.height];
  2214. for (int i = 0; i < canvas.width*canvas.height; i++) {
  2215. steps[i] = (int)map(random(1), 0, 1, minsteps, maxsteps);
  2216. }
  2217. }
  2218. void apply() {
  2219. minsteps = (int)map(params.get(1).value, 0, 1, 1, max(canvas.width, canvas.height)/10);
  2220. maxsteps = (int)map(params.get(0).value, 0, 1, minsteps, max(canvas.width, canvas.height)/10);
  2221. autoPivot = params.get(2).value;
  2222. //brightmode = boolean((int)params.get(3).value);
  2223. //autotoggle = boolean((int)params.get(4).value);
  2224. if (rw != canvas.width || rh != canvas.height) {
  2225. rw = canvas.width;
  2226. rh = canvas.height;
  2227. steps = new int[canvas.width*canvas.height];
  2228. }
  2229. for (int i = 0; i < steps.length; i++) {
  2230. steps[i] = (int)map(random(1), 0, 1, minsteps, maxsteps);
  2231. }
  2232. canvas.beginDraw();
  2233. canvas.loadPixels();
  2234. for ( int x = 0, w = canvas.width; x<w; x++) {
  2235. for ( int h = canvas.height, y = h-1; y>-1; y--) {
  2236. /*
  2237. if ( alternatetoggle ) {
  2238. brightmode = !brightmode;
  2239. } else {
  2240. if ( autotoggle ) {
  2241. brightmode = y > (h*autoPivot);
  2242. }
  2243. }
  2244. */
  2245. //if (autotoggle) {
  2246. brightmode = y > (h*autoPivot);
  2247. //}
  2248. float rat = 1.0;
  2249. int pos = x + y * w;
  2250. color c = canvas.pixels[pos];
  2251. int ty = y;
  2252. while ( rat > 1.0/steps[x*y]*2 ) {
  2253. ty++;
  2254. if ( ty >= h ) break;
  2255. int tpos = x + ty * w;
  2256. color tc = canvas.pixels[tpos];
  2257. if (
  2258. ( !brightmode && brightness(tc) < brightness(c) )
  2259. || ( brightmode && brightness(tc) > brightness(c) )
  2260. ) break;
  2261. canvas.pixels[tpos] = blendC(tc, c, rat);
  2262. rat-= rat/steps[x*y];
  2263. }
  2264. }
  2265. }
  2266. canvas.updatePixels();
  2267. canvas.endDraw();
  2268. }
  2269. color blendC(color tc, color sc, float rat) {
  2270. return color(
  2271. (red(tc)*(1.0-rat))+(red(sc)*rat),
  2272. (green(tc)*(1.0-rat))+(green(sc)*rat),
  2273. (blue(tc)*(1.0-rat))+(blue(sc)*rat)
  2274. );
  2275. }
  2276. }
  2277. /*
  2278. WRONGQSORT
  2279. */
  2280. class WRONGQSORT extends Shader {
  2281. boolean mode = L; // L or R, which sort part is broken
  2282. boolean do_blend = false; // blend image after process
  2283. int blend_mode = OVERLAY; // blend type
  2284. static final boolean L = true;
  2285. static final boolean R = false;
  2286. // working buffer
  2287. PGraphics buffer;
  2288. // image
  2289. PImage img;
  2290. float random_point = 0.5;
  2291. int len;
  2292. int rw, rh;
  2293. WRONGQSORT() {
  2294. name = "fxWrongQSort";
  2295. params.add(new Param ("v", FLOATVAL, 0.1, 1, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  2296. params.add(new Param ("randomize", FLOATVAL, 0.1, 0.9, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  2297. params.add(new Param ("mode", INTVAL, 0, 1, new int[]{RANDOM, SQUAR}));
  2298. params.add(new Param ("do blend", INTVAL, 0, 1, new int[]{RANDOM, SQUAR}));
  2299. params.add(new Param ("blend mode", INTVAL, 0, blends.length-1, new int[]{RANDOM}));
  2300. params.add(new Param ("direction", INTVAL, 0, 3, new int[]{RANDOM}));
  2301. directionParamIndex = 5;
  2302. img = createImage(canvas.width, canvas.height, ARGB);
  2303. img = canvas.get();
  2304. buffer = createGraphics(canvas.width, canvas.height);
  2305. buffer.beginDraw();
  2306. buffer.noStroke();
  2307. buffer.smooth(8);
  2308. buffer.background(0);
  2309. buffer.image(img, 0, 0);
  2310. buffer.endDraw();
  2311. }
  2312. void apply() {
  2313. random_point = params.get(1).value;
  2314. mode = boolean((int)params.get(2).value);
  2315. do_blend = boolean((int)params.get(3).value);
  2316. blend_mode = blends[(int)params.get(4).value];
  2317. if (rw != canvas.width || rh != canvas.height) {
  2318. rw = canvas.width;
  2319. rh = canvas.height;
  2320. img.resize(rw, rh);
  2321. buffer = createGraphics(rw, rh);
  2322. }
  2323. img = canvas.get();
  2324. len = rw * rh;
  2325. int v = (int)map(params.get(0).value, 0, 1, 1, len-1);
  2326. buffer.beginDraw();
  2327. buffer.image(img, 0, 0);
  2328. buffer.endDraw();
  2329. buffer.loadPixels();
  2330. int x = 0;
  2331. while (x<len) {
  2332. if (x+v<len) quicksort(buffer.pixels, x, x+v);
  2333. else quicksort(buffer.pixels, x, len-1);
  2334. x+=v;
  2335. }
  2336. buffer.updatePixels();
  2337. buffer.beginDraw();
  2338. if (do_blend) {
  2339. buffer.blend(img, 0, 0, img.width, img.height, 0, 0, buffer.width, buffer.height, blend_mode);
  2340. }
  2341. buffer.endDraw();
  2342. canvas.beginDraw();
  2343. canvas.image(buffer, canvas.width/2, canvas.height/2);
  2344. canvas.endDraw();
  2345. }
  2346. int partition(int x[], int left, int right) {
  2347. int i = left;
  2348. int j = right;
  2349. int temp;
  2350. int pivot = x [(int)map(random_point, 0, 1, left, right)];
  2351. while (i<= j) {
  2352. while (x[i] < pivot) {
  2353. i++;
  2354. }
  2355. while (x[j] > pivot) {
  2356. j--;
  2357. }
  2358. if (i <= j) {
  2359. temp = x[i];
  2360. x[i] = x [j];
  2361. x[j] = temp;
  2362. i++;
  2363. j--;
  2364. }
  2365. }
  2366. return i;
  2367. }
  2368. void quicksort(int x[], int left, int right) {
  2369. if (left<right) {
  2370. int index = partition(x, left, right);
  2371. if (mode) {
  2372. if (left < index-1) quicksort(x, left, index-1);
  2373. if (right < index) quicksort(x, index, right);
  2374. } else {
  2375. if (left > index-1) quicksort(x, left, index-1);
  2376. if (right > index) quicksort(x, index, right);
  2377. }
  2378. }
  2379. }
  2380. }
  2381. /*
  2382. VHS
  2383. */
  2384. class VHS extends Shader {
  2385. PImage timg;
  2386. int bass, treble, sxl, syl;
  2387. VHS () {
  2388. name = "fxVHS";
  2389. params.add(new Param ("sine x length", INTVAL, 1, 100, new int[]{TRIANG, SINE}));
  2390. params.add(new Param ("sine y length", INTVAL, 1, 100, new int[]{TRIANG, SINE}));
  2391. params.add(new Param ("bass", INTVAL, -15, 15, new int[]{TRIANG, SINE}));
  2392. params.add(new Param ("treble", INTVAL, -15, 15, new int[]{TRIANG, SINE}));
  2393. params.add(new Param ("direction", INTVAL, 0, 3, new int[]{RANDOM}));
  2394. directionParamIndex = 4;
  2395. }
  2396. void apply() {
  2397. sxl = (int)params.get(0).value;
  2398. syl = (int)params.get(1).value;
  2399. bass = (int)params.get(2).value;
  2400. treble = (int)params.get(3).value;
  2401. int virtw = canvas.width;
  2402. int virth = canvas.height;
  2403. PImage timg = createImage(canvas.width, canvas.height, RGB);
  2404. timg = canvas.get();
  2405. PImage hay = sinwav(timg, sxl, syl);
  2406. PImage result = createImage(timg.width, timg.height, RGB);
  2407. result.copy(hay, 0, 0, virtw, virth, 0, 0, result.width, result.height);
  2408. canvas.beginDraw();
  2409. canvas.image(basstreble(result, bass, treble), canvas.width/2, canvas.height/2, canvas.width, canvas.height); //0 to 100
  2410. canvas.endDraw();
  2411. }
  2412. PImage sinwav(PImage img, int xp, int yp) {
  2413. int ctr = 0;
  2414. img.loadPixels();
  2415. float ylength = xp;
  2416. float xlength = yp; // was map (yp, 0,100, 1, 100);
  2417. PImage result = createImage(img.width, img.height, RGB);
  2418. for ( int y =0, h = img.height; y<h; y++) {
  2419. for ( int x = 0, w = img.width; x<w; x++, ctr++) {
  2420. int pos = x + y * w;
  2421. color c = img.pixels[pos];
  2422. int epos = (int)(( x + sin(y/ylength)*xlength)+ y * w);
  2423. if ( epos < result.pixels.length )
  2424. result.pixels[epos] = c;
  2425. else
  2426. result.pixels[pos] = c;
  2427. }
  2428. }
  2429. result.updatePixels();
  2430. return result;
  2431. }
  2432. PImage basstreble(PImage img, int xp, int yp) {
  2433. float dB_bass = xp;
  2434. float dB_treble = yp;
  2435. PImage result = createImage(img.width, img.height, RGB);
  2436. float slope = 0.4;
  2437. double hzBass = 250.0;
  2438. double hzTreble = 4000.0;
  2439. float b0, b1, b2, a0, a1, a2, xn2Bass, xn1Bass, yn2Bass, yn1Bass, b0Bass, b1Bass, b2Bass, xn1Treble, xn2Treble, yn1Treble, yn2Treble, a0Bass, a1Bass, a2Bass, a0Treble, a1Treble, a2Treble, b0Treble, b1Treble, b2Treble;
  2440. double mMax = 0.0;
  2441. double mSampleRate = 44000;
  2442. xn1Bass = xn2Bass = yn1Bass = yn2Bass = 0.0;
  2443. xn1Treble = xn2Treble = yn1Treble = yn2Treble = 0.0;
  2444. float w = (float)(2 * PI * hzBass / mSampleRate);
  2445. float a = exp((float)(log(10.0) * dB_bass / 40));
  2446. float b = sqrt((float)((a * a + 1) / slope - (pow((float)(a - 1), 2))));
  2447. b0Bass = a * ((a + 1) - (a - 1) * cos(w) + b * sin(w));
  2448. b1Bass = 2 * a * ((a - 1) - (a + 1) * cos(w));
  2449. b2Bass = a * ((a + 1) - (a - 1) * cos(w) - b * sin(w));
  2450. a0Bass = ((a + 1) + (a - 1) * cos(w) + b * sin(w));
  2451. a1Bass = -2 * ((a - 1) + (a + 1) * cos(w));
  2452. a2Bass = (a + 1) + (a - 1) * cos(w) - b * sin(w);
  2453. w = (float)(2 * PI * hzTreble / mSampleRate);
  2454. a = exp((float)(log(10.0) * dB_treble / 40));
  2455. b = sqrt((float)((a * a + 1) / slope - (pow((float)(a - 1), 2))));
  2456. b0Treble = a * ((a + 1) + (a - 1) * cos(w) + b * sin(w));
  2457. b1Treble = -2 * a * ((a - 1) + (a + 1) * cos(w));
  2458. b2Treble = a * ((a + 1) + (a - 1) * cos(w) - b * sin(w));
  2459. a0Treble = ((a + 1) - (a - 1) * cos(w) + b * sin(w));
  2460. a1Treble = 2 * ((a - 1) - (a + 1) * cos(w));
  2461. a2Treble = (a + 1) - (a - 1) * cos(w) - b * sin(w);
  2462. img.loadPixels();
  2463. result.loadPixels();
  2464. for ( int i = 0, l = img.pixels.length; i<l; i++) {
  2465. int[] rgb = new int[3];
  2466. rgb[0] = (int)red(img.pixels[i]);
  2467. rgb[1] = (int)green(img.pixels[i]);
  2468. rgb[2] = (int)blue(img.pixels[i]);
  2469. for ( int ri = 0; ri<3; ri++ ) {
  2470. float in = map(rgb[ri], 0, 255, 0, 1);
  2471. float out = (b0Bass * in + b1Bass * xn1Bass + b2Bass * xn2Bass - a1Bass * yn1Bass - a2Bass * yn2Bass ) / a0Bass;
  2472. //println(a0Bass);
  2473. xn2Bass = xn1Bass;
  2474. xn1Bass = in;
  2475. yn2Bass = yn1Bass;
  2476. yn1Bass = out;
  2477. //treble filter
  2478. in = out;
  2479. out = (b0Treble * in + b1Treble * xn1Treble + b2Treble * xn2Treble - a1Treble * yn1Treble - a2Treble * yn2Treble) / a0Treble;
  2480. xn2Treble = xn1Treble;
  2481. xn1Treble = in;
  2482. yn2Treble = yn1Treble;
  2483. yn1Treble = out;
  2484. //retain max value for use in normalization
  2485. if ( mMax < abs(out))
  2486. mMax = abs(out);
  2487. rgb[ri] = (int)map(out, 0, 1, 0, 255);
  2488. }
  2489. result.pixels[i] = color(rgb[0], rgb[1], rgb[2]);
  2490. }
  2491. result.updatePixels();
  2492. return result;
  2493. }
  2494. }
  2495. /*
  2496. LZ7
  2497. */
  2498. class LZ7 extends Shader {
  2499. // choose colorspace
  2500. int colorspace = HSB; // HSB or RGB
  2501. // set compressor attributes for each channel in chosen colorspace
  2502. // first number is length of dictionary in LZ77 - values 100 - 4000
  2503. // second number is length of word (ahead buffer) in LZ77 - about 5% - 50% of dictionary size
  2504. int[][] compressor_attributes = { {2000, 250}, // channel 1 (H or R)
  2505. {50, 10}, // channel 2 (S or G)
  2506. {100, 100} }; // channel 3 (B or B)
  2507. // set number of glitches made for each channel
  2508. // first number is actual number of random change in compressed channel
  2509. // second number is amount of change (values from 0.01 to 4)
  2510. float[][] number_of_glitches = { {5000, 2}, // channel 1
  2511. {500, 1}, // channel 2
  2512. {50, 0.1} }; // channel 3
  2513. // working buffer
  2514. PGraphics buffer;
  2515. // image
  2516. PImage img;
  2517. boolean do_blend = false; // blend image after process
  2518. int blend_mode = OVERLAY; // blend type
  2519. LZ77 comp1, comp2, comp3;
  2520. byte[] cr, cb, cg;
  2521. //red channel dictionary size
  2522. //red channel word size
  2523. //red channel randomness
  2524. //red channel amount of change
  2525. LZ7() {
  2526. name = "fxLZ77";
  2527. params.add(new Param("dictionary size (red/hue)", INTVAL, 100, 3000, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  2528. params.add(new Param("word length (red/hue)", FLOATVAL, 0.05, 0.5, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  2529. params.add(new Param("randomness (red/hue)", INTVAL, 20, 5000, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  2530. params.add(new Param("amount of change (red/hue)", FLOATVAL, 0.01, 4, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  2531. params.add(new Param("dictionary size (green/saturation)", INTVAL, 100, 3000, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  2532. params.add(new Param("word length (green/saturation)", FLOATVAL, 0.05, 0.5, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  2533. params.add(new Param("randomness (green/saturation)", INTVAL, 20, 5000, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  2534. params.add(new Param("amount of change (green/saturation)", FLOATVAL, 0.01, 4, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  2535. params.add(new Param("dictionary size (blue/brightness)", INTVAL, 100, 3000, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  2536. params.add(new Param("word length (blue/brightness)", FLOATVAL, 0.05, 0.5, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  2537. params.add(new Param("randomness (blue/brightness)", INTVAL, 20, 5000, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  2538. params.add(new Param("amount of change (blue/brightness)", FLOATVAL, 0.01, 4, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  2539. params.add(new Param("colorspace (rgb / hsb)", INTVAL, 0, 1, new int[]{RANDOM, SQUAR}));
  2540. params.add(new Param("do blend", INTVAL, 0, 1, new int[]{RANDOM, SQUAR}));
  2541. params.add(new Param("blend mode", INTVAL, 0, blends.length-1, new int[]{RANDOM}));
  2542. params.add(new Param("direction", INTVAL, 0, 3, new int[]{RANDOM}));
  2543. directionParamIndex = 15;
  2544. rw = canvas.width;
  2545. rh = canvas.height;
  2546. buffer = createGraphics(rw, rh);
  2547. buffer.beginDraw();
  2548. buffer.noStroke();
  2549. //buffer.smooth(8);
  2550. buffer.background(0);
  2551. buffer.endDraw();
  2552. img = createImage(canvas.width, canvas.height, RGB);
  2553. cr = new byte[rw*rh];
  2554. cb = new byte[rw*rh];
  2555. cg = new byte[rw*rh];
  2556. }
  2557. int rw, rh;
  2558. void apply() {
  2559. if (rw != canvas.width || rh != canvas.height) {
  2560. rw = canvas.width;
  2561. rh = canvas.height;
  2562. cr = new byte[rw*rh];
  2563. cb = new byte[rw*rh];
  2564. cg = new byte[rw*rh];
  2565. buffer = createGraphics(rw, rh);
  2566. img.resize(rw, rh);
  2567. }
  2568. img = canvas.get();
  2569. colorspace = (int)params.get(12).value == 0 ?RGB:HSB;
  2570. do_blend = boolean((int)params.get(13).value);
  2571. blend_mode = blends[(int)params.get(14).value];
  2572. //red
  2573. compressor_attributes[0][0] = (int)params.get(0).value;
  2574. compressor_attributes[0][1] = (int)(params.get(1).value*compressor_attributes[0][0]);
  2575. number_of_glitches[0][0] = (int)params.get(2).value;
  2576. number_of_glitches[0][1] = params.get(3).value;
  2577. //green
  2578. compressor_attributes[1][0] = (int)params.get(4).value;
  2579. compressor_attributes[1][1] = (int)(params.get(5).value*compressor_attributes[1][0]);
  2580. number_of_glitches[1][0] = (int)params.get(6).value;
  2581. number_of_glitches[1][1] = params.get(7).value;
  2582. //blue
  2583. compressor_attributes[2][0] = (int)params.get(8).value;
  2584. compressor_attributes[2][1] = (int)(params.get(9).value*compressor_attributes[2][0]);
  2585. number_of_glitches[2][0] = (int)params.get(10).value;
  2586. number_of_glitches[2][1] = params.get(11).value;
  2587. comp1 = new LZ77( compressor_attributes[0][0], compressor_attributes[0][1] );
  2588. comp2 = new LZ77( compressor_attributes[1][0], compressor_attributes[1][1] );
  2589. comp3 = new LZ77( compressor_attributes[2][0], compressor_attributes[2][1] );
  2590. buffer.beginDraw();
  2591. //print("Preparing... ");
  2592. img.loadPixels();
  2593. int iter=0;
  2594. for (int i=0; i<img.pixels.length; i++) {
  2595. color c = img.pixels[i];
  2596. if (colorspace == HSB) {
  2597. cr[iter]= (byte)hue(c);
  2598. cg[iter]= (byte)saturation(c);
  2599. cb[iter]= (byte)brightness(c);
  2600. } else {
  2601. cr[iter]= (byte)red(c);
  2602. cg[iter]= (byte)green(c);
  2603. cb[iter]= (byte)blue(c);
  2604. }
  2605. iter++;
  2606. }
  2607. //println("done");
  2608. //print("Glitching channel 1... ");
  2609. comp1.doCompress(cr);
  2610. comp1.glitch( (int)number_of_glitches[0][0], number_of_glitches[0][1] );
  2611. comp1.doDecompress(cr);
  2612. //println("done");
  2613. //print("Glitching channel 2... ");
  2614. comp2.doCompress(cg);
  2615. comp2.glitch( (int)number_of_glitches[1][0], number_of_glitches[1][1] );
  2616. comp2.doDecompress(cg);
  2617. //println("done");
  2618. //print("Glitching channel 3... ");
  2619. comp3.doCompress(cb);
  2620. comp3.glitch( (int)number_of_glitches[2][0], number_of_glitches[2][1] );
  2621. comp3.doDecompress(cb);
  2622. //println("done");
  2623. for (int i = 0; i < 3; i++) {
  2624. //println("Channel "+(i+1)+" = ("+compressor_attributes[i][0]+","+compressor_attributes[i][1]+")" + ", glitches = ("+number_of_glitches[i][0]+","+number_of_glitches[i][1]+")");
  2625. }
  2626. buffer.loadPixels();
  2627. if (colorspace == HSB) colorMode(HSB);
  2628. else colorMode(RGB);
  2629. iter=0;
  2630. for (int i=0; i<buffer.pixels.length; i++) {
  2631. float r = cr[iter];
  2632. r = r>=0?r:r+256;
  2633. float g = cg[iter];
  2634. g = g>=0?g:g+256;
  2635. float b = cb[iter];
  2636. b = b>=0?b:b+256;
  2637. buffer.pixels[i] = color(r, g, b);
  2638. iter++;
  2639. }
  2640. buffer.updatePixels();
  2641. if (do_blend)
  2642. buffer.blend(img, 0, 0, img.width, img.height, 0, 0, buffer.width, buffer.height, blend_mode);
  2643. buffer.endDraw();
  2644. canvas.beginDraw();
  2645. canvas.image(buffer, canvas.width/2, canvas.height/2);
  2646. canvas.endDraw();
  2647. }
  2648. }
  2649. class Tuple {
  2650. public int offset, len;
  2651. byte chr;
  2652. public Tuple(int o, int l, byte c) {
  2653. offset = o;
  2654. len = l;
  2655. chr = c;
  2656. }
  2657. }
  2658. class LZ77 {
  2659. int windowWidth;
  2660. int lookAheadWidht;
  2661. public LZ77(int ww, int law) {
  2662. windowWidth = ww;
  2663. lookAheadWidht = law;
  2664. }
  2665. ArrayList<Tuple> clist = new ArrayList<Tuple>();
  2666. public void glitch(int no, float fac) {
  2667. for (int i=0; i<no; i++) {
  2668. Tuple r = clist.get( (int)random(clist.size()));
  2669. int what = (int)random(3);
  2670. switch(what) {
  2671. case 0:
  2672. r.chr = (byte)random(256);
  2673. break;
  2674. case 1:
  2675. r.offset = (int)random(2*windowWidth*fac);
  2676. break;
  2677. default:
  2678. r.len = (int)random(2*lookAheadWidht*fac);
  2679. }
  2680. }
  2681. }
  2682. public void doCompress(byte[] buff) {
  2683. int currByte = 1;
  2684. // first is always byte
  2685. clist.add( new Tuple(0, 0, buff[0]) );
  2686. while (currByte < buff.length) {
  2687. int bend = constrain(currByte-windowWidth, 0, buff.length);
  2688. int boff = 0;
  2689. int blen = 0;
  2690. if (currByte<buff.length-1)
  2691. for (int i = currByte-1; i>=bend; i--) {
  2692. if (buff[currByte] == buff[i]) {
  2693. int tboff = abs(i-currByte);
  2694. int tblen = 1;
  2695. int laEnd = constrain(currByte+lookAheadWidht, 0, buff.length-1);
  2696. int mi = currByte+1;
  2697. while (mi<laEnd && (i+mi-currByte)<currByte) {
  2698. if (buff[mi] == buff[i+mi-currByte]) {
  2699. mi++;
  2700. tblen++;
  2701. } else {
  2702. break;
  2703. }
  2704. }
  2705. if (tblen>blen) {
  2706. blen = tblen;
  2707. boff = tboff;
  2708. }
  2709. }
  2710. }
  2711. currByte +=blen+1;
  2712. // println("currchar = " + (currByte-1)+",blen = " + blen);
  2713. clist.add( new Tuple(boff, blen, buff[currByte-1]) );
  2714. // println(boff + ", " + blen + ", " + buff[currByte-1]);
  2715. }
  2716. //println("clist " + clist.size()*2);
  2717. }
  2718. void doDecompress(byte[] buff) {
  2719. int i = 0;
  2720. for (Tuple t : clist) {
  2721. if (i>=buff.length) break;
  2722. if (t.offset == 0) {
  2723. buff[i++] = t.chr;
  2724. } else {
  2725. int start = i-t.offset;
  2726. int end = start + t.len;
  2727. for (int c = start; c<end; c++) {
  2728. int pos = constrain(c, 0, buff.length-1);
  2729. buff[constrain(i++, 0, buff.length-1)] = buff[pos];
  2730. if (i>=buff.length) break;
  2731. }
  2732. if (i>=buff.length) break;
  2733. buff[i++] = t.chr;
  2734. }
  2735. }
  2736. }
  2737. }
  2738. /*
  2739. LENS
  2740. */
  2741. class LENS extends Shader {
  2742. // parameters
  2743. float bendx = 0.1; // from 0 to 1
  2744. float bendy = 0.1; // from 0 to 1
  2745. float[] power_vals = { 2, 0.5 }; // two values of power from 0.1 to 10, one for x and second for y
  2746. int[] types = { LINEAR, POWER }; // always to types one for x second for y
  2747. int[] channels = { BRIGHTNESS, SATURATION }; // as above
  2748. float[] facts = new float[2];
  2749. //////////////
  2750. PImage img;
  2751. PImage limg;
  2752. int shaderListLength;
  2753. // working buffer
  2754. PGraphics buffer;
  2755. LENS() {
  2756. name = "fxLens";
  2757. shaderListLength = gui.shaderList.size();
  2758. params.add(new Param("lens image layer", INTVAL, 0, shaderListLength-1, new int[]{RANDOM}));
  2759. params.add(new Param("power x", FLOATVAL, 0.1, 10, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  2760. params.add(new Param("power y", FLOATVAL, 0.1, 10, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  2761. params.add(new Param("lens type x", INTVAL, 0, 3, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  2762. params.add(new Param("lens type y", INTVAL, 0, 3, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  2763. params.add(new Param("channel x", INTVAL, 0, 11, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  2764. params.add(new Param("channel y", INTVAL, 0, 11, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  2765. params.add(new Param("curvature factor x", FLOATVAL, 0.01, 1, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  2766. params.add(new Param("curvature factor y", FLOATVAL, 0.01, 1, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  2767. params.add(new Param("direction", INTVAL, 0, 3, new int[]{RANDOM}));
  2768. directionParamIndex = 9;
  2769. rw = canvas.width;
  2770. rh = canvas.height;
  2771. img = createImage(rw, rh, ARGB);
  2772. limg = createImage(rw, rh, ARGB);
  2773. buffer = createGraphics(rw, rh);
  2774. buffer.beginDraw();
  2775. buffer.noStroke();
  2776. buffer.endDraw();
  2777. }
  2778. int rw, rh;
  2779. void apply() {
  2780. if (rw != canvas.width || rh != canvas.height) {
  2781. rw = canvas.width;
  2782. rh = canvas.height;
  2783. buffer = createGraphics(rw, rh);
  2784. buffer.beginDraw();
  2785. buffer.noStroke();
  2786. buffer.endDraw();
  2787. img.resize(rw, rh);
  2788. limg.resize(rw, rh);
  2789. }
  2790. if (shaderListLength != gui.shaderList.size()) {
  2791. shaderListLength = gui.shaderList.size();
  2792. changeParam(0, new Param("lens image layer", INTVAL, 0, shaderListLength-1, new int[]{RANDOM}));
  2793. }
  2794. img = canvas.get();
  2795. if ((int)params.get(0).value == pos) {
  2796. limg = canvas.get();
  2797. } else {
  2798. limg = gui.shaderList.get((int)params.get(0).value).result.get();
  2799. }
  2800. power_vals[0] = params.get(1).value;
  2801. power_vals[1] = params.get(2).value;
  2802. types[0] = (int)params.get(3).value;
  2803. types[1] = (int)params.get(4).value;
  2804. channels[0] = (int)params.get(5).value;
  2805. channels[1] = (int)params.get(6).value;
  2806. bendx = params.get(7).value;
  2807. bendy = params.get(8).value;
  2808. facts[0] = bendx * img.width;
  2809. facts[1] = bendy * img.height;
  2810. img.loadPixels();
  2811. limg.loadPixels();
  2812. buffer.beginDraw();
  2813. buffer.background(0);
  2814. for (int x=0; x<img.width; x++) {
  2815. int lx = (int)map(x, 0, img.width-1, 0, limg.width-1);
  2816. for (int y=0; y<img.height; y++) {
  2817. int ly = (int)map(y, 0, img.height-1, 0, limg.height-1);
  2818. color c = limg.pixels[lx+ly*limg.width];
  2819. int posx = (x+getShift(c, 0)+2*img.width)%img.width;
  2820. int posy = (y+getShift(c, 1)+2*img.height)%img.height;
  2821. color n = img.pixels[posx+posy*img.width];
  2822. buffer.fill(n);
  2823. // fill(red(c),green(c),blue(n)); // work only on blue channel
  2824. // fill(red(n), abs(green(c)-green(n)), blue(n)); // green channel is blended using difference method
  2825. buffer.rect(x, y, 1, 1);
  2826. }
  2827. }
  2828. buffer.endDraw();
  2829. img.updatePixels();
  2830. limg.updatePixels();
  2831. canvas.beginDraw();
  2832. canvas.image(buffer, canvas.width/2, canvas.height/2);
  2833. canvas.endDraw();
  2834. }
  2835. float getChannel(color c, int channel) {
  2836. int ch = channel>5?channel-6:channel;
  2837. float cc;
  2838. switch(ch) {
  2839. case RED:
  2840. cc = red(c);
  2841. break;
  2842. case GREEN:
  2843. cc = green(c);
  2844. break;
  2845. case BLUE:
  2846. cc = blue(c);
  2847. break;
  2848. case HUE:
  2849. cc = hue(c);
  2850. break;
  2851. case SATURATION:
  2852. cc = saturation(c);
  2853. break;
  2854. default:
  2855. cc= brightness(c);
  2856. break;
  2857. }
  2858. return channel>5?255-cc:cc;
  2859. }
  2860. int getShift(color c, int idx) {
  2861. float cc = getChannel(c, channels[idx]);
  2862. switch(types[idx]) {
  2863. case LINEAR:
  2864. return (int)(facts[idx] * cc/255.0);
  2865. case POWER:
  2866. return (int)(facts[idx]*map(pow(cc/255.0, power_vals[idx]), 0, 1, -1, 1));
  2867. case SINUSOIDAL:
  2868. return (int)(facts[idx]*sin(map(cc, 0, 255, -PI, PI)));
  2869. default:
  2870. { // POLAR
  2871. float c1 = idx==0?cc:getChannel(c, channels[1]);
  2872. float c2 = idx==1?cc:getChannel(c, channels[0]);
  2873. float ang = map(c1, 0, 255, 0, TWO_PI);
  2874. float r = map(c2, 0, 255, 0, facts[0]);
  2875. return (int)(idx==0?r*cos(ang):r*sin(ang));
  2876. }
  2877. }
  2878. }
  2879. }
  2880. /*
  2881. SLICER
  2882. */
  2883. class SLICER extends Shader {
  2884. ArrayList<Edge> edges = new ArrayList<Edge>();
  2885. SegmentNode[] elements;
  2886. Map<Integer, S> m = new HashMap<Integer, S>();
  2887. int max_patterns = 20; // CAN I KILL THIS?
  2888. float max_rotation = TWO_PI; // random or fixed rotation up to specified angle, 0 - TWO_PI, 0 - no rotation
  2889. boolean fixed_rotation = true; // fixed or random rotation
  2890. int thr_min = -1; // you can change color of segment for specified brightness threshold
  2891. int thr_max = -1; // set to -1 if you don't want to use it, values from 0 to 255
  2892. color[] palette = { #000000, #E7CBB3, #CEC6AF, #A0C3BC, #7C7F84, #ffffff }; // choose colors for palette you want to use with threshold, colors will be choosen randomly
  2893. // SEPARATE config
  2894. float max_shift = 2; // max expected shift, using gaussian random, so bigger number, more distortion
  2895. int type = ROTATE; // choose type of distortion: PATTERNS, SEPARATE, ROTATE, SHIFTCOPY, SORT
  2896. boolean do_blend = false; // blend result with original?
  2897. int blend_type = SUBTRACT; // list here: https://processing.org/reference/blend_.html
  2898. // segmentation config START
  2899. float threshold = 500.0; // higher number - bigger segments
  2900. int min_comp_size = 200; // minimal segment size (in pixels), minimum 10
  2901. int blur = 0; // sometimes it's good to blur image to have less sharp segment edges, 0 = off, blur > 0 - blur kernel size
  2902. int stat_type = DIST; // edge calculation method
  2903. final static int DIST = 0;
  2904. final static int HUE = 1;
  2905. final static int BRIGHTNESS = 2;
  2906. final static int SATURATION = 3;
  2907. final static int ABSDIST = 4;
  2908. // do not touch it
  2909. PImage img, mimg; // load image to this variable
  2910. int num;
  2911. // segmentation config END
  2912. // do not touch, list of types
  2913. final static int PATTERNS = 0; // fill segments with patterns
  2914. final static int SEPARATE = 1; // separate segments (black background visible)
  2915. final static int ROTATE = 2; // rotate content of the segments
  2916. final static int SHIFTCOPY = 3; // copy content from shifted image
  2917. final static int SORT = 4; // sort segments by color value
  2918. // working buffer
  2919. PGraphics buffer;
  2920. SLICER() {
  2921. name = "fxSlicer";
  2922. params.add(new Param("mask layer", INTVAL, 0, shaderListLength-1, new int[]{RANDOM}));
  2923. params.add(new Param("max rotation", FLOATVAL, 0, TWO_PI, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  2924. params.add(new Param("min threshold", INTVAL, -1, 255, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  2925. params.add(new Param("max threshold", INTVAL, -1, 255, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  2926. params.add(new Param("max shift", FLOATVAL, 0, 5, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  2927. params.add(new Param("type", INTVAL, 0, 5, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  2928. params.add(new Param("do blend", INTVAL, 0, 1, new int[]{RANDOM, SQUAR}));
  2929. params.add(new Param("blend type", INTVAL, 0, blends.length-1, new int[]{RANDOM}));
  2930. params.add(new Param("threshold", FLOATVAL, 100, 2000, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  2931. params.add(new Param("min comp size", INTVAL, 10, 500, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  2932. params.add(new Param("blur", INTVAL, 0, 6, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  2933. params.add(new Param("stat type", INTVAL, 0, 6, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  2934. params.add(new Param("fixed rotation", INTVAL, 0, 1, new int[]{RANDOM, SQUAR}));
  2935. params.add(new Param("direction", INTVAL, 0, 3, new int[]{RANDOM}));
  2936. directionParamIndex = 13;
  2937. shaderListLength = gui.shaderList.size();
  2938. img = createImage(canvas.width, canvas.height, ARGB);
  2939. mimg = createImage(canvas.width, canvas.height, ARGB);
  2940. buffer = createGraphics(img.width, img.height);
  2941. buffer.beginDraw();
  2942. buffer.noStroke();
  2943. buffer.smooth(8);
  2944. buffer.background(0);
  2945. buffer.endDraw();
  2946. }
  2947. int rw, rh, shaderListLength;
  2948. void apply() {
  2949. if (canvas.width != rw || canvas.height != rh) {
  2950. rw = canvas.width;
  2951. rh = canvas.height;
  2952. buffer = createGraphics(rw, rh);
  2953. buffer.beginDraw();
  2954. buffer.noStroke();
  2955. buffer.endDraw();
  2956. img.resize(rw, rh);
  2957. mimg.resize(rw, rh);
  2958. }
  2959. if (shaderListLength != gui.shaderList.size()) {
  2960. shaderListLength = gui.shaderList.size();
  2961. changeParam(0, new Param("mask layer", INTVAL, 0, shaderListLength-1, new int[]{RANDOM}));
  2962. }
  2963. img = canvas.get();
  2964. if ((int)params.get(0).value == pos) {
  2965. mimg = canvas.get();
  2966. } else {
  2967. mimg = gui.shaderList.get((int)params.get(0).value).result.get();
  2968. }
  2969. max_rotation = params.get(1).value;
  2970. thr_min = (int)params.get(2).value;
  2971. thr_max = (int)params.get(3).value;
  2972. max_shift = params.get(4).value;
  2973. type = (int)params.get(5).value;
  2974. do_blend = boolean((int)params.get(6).value);
  2975. blend_type = blends[(int)params.get(7).value];
  2976. threshold = params.get(8).value;
  2977. min_comp_size = (int)params.get(9).value;
  2978. blur = (int)params.get(10).value;
  2979. stat_type = (int)params.get(11).value;
  2980. fixed_rotation = boolean((int)params.get(12).value);
  2981. //println("");
  2982. //println("Processing...");
  2983. edges.clear();
  2984. makeEdges();
  2985. calculateSegmentation();
  2986. buffer.beginDraw();
  2987. m.clear();
  2988. if (type == PATTERNS) preparePatterns();
  2989. for (int x=0; x<img.width; x++)
  2990. for (int y=0; y<img.height; y++) {
  2991. Integer segment = findEnd(y*img.width+x);
  2992. S segm;
  2993. if (m.containsKey(segment)) {
  2994. segm = m.get(segment);
  2995. if (type == SORT) sortHelper(segm, x, y);
  2996. } else {
  2997. segm = new S();
  2998. segm.rots = sin(fixed_rotation?max_rotation:random(max_rotation));
  2999. segm.rotc = cos(fixed_rotation?max_rotation:random(max_rotation));
  3000. segm.c = img.get(x, y);
  3001. segm.dx = (int)(max_shift*randomGaussian());
  3002. segm.dy = (int)(max_shift*randomGaussian());
  3003. segm.x = x;
  3004. segm.y = y;
  3005. if (brightness(segm.c)>=thr_min && brightness(segm.c)<=thr_max) segm.c = palette[(int)random(palette.length)];
  3006. if (type == PATTERNS) {
  3007. segm.pat = patterns[(int)random(max_patterns)];
  3008. segm.pats = random(0.5, 10);
  3009. }
  3010. if (type == SORT) {
  3011. segm.xy = random(1)<0.5;
  3012. int size = elements[segment].size;
  3013. segm.clrs = new color[size];
  3014. segm.positions = new int[size];
  3015. segm.iters = 0;
  3016. sortHelper(segm, x, y);
  3017. }
  3018. m.put(segment, segm);
  3019. }
  3020. if (type == PATTERNS) {
  3021. int vx = segm.x-x;
  3022. int vy = segm.y-y;
  3023. float sinr = segm.rots;
  3024. float cosr = segm.rotc;
  3025. int imgx = int(segm.pat.width+x+(cosr*vx-sinr*vy))%segm.pat.width;
  3026. int imgy = int(segm.pat.height+x+(sinr*vx+cosr*vy))%segm.pat.height;
  3027. buffer.fill(segm.pat.get(imgx, imgy));
  3028. buffer.rect(x, y, 1, 1);
  3029. } else if (type == SEPARATE) {
  3030. buffer.fill(segm.c);
  3031. buffer.rect(x+segm.dx, y+segm.dy, 1, 1);
  3032. } else if (type == SHIFTCOPY) {
  3033. int imgx = (2*x-segm.x)%img.width;
  3034. int imgy = (2*y-segm.y)%img.height;
  3035. buffer.fill(img.get(imgx, imgy));
  3036. buffer.rect(x, y, 1, 1);
  3037. } else if (type == ROTATE) {
  3038. int vx = segm.x-x;
  3039. int vy = segm.y-y;
  3040. float sinr = segm.rots;
  3041. float cosr = segm.rotc;
  3042. int imgx = int(img.width+x+(cosr*vx-sinr*vy))%img.width;
  3043. int imgy = int(img.height+y+(sinr*vx+cosr*vy))%img.height;
  3044. buffer.fill(img.get(imgx, imgy));
  3045. buffer.rect(x, y, 1, 1);
  3046. }
  3047. }
  3048. if (type == SORT) {
  3049. for (Integer key : m.keySet()) {
  3050. S segm = m.get(key);
  3051. segm.clrs = sort(segm.clrs);
  3052. segm.positions = sort(segm.positions);
  3053. }
  3054. for (Integer key : m.keySet()) {
  3055. S segm = m.get(key);
  3056. for (int i=0; i<segm.positions.length; i++) {
  3057. int x, y;
  3058. if (segm.xy) {
  3059. x = (segm.positions[i] >> 16) & 0xffff;
  3060. y = segm.positions[i] & 0xffff;
  3061. } else {
  3062. y = (segm.positions[i] >> 16) & 0xffff;
  3063. x = segm.positions[i] & 0xffff;
  3064. }
  3065. buffer.fill(segm.clrs[i]);
  3066. buffer.rect(x, y, 1, 1);
  3067. }
  3068. }
  3069. }
  3070. if (do_blend)
  3071. buffer.blend(img, 0, 0, img.width, img.height, 0, 0, buffer.width, buffer.height, blend_type);
  3072. buffer.endDraw();
  3073. canvas.beginDraw();
  3074. canvas.image(buffer, canvas.width/2, canvas.height/2);
  3075. canvas.endDraw();
  3076. }
  3077. void sortHelper(S segm, int x, int y) {
  3078. int xyval;
  3079. if (segm.xy)
  3080. xyval = (x << 16) | y;
  3081. else
  3082. xyval = (y << 16) | x;
  3083. segm.clrs[segm.iters] = img.get(x, y);
  3084. segm.positions[segm.iters++] = xyval;
  3085. }
  3086. final float getStat(color c1, color c2) {
  3087. switch(stat_type) {
  3088. case HUE:
  3089. abs(hue(c1)-hue(c2));
  3090. case BRIGHTNESS:
  3091. abs(brightness(c1)-brightness(c2));
  3092. case SATURATION:
  3093. abs(saturation(c1)-saturation(c2));
  3094. case ABSDIST:
  3095. return abs(red(c1)-red(c2)) + abs(green(c1)-green(c2)) + abs(blue(c1)-blue(c2));
  3096. default:
  3097. return sq(red(c1)-red(c2)) + sq(green(c1)-green(c2)) + sq(blue(c1)-blue(c2));
  3098. }
  3099. }
  3100. void makeEdges() {
  3101. PImage img2 = mimg.get(0, 0, img.width, img.height);
  3102. if (blur > 0) img2.filter(BLUR, blur);
  3103. // make grid each point connected to neighbours
  3104. for (int x=0; x<img2.width; x++)
  3105. for (int y=0; y<img2.height; y++) {
  3106. color c = img2.get(x, y);
  3107. if (x<img2.width-1) {
  3108. Edge e = new Edge();
  3109. e.a = y*img2.width+x;
  3110. e.b = y*img2.width+x+1;
  3111. e.weight = getStat(c, img2.get(x+1, y));
  3112. edges.add(e);
  3113. }
  3114. if (y<img2.height-1) {
  3115. Edge e = new Edge();
  3116. e.a = y*img2.width+x;
  3117. e.b = (y+1)*img2.width+x;
  3118. e.weight = getStat(c, img2.get(x, y+1));
  3119. edges.add(e);
  3120. }
  3121. if ( (x<img2.width-1) && (y<img2.height-1)) {
  3122. Edge e = new Edge();
  3123. e.a = y*img2.width+x;
  3124. e.b = (y+1)*img2.width+x+1;
  3125. e.weight = getStat(c, img2.get(x+1, y+1));
  3126. edges.add(e);
  3127. }
  3128. if ( (x<img2.width-1) && (y>0)) {
  3129. Edge e = new Edge();
  3130. e.a = y*img2.width+x;
  3131. e.b = (y-1)*img2.width+x+1;
  3132. e.weight = getStat(c, img2.get(x+1, y-1));
  3133. edges.add(e);
  3134. }
  3135. }
  3136. // sort edges
  3137. Collections.sort(edges);
  3138. }
  3139. int findEnd(int x) {
  3140. int y = x;
  3141. while (y != elements[y].parent) y = elements[y].parent;
  3142. elements[x].parent = y;
  3143. return y;
  3144. }
  3145. void joinSegments(int x, int y) {
  3146. if (elements[x].rank > elements[y].rank) {
  3147. elements[y].parent = x;
  3148. elements[x].size += elements[y].size;
  3149. } else {
  3150. elements[x].parent = y;
  3151. elements[y].size += elements[x].size;
  3152. if (elements[x].rank == elements[y].rank) elements[y].rank++;
  3153. }
  3154. num--;
  3155. }
  3156. void calculateSegmentation() {
  3157. int no_vertices = img.width*img.height;
  3158. num = no_vertices;
  3159. elements = new SegmentNode[no_vertices];
  3160. // init nodes
  3161. for (int i=0; i<no_vertices; i++) {
  3162. SegmentNode s = new SegmentNode();
  3163. s.rank = 0;
  3164. s.size = 1;
  3165. s.parent = i;
  3166. elements[i]=s;
  3167. }
  3168. float[] thresholds = new float[no_vertices];
  3169. Arrays.fill(thresholds, threshold);
  3170. for (Edge edge : edges) {
  3171. int a = findEnd(edge.a);
  3172. int b = findEnd(edge.b);
  3173. if (a!=b) {
  3174. if (edge.weight <= thresholds[a] && edge.weight <= thresholds[b]) {
  3175. joinSegments(a, b);
  3176. a = findEnd(a);
  3177. thresholds[a] = edge.weight + threshold/elements[a].size;
  3178. }
  3179. }
  3180. }
  3181. for (Edge edge : edges) {
  3182. int a = findEnd(edge.a);
  3183. int b = findEnd(edge.b);
  3184. if ( (a != b) && ((elements[a].size < min_comp_size) || (elements[b].size < min_comp_size))) {
  3185. joinSegments(a, b);
  3186. }
  3187. }
  3188. //println("Segments: " +num);
  3189. }
  3190. PImage[] patterns;
  3191. void preparePatterns() {
  3192. patterns = new PImage[max_patterns];
  3193. for (int i=0; i<max_patterns; i++) {
  3194. patterns[i] = getSelfPattern();
  3195. }
  3196. }
  3197. PImage getSelfPattern() {
  3198. int x = (int)random(img.width-50);
  3199. int y = (int)random(img.height-50);
  3200. int sx = (int)random(50, img.width-x-1);
  3201. int sy = (int)random(50, img.height-y-1);
  3202. return img.get(x, y, sx, sy);
  3203. }
  3204. PImage getLayerPattern(int layer) { //use me
  3205. int x = (int)random(gui.shaderList.get(layer).canvas.width-50);
  3206. int y = (int)random(gui.shaderList.get(layer).canvas.height-50);
  3207. int sx = (int)random(50, gui.shaderList.get(layer).canvas.width-x-1);
  3208. int sy = (int)random(50, gui.shaderList.get(layer).canvas.height-y-1);
  3209. return gui.shaderList.get(layer).canvas.get(x, y, sx, sy);
  3210. }
  3211. }
  3212. // general class to save distortions for particular segment
  3213. class S {
  3214. color c; // color of the segment root point
  3215. int x, y; // position of segment root point
  3216. int dx, dy; // segment shift
  3217. float rots, rotc, pats;
  3218. PImage pat;
  3219. // sort
  3220. color[] clrs;
  3221. int[] positions;
  3222. boolean xy;
  3223. int iters;
  3224. }
  3225. class Edge implements Comparable {
  3226. int a, b;
  3227. float weight;
  3228. int compareTo(Object o) {
  3229. Edge e = (Edge)o;
  3230. return this.weight<e.weight?-1:this.weight>e.weight?1:0;
  3231. }
  3232. }
  3233. class SegmentNode {
  3234. int rank, parent, size;
  3235. }
  3236. /*
  3237. STREAKER
  3238. */
  3239. class STREAKER extends Shader {
  3240. final int EXCLUSIVE = 0;
  3241. final int LESSER = 1;
  3242. final int GREATER = 2;
  3243. final int CLASSIC = 0;
  3244. final int RGBSUM = 1;
  3245. final int BRIGHT = 2;
  3246. PImage img;
  3247. float tol = 100.0; // tolerance
  3248. int mode = LESSER; // EXCLUSIVE, LESSER, GREATER
  3249. int sum = BRIGHT; // CLASSIC, RGBSUM, BRIGHT
  3250. int lim = 1; // move divisor
  3251. int iterations = 1;
  3252. float rand = 5;
  3253. boolean h = false;
  3254. boolean v = true;
  3255. boolean Hrev = false;
  3256. boolean Vrev = false;
  3257. int W, H;
  3258. STREAKER() {
  3259. name = "fxStreaker";
  3260. img = createImage(canvas.width, canvas.height, ARGB);
  3261. params.add(new Param("vertical/horizontal/both", INTVAL, 0, 2, new int[]{RANDOM}));
  3262. params.add(new Param("verticals up / down", INTVAL, 0, 1, new int[]{RANDOM, SQUAR}));
  3263. params.add(new Param("horicontals up / down", INTVAL, 0, 1, new int[]{RANDOM, SQUAR}));
  3264. params.add(new Param("tolerance", FLOATVAL, 0, 100, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  3265. params.add(new Param("tolerance randomness", FLOATVAL, 0, 50, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  3266. params.add(new Param("detection mode (EXCLUSIVE, LESSER, GREATER)", INTVAL, 0, 2, new int[]{RANDOM}));
  3267. params.add(new Param("sum (RBG sum, brightness, R>G>B)", INTVAL, 0, 2, new int[]{RANDOM}));
  3268. params.add(new Param("move divisor", INTVAL, 1, 5, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  3269. params.add(new Param("iterations", INTVAL, 1, 10, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  3270. params.add(new Param("direction", INTVAL, 0, 3, new int[]{RANDOM}));
  3271. directionParamIndex = 9;
  3272. W = canvas.width;
  3273. H = canvas.height;
  3274. }
  3275. void apply() {
  3276. if (W != canvas.width || H != canvas.height) {
  3277. W = canvas.width;
  3278. H = canvas.height;
  3279. img.resize(W, H);
  3280. }
  3281. img = canvas.get();
  3282. int p0 = (int)params.get(0).value;
  3283. v = (p0 == 0 || p0 == 2) ? true : false;
  3284. h = (p0 == 1 || p0 == 2) ? true : false;
  3285. Vrev = boolean((int)params.get(1).value);
  3286. Hrev = boolean((int)params.get(2).value);
  3287. tol = params.get(3).value;
  3288. rand = params.get(4).value;
  3289. mode = (int)params.get(5).value;
  3290. sum = (int)params.get(6).value;
  3291. lim = (int)params.get(7).value;
  3292. iterations = (int)params.get(8).value;
  3293. PGraphics temp = createGraphics(img.width, img.height);
  3294. int off = 0;
  3295. color c;
  3296. boolean a = false;
  3297. for (int i = 0; i < iterations; i++) {
  3298. img.loadPixels();
  3299. temp.beginDraw();
  3300. temp.image(img, 0, 0);
  3301. if (h) {
  3302. if (!Hrev) {
  3303. for (int y = 0; y < img.height-1; y++) {
  3304. for (int x = 0; x < img.width-1; x++) {
  3305. c = img.pixels[x+(y*img.width)];
  3306. while (check (x, y, x+off+1, y) == true && x+off+1 < img.width) {
  3307. off++;
  3308. a = true;
  3309. }
  3310. if (a) {
  3311. temp.stroke(c);
  3312. temp.line(x, y, x+(off/lim), y);
  3313. x = x+(off/lim);
  3314. a = false;
  3315. off = 0;
  3316. }
  3317. }
  3318. }
  3319. } else { // hrev
  3320. for (int y = 0; y < img.height-1; y++) {
  3321. for (int x = img.width-1; x > 1; x--) {
  3322. c = img.pixels[x+(y*img.width)];
  3323. while (check (x, y, x-off-1, y) == true && x-off-1 > 0) {
  3324. off++;
  3325. a = true;
  3326. }
  3327. if (a) {
  3328. temp.stroke(c);
  3329. temp.line(x, y, x-(off/lim), y);
  3330. x = x-(off/lim);
  3331. a = false;
  3332. off = 0;
  3333. }
  3334. }
  3335. }
  3336. }
  3337. }
  3338. if (v) {
  3339. if (!Vrev) {
  3340. for (int x = 0; x < img.width-1; x++) {
  3341. for (int y = 0; y < img.height-1; y++) {
  3342. c = img.pixels[x+(y*img.width)];
  3343. while (check (x, y, x, y+off+1) == true && y+off+1 < img.height-1 ) {
  3344. off++;
  3345. a = true;
  3346. }
  3347. if (a) {
  3348. temp.stroke(c);
  3349. temp.line(x, y, x, y+(off/lim));
  3350. y = y+(off/lim);
  3351. a = false;
  3352. off = 0;
  3353. }
  3354. }
  3355. }
  3356. } else { //Vrev
  3357. for (int x = 0; x < img.width-1; x++) {
  3358. for (int y = img.height-1; y > 1; y--) {
  3359. c = img.pixels[x+(y*img.width)];
  3360. while (check (x, y, x, y-off-1) == true && y-off-1 > 0) {
  3361. off++;
  3362. a = true;
  3363. }
  3364. if (a) {
  3365. temp.stroke(c);
  3366. temp.line(x, y, x, y-(off/lim));
  3367. y = y-(off/lim);
  3368. a = false;
  3369. off = 0;
  3370. }
  3371. }
  3372. }
  3373. }
  3374. }
  3375. temp.endDraw();
  3376. img = temp.get();
  3377. img.updatePixels();
  3378. }
  3379. canvas.beginDraw();
  3380. canvas.image(img, canvas.width/2, canvas.height/2);
  3381. canvas.endDraw();
  3382. }
  3383. boolean check(int x, int y, int xc, int yc) {
  3384. float src, dst, r;
  3385. r = (rand != 0) ? random(0, rand) : 0;
  3386. switch(sum) {
  3387. case 1: //rgbsum
  3388. src = rgbsum(x, y);
  3389. dst = rgbsum(xc, yc);
  3390. break;
  3391. case 2: // brightness
  3392. src = brightness(img.pixels[x+(y*img.width)]);
  3393. dst = brightness(img.pixels[xc+(yc*img.width)]);
  3394. break;
  3395. default: // 'classic' or asdfish
  3396. src = map(img.pixels[x+(y*img.width)], 0, 0xFFFFFF, 0.0, 255.0);
  3397. dst = map(img.pixels[xc+(yc*img.width)], 0, 0xFFFFFF, 0.0, 255.0);
  3398. break;
  3399. }
  3400. if (mode == 0 && (src < dst-tol-r || src > dst+tol+r)) return true;
  3401. else if (mode == 1 && src > dst+tol-r) return true;
  3402. else if (mode == 2 && src < dst-tol+r) return true;
  3403. else return false;
  3404. }
  3405. float rgbsum(int x, int y) {
  3406. int r = img.pixels[x+(y*img.width)] >> 24 & 0xff;
  3407. int g = img.pixels[x+(y*img.width)] >> 16 & 0xff;
  3408. int b = img.pixels[x+(y*img.width)] & 0xff;
  3409. float result = (r + g + b) / 3;
  3410. return result;
  3411. }
  3412. }
  3413. /*
  3414. SEGMENTER
  3415. */
  3416. class SEGMENTER extends Shader {
  3417. int thres = 64; // threshold
  3418. int mode = 0; // lighter/darker, essentially 'reverses' the sort
  3419. boolean diag = true; // diagonal/straight
  3420. boolean v = true; // use to select initial direction.
  3421. boolean h = true; // if cycling, use V=true H=false.
  3422. boolean choice = false;
  3423. int iterations;
  3424. PImage img;
  3425. int[] bounds = {0, 0, 0, 0};
  3426. boolean running = true;
  3427. SEGMENTER() {
  3428. name = "fxSegmenter";
  3429. params.add(new Param("threshold", INTVAL, 8, 252, new int[]{SINE, TRIANG}));
  3430. params.add(new Param("mode", INTVAL, 0, 1, new int[]{RANDOM, SQUAR}));
  3431. params.add(new Param("diagonal", INTVAL, 0, 1, new int[]{RANDOM, SQUAR}));
  3432. params.add(new Param("horizontal", INTVAL, 0, 1, new int[]{RANDOM, SQUAR}));
  3433. params.add(new Param("vertical", INTVAL, 0, 1, new int[] {RANDOM, SQUAR}));
  3434. params.add(new Param("weirdo pattern mode", INTVAL, 0, 1, new int[] {RANDOM, SQUAR}));
  3435. params.add(new Param("iterations", INTVAL, 1, 100, new int[] {SINE, TRIANG}));
  3436. params.add(new Param("direction", INTVAL, 0, 3, new int[]{RANDOM}));
  3437. directionParamIndex = 7;
  3438. img = createImage(canvas.width, canvas.height, ARGB);
  3439. canvas.beginDraw();
  3440. canvas.colorMode(HSB);
  3441. canvas.endDraw();
  3442. }
  3443. int rw, rh;
  3444. void apply() {
  3445. if (rw != canvas.width || rh != canvas.height) {
  3446. rw = canvas.width;
  3447. rh = canvas.height;
  3448. img.resize(rw, rh);
  3449. bounds[0]= 0;
  3450. bounds[1]= 0;
  3451. bounds[2]= rw;
  3452. bounds[3]= rh;
  3453. }
  3454. img = canvas.get();
  3455. thres = (int)params.get(0).value;
  3456. mode = (int)params.get(1).value;
  3457. diag = boolean((int)params.get(2).value);
  3458. v = boolean((int)params.get(3).value);
  3459. h = boolean((int)params.get(4).value);
  3460. choice = boolean((int)params.get(5).value);
  3461. iterations = (int)params.get(6).value;
  3462. canvas.beginDraw();
  3463. canvas.image(img, canvas.width/2, canvas.height/2);
  3464. canvas.endDraw();
  3465. canvas.beginDraw();
  3466. for (int i = 0; i < iterations; i++) {
  3467. canvas.loadPixels();
  3468. for (int j = bounds[1]; j < bounds[3]-1; j++) {
  3469. for (int k = bounds[0]; k < bounds[2]-1; k++) {
  3470. float bright = canvas.brightness(canvas.get(k, j));
  3471. color c;
  3472. if (!choice) {
  3473. if (diag) {
  3474. if (mode == 0) {
  3475. if (h && bright < abs(thres)&& k > bounds[0]+1 && j > bounds[1]+1 && (bright < canvas.brightness(canvas.pixels[k-1+((j-1)*canvas.width)]))) {
  3476. swap(k, j, k-1, j-1);
  3477. } else if (v && bright < abs(thres*2) && j > bounds[1]+1 && k < bounds[2]-1 && (bright < canvas.brightness(canvas.pixels[k+1+((j-1)*canvas.width)]))) {
  3478. swap(k, j, k+1, j-1);
  3479. } else if (h && bright < abs(thres*3) && k < bounds[2]-1 && j < bounds[3]-1 && (bright < canvas.brightness(canvas.pixels[k+1+((j+1)*canvas.width)]))) {
  3480. swap(k, j, k+1, j+1);
  3481. } else if (v && k > bounds[0] && j < bounds[3]-1 && (bright < canvas.brightness(canvas.pixels[k-1+((j+1)*canvas.width)]))) {
  3482. swap(k, j, k-1, j+1);
  3483. }
  3484. } else { // mode
  3485. if (h && bright < abs(thres)&& k > bounds[0] && j > bounds[1] && (bright > canvas.brightness(canvas.pixels[k-1+((j-1)*canvas.width)]))) {
  3486. swap(k, j, k-1, j-1);
  3487. } else if (v && bright < abs(thres*2) && j > bounds[1] && k < bounds[2]-1 && (bright > canvas.brightness(canvas.pixels[k+1+((j-1)*canvas.width)]))) {
  3488. swap(k, j, k+1, j-1);
  3489. } else if (h && bright < abs(thres*3) && k < bounds[2]-1 && j < bounds[3]-1 && (bright > canvas.brightness(canvas.pixels[k+1+((j+1)*canvas.width)]))) {
  3490. swap(k, j, k+1, j+1);
  3491. } else if (v && k > bounds[0] && j < bounds[3]-1 && (bright > canvas.brightness(canvas.pixels[k-1+((j+1)*canvas.width)]))) {
  3492. swap(k, j, k-1, j+1);
  3493. }
  3494. } // mode
  3495. }//diag
  3496. else {
  3497. if (mode == 0) {
  3498. if (h && bright < abs(thres)&& k > bounds[0] && (bright < canvas.brightness(canvas.get(k-1, j)))) {
  3499. swap(k, j, k-1, j);
  3500. } else if (v && bright < abs(thres*2) && j > bounds[1] && (bright < canvas.brightness(canvas.get(k, j-1)))) {
  3501. swap(k, j, k, j-1);
  3502. } else if (h && bright < abs(thres*3) && k < bounds[2]-1 && (bright < canvas.brightness(canvas.get(k+1, j)))) {
  3503. swap(k, j, k+1, j);
  3504. } else if (v && k > bounds[0] && j < bounds[3]-1 && (bright < canvas.brightness(canvas.get(k, j+1)))) {
  3505. swap(k, j, k, j+1);
  3506. }
  3507. } else { // mode
  3508. if (h && bright < abs(thres)&& k > bounds[0] && (bright > canvas.brightness(canvas.get(k-1, j)))) {
  3509. swap(k, j, k-1, j);
  3510. } else if (v && bright < abs(thres*2) && j > bounds[1] && (bright > canvas.brightness(canvas.get(k, j-1)))) {
  3511. swap(k, j, k, j-1);
  3512. } else if (h && bright < abs(thres*3) && k < bounds[2]-1 && (bright > canvas.brightness(canvas.get(k+1, j)))) {
  3513. swap(k, j, k+1, j);
  3514. } else if (v && k > bounds[0] && j < bounds[3]-1 && (bright > canvas.brightness(canvas.get(k, j+1)))) {
  3515. swap(k, j, k, j+1);
  3516. }
  3517. } // mode
  3518. } // diag
  3519. } else { //choice
  3520. //weirdo pattern mode
  3521. if (mode == 0) {
  3522. if (bright < thres && k-1+((j-1)*canvas.width) > 0) {
  3523. swap(k, j, k-1, j-1);
  3524. } else if (bright < abs(thres*2) && k+1+((j-1)*canvas.width) > 0) {
  3525. swap(k, j, k+1, j-1);
  3526. } else if (bright < abs(thres*3) && k+1+((j+1)*canvas.width) < canvas.width*canvas.height) {
  3527. swap(k, j, k+1, j+1);
  3528. } else if (k-1+((j+1)*canvas.width) < canvas.width*canvas.height) {
  3529. swap(k, j, k-1, j+1);
  3530. }
  3531. } else { // mode
  3532. if (bright > abs(thres*3) && k-1+((j-1)*canvas.width) > 0) {
  3533. if (k-1+((j-1)*canvas.width) > 0) {
  3534. swap(k, j, k-1, j-1);
  3535. }
  3536. } else
  3537. if (bright > abs(thres*2) && k+1+((j-1)*canvas.width) > 0) {
  3538. if (k+1+((j-1)*canvas.width) > 0) {
  3539. swap(k, j, k+1, j-1);
  3540. }
  3541. } else
  3542. if (bright < thres && k+1+((j+1)*canvas.width) < canvas.width*canvas.height) {
  3543. swap(k, j, k+1, j+1);
  3544. } else if (k-1+((j+1)*canvas.width) < canvas.width*canvas.height) {
  3545. swap(k, j, k-1, j+1);
  3546. }
  3547. } // mode
  3548. }//choice
  3549. }//hori loop
  3550. }//vert loop
  3551. canvas.updatePixels();
  3552. }//iterations
  3553. canvas.endDraw();
  3554. }
  3555. void swap(int x, int y, int xc, int yc) {
  3556. // if (x+(y*width) < width*height && xc+(yc*width) < width*height && xc+(yc*width) > -1) {
  3557. color c = canvas.pixels[x+(y*canvas.width)];
  3558. canvas.pixels[x+(y*canvas.width)] = canvas.pixels[xc+(yc*canvas.width)];
  3559. canvas.pixels[xc+((yc)*canvas.width)] = c;
  3560. // }
  3561. }
  3562. }
  3563. /*
  3564. COLORCRUSHER
  3565. */
  3566. class COLORCRUSHER extends Shader {
  3567. float c;
  3568. int m = 5;
  3569. COLORCRUSHER() {
  3570. name = "fxColorCrusher";
  3571. params.add(new Param("multiplier", INTVAL, 2, 10, new int[]{SINE, TAN, SAWTOOTH, TRIANG}));
  3572. }
  3573. void apply() {
  3574. m = (int)params.get(0).value;
  3575. canvas.beginDraw();
  3576. canvas.loadPixels();
  3577. for (int i = 0; i < canvas.pixels.length; i++) {
  3578. c = color(canvas.pixels[i]);
  3579. canvas.pixels[i] = int(c*m);
  3580. }
  3581. canvas.updatePixels();
  3582. canvas.endDraw();
  3583. }
  3584. }
  3585. /*
  3586. RAINBOWHUE
  3587. */
  3588. //...
  3589. /*
  3590. JPGCorruption
  3591. by Victor Giers
  3592. */
  3593. class JPGCORRUPTION extends Shader {
  3594. PImage img;
  3595. byte[] brokenfile;
  3596. JPGCORRUPTION() {
  3597. name = "fxJPGHexGlitch";
  3598. params.add(new Param("byte amount to change probability", INTVAL, 2, 200, new int[]{RANDOM}));
  3599. params.add(new Param("iterations", INTVAL, 2, 10, new int[]{RANDOM}));
  3600. params.add(new Param("direction", INTVAL, 0, 3, new int[]{RANDOM}));
  3601. directionParamIndex = 2;
  3602. rw = canvas.width;
  3603. rh = canvas.height;
  3604. img = createImage(rw, rh, ARGB);
  3605. }
  3606. int rw, rh;
  3607. void apply() {
  3608. if (rw != canvas.width || rh != canvas.height) {
  3609. rw = canvas.width;
  3610. rh = canvas.height;
  3611. img.resize(rw, rh);
  3612. }
  3613. int probparam = (int)params.get(0).value;
  3614. int iterations = (int)params.get(1).value;
  3615. img = canvas.get();
  3616. canvas.beginDraw();
  3617. for (int k = 0; k < iterations; k++) {
  3618. canvas.image(img, canvas.width/2, canvas.height/2);
  3619. canvas.save(dataPath("")+"/JPGHex.jpg"); //save as jpg
  3620. brokenfile = loadBytes(dataPath("")+"/JPGHex.jpg"); //and reload. just in case it wasnt a jpg.
  3621. double probability = float(probparam) / float(brokenfile.length);
  3622. byte[] savebytes2 = new byte[brokenfile.length];
  3623. boolean headerEnd = false;
  3624. boolean FFfound = false;
  3625. int glitchCount = 0;
  3626. for (int i = 0; i < brokenfile.length; i++) {
  3627. String hexStr = hex(brokenfile[i]);
  3628. if (FFfound && hexStr.equals("DA")) headerEnd = true;
  3629. FFfound = false;
  3630. if (hexStr.equals("FF")) FFfound = true;
  3631. if (headerEnd && random(1)<probability) {
  3632. String randomHex = (str(Character.forDigit((int)random(16), 16)) + str(Character.forDigit((int)random(16), 16))).toUpperCase();
  3633. hexStr = randomHex;
  3634. glitchCount++;
  3635. }
  3636. byte hexByte[] = fromHexString(hexStr);
  3637. for (int j = 0; j < hexByte.length; j++) {
  3638. savebytes2[i] += hexByte[j];
  3639. }
  3640. }
  3641. //println("Glitched " + glitchCount + " bytes");
  3642. saveBytes(dataPath("") + "/JPGHex.jpg", savebytes2);
  3643. img = loadImage(dataPath("") + "/JPGHex.jpg");
  3644. }
  3645. canvas.endDraw();
  3646. }
  3647. byte[] fromHexString(final String encoded) {
  3648. if ((encoded.length() % 2) != 0)
  3649. throw new IllegalArgumentException("Input string must contain an even number of characters");
  3650. final byte result[] = new byte[encoded.length()/2];
  3651. final char enc[] = encoded.toCharArray();
  3652. for (int i = 0; i < enc.length; i += 2) {
  3653. StringBuilder curr = new StringBuilder(2);
  3654. curr.append(enc[i]).append(enc[i + 1]);
  3655. result[i/2] = (byte) Integer.parseInt(curr.toString(), 16);
  3656. }
  3657. return result;
  3658. }
  3659. }
  3660. class WEBPCORRUPTION extends Shader {
  3661. PImage img;
  3662. byte[] brokenfile;
  3663. int rw, rh;
  3664. String[] convertToPNG;
  3665. String[] convertToWebp;
  3666. WEBPCORRUPTION() {
  3667. name = "fxWebpCorruption";
  3668. params.add(new Param("byte amount to change probability", INTVAL, 2, 50, new int[]{RANDOM}));
  3669. params.add(new Param("direction", INTVAL, 0, 3, new int[]{RANDOM}));
  3670. directionParamIndex = 1;
  3671. rw = canvas.width;
  3672. rh = canvas.height;
  3673. img = createImage(rw, rh, ARGB);
  3674. convertToPNG = new String[]{"/usr/local/bin/convert", "-verbose", dataPath("") + "/webp_glitched.webp", dataPath("") + "/webp_glitched.png"};
  3675. convertToWebp = new String[]{"/usr/local/bin/convert", "-verbose", dataPath("") + "/webp_orig.png", dataPath("") + "/webp_orig.webp"};
  3676. }
  3677. void apply() {
  3678. if (rw != canvas.width || rh != canvas.height) {
  3679. rw = canvas.width;
  3680. rh = canvas.height;
  3681. img.resize(rw, rh);
  3682. }
  3683. int probparam = (int)params.get(0).value;
  3684. img = canvas.get();
  3685. canvas.beginDraw();
  3686. canvas.image(img, canvas.width/2, canvas.height/2);
  3687. File oldImage = new File(dataPath("")+"/webp_orig.png");
  3688. if (oldImage.exists()) {
  3689. oldImage.delete();
  3690. }
  3691. oldImage = new File(dataPath("")+"/webp_orig.webp"); //is it better to move this up again?
  3692. if (oldImage.exists()) {
  3693. oldImage.delete();
  3694. }
  3695. oldImage = new File(dataPath("")+"/webp_glitched.webp");
  3696. if (oldImage.exists()) {
  3697. oldImage.delete();
  3698. }
  3699. oldImage = new File(dataPath("")+"/webp_glitched.png");
  3700. if (oldImage.exists()) {
  3701. oldImage.delete();
  3702. }
  3703. canvas.save(dataPath("")+"/webp_orig.png"); //save as png
  3704. int failCount = 0;
  3705. while ((runCommand(convertToPNG) != 0) && failCount < 25) {
  3706. failCount ++;
  3707. println("Trying to convert...");
  3708. while (runCommand(convertToWebp) != 0) {
  3709. println("Conversion failed, trying again...");
  3710. }
  3711. brokenfile = loadBytes(dataPath("")+"/webp_orig.webp"); //and reload. just in case it wasnt a jpg.
  3712. byte[] savebytes = new byte[brokenfile.length];
  3713. double probability = float(probparam) / float(brokenfile.length);
  3714. int glitchCount = 0;
  3715. for (int i = 0; i < brokenfile.length; i++) {
  3716. String hexStr = hex(brokenfile[i]);
  3717. if (i > 10) { // skip header
  3718. if (random(1)<probability) {
  3719. String randomHex = (str(Character.forDigit((int)random(16), 16)) + str(Character.forDigit((int)random(16), 16))).toUpperCase();
  3720. hexStr = randomHex;
  3721. glitchCount++;
  3722. }
  3723. }
  3724. byte hexByte[] = fromHexString(hexStr);
  3725. for (int j = 0; j < hexByte.length; j++) {
  3726. savebytes[i] += hexByte[j];
  3727. }
  3728. }
  3729. println("Glitched " + glitchCount + " bytes");
  3730. saveBytes(dataPath("") + "/webp_glitched.webp", savebytes);
  3731. File newImage = new File(dataPath("")+"/webp_glitched.webp");
  3732. while (!newImage.exists()) {
  3733. println("Waiting until bytes have been written to disk...");
  3734. }
  3735. /*
  3736. String[] convertToPNG = {"/usr/local/bin/convert", "-verbose", dataPath("") + "/webp_glitched.webp", dataPath("") + "/webp_glitched.png"};
  3737. while (!runCommand(convertToPNG)) {
  3738. println("Trying to convert...");
  3739. }
  3740. */
  3741. }
  3742. if (failCount == 25) println("Failed 50 times, skipping webp glitch");
  3743. else img = loadImage(dataPath("") + "/webp_glitched.png");
  3744. //launch(dataPath("") + "/webpdecode.command");
  3745. //delay(1500);
  3746. //try or load fallback image and redo in while loop
  3747. //PImage compare = img.get();
  3748. //img = loadImage(dataPath("") + "/result.png");
  3749. canvas.image(img, canvas.width/2, canvas.height/2);
  3750. canvas.endDraw();
  3751. }
  3752. byte[] fromHexString(final String encoded) {
  3753. if ((encoded.length() % 2) != 0)
  3754. throw new IllegalArgumentException("Input string must contain an even number of characters");
  3755. final byte result[] = new byte[encoded.length()/2];
  3756. final char enc[] = encoded.toCharArray();
  3757. for (int i = 0; i < enc.length; i += 2) {
  3758. StringBuilder curr = new StringBuilder(2);
  3759. curr.append(enc[i]).append(enc[i + 1]);
  3760. result[i/2] = (byte) Integer.parseInt(curr.toString(), 16);
  3761. }
  3762. return result;
  3763. }
  3764. }
  3765. /*
  3766. SOX
  3767. */
  3768. class SOX extends Shader {
  3769. PImage img;
  3770. int rw, rh;
  3771. int depth = 8;
  3772. int iterations = 1;
  3773. int samplerate = 44100;
  3774. int channels = 1;
  3775. String coding = "a-law";
  3776. String type = "al";
  3777. int encoding = 0;
  3778. boolean rgbyuv = true;
  3779. boolean do_blend = false;
  3780. int blend_type = 1;
  3781. String[] effectParams;
  3782. SOX() {
  3783. }
  3784. void setSoxParams() {
  3785. rw = canvas.width;
  3786. rh = canvas.height;
  3787. img = createImage(rw, rh, ARGB);
  3788. params.add(new Param("direction", INTVAL, 0, 3, new int[]{RANDOM}));
  3789. directionParamIndex = 0;
  3790. params.add(new Param("iterations", INTVAL, 1, 10, new int[]{RANDOM}));
  3791. params.add(new Param("do blend", INTVAL, 0, 1, new int[]{RANDOM, SQUAR}));
  3792. params.add(new Param("blend type", INTVAL, 0, blends.length-1, new int[]{RANDOM}));
  3793. params.add(new Param("bitdepth (8, 16, 24)", INTVAL, 1, 3, new int[]{RANDOM}));
  3794. params.add(new Param("samplerate", INTVAL, 1400, 200000, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  3795. params.add(new Param("encoding", INTVAL, 0, 7, new int[]{RANDOM}));
  3796. params.add(new Param("yuv / rgb", INTVAL, 0, 1, new int[]{RANDOM, SQUAR}));
  3797. params.add(new Param("channels (mono / stereo)", INTVAL, 1, 2, new int[]{RANDOM, SQUAR}));
  3798. }
  3799. void apply() {
  3800. iterations = (int)params.get(1).value;
  3801. do_blend = boolean((int)params.get(2).value);
  3802. blend_type = blends[(int)params.get(3).value];
  3803. depth = (int)params.get(4).value * 8;
  3804. samplerate = (int)params.get(5).value;
  3805. encoding = (int)params.get(6).value;
  3806. switch(encoding) {
  3807. case(0):
  3808. type = "s8";
  3809. coding = "signed-integer";
  3810. break;
  3811. case(1):
  3812. type = "u8";
  3813. coding = "unsigned-integer";
  3814. break;
  3815. case(2):
  3816. type = "s16";
  3817. coding = "signed-integer";
  3818. break;
  3819. case(3):
  3820. type = "u16";
  3821. coding = "unsigned-integer";
  3822. break;
  3823. case(4):
  3824. type = "s24";
  3825. coding = "signed-integer";
  3826. break;
  3827. case(5):
  3828. type = "u24";
  3829. coding = "unsigned-integer";
  3830. break;
  3831. case(6):
  3832. type = "al";
  3833. coding = "a-law";
  3834. break;
  3835. case(7):
  3836. type = "ul";
  3837. coding = "u-law";
  3838. break;
  3839. default:
  3840. type = "f32";
  3841. coding = "float";
  3842. break;
  3843. }
  3844. rgbyuv = boolean((int)params.get(7).value);
  3845. channels = (int)params.get(8).value;
  3846. getParams();
  3847. if (rw != canvas.width || rh != canvas.height) {
  3848. rw = canvas.width;
  3849. rh = canvas.height;
  3850. img.resize(rw, rh);
  3851. }
  3852. img = canvas.get();
  3853. canvas.beginDraw();
  3854. canvas.image(img, canvas.width/2, canvas.height/2);
  3855. File oldImage = new File(dataPath("")+"/sox.raw");
  3856. if (oldImage.exists()) {
  3857. oldImage.delete();
  3858. }
  3859. oldImage = new File(dataPath("")+"/sox.png");
  3860. if (oldImage.exists()) {
  3861. oldImage.delete();
  3862. }
  3863. oldImage = new File(dataPath("")+"/sox_sonified.raw");
  3864. if (oldImage.exists()) {
  3865. oldImage.delete();
  3866. }
  3867. canvas.save(dataPath("")+"/sox.png"); //save as png
  3868. String[] convertToRAW = new String[]{"/usr/local/bin/convert", "-verbose", dataPath("") + "/sox.png", "-depth", str(depth), ((rgbyuv) ? "rgb" : "yuv") + ":" + dataPath("") + "/sox.raw"};
  3869. String[] soxCall = new String[]{"/usr/local/bin/sox", "-r", str(samplerate), "-e", coding, "-b", "8", "-c", "2", "-t", type, dataPath("") + "/sox.raw", dataPath("") + "/sox_sonified.raw"};
  3870. String[] sonify = concat(soxCall, effectParams);
  3871. String[] convertToPNG = new String[]{"/usr/local/bin/convert", "-verbose", "-size", str(rw) + "x" + str(rh), "-depth", str(depth), ((rgbyuv) ? "rgb" : "yuv") + ":" + dataPath("") + "/sox_sonified.raw", dataPath("") + "/sox.png"};
  3872. for (int i = 0; i < iterations; i++) {
  3873. if (runCommand(convertToRAW) != 0) {
  3874. println("Conversion to RAW failed");
  3875. }
  3876. if (runCommand(sonify) != 0) {
  3877. println("Sonification failed");
  3878. }
  3879. if (runCommand(convertToPNG) != 0) {
  3880. println("Conversion to PNG failed");
  3881. }
  3882. img = loadImage(dataPath("") + "/sox.png");
  3883. }
  3884. if (do_blend) {
  3885. canvas.blend(img, 0, 0, img.width, img.height, 0, 0, canvas.width, canvas.height, blend_type);
  3886. } else {
  3887. canvas.image(img, canvas.width/2, canvas.height/2);
  3888. }
  3889. canvas.endDraw();
  3890. }
  3891. void getParams() {
  3892. }
  3893. }
  3894. /*
  3895. SOXECHO
  3896. NEEDS FIXING
  3897. */
  3898. class SOXECHO extends SOX {
  3899. float gainin = 0.8;
  3900. float gainout = 0.8;
  3901. float delay = 0.8;
  3902. float decay = 0.8;
  3903. SOXECHO() {
  3904. name = "fxSoxEcho";
  3905. setSoxParams();
  3906. params.add(new Param("gain in", FLOATVAL, 0.01, 1, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  3907. params.add(new Param("gain out", FLOATVAL, 0.01, 1000, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  3908. params.add(new Param("delay", FLOATVAL, 0.01, 1000, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  3909. params.add(new Param("decay", FLOATVAL, 0.01, 1, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  3910. }
  3911. void getParams() {
  3912. gainin = params.get(9).value;
  3913. gainout = params.get(10).value;
  3914. delay = params.get(11).value;
  3915. decay = params.get(12).value;
  3916. effectParams = new String[]{"echo", str(gainin), str(gainout), str(delay), str(decay)};
  3917. }
  3918. }
  3919. /*
  3920. SOXALLPASS
  3921. */
  3922. class SOXALLPASS extends SOX {
  3923. String hkqo = "h";
  3924. int frequency = 100;
  3925. int widt = 100;
  3926. SOXALLPASS() {
  3927. name = "fxSoxAllpass";
  3928. setSoxParams();
  3929. params.add(new Param("frequency", INTVAL, 1, 1000, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  3930. params.add(new Param("width", INTVAL, 1, 10000, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  3931. params.add(new Param("h/k/q/o", INTVAL, 0, 3, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  3932. }
  3933. void getParams() {
  3934. frequency = (int)params.get(9).value;
  3935. widt = (int)params.get(10).value;
  3936. switch((int)params.get(11).value) {
  3937. case(0):
  3938. hkqo = "h";
  3939. break;
  3940. case(1):
  3941. hkqo = "k";
  3942. break;
  3943. case(2):
  3944. hkqo = "q";
  3945. break;
  3946. default:
  3947. hkqo = "o";
  3948. break;
  3949. }
  3950. effectParams = new String[]{"allpass", str(frequency), str(widt) + hkqo};
  3951. }
  3952. }
  3953. /*
  3954. SOXBAND
  3955. */
  3956. class SOXBAND extends SOX {
  3957. String hkqo = "h";
  3958. int center = 100;
  3959. int widt = 100;
  3960. boolean n;
  3961. SOXBAND() {
  3962. name = "fxSoxBand";
  3963. setSoxParams();
  3964. params.add(new Param("center", INTVAL, 1, 10000, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  3965. params.add(new Param("width", INTVAL, 1, 10000, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  3966. params.add(new Param("h/k/q/o", INTVAL, 0, 3, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  3967. params.add(new Param("-n", INTVAL, 0, 1, new int[]{RANDOM, SQUAR}));
  3968. }
  3969. void getParams() {
  3970. center = (int)params.get(9).value;
  3971. widt = (int)params.get(10).value;
  3972. switch((int)params.get(11).value) {
  3973. case(0):
  3974. hkqo = "h";
  3975. break;
  3976. case(1):
  3977. hkqo = "k";
  3978. break;
  3979. case(2):
  3980. hkqo = "q";
  3981. break;
  3982. default:
  3983. hkqo = "o";
  3984. break;
  3985. }
  3986. n = boolean((int)params.get(12).value);
  3987. effectParams = new String[]{ "band", (n ? "-n " : "") + str(center), str(widt) + hkqo};
  3988. }
  3989. }
  3990. /*
  3991. SOXBANDPASS
  3992. */
  3993. class SOXBANDPASS extends SOX {
  3994. int widt, frequency;
  3995. String hkqo;
  3996. boolean c;
  3997. SOXBANDPASS() {
  3998. name = "soxBandPass";
  3999. setSoxParams();
  4000. params.add(new Param("frequency", INTVAL, 1, 10000, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  4001. params.add(new Param("width", INTVAL, 1, 10000, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  4002. params.add(new Param("h/k/q/o", INTVAL, 0, 3, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  4003. params.add(new Param("-c", INTVAL, 0, 1, new int[]{RANDOM, SQUAR}));
  4004. }
  4005. void getParams() {
  4006. frequency = (int)params.get(9).value;
  4007. widt = (int)params.get(10).value;
  4008. switch((int)params.get(11).value) {
  4009. case(0):
  4010. hkqo = "h";
  4011. break;
  4012. case(1):
  4013. hkqo = "k";
  4014. break;
  4015. case(2):
  4016. hkqo = "q";
  4017. break;
  4018. default:
  4019. hkqo = "o";
  4020. break;
  4021. }
  4022. c = boolean((int)params.get(12).value);
  4023. effectParams = new String[]{"bandpass", (c ? "-c " : "") + str(frequency), str(widt) + hkqo};
  4024. }
  4025. }
  4026. /*
  4027. SOXBANDREJECT
  4028. */
  4029. class SOXBANDREJECT extends SOX {
  4030. int widt, frequency;
  4031. String hkqo;
  4032. SOXBANDREJECT() {
  4033. name = "soxBandReject";
  4034. setSoxParams();
  4035. params.add(new Param("frequency", INTVAL, 1, 10000, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  4036. params.add(new Param("width", INTVAL, 1, 10000, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  4037. params.add(new Param("h/k/q/o", INTVAL, 0, 3, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  4038. }
  4039. void getParams() {
  4040. frequency = (int)params.get(9).value;
  4041. widt = (int)params.get(10).value;
  4042. switch((int)params.get(11).value) {
  4043. case(0):
  4044. hkqo = "h";
  4045. break;
  4046. case(1):
  4047. hkqo = "k";
  4048. break;
  4049. case(2):
  4050. hkqo = "q";
  4051. break;
  4052. default:
  4053. hkqo = "o";
  4054. break;
  4055. }
  4056. effectParams = new String[]{"bandreject", str(frequency), str(widt) + hkqo};
  4057. }
  4058. }
  4059. /*
  4060. SOXBASS
  4061. */
  4062. class SOXBASS extends SOX {
  4063. int widt, frequency, gain;
  4064. float seconds;
  4065. String hkqo;
  4066. SOXBASS() {
  4067. name = "soxBass";
  4068. setSoxParams();
  4069. params.add(new Param("gain", INTVAL, 1, 100, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  4070. params.add(new Param("frequency", INTVAL, 1, 10000, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  4071. params.add(new Param("width", INTVAL, 1, 10000, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  4072. params.add(new Param("h/k/q/o", INTVAL, 0, 3, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  4073. params.add(new Param("seconds", FLOATVAL, 0.001, 10, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  4074. }
  4075. void getParams() {
  4076. gain = (int)params.get(9).value;
  4077. frequency = (int)params.get(10).value;
  4078. widt = (int)params.get(11).value;
  4079. switch((int)params.get(12).value) {
  4080. case(0):
  4081. hkqo = "h";
  4082. break;
  4083. case(1):
  4084. hkqo = "k";
  4085. break;
  4086. case(2):
  4087. hkqo = "q";
  4088. break;
  4089. default:
  4090. hkqo = "o";
  4091. break;
  4092. }
  4093. seconds = params.get(13).value;
  4094. effectParams = new String[]{"bass", str(gain), str(frequency), str(widt) + hkqo};
  4095. }
  4096. }
  4097. /*
  4098. SOXBEND
  4099. */
  4100. class SOXBEND extends SOX {
  4101. int framerate, oversample, start, cents, end;
  4102. SOXBEND() {
  4103. name = "soxBend";
  4104. setSoxParams();
  4105. //params.add(new Param("frequency", INTVAL, 1, 10000, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  4106. //params.add(new Param("width", INTVAL, 1, 10000, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  4107. //params.add(new Param("h/k/q/o", INTVAL, 0, 3, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  4108. }
  4109. void getParams() {
  4110. //frequency = (int)params.get(9).value;
  4111. //widt = (int)params.get(10).value;
  4112. //effectParams = new String[]{"bend", str(frequency), str(widt) + hkqo};
  4113. }
  4114. }