compositor for 2d glitch effects
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

effects.pde 117KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246
  1. /*
  2. ASDFPIXELSORT
  3. */
  4. class ASDFPIXELSORT extends Shader {
  5. ASDFPIXELSORT() {
  6. name = "fxASDFPixelSort";
  7. params.add(new Param("black", INTVAL, -17000000, -2000000, new int[]{SINE, SAWTOOTH, RAMPUPDOWN, TAN, TANINVERSE, TRIANG}));
  8. params.add(new Param("target", INTVAL, 0, 2, new int[]{RANDOM}));
  9. params.add(new Param("direction", INTVAL, 0, 3, new int[]{RANDOM}));
  10. directionParamIndex = 2;
  11. }
  12. int previousMode;
  13. void apply() {
  14. if (previousMode != int(params.get(1).value)) {
  15. if (params.get(1).value == 0) changeParam(0, new Param("black", INTVAL, -17000000, -2000000, new int[]{SINE, SAWTOOTH, RAMPUPDOWN, TAN, TANINVERSE, TRIANG}));
  16. if (params.get(1).value == 1) changeParam(0, new Param("brightness", INTVAL, 0, 200, new int[]{SINE, SAWTOOTH, RAMPUPDOWN, TAN, TANINVERSE, TRIANG}));
  17. if (params.get(1).value == 2) changeParam(0, new Param("white", INTVAL, -15000000, -700000, new int[]{SINE, SAWTOOTH, RAMPUPDOWN, TAN, TANINVERSE, TRIANG}));
  18. }
  19. previousMode = (int)params.get(1).value;
  20. row = 0;
  21. column = 0;
  22. colorMode(RGB);
  23. canvas.beginDraw();
  24. while (column < canvas.width-1) {
  25. canvas.loadPixels();
  26. sortColumn();
  27. column++;
  28. canvas.updatePixels();
  29. }
  30. while (row < canvas.height-1) {
  31. canvas.loadPixels();
  32. sortRow();
  33. row++;
  34. canvas.updatePixels();
  35. }
  36. canvas.endDraw();
  37. }
  38. int row = 0;
  39. int column = 0;
  40. void sortRow() {
  41. int x = 0;
  42. int y = row;
  43. int xend = 0;
  44. while (xend < canvas.width-1) {
  45. switch((int)params.get(1).value) {
  46. case 0:
  47. x = getFirstNotBlackX(x, y);
  48. xend = getNextBlackX(x, y);
  49. break;
  50. case 1:
  51. x = getFirstBrightX(x, y);
  52. xend = getNextDarkX(x, y);
  53. break;
  54. case 2:
  55. x = getFirstNotWhiteX(x, y);
  56. xend = getNextWhiteX(x, y);
  57. break;
  58. default:
  59. break;
  60. }
  61. if (x < 0) break;
  62. int sortLength = xend-x;
  63. color[] unsorted = new color[sortLength];
  64. color[] sorted = new color[sortLength];
  65. for (int i=0; i<sortLength; i++) {
  66. unsorted[i] = canvas.pixels[x + i + y * canvas.width];
  67. }
  68. sorted = sort(unsorted);
  69. for (int i=0; i<sortLength; i++) {
  70. canvas.pixels[x + i + y * canvas.width] = sorted[i];
  71. }
  72. x = xend+1;
  73. }
  74. }
  75. void sortColumn() {
  76. int x = column;
  77. int y = 0;
  78. int yend = 0;
  79. while (yend < canvas.height-1) {
  80. switch((int)params.get(1).value) {
  81. case 0:
  82. y = getFirstNotBlackY(x, y);
  83. yend = getNextBlackY(x, y);
  84. break;
  85. case 1:
  86. y = getFirstBrightY(x, y);
  87. yend = getNextDarkY(x, y);
  88. break;
  89. case 2:
  90. y = getFirstNotWhiteY(x, y);
  91. yend = getNextWhiteY(x, y);
  92. break;
  93. default:
  94. break;
  95. }
  96. if (y < 0) break;
  97. int sortLength = yend-y;
  98. color[] unsorted = new color[sortLength];
  99. color[] sorted = new color[sortLength];
  100. for (int i=0; i<sortLength; i++) {
  101. unsorted[i] = canvas.pixels[x + (y+i) * canvas.width];
  102. }
  103. sorted = sort(unsorted);
  104. for (int i=0; i<sortLength; i++) {
  105. canvas.pixels[x + (y+i) * canvas.width] = sorted[i];
  106. }
  107. y = yend+1;
  108. }
  109. }
  110. //BLACK
  111. int getFirstNotBlackX(int _x, int _y) {
  112. int x = _x;
  113. int y = _y;
  114. color c;
  115. while ( (c = canvas.pixels[x + y * canvas.width]) < params.get(0).value) {
  116. x++;
  117. if (x >= canvas.width) return -1;
  118. }
  119. return x;
  120. }
  121. int getNextBlackX(int _x, int _y) {
  122. int x = _x+1;
  123. int y = _y;
  124. color c;
  125. while ( (c = canvas.pixels[x + y * canvas.width]) > params.get(0).value) {
  126. x++;
  127. if (x >= canvas.width) return canvas.width-1;
  128. }
  129. return x-1;
  130. }
  131. //BRIGHTNESS
  132. int getFirstBrightX(int _x, int _y) {
  133. int x = _x;
  134. int y = _y;
  135. color c;
  136. while (brightness (c = canvas.pixels[x + y * canvas.width]) < params.get(0).value) {
  137. x++;
  138. if (x >= canvas.width) return -1;
  139. }
  140. return x;
  141. }
  142. int getNextDarkX(int _x, int _y) {
  143. int x = _x+1;
  144. int y = _y;
  145. color c;
  146. while (brightness (c = canvas.pixels[x + y * canvas.width]) > params.get(0).value) {
  147. x++;
  148. if (x >= canvas.width) return canvas.width-1;
  149. }
  150. return x-1;
  151. }
  152. //WHITE
  153. int getFirstNotWhiteX(int _x, int _y) {
  154. int x = _x;
  155. int y = _y;
  156. color c;
  157. while ( (c = canvas.pixels[x + y * canvas.width]) > params.get(0).value) {
  158. x++;
  159. if (x >= canvas.width) return -1;
  160. }
  161. return x;
  162. }
  163. int getNextWhiteX(int _x, int _y) {
  164. int x = _x+1;
  165. int y = _y;
  166. color c;
  167. while ( (c = canvas.pixels[x + y * canvas.width]) < params.get(0).value) {
  168. x++;
  169. if (x >= canvas.width) return canvas.width-1;
  170. }
  171. return x-1;
  172. }
  173. //BLACK
  174. int getFirstNotBlackY(int _x, int _y) {
  175. int x = _x;
  176. int y = _y;
  177. color c;
  178. if (y < canvas.height) {
  179. while ( (c = canvas.pixels[x + y * canvas.width]) < params.get(0).value) {
  180. y++;
  181. if (y >= canvas.height) return -1;
  182. }
  183. }
  184. return y;
  185. }
  186. int getNextBlackY(int _x, int _y) {
  187. int x = _x;
  188. int y = _y+1;
  189. color c;
  190. if (y < canvas.height) {
  191. while ( (c = canvas.pixels[x + y * canvas.width]) > params.get(0).value) {
  192. y++;
  193. if (y >= canvas.height) return canvas.height-1;
  194. }
  195. }
  196. return y-1;
  197. }
  198. //BRIGHTNESS
  199. int getFirstBrightY(int _x, int _y) {
  200. int x = _x;
  201. int y = _y;
  202. color c;
  203. if (y < canvas.height) {
  204. while (brightness (c = canvas.pixels[x + y * canvas.width]) < params.get(0).value) {
  205. y++;
  206. if (y >= canvas.height) return -1;
  207. }
  208. }
  209. return y;
  210. }
  211. int getNextDarkY(int _x, int _y) {
  212. int x = _x;
  213. int y = _y+1;
  214. color c;
  215. if (y < canvas.height) {
  216. while (brightness (c = canvas.pixels[x + y * canvas.width]) > params.get(0).value) {
  217. y++;
  218. if (y >= canvas.height) return canvas.height-1;
  219. }
  220. }
  221. return y-1;
  222. }
  223. //WHITE
  224. int getFirstNotWhiteY(int _x, int _y) {
  225. int x = _x;
  226. int y = _y;
  227. color c;
  228. if (y < canvas.height) {
  229. while ( (c = canvas.pixels[x + y * canvas.width]) > params.get(0).value) {
  230. y++;
  231. if (y >= canvas.height) return -1;
  232. }
  233. }
  234. return y;
  235. }
  236. int getNextWhiteY(int _x, int _y) {
  237. int x = _x;
  238. int y = _y+1;
  239. color c;
  240. if (y < canvas.height) {
  241. while ( (c = canvas.pixels[x + y * canvas.width]) < params.get(0).value) {
  242. y++;
  243. if (y >= canvas.height) return canvas.height-1;
  244. }
  245. }
  246. return y-1;
  247. }
  248. }
  249. /*
  250. DISTORTER
  251. */
  252. class DISTORTER extends Shader {
  253. boolean do_blend = false; // blend image after process
  254. int blend_mode = OVERLAY; // blend type
  255. int channel = BRIGHTNESS; // channel used in processing (R,G,B) or (H,S,B)
  256. float scalex = 0.05; // from 0.01 to 1
  257. float scaley = 0.1; // from 0.01 to 1
  258. boolean shift_hue = true;
  259. float shift_amt = 0.1; // from 0 to 1
  260. PImage buffer;
  261. 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
  262. int[][] distort = new int[2][distortionMatrixSize];
  263. final static float tick = 1.0/distortionMatrixSize;
  264. int mode = 0;
  265. int initBufferW, initBufferH;
  266. DISTORTER() {
  267. buffer = createImage(canvas.width, canvas.height, ARGB);
  268. initBufferW = buffer.width;
  269. initBufferH = buffer.height;
  270. name = "fxDistorter";
  271. params.add(new Param("width", FLOATVAL, 2, buffer.width/4-1, new int[]{SINE, SAWTOOTH, RAMPUPDOWN, TAN, TANINVERSE, TRIANG}));
  272. params.add(new Param("height", FLOATVAL, 2, buffer.height/4-1, new int[]{SINE, SAWTOOTH, RAMPUPDOWN, TAN, TANINVERSE, TRIANG}));
  273. params.add(new Param("do blend", INTVAL, 0, 1, new int[]{RANDOM, SQUAR}));
  274. params.add(new Param("shift hue amount", FLOATVAL, 0, 1, new int[]{SAWTOOTH, SAWTOOTHINVERSE, TAN, TANINVERSE, RAMP, RAMPINVERSE}));
  275. params.add(new Param("scale x", FLOATVAL, 0.01, 1, new int[]{SINE, SAWTOOTH, RAMPUPDOWN, TAN, TANINVERSE, TRIANG}));
  276. params.add(new Param("scale y", FLOATVAL, 0.01, 1, new int[]{SINE, SAWTOOTH, RAMPUPDOWN, TAN, TANINVERSE, TRIANG}));
  277. params.add(new Param("blend mode", INTVAL, 0, blends.length-1, new int[]{SINE, SAWTOOTH, RAMPUPDOWN, TAN, TANINVERSE, TRIANG}));
  278. params.add(new Param("channel", INTVAL, 0, 12, new int[]{SINE, SAWTOOTH, RAMPUPDOWN, TAN, TANINVERSE, TRIANG}));
  279. params.add(new Param("direction", INTVAL, 0, 3, new int[]{RANDOM}));
  280. directionParamIndex = 8;
  281. //params.add(new Param(DIRECTION));
  282. // channel, blend_mode
  283. //params.add(new Param("height", FLOATVAL, 1, buffer.height/4-1, new int[]{SINE, SAWTOOTH, RAMPUPDOWN, TAN, TANINVERSE, TRIANG}));
  284. // prepare distortion pattern
  285. for (int i=0; i<distortionMatrixSize; i++) {
  286. distort[0][i] = (int)random(-128, 128);
  287. distort[1][i] = (int)random(-128, 128);
  288. }
  289. }
  290. // ALL Channels, Nxxx stand for negative (255-value)
  291. // channels to work with
  292. final static int RED = 0;
  293. final static int GREEN = 1;
  294. final static int BLUE = 2;
  295. final static int HUE = 3;
  296. final static int SATURATION = 4;
  297. final static int BRIGHTNESS = 5;
  298. final static int NRED = 6;
  299. final static int NGREEN = 7;
  300. final static int NBLUE = 8;
  301. final static int NHUE = 9;
  302. final static int NSATURATION = 10;
  303. final static int NBRIGHTNESS = 11;
  304. void apply() {
  305. buffer = canvas.get();
  306. buffer.resize(canvas.width, canvas.height);
  307. float neww = map(params.get(0).value, 2, initBufferW-2, 2, buffer.width/4-2);
  308. float newh = map(params.get(1).value, 2, initBufferH-2, 2, buffer.height/4-2);
  309. do_blend = boolean(int(params.get(2).value));
  310. shift_amt = params.get(3).value;
  311. scalex = params.get(4).value;
  312. scaley = params.get(5).value;
  313. blend_mode = blends[(int)params.get(6).value];
  314. channel = (int)params.get(7).value;
  315. float totalnum = neww+newh;
  316. float times = (totalnum/floor(totalnum/neww));
  317. float offx = (totalnum%neww)/times;
  318. float ratiox = neww/buffer.width;
  319. //println(ratiox);
  320. canvas.beginDraw();
  321. canvas.noStroke();
  322. for (int y=0; y<buffer.height; y++) {
  323. float yy = y/(float)buffer.height;
  324. for (int x=0; x<buffer.width; x++) {
  325. float xx = x/(float)buffer.width;
  326. float offy = floor(newh*yy);
  327. float fx = xx*ratiox+offx*offy;
  328. float shift = fx%1.0;
  329. float st = shift/tick;
  330. int no1 = floor(st)%distortionMatrixSize;
  331. int no2 = ceil(st)%distortionMatrixSize ;
  332. float l = st-(float)no1;
  333. float cx = lerp(distort[0][no1], distort[0][no2], l);
  334. float cy = lerp(distort[1][no1], distort[1][no2], l);
  335. float rx =getChannel(buffer.get(x, y), channel);
  336. int sx = (int)((buffer.width+x+cx*rx*scalex*0.1)%buffer.width);
  337. int sy = (int)((buffer.height+y+cy*scaley)%buffer.height);
  338. color c=buffer.get(sx, sy);
  339. if (shift_hue) {
  340. colorMode(HSB, 255);
  341. c = color((hue(c)+shift_amt*255*noise(newh+y))%255.0, constrain(saturation(c)*1.2, 0, 255), constrain(brightness(c), 0, 255));
  342. colorMode(RGB, 255);
  343. }
  344. // buffer.fill(lerpColor(c,img.get(x,y),0.2));
  345. canvas.fill(c); //wärs nich effizienter die pixelmatrix zu ändern ?
  346. canvas.rect(x, y, 1, 1);
  347. }
  348. }
  349. if (do_blend)
  350. canvas.blend(buffer, 0, 0, buffer.width, buffer.height, 0, 0, canvas.width, canvas.height, blend_mode);
  351. canvas.endDraw();
  352. }
  353. float getChannel(color c, int channel) {
  354. int ch = channel>5?channel-6:channel;
  355. float cc;
  356. switch(ch) {
  357. case RED:
  358. cc = red(c);
  359. break;
  360. case GREEN:
  361. cc = green(c);
  362. break;
  363. case BLUE:
  364. cc = blue(c);
  365. break;
  366. case HUE:
  367. cc = hue(c);
  368. break;
  369. case SATURATION:
  370. cc = saturation(c);
  371. break;
  372. default:
  373. cc= brightness(c);
  374. break;
  375. }
  376. return channel>5?255-cc:cc;
  377. }
  378. }
  379. /*
  380. FM
  381. */
  382. class FM extends Shader {
  383. // configuration
  384. int colorspace = RGB;
  385. int quantval = 30; // 0 - off, less - more glitch, more - more precision
  386. boolean do_blend = true; // blend image after process
  387. int blend_mode = OVERLAY; // blend type
  388. //unused parameters (giers):
  389. final static boolean first_channel_only = false; // for L.. or Y.. colorspaces set true to modulate only luma;
  390. final static boolean lowpass1_on = true; // on/off of first low pass filter
  391. final static boolean lowpass2_on = true; // on/off of second low pass filter
  392. final static boolean lowpass3_on = true; // on/off of third low pass filter
  393. // better don't touch it, lowpass filters are run in cascade
  394. float lowpass1_cutoff = 0.25; // percentage of rate
  395. float lowpass2_cutoff = 0.1;
  396. float lowpass3_cutoff = 0.05;
  397. // working buffer
  398. PGraphics buffer;
  399. // local variables
  400. float min_omega, max_omega;
  401. float min_phase_mult=0.05;
  402. float max_phase_mult=50.0;
  403. LowpassFilter lpf1, lpf2, lpf3;
  404. int[][] pxls;
  405. boolean negate = false;
  406. FM() {
  407. name = "fxFM";
  408. params.add(new Param ("do blend", INTVAL, 0, 1, new int[]{RANDOM, SQUAR}));
  409. params.add(new Param ("blend_mode", INTVAL, 0, blends.length-1, new int[]{RANDOM}));
  410. params.add(new Param ("omega", FLOATVAL, 0, 1, new int[]{SINE, SAWTOOTH, TRIANG}));
  411. params.add(new Param ("phase", FLOATVAL, 0, 1, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  412. params.add(new Param ("colorspace", INTVAL, 0, 16, new int[]{RANDOM}));
  413. params.add(new Param ("quant", INTVAL, 0, 40, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  414. params.add(new Param("direction", INTVAL, 0, 3, new int[]{RANDOM}));
  415. directionParamIndex = 6;
  416. buffer = createGraphics(canvas.width, canvas.height);
  417. buffer.beginDraw();
  418. buffer.noStroke();
  419. //buffer.smooth(8);
  420. //buffer.background(0);
  421. // buffer.image(canvas, 0, 0);
  422. buffer.endDraw();
  423. float rate = 100000.0;
  424. lpf1 = new LowpassFilter(rate, lowpass1_cutoff*rate);
  425. lpf2 = new LowpassFilter(rate, lowpass2_cutoff*rate);
  426. lpf3 = new LowpassFilter(rate, lowpass3_cutoff*rate);
  427. //img.loadPixels();
  428. }
  429. void prepareData() {
  430. pxls = new int[3][canvas.pixels.length];
  431. for (int i=0; i<canvas.pixels.length; i++) {
  432. int cl = toColorspace(canvas.pixels[i], colorspace);
  433. pxls[0][i] = (cl >> 16) & 0xff;
  434. pxls[1][i] = (cl >> 8) & 0xff;
  435. pxls[2][i] = (cl) & 0xff;
  436. }
  437. }
  438. float omega, min_phase, max_phase;
  439. int rw, rh;
  440. void apply() {
  441. buffer.setSize(canvas.width, canvas.height);
  442. min_omega = TWO_PI/(0.05*canvas.width);
  443. max_omega = TWO_PI/(300.0*canvas.width);
  444. rw = canvas.width;
  445. do_blend = boolean(int(params.get(0).value));
  446. blend_mode = blends[(int)params.get(1).value];
  447. omega = map(sqrt(params.get(2).value), 0, 1, min_omega, max_omega);
  448. float phase = map(sq(params.get(3).value), 0, 1, min_phase_mult, max_phase_mult);
  449. colorspace = (int)params.get(4).value;
  450. quantval = (int) params.get(5).value;
  451. if (rw != canvas.width || rh != canvas.height) {
  452. rw = canvas.width;
  453. rh = canvas.height;
  454. min_omega = TWO_PI/(0.05*canvas.width);
  455. max_omega = TWO_PI/(300.0*canvas.width);
  456. }
  457. prepareData();
  458. //buffer = canvas.get(0, 0, canvas.width, canvas.height);
  459. max_phase = phase * omega;
  460. min_phase = -max_phase;
  461. processImage();
  462. }
  463. void processImage() {
  464. buffer.beginDraw();
  465. buffer.loadPixels();
  466. int [][] dest_pxls = new int[3][canvas.pixels.length];
  467. if (first_channel_only) {
  468. arrayCopy(pxls[1], dest_pxls[1]);
  469. arrayCopy(pxls[2], dest_pxls[2]);
  470. }
  471. for (int i=0; i< (first_channel_only?1:3); i++) {
  472. for (int y=0; y<canvas.height; y++) {
  473. int off = y * canvas.width;
  474. //reset filters each line
  475. lpf1.resetFilter(map(pxls[i][off], 0, 255, min_phase, max_phase));
  476. lpf2.resetFilter(map(pxls[i][off], 0, 255, min_phase, max_phase));
  477. lpf3.resetFilter(map(pxls[i][off], 0, 255, min_phase, max_phase));
  478. float sig_int = 0; // integral of the signal
  479. float pre_m = 0; // previous value of modulated signal
  480. for (int x=0; x<canvas.width; x++) {
  481. /////////////////////////
  482. // FM part starts here
  483. /////////////////////////
  484. float sig = map(pxls[i][x+off], 0, 255, min_phase, max_phase); // current signal value
  485. sig_int += sig; // current value of signal integral
  486. float m = cos(omega * x + sig_int); // modulate signal
  487. if ( quantval > 0) {
  488. m = map((int)map(m, -1, 1, 0, quantval), 0, quantval, -1, 1); // quantize
  489. }
  490. float dem = abs(m-pre_m); // demodulate signal, derivative
  491. pre_m = m; // remember current value
  492. // lowpass filter chain
  493. if (lowpass1_on) dem = lpf1.lowpass(dem);
  494. if (lowpass2_on) dem = lpf2.lowpass(dem);
  495. if (lowpass3_on) dem = lpf3.lowpass(dem);
  496. // remap signal back to channel value
  497. int v = constrain( (int)map(2*(dem-omega), min_phase, max_phase, 0, 255), 0, 255);
  498. //////////////////////
  499. // FM part ends here
  500. //////////////////////
  501. dest_pxls[i][x+off] = negate?255-v:v;
  502. }
  503. }
  504. }
  505. for (int i=0; i<buffer.pixels.length; i++) {
  506. buffer.pixels[i] = fromColorspace(0xff000000 | (dest_pxls[0][i] << 16) | (dest_pxls[1][i] << 8) | (dest_pxls[2][i]), colorspace);
  507. }
  508. buffer.updatePixels();
  509. if (do_blend)
  510. buffer.blend(canvas, 0, 0, canvas.width, canvas.height, 0, 0, buffer.width, buffer.height, blend_mode);
  511. buffer.endDraw();
  512. canvas.beginDraw();
  513. canvas.image(buffer, canvas.width/2, canvas.height/2, canvas.width, canvas.height);
  514. canvas.endDraw();
  515. }
  516. class LowpassFilter {
  517. float alpha;
  518. float prev;
  519. public LowpassFilter(float rate, float hz) {
  520. alpha = 0.0;
  521. prev = 0.0;
  522. setFilter(rate, hz);
  523. }
  524. void setFilter(float rate, float hz) {
  525. float timeInterval = 1.0/rate;
  526. float tau = 1.0 / (hz * TWO_PI);
  527. alpha = timeInterval / (tau + timeInterval);
  528. }
  529. void resetFilter(float val) {
  530. prev = val;
  531. }
  532. void resetFilter() {
  533. resetFilter(0);
  534. }
  535. float lowpass(float sample) {
  536. float stage1 = sample * alpha;
  537. float stage2 = prev - (prev * alpha);
  538. prev = (stage1 + stage2);
  539. return prev;
  540. }
  541. float highpass(float sample) {
  542. return sample - lowpass(sample);
  543. }
  544. }
  545. }
  546. /*
  547. WZIP
  548. */
  549. class WZIP extends Shader {
  550. final float sqrt05 = sqrt(0.5);
  551. float[] raw, raw1, raw2, raw3;
  552. float[] in, w, out;
  553. float[] in1, in2, in3, out1, out2, out3;
  554. int n, n2, s;
  555. float scalingfactorin, scalingfactorout;
  556. PImage img;
  557. String sessionid;
  558. WZIP() {
  559. name = "fxWZIP";
  560. params.add(new Param ("scale", FLOATVAL, 0.1, 1000, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  561. params.add(new Param ("factor in", FLOATVAL, 0.01, 1, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  562. params.add(new Param ("factor out", FLOATVAL, 0.01, 1, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  563. params.add(new Param("hsb/rgb", INTVAL, 0, 1, new int[]{RANDOM, SQUAR}));
  564. params.add(new Param("mode", INTVAL, 0, 1, new int[]{RANDOM, SQUAR}));
  565. params.add(new Param("direction", INTVAL, 0, 3, new int[]{RANDOM}));
  566. directionParamIndex = 5;
  567. sessionid = hex((int)random(0xffff), 4);
  568. img = createImage(canvas.width, canvas.height, ARGB);
  569. img = canvas.get(0, 0, canvas.width, canvas.height);
  570. }
  571. void apply() {
  572. // img = createImage(canvas.width, canvas.height, ARGB);
  573. img.resize(canvas.width, canvas.height);
  574. img = canvas.get(0, 0, canvas.width, canvas.height);
  575. s = img.width*img.height;
  576. raw = new float[s*3];
  577. raw1 = new float[s];
  578. raw2 = new float[s];
  579. raw3 = new float[s];
  580. canvas.beginDraw();
  581. canvas.background(0);
  582. canvas.noStroke();
  583. if (boolean((int)params.get(3).value)) { /////////////////////
  584. canvas.colorMode(HSB, 255);
  585. colorMode(HSB, 255);
  586. } else {
  587. canvas.colorMode(RGB, 255);
  588. colorMode(RGB, 255);
  589. }
  590. scalingfactorin = map(params.get(1).value, 0, 1, 0, params.get(0).value); /////////////////////
  591. scalingfactorout = map(params.get(2).value, 0, 1, 0, params.get(0).value); /////////////////////
  592. int iter=0;
  593. int iter2 = 0;
  594. for (int y=0; y<img.height; y++) {
  595. for (int x=0; x<img.width; x++) {
  596. color c = img.get(x, y);
  597. float r, g, b;
  598. if (boolean((int)params.get(3).value)) { /////////////////////
  599. r = hue(c)>127?hue(c)-256:hue(c);
  600. g = saturation(c)>127?saturation(c)-256:saturation(c);
  601. b = brightness(c)>127?brightness(c)-256:brightness(c);
  602. } else {
  603. r = red(c)>127?red(c)-256:red(c);
  604. g = green(c)>127?green(c)-256:green(c);
  605. b = blue(c)>127?blue(c)-256:blue(c);
  606. }
  607. raw[iter++] = r;
  608. raw[iter++] = g;
  609. raw[iter++] = b;
  610. raw1[iter2] = r;
  611. raw2[iter2] = g;
  612. raw3[iter2] = b;
  613. iter2++;
  614. }
  615. }
  616. n = (int)pow(2, ceil(log(s*3)/log(2)));
  617. n2 = (int)pow(2, ceil(log(s)/log(2)));
  618. in = new float[n];
  619. w = new float[n];
  620. out = new float[n];
  621. out1 = new float[n2];
  622. out2 = new float[n2];
  623. out3 = new float[n2];
  624. in1 = new float[n2];
  625. in2 = new float[n2];
  626. in3 = new float[n2];
  627. arrayCopy(raw, 0, in, 0, raw.length);
  628. for (int i=raw.length; i<n; i++) in[i] = raw[raw.length-1];
  629. arrayCopy(raw1, 0, in1, 0, s);
  630. arrayCopy(raw2, 0, in2, 0, s);
  631. arrayCopy(raw3, 0, in3, 0, s);
  632. for (int i=s; i<n2; i++) {
  633. in1[i] = raw1[s-1];
  634. in2[i] = raw2[s-1];
  635. in3[i] = raw3[s-1];
  636. }
  637. if (boolean((int)params.get(4).value)) option1(); /////////////////////
  638. else option2();
  639. canvas.colorMode(RGB);
  640. colorMode(RGB);
  641. canvas.endDraw();
  642. }
  643. float clamp(float c) {
  644. return(abs(c<0?256+c:c)%255.0);
  645. }
  646. void option2() {
  647. wtrafo(in1, n2);
  648. wbtrafo(out1, n2);
  649. wtrafo(in2, n2);
  650. wbtrafo(out2, n2);
  651. wtrafo(in3, n2);
  652. wbtrafo(out3, n2);
  653. for (int i=0; i<s; i++) {
  654. float r = clamp(out1[i]);
  655. float g = clamp(out2[i]);
  656. float b = clamp(out3[i]);
  657. canvas.fill(r, g, b);
  658. canvas.rect(i%canvas.width, i/canvas.width, 1, 1);
  659. }
  660. }
  661. void option1() {
  662. wtrafo(in, n);
  663. wbtrafo(out, n);
  664. float r=0, g=0, b=0;
  665. int state = 0;
  666. for (int i=0; i<raw.length; i++) {
  667. float c = clamp(out[i]);
  668. switch(state) {
  669. case 0:
  670. r = c;
  671. break;
  672. case 1:
  673. g = c;
  674. break;
  675. case 2:
  676. b = c;
  677. break;
  678. default:
  679. {
  680. r = c;
  681. canvas.fill(r, g, b);
  682. canvas.rect(floor(i/3.0)%canvas.width, floor(i/3.0)/canvas.width, 1, 1);
  683. state = 0;
  684. }
  685. }
  686. state++;
  687. }
  688. }
  689. void wbtrafo(float[] y, int n) {
  690. float[] d = new float[n];
  691. d[n-2] = w[n-1];
  692. int b1 = n-4;
  693. int b2 = n-2;
  694. int a=1;
  695. while (a<n/2) {
  696. for (int i=0; i<a; i++) {
  697. d[2*i+b1]=(d[i+b2]+w[i+b2])*sqrt05;
  698. d[2*i+1+b1]=(d[i+b2]-w[i+b2])*sqrt05;
  699. }
  700. b2=b1;
  701. b1=b1-4*a;
  702. a*=2;
  703. }
  704. for (int i=0; i<a; i++) {
  705. y[2*i]=(d[i]+w[i])*sqrt05;
  706. y[2*i+1]=(d[i]-w[i])*sqrt05;
  707. }
  708. for (int i=0; i<n; i++) y[i] *= scalingfactorout;
  709. }
  710. void wtrafo(float[] y, int n) {
  711. float[] d = new float[n];
  712. int a = n/2;
  713. for (int i=0; i<a; i++) {
  714. w[i] = (y[2*i]-y[2*i+1])*sqrt05;
  715. d[i] = (y[2*i]+y[2*i+1])*sqrt05;
  716. }
  717. int b1 = 0;
  718. int b2 = a;
  719. a/=2;
  720. while (a>0) {
  721. for (int i=0; i<a; i++) {
  722. w[i+b2]=(d[2*i+b1]-d[2*i+1+b1])*sqrt05;
  723. d[i+b2]=(d[2*i+b1]+d[2*i+1+b1])*sqrt05;
  724. }
  725. b1=b2;
  726. b2=b2+a;
  727. a/=2;
  728. }
  729. w[b2] = d[b1];
  730. for (int i=0; i<n-1; i++) w[i] = (int)(w[i]/scalingfactorin);
  731. if (w[n-1]>0) w[n-1] = (int)(w[n-1]/scalingfactorin+0.5);
  732. else w[n-1] = (int)(w[n-1]/scalingfactorin-0.5);
  733. }
  734. }
  735. /*
  736. AUECHO
  737. */
  738. class AUECHO extends Shader {
  739. final int[] blends = {BLEND, ADD, SUBTRACT, DARKEST, LIGHTEST, DIFFERENCE, EXCLUSION, MULTIPLY, SCREEN, OVERLAY, HARD_LIGHT, SOFT_LIGHT, DODGE, BURN};
  740. AUECHO() {
  741. name = "fxAUecho";
  742. params.add(new Param("mode", INTVAL, 0, 1, new int[]{RANDOM, SQUAR}));
  743. params.add(new Param ("echo", FLOATVAL, 0.001, 1, new int[]{TRIANG, SINE, RAMPUPDOWN, }));
  744. params.add(new Param ("decay", FLOATVAL, 0.001, 1, new int[]{TRIANG, SINE, RAMPUPDOWN }));
  745. params.add(new Param ("blend mode", INTVAL, 0, this.blends.length-1, new int[]{RANDOM }));
  746. params.add(new Param("direction", INTVAL, 0, 3, new int[]{RANDOM}));
  747. directionParamIndex = 4;
  748. }
  749. void apply() {
  750. canvas.beginDraw();
  751. if (boolean((int)params.get(0).value)) {
  752. canvas.colorMode(HSB);
  753. colorMode(HSB);
  754. } else {
  755. canvas.colorMode(RGB);
  756. colorMode(RGB);
  757. }
  758. canvas.loadPixels();
  759. float _delay = params.get(1).value;
  760. float decay = params.get(2).value;
  761. int delay = (int)(canvas.pixels.length * _delay);
  762. color[] history = new color[canvas.pixels.length];
  763. int blendMode =this.blends[(int)params.get(3).value];
  764. for ( int i = 0, l = canvas.pixels.length; i<l; i++) {
  765. history[i] = canvas.pixels[i];
  766. }
  767. for ( int i = 0, l = canvas.pixels.length; i<l; i++) {
  768. int fromPos = i-delay < 0 ? l-abs(i-delay) : i-delay;
  769. color fromColor = history[fromPos];
  770. float r = red(fromColor) * decay;
  771. float g = green(fromColor) * decay;
  772. float b = blue(fromColor) * decay;
  773. color origColor = history[i];
  774. color toColor = color(
  775. r = r + red(origColor) > 255 ? r + red(origColor) - 255 : r + red(origColor), // simulate overflow ;)
  776. g = g + green(origColor) > 255 ? g + green(origColor) - 255 : g + green(origColor),
  777. b = b + blue(origColor) > 255 ? b + blue(origColor) - 255 : b + blue(origColor) );
  778. //canvas.pixels[i] = history[i] = toColor;
  779. canvas.pixels[i] = history[i] = blendColor(origColor, toColor, blendMode);
  780. }
  781. canvas.updatePixels();
  782. if (boolean((int)params.get(0).value)) {
  783. canvas.colorMode(RGB);
  784. colorMode(RGB);
  785. }
  786. canvas.endDraw();
  787. }
  788. }
  789. /*
  790. SLITSCAN
  791. */
  792. class SLITSCAN extends Shader {
  793. int[] fx;
  794. int[] fy;
  795. float[] phx;
  796. float[] phy;
  797. int[] sx, sy;
  798. boolean[] skipfx;
  799. boolean[] skipfy;
  800. boolean dox, doy;
  801. PImage buffer;
  802. float[][] ft = new float[2][32];
  803. int depth; // number of octaves
  804. int fxnum;
  805. int fynum;
  806. SLITSCAN() {
  807. name = "fxSlitSscan";
  808. params.add(new Param("direction", INTVAL, 0, 3, new int[]{RANDOM}));
  809. directionParamIndex = 0;
  810. buffer = createImage(canvas.width, canvas.height, ARGB);
  811. for (int i=0; i<32; i++) {
  812. ft[0][i] = pow(2.0, i);
  813. ft[1][i] = 0.5*1.0/ft[0][i];
  814. }
  815. }
  816. void apply() {
  817. canvas.beginDraw();
  818. canvas.colorMode(RGB);
  819. canvas.noStroke();
  820. colorMode(RGB);
  821. canvas.fill(255);
  822. buffer.resize(canvas.width, canvas.height);
  823. buffer = canvas.get(0, 0, canvas.width, canvas.height);
  824. //int s = buffer.width>buffer.height?buffer.height:buffer.width;
  825. int s = min(buffer.width, buffer.height);
  826. depth = (int)(log(s)/log(2));
  827. fxnum = (int)random(depth); ////
  828. fynum = (int)random(depth); ////
  829. fx = new int[fxnum+1];
  830. fy = new int[fynum+1];
  831. sx = new int[fxnum+1];
  832. sy = new int[fynum+1];
  833. phx = new float[fxnum+1];
  834. phy = new float[fynum+1];
  835. skipfx = new boolean[fxnum+1];
  836. skipfy = new boolean[fynum+1];
  837. for (int i=0; i<fxnum; i++) {
  838. fx[i]=(int)random(6);
  839. phx[i] = random(1);
  840. skipfx[i] = random(1)<0.2;
  841. sx[i] = random(1)<0.2?-1:1;
  842. }
  843. for (int i=0; i<fynum; i++) {
  844. fy[i]=(int)random(6);
  845. phy[i] = random(1);
  846. skipfy[i] = random(1)<0.2;
  847. sy[i] = random(1)<0.2?-1:1;
  848. }
  849. dox = random(1)<0.8;
  850. doy = dox?random(1)<0.8:true;
  851. float v=0;
  852. for (int y=0; y<buffer.height; y++)
  853. for (int x=0; x<buffer.width; x++) {
  854. float iy = map(y, 0, buffer.height, 0, 1);
  855. v=0;
  856. if (doy) for (int i=0; i<fy.length; i++)
  857. if (!skipfy[i]) v+=sy[i]*getValue(fy[i], iy, i, phy[i]);
  858. float ry = 2*iy+v;
  859. float y2 = (3*buffer.height+ry * buffer.height/2)%buffer.height;
  860. float ix = map(x, 0, buffer.width, 0, 1);
  861. v=0;
  862. if (dox) for (int i=0; i<fx.length; i++)
  863. if (!skipfx[i]) v+=sx[i]*getValue(fx[i], ix, i, phx[i]);
  864. float rx = 2*ix+v;
  865. float x2 = (3*buffer.width+rx * buffer.width/2)%buffer.width;
  866. canvas.fill(buffer.get((int)x2, (int)y2));
  867. canvas.rect(x, y, 1, 1);
  868. }
  869. canvas.endDraw();
  870. }
  871. float getValue(int fun, float idx, int freq, float phase) {
  872. switch(fun) {
  873. case 0:
  874. return getSin(idx, freq, phase);
  875. case 1:
  876. return getSaw(idx, freq, phase);
  877. case 2:
  878. return getTriangle(idx, freq, phase);
  879. case 3:
  880. return getCutTriangle(idx, freq, phase);
  881. case 4:
  882. return getSquare(idx, freq, phase);
  883. case 5:
  884. return getNoise(idx, freq, phase);
  885. default:
  886. return getSin(idx, freq, phase);
  887. }
  888. }
  889. float getNoise(float idx, int freq, float phase) {
  890. return 2*ft[1][freq]*(noise((idx+phase)*ft[0][freq])-0.5);
  891. }
  892. float getSin(float idx, int freq, float phase) {
  893. float p = ft[0][freq];
  894. return ft[1][freq] * sin(idx*TWO_PI*p+phase*TWO_PI);
  895. }
  896. float getSaw(float idx, int freq, float phase) {
  897. float p = ft[0][freq];
  898. float rp = 2.0*ft[1][freq];
  899. float p2 = p*((idx+phase+ft[1][freq])%1.0);
  900. return rp*(p2-floor(p2)-0.5);
  901. }
  902. float getSquare(float idx, int freq, float phase) {
  903. float p = ft[0][freq];
  904. float rp = ft[1][freq];
  905. return (((idx*p)+phase)%1.0)<0.5?rp:-rp;
  906. }
  907. float getTriangle(float idx, int freq, float phase) {
  908. return 2*abs(getSaw(idx, freq, phase+0.5*ft[1][freq]))-ft[1][freq];
  909. }
  910. float getCutTriangle(float idx, int freq, float phase) {
  911. return constrain(getTriangle(idx, freq, phase), -ft[1][freq+1], ft[1][freq+1]);
  912. }
  913. }
  914. /*
  915. WAHWAH
  916. */
  917. class WAHWAH extends Shader {
  918. float sequence, lfoskip, xn1, xn2, yn1, yn2, b0, b1, b2, a0, a1, a2, freqofs, freq, freqoff, startsequence, res, depth;
  919. float mCurRate = 0.4, skipcount = 0;
  920. int lfoskipsamples = 0;
  921. float frequency, omega, sn, cs, alpha;
  922. float in, out;
  923. float val;
  924. WAHWAH() {
  925. name = "fxWahWah";
  926. //params.add(new Param("mode", INTVAL, 0, 1, new int[]{RANDOM, SQUAR}));
  927. params.add(new Param ("resolution", FLOATVAL, 1, 100, new int[]{TRIANG, SINE, RAMPUPDOWN, }));
  928. params.add(new Param ("depth", FLOATVAL, 0.0001, 1, new int[]{TRIANG, SINE, RAMPUPDOWN }));
  929. params.add(new Param ("frequency offset", FLOATVAL, 0, 0.9, new int[]{TRIANG, SINE, RAMPUPDOWN }));
  930. params.add(new Param ("mCurRate", FLOATVAL, 0, 1, new int[]{TRIANG, SINE, RAMPUPDOWN }));
  931. params.add(new Param ("direction", INTVAL, 0, 3, new int[]{RANDOM}));
  932. directionParamIndex = 4;
  933. // params.add(new Param ("blend mode", INTVAL, 0, this.blends.length-1, new int[]{RANDOM }));
  934. }
  935. void apply() {
  936. res = params.get(0).value;
  937. depth = params.get(1).value;
  938. freqofs = params.get(2).value;
  939. //res = 12.5
  940. //depth = 0.8;
  941. //freqofs = 0.9;
  942. freq = 1.5;
  943. startsequence = 0.2;
  944. lfoskip = freq * 2 * PI / mCurRate;
  945. skipcount = xn1 = xn2 = yn1 = yn2 = b0 = b1 = b2 = a0 = a1 = a2 = 0;
  946. sequence = startsequence;
  947. canvas.beginDraw();
  948. canvas.colorMode(RGB);
  949. canvas.loadPixels();
  950. float[] rgb = new float[3];
  951. for ( int i = 0, len = canvas.pixels.length; i < len; i++) {
  952. rgb[0] = red(canvas.pixels[i]);
  953. rgb[1] = green(canvas.pixels[i]);
  954. rgb[2] = blue(canvas.pixels[i]);
  955. for ( int ri = 0; ri < 3; ri++ ) {
  956. in = map(rgb[ri], 0, 255, 0, 1);
  957. frequency = (1+cos(skipcount * lfoskip + sequence ))/2;
  958. frequency = frequency * depth * (1-freqofs) + freqofs;
  959. frequency = exp((frequency - 1) * 6 );
  960. omega = PI * frequency;
  961. sn = sin(omega);
  962. cs = cos(omega);
  963. alpha = sn/(2*res);
  964. b0 = (1-cs) /2;
  965. b1 = 1 - cs;
  966. b2 = (1-cs)/2;
  967. a0 = 1 + alpha;
  968. a1 = -2 * cs;
  969. a2 = 1 - alpha;
  970. out = ( b0 * in + b1 * xn1 + b2 * xn2 - a1 * yn1 - a2 * yn2 ) / a0;
  971. xn2 = xn1;
  972. xn1 = in;
  973. yn2 = yn1;
  974. yn1 = out;
  975. rgb[ri] = map(out, 0, 1, 0, 255);
  976. }
  977. canvas.pixels[i] = color(rgb[0], rgb[1], rgb[2]);
  978. }
  979. canvas.updatePixels();
  980. canvas.endDraw();
  981. }
  982. }
  983. /*
  984. PHASER
  985. */
  986. class PHASER extends Shader {
  987. //float samplerate = 92230.0; // try setting this to 44100.0 or 2048.5 for kicks
  988. float samplerate = 44100; // try setting this to 44100.0 or 2048.5 for kicks
  989. int mode;
  990. PHASER() {
  991. name ="fxPhaser";
  992. params.add(new Param("mode", INTVAL, 0, 1, new int[]{RANDOM, SQUAR}));
  993. params.add(new Param ("frequency", FLOATVAL, 0.1, 40.0, new int[]{TRIANG, SINE, RAMPUPDOWN }));
  994. params.add(new Param ("depth", INTVAL, 1, 255, new int[]{TRIANG, SINE, RAMPUPDOWN }));
  995. params.add(new Param ("feedback", INTVAL, -100, 100, new int[]{TRIANG, SINE, RAMPUPDOWN }));
  996. params.add(new Param ("phase", FLOATVAL, 0, TWO_PI, new int[]{TRIANG, SINE, RAMPUPDOWN }));
  997. params.add(new Param ("stages", INTVAL, 1, 24, new int[]{TRIANG, SINE, RAMPUPDOWN }));
  998. params.add(new Param ("sample rate", FLOATVAL, 512, 92230, new int[]{TRIANG, SINE, RAMPUPDOWN }));
  999. params.add(new Param("direction", INTVAL, 0, 3, new int[]{RANDOM}));
  1000. directionParamIndex = 7;
  1001. //params.add(new Param ("frequency offset", FLOATVAL, 0, 1, new int[]{TRIANG, SINE, RAMPUPDOWN }));
  1002. }
  1003. /*
  1004. mDepth = (int) map(knobZero, 0, 255, 255, 0);
  1005. mFeedback = (int) map(knobOne, 0, 255, -100, 100);
  1006. // enable these for some more fun :)
  1007. if (mode == 1) {
  1008. mSampleRate = map(knobTwo, 0, 255, 1, 512);
  1009. mStages = (int) ( 2*map(knobThree, 0, 255, 1, 12));
  1010. }
  1011. */
  1012. void apply() {
  1013. mode = (int)params.get(0).value;
  1014. float mFreq = params.get(1).value;
  1015. int mDryWet = 255;
  1016. int mDepth = (int)params.get(2).value;
  1017. int mFeedback = (int)params.get(3).value;
  1018. float mPhase = params.get(4).value;
  1019. //these two are only changed if mode = 1
  1020. int mStages = 2;
  1021. float mSampleRate = samplerate;
  1022. canvas.beginDraw();
  1023. canvas.loadPixels();
  1024. //constants
  1025. float phaserlfoshape = 4.0;
  1026. int lfoskipsamples = 20; //how many samples are processed before recomputing lfo
  1027. int numStages = 24;
  1028. //getParams
  1029. /*
  1030. Phaser Parameters
  1031. mFreq - Phaser's LFO frequency
  1032. mPhase - Phaser's LFO startsequence (radians), needed for stereo Phasers
  1033. mDepth - Phaser depth (0 - no depth, 255 - max depth)
  1034. mStages - Phaser stages (recomanded from 2 to 16-24, and EVEN NUMBER)
  1035. mDryWet - Dry/wet mix, (0 - dry, 128 - dry=wet, 255 - wet)
  1036. mFeedback - Phaser FeedBack (0 - no feedback, 100 = 100% Feedback,
  1037. -100 = -100% FeedBack)
  1038. */
  1039. // enable these for some more fun :)
  1040. if (mode == 1) {
  1041. mStages = (int)params.get(5).value;
  1042. mSampleRate = params.get(6).value;
  1043. }
  1044. //init
  1045. float gain = 0, fbout = 0;
  1046. float lfoskip = mFreq * 2 * PI / mSampleRate;
  1047. float sequence = mPhase * PI / 180;
  1048. float[] old = new float[mStages];
  1049. for ( int j = 0; j < mStages; j++) {
  1050. old[j] = 0.0;
  1051. }
  1052. /* EffectPhaser::ProcessBlock */
  1053. int skipcount = 0;
  1054. float[] rgb = new float[3];
  1055. for ( int i = 0, l = canvas.pixels.length; i<l; i++ ) {
  1056. color c = canvas.pixels[i];
  1057. rgb[0] = map(red(c), 0, 255, 0, 1);
  1058. rgb[1] = map(green(c), 0, 255, 0, 1);
  1059. rgb[2] = map(blue(c), 0, 255, 0, 1);
  1060. for ( int ci = 0; ci < 3; ci++) {
  1061. float in = rgb[ci];
  1062. float m = in + fbout * mFeedback / 100;
  1063. if ( (( skipcount++) % lfoskipsamples ) == 0 ) { //recomopute lfo
  1064. gain = (1.0 + cos(skipcount * lfoskip + sequence)) / 2.0; //compute sine between 0 and 1
  1065. gain = exp(gain * phaserlfoshape) / exp(phaserlfoshape); // change lfo shape
  1066. gain = 1.0 - gain / 255.0 * mDepth; // attenuate the lfo
  1067. }
  1068. //phasing routine
  1069. for ( int j = 0; j<mStages; j++) {
  1070. float tmp = old[j];
  1071. old[j] = gain * tmp + m;
  1072. m = tmp - gain * old[j];
  1073. }
  1074. fbout = m;
  1075. rgb[ci] = (float) (( m * mDryWet + in * (255-mDryWet)) / 255);
  1076. }
  1077. color rc = color(
  1078. map(rgb[0], 0, 1, 0, 255),
  1079. map(rgb[1], 0, 1, 0, 255),
  1080. map(rgb[2], 0, 1, 0, 255));
  1081. canvas.pixels[i] = rc;
  1082. }
  1083. canvas.updatePixels();
  1084. canvas.endDraw();
  1085. }
  1086. }
  1087. /*
  1088. ECHO
  1089. */
  1090. class ECHO extends Shader {
  1091. int mode = 0;
  1092. PImage result;
  1093. ECHO() {
  1094. name = "fxEcho";
  1095. params.add(new Param("mode", INTVAL, 0, 1, new int[]{RANDOM, SQUAR}));
  1096. params.add(new Param ("xp", INTVAL, 0, 100, new int[]{TRIANG, SINE, RAMPUPDOWN }));
  1097. params.add(new Param ("yp", INTVAL, 0, 100, new int[]{TRIANG, SINE, RAMPUPDOWN }));
  1098. params.add(new Param("direction", INTVAL, 0, 3, new int[]{RANDOM}));
  1099. directionParamIndex = 3;
  1100. result = createImage(canvas.width, canvas.height, RGB);
  1101. }
  1102. void apply() {
  1103. mode = (int)params.get(0).value;
  1104. int xp = (int)params.get(1).value;
  1105. int yp = (int)params.get(2).value;
  1106. canvas.beginDraw();
  1107. canvas.colorMode(RGB);
  1108. colorMode(RGB);
  1109. canvas.imageMode(CORNER);
  1110. if (mode == 0) {
  1111. canvas.image(auEcho(canvas, xp, yp), 0, 0);
  1112. } else if (mode == 1) {
  1113. canvas.image(auEchoWTF(canvas, xp, yp), 0, 0);
  1114. }
  1115. canvas.endDraw();
  1116. }
  1117. PImage auEcho(PImage img, int xp, int yp) {
  1118. result.resize(img.width, img.height);
  1119. float _delay = map(xp, 0, 100, 0.001, 1.0);
  1120. float decay = map(yp, 0, 100, 0.0, 1.0);
  1121. int delay = (int)(img.pixels.length * _delay);
  1122. color[] history = new color[img.pixels.length];
  1123. int blendMode = BLEND;
  1124. img.loadPixels();
  1125. result.loadPixels();
  1126. for ( int i = 0, l = img.pixels.length; i<l; i++) {
  1127. history[i] = img.pixels[i];
  1128. }
  1129. for ( int i = 0, l = img.pixels.length; i<l; i++) {
  1130. int fromPos = i-delay < 0 ? l-abs(i-delay) : i-delay;
  1131. color fromColor = history[fromPos];
  1132. float r = red(fromColor) * decay;
  1133. float g = green(fromColor) * decay;
  1134. float b = blue(fromColor) * decay;
  1135. color origColor = history[i];
  1136. color toColor = color(
  1137. r + red(origColor),
  1138. g + green(origColor),
  1139. b + blue(origColor) );
  1140. result.pixels[i] = history[i] = blendColor(origColor, toColor, blendMode);
  1141. }
  1142. return result;
  1143. }
  1144. PImage auEchoWTF(PImage img, int xp, int yp) {
  1145. result.resize(img.width, img.height);
  1146. float delay = map(xp, 0, 100, 0.001, 5);
  1147. float decay = map(yp, 0, 100, 0.0, 5.0);
  1148. int histPos = 0;
  1149. int histLen = img.pixels.length*3;
  1150. float[] history = new float[histLen*3];
  1151. img.loadPixels();
  1152. result.loadPixels();
  1153. float ibuf = 0.0, obuf = 0.0;
  1154. float[] rgb = new float[3];
  1155. for ( int i = 0, l = img.pixels.length; i<l; i++, histPos++) {
  1156. color c = img.pixels[i];
  1157. rgb[0] = map(red(c), 0, 255, 0, 1);
  1158. rgb[1] = map(green(c), 0, 255, 0, 1);
  1159. rgb[2] = map(blue(c), 0, 255, 0, 1);
  1160. history[i] = rgb[0];
  1161. history[i+1] = rgb[1];
  1162. history[i+2] = rgb[2];
  1163. }
  1164. for ( int i = 0, l = img.pixels.length; i<l; i++, histPos++) {
  1165. color c = img.pixels[i];
  1166. rgb[0] = map(red(c), 0, 255, 0, 1);
  1167. rgb[1] = map(green(c), 0, 255, 0, 1);
  1168. rgb[2] = map(blue(c), 0, 255, 0, 1);
  1169. if ( histPos == histLen ) histPos = 0;
  1170. for ( int ri = 0; ri < 3; ri++ ) {
  1171. history[histPos+ri] = rgb[ri] = rgb[ri] + history[histPos+ri] * decay;
  1172. }
  1173. color out = color(
  1174. (int)map(rgb[0], 0, 1, 0, 255),
  1175. (int)map(rgb[1], 0, 1, 0, 255),
  1176. (int)map(rgb[2], 0, 1, 0, 255));
  1177. result.pixels[i] = out;
  1178. }
  1179. return result;
  1180. }
  1181. }
  1182. /*
  1183. DARKER
  1184. */
  1185. class DARKER extends Shader {
  1186. float thresh = 127;
  1187. float darken = 150;
  1188. int mode = 1;
  1189. int bangCount = 0;
  1190. DARKER() {
  1191. name = "fxDarker";
  1192. params.add(new Param("count", INTVAL, 1, 4, new int[]{TRIANG, SINE, RAMPUPDOWN, TAN, TANINVERSE}));
  1193. params.add(new Param("threshold", INTVAL, 60, 180, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  1194. params.add(new Param("darken", INTVAL, 140, 220, new int[]{TRIANG, SINE, RAMPUPDOWN }));
  1195. params.add(new Param("mode", INTVAL, 0, 1, new int[]{SQUAR, RANDOM}));
  1196. //thresh = int(random(60, 180));
  1197. //darken = int(random(140, 220));
  1198. }
  1199. void apply() {
  1200. // bright = knobZero;
  1201. int count = int(params.get(0).value);
  1202. darken = int(params.get(1).value);
  1203. thresh = int(params.get(2).value);
  1204. mode = int(params.get(3).value);
  1205. canvas.beginDraw();
  1206. canvas.colorMode(HSB);
  1207. colorMode(HSB);
  1208. canvas.loadPixels();
  1209. if (mode == 0) {
  1210. for (int h = 1; h < count+1; h++) {
  1211. for (int i = 0; i < canvas.width*canvas.height; i++) {
  1212. float hue = hue(canvas.pixels[i]);
  1213. float sat = saturation(canvas.pixels[i]);
  1214. float bright = brightness(canvas.pixels[i]);
  1215. if (bright > thresh/h) {
  1216. bright -= darken/h;
  1217. constrain(bright, 0, 255);
  1218. }
  1219. color c = color(hue, sat, bright);
  1220. canvas.pixels[i] = c;
  1221. }
  1222. }
  1223. } else if (mode == 1) {
  1224. for (int h = 1; h < count+1; h++) {
  1225. for (int i = 0; i < canvas.width*canvas.height; i++) {
  1226. float hue = hue(canvas.pixels[i]);
  1227. float sat = saturation(canvas.pixels[i]);
  1228. float bright = brightness(canvas.pixels[i]);
  1229. if (bright < thresh/h) {
  1230. bright -= darken/h;
  1231. constrain(bright, 0, 255);
  1232. }
  1233. color c = color(hue, sat, bright);
  1234. canvas.pixels[i] = c;
  1235. }
  1236. }
  1237. }
  1238. canvas.updatePixels();
  1239. canvas.endDraw();
  1240. colorMode(RGB);
  1241. }
  1242. }
  1243. /*
  1244. BRIGHTER
  1245. */
  1246. class BRIGHTER extends Shader {
  1247. float thresh = 120;
  1248. float thresh2 = 150;
  1249. float brighten = 180;
  1250. float speed;
  1251. BRIGHTER() {
  1252. name = "fxBrighter";
  1253. params.add(new Param("threshold", INTVAL, 0, 255, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  1254. params.add(new Param("threshold 2", INTVAL, 0, 255, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  1255. params.add(new Param("brighten", INTVAL, 0, 255, new int[]{TRIANG, SINE, RAMPUPDOWN }));
  1256. }
  1257. void apply() {
  1258. brighten = int(params.get(2).value);
  1259. thresh2 = int(params.get(1).value);
  1260. thresh = int(params.get(0).value);
  1261. canvas.beginDraw();
  1262. canvas.colorMode(HSB);
  1263. colorMode(HSB);
  1264. canvas.loadPixels();
  1265. for (int i = 0; i < canvas.width*canvas.height; i++) {
  1266. float hue = hue(canvas.pixels[i]);
  1267. float sat = saturation(canvas.pixels[i]);
  1268. float bright = brightness(canvas.pixels[i]);
  1269. if (bright < thresh && bright > thresh2) {
  1270. bright += brighten;
  1271. constrain(bright, 0, 255);
  1272. }
  1273. color c = color(hue, sat, bright);
  1274. canvas.pixels[i] = c;
  1275. }
  1276. canvas.colorMode(RGB);
  1277. canvas.updatePixels();
  1278. canvas.endDraw();
  1279. colorMode(RGB);
  1280. }
  1281. }
  1282. /*
  1283. AMPLIFY
  1284. */
  1285. //13
  1286. class AMPLIFY extends Shader {
  1287. int spawnT;
  1288. float h, s, b;
  1289. AMPLIFY() {
  1290. name = "fxAmplify";
  1291. params.add(new Param("hue / red", FLOATVAL, -255, 255, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  1292. params.add(new Param("saturation / green", FLOATVAL, -255, 255, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  1293. params.add(new Param("brightness / blue", FLOATVAL, -255, 255, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  1294. params.add(new Param("RGB / HSB", INTVAL, 0, 1, new int[]{SQUAR, RANDOM}));
  1295. }
  1296. void apply() {
  1297. canvas.beginDraw();
  1298. if (params.get(3).value > 0) colorMode(HSB);
  1299. else {
  1300. colorMode(RGB);
  1301. }
  1302. canvas.loadPixels();
  1303. for (int i = 0; i < canvas.width*canvas.height; i++) {
  1304. float h = hue(canvas.pixels[i]);
  1305. float s = saturation(canvas.pixels[i]);
  1306. float b = brightness(canvas.pixels[i]);
  1307. canvas.pixels[i] = color(h+params.get(0).value, s+params.get(1).value, b+params.get(2).value);
  1308. }
  1309. canvas.updatePixels();
  1310. canvas.endDraw();
  1311. colorMode(RGB);
  1312. }
  1313. }
  1314. /*
  1315. BROKENCOLORROT
  1316. */
  1317. class BROKENCOLORROT extends Shader {
  1318. int spawnT;
  1319. float h, s, b;
  1320. BROKENCOLORROT() {
  1321. name = "fxBrokenColorRot";
  1322. params.add(new Param("hue", INTVAL, 0, 255, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  1323. params.add(new Param("saturation", INTVAL, 0, 255, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  1324. params.add(new Param("brightness", INTVAL, 0, 255, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  1325. params.add(new Param("mode", INTVAL, 0, 1, new int[]{SQUAR, RANDOM}));
  1326. params.add(new Param("direction", INTVAL, 0, 3, new int[]{RANDOM}));
  1327. directionParamIndex = 4;
  1328. }
  1329. void apply() {
  1330. canvas.beginDraw();
  1331. if (params.get(3).value > 0) colorMode(HSB);
  1332. else {
  1333. colorMode(RGB);
  1334. }
  1335. canvas.loadPixels();
  1336. float h = params.get(0).value;
  1337. float s = params.get(1).value;
  1338. float b = params.get(2).value;
  1339. for (int i = 0; i < canvas.width*canvas.height; i++) {
  1340. h = hue(canvas.pixels[i])+h;
  1341. if (h > 255) h -= 255;
  1342. s = saturation(canvas.pixels[i])+s;
  1343. if (s > 255) s -= 255;
  1344. b = brightness(canvas.pixels[i])+b;
  1345. if (b > 255) b -= 255;
  1346. canvas.pixels[i] = color(h, s, b);
  1347. }
  1348. canvas.updatePixels();
  1349. canvas.endDraw();
  1350. colorMode(RGB);
  1351. }
  1352. }
  1353. /*
  1354. POSTERIZE
  1355. */
  1356. class POSTER extends Shader {
  1357. POSTER() {
  1358. name = "fxPosterize";
  1359. params.add(new Param("levels", INTVAL, 2, 10, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  1360. }
  1361. void apply() {
  1362. canvas.beginDraw();
  1363. canvas.filter(POSTERIZE, (int)params.get(0).value);
  1364. canvas.endDraw();
  1365. }
  1366. }
  1367. /*
  1368. DUAL
  1369. */
  1370. class DUAL extends Shader {
  1371. PImage buffer;
  1372. int dualColor;
  1373. int dirx = 1;
  1374. int diry = 1;
  1375. DUAL() {
  1376. name = "fxDual";
  1377. params.add(new Param("dual color", INTVAL, 2000000, 15000000, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  1378. params.add(new Param("flip direction", INTVAL, 0, 3, new int[]{RANDOM}));
  1379. params.add(new Param("mode", INTVAL, 0, 1, new int[]{SQUAR, RANDOM}));
  1380. params.add(new Param("direction", INTVAL, 0, 3, new int[]{RANDOM}));
  1381. directionParamIndex = 3;
  1382. buffer = createImage(canvas.width, canvas.height, ARGB);
  1383. }
  1384. void apply() {
  1385. switch((int)params.get(1).value) {
  1386. case(0):
  1387. dirx = 1;
  1388. diry = 1;
  1389. break;
  1390. case(1):
  1391. dirx = -1;
  1392. diry = 1;
  1393. break;
  1394. case(2):
  1395. dirx = 1;
  1396. diry = -1;
  1397. break;
  1398. case(3):
  1399. dirx = -1;
  1400. diry = -1;
  1401. break;
  1402. }
  1403. dualColor = (int)params.get(0).value;
  1404. buffer.resize(canvas.width, canvas.height);
  1405. canvas.beginDraw();
  1406. canvas.imageMode(CORNER);
  1407. canvas.loadPixels();
  1408. buffer.loadPixels();
  1409. if ((int)params.get(2).value > 0) {
  1410. for (int i = 0; i < canvas.width*canvas.height; i++) {
  1411. buffer.pixels[i] = canvas.pixels[i]+dualColor;
  1412. }
  1413. } else {
  1414. for (int i = 0; i < canvas.width*canvas.height; i++) {
  1415. buffer.pixels[i] = canvas.pixels[i]+dualColor;
  1416. buffer.pixels[i] = buffer.pixels[i]+i/10;
  1417. }
  1418. }
  1419. buffer.updatePixels();
  1420. canvas.updatePixels();
  1421. canvas.pushMatrix();
  1422. canvas.scale(dirx, diry);
  1423. canvas.image(buffer, 0, 0, dirx * canvas.width, diry * canvas.height);
  1424. canvas.popMatrix();
  1425. canvas.endDraw();
  1426. }
  1427. }
  1428. /*
  1429. GRAUZONE
  1430. */
  1431. class GRAUZONE extends Shader {
  1432. int nFrames = 20;
  1433. int iWrite = 0, iRead = 1;
  1434. PImage[] buffer;
  1435. PGraphics grauz;
  1436. GRAUZONE() {
  1437. name = "fxGrauzone";
  1438. params.add(new Param("delay (in frames)", INTVAL, 3, 100, new int[]{RANDOM}));
  1439. nFrames = (int)params.get(0).value;
  1440. buffer = new PImage[nFrames];
  1441. }
  1442. int nFramesPrev;
  1443. void apply() {
  1444. nFramesPrev = nFrames;
  1445. if (nFramesPrev != (int)params.get(0).value) {
  1446. iWrite = 0;
  1447. iRead = 1;
  1448. int nFramesOld = nFrames;
  1449. nFrames = (int)params.get(0).value;
  1450. if (nFrames > nFramesOld) {
  1451. buffer = new PImage[nFrames];
  1452. }
  1453. }
  1454. buffer[iWrite] = canvas.get();
  1455. grauz = createGraphics(canvas.width, canvas.height);
  1456. grauz.beginDraw();
  1457. // grauz.resize(canvas.width, canvas.height);
  1458. buffer[iWrite] = canvas.get();
  1459. if (buffer[iRead] != null) {
  1460. grauz.tint(255, 127);
  1461. buffer[iRead].filter(INVERT);
  1462. grauz.image(buffer[iRead], 0, 0, canvas.width, canvas.height);
  1463. grauz.tint(255, 255);
  1464. }
  1465. grauz.endDraw();
  1466. canvas.beginDraw();
  1467. canvas.imageMode(CORNER);
  1468. canvas.image(grauz, 0, 0, canvas.width, canvas.height);
  1469. canvas.endDraw();
  1470. iWrite++;
  1471. iRead++;
  1472. if (iRead >= nFrames-1) {
  1473. iRead = 0;
  1474. }
  1475. if (iWrite >= nFrames-1) {
  1476. iWrite = 0;
  1477. }
  1478. }
  1479. }
  1480. /*
  1481. COPYZOOM
  1482. */
  1483. class COPYZOOM extends Shader {
  1484. int coprx, copry, coprw, coprh;
  1485. PImage buffer;
  1486. COPYZOOM() {
  1487. name = "fxCopyZoom";
  1488. params.add(new Param("w", FLOATVAL, 0, 1, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  1489. params.add(new Param("h", FLOATVAL, 0, 1, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  1490. params.add(new Param("x", FLOATVAL, 0, 1, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  1491. params.add(new Param("y", FLOATVAL, 0, 1, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  1492. buffer = createImage(canvas.width, canvas.height, ARGB);
  1493. }
  1494. void apply() {
  1495. canvas.imageMode(CORNER);
  1496. if (buffer.width != canvas.width || buffer.height != canvas.height) buffer.resize(canvas.width, canvas.height);
  1497. buffer = canvas.get();
  1498. coprw = int(map(params.get(0).value, 0, 1, 1, canvas.width));
  1499. coprh = int(map(params.get(1).value, 0, 1, 1, canvas.height));
  1500. coprx = int(map(params.get(2).value, 0, 1, 0, canvas.width-coprw));
  1501. copry = int(map(params.get(3).value, 0, 1, 0, canvas.height-coprh));
  1502. canvas.beginDraw();
  1503. buffer.copy(coprx, copry, coprw, coprh, 0, 0, canvas.width, canvas.height);
  1504. canvas.image(buffer, 0, 0, canvas.width, canvas.height);
  1505. canvas.endDraw();
  1506. }
  1507. }
  1508. /*
  1509. SUBTLESORT
  1510. */
  1511. class SUBTLESORT extends Shader {
  1512. int direction = 0;
  1513. int mode = 0;
  1514. int c;
  1515. //int count = int(random(777));
  1516. color col;
  1517. final static int RED = 0;
  1518. final static int GREEN = 1;
  1519. final static int BLUE = 2;
  1520. final static int HUE = 3;
  1521. final static int SATURATION = 4;
  1522. final static int BRIGHTNESS = 5;
  1523. final static int NRED = 6;
  1524. final static int NGREEN = 7;
  1525. final static int NBLUE = 8;
  1526. final static int NHUE = 9;
  1527. final static int NSATURATION = 10;
  1528. final static int NBRIGHTNESS = 11;
  1529. // channels for depth: RED, GREEN, BLUE, HUE, SATURATION, BRIGHTNESS, NRED, NGREEN, NBLUE, NHUE, NSATURATION, NBRIGHTNESS.
  1530. int channel = BRIGHTNESS;
  1531. // channel weight.
  1532. float channel_weight = .2;
  1533. //
  1534. SUBTLESORT() {
  1535. name ="fxSubtleSort";
  1536. params.add(new Param ("channel weight", FLOATVAL, 0.001, 20, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  1537. params.add(new Param ("channel", INTVAL, 0, 6, new int[]{RANDOM}));
  1538. //params.add(new Param("direction", INTVAL, 0, 3, new int[]{RANDOM}));
  1539. params.add(new Param("mode", INTVAL, 0, 1, new int[]{SQUARE, RANDOM}));
  1540. params.add(new Param("direction", INTVAL, 0, 3, new int[]{RANDOM}));
  1541. directionParamIndex = 3;
  1542. }
  1543. void apply() {
  1544. channel_weight = map(renderSize, 4, 15000, 0, 1.5)*params.get(0).value;
  1545. channel = (int)params.get(1).value;
  1546. direction = (int)params.get(2).value;
  1547. mode = (int)params.get(3).value;
  1548. canvas.beginDraw();
  1549. canvas.noStroke();
  1550. //if (direction == 0) {
  1551. for (int i = 0; i < canvas.width; i++) {
  1552. for (int j = 0; j < canvas.height; j++) {
  1553. c = i+(j*canvas.width);
  1554. col = canvas.pixels[c];
  1555. canvas.fill(col);
  1556. canvas.rect(i, j+(getChannel(col)), 1, getChannel(col));
  1557. }
  1558. }
  1559. //}
  1560. /*else if (direction == 1) {
  1561. for (int i = 0; i < canvas.width; i++) {
  1562. for (int j = 0; j < canvas.height; j++) {
  1563. c = i+(j*canvas.width);
  1564. col = canvas.pixels[c];
  1565. canvas.fill(col);
  1566. canvas.rect(i, j-(getChannel(col)*mode), 1, -getChannel(col));
  1567. }
  1568. }
  1569. } else if (direction == 2) {
  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-(getChannel(col)*mode), j, -getChannel(col), 1);
  1576. }
  1577. }
  1578. } else if (direction == 3) {
  1579. for (int i = 0; i < canvas.width; i++) {
  1580. for (int j = 0; j < canvas.height; j++) {
  1581. c = i+(j*canvas.width);
  1582. col = canvas.pixels[c];
  1583. canvas.fill(col);
  1584. canvas.rect(i+(getChannel(col)), j, getChannel(col), 1);
  1585. }
  1586. }
  1587. }*/
  1588. canvas.endDraw();
  1589. }
  1590. float getChannel(color c) {
  1591. int ch = channel;
  1592. float cc;
  1593. switch(ch) {
  1594. case RED:
  1595. cc = red(c);
  1596. break;
  1597. case GREEN:
  1598. cc = green(c);
  1599. break;
  1600. case BLUE:
  1601. cc = blue(c);
  1602. break;
  1603. case HUE:
  1604. cc = hue(c);
  1605. break;
  1606. case SATURATION:
  1607. cc = saturation(c);
  1608. break;
  1609. default:
  1610. cc= brightness(c);
  1611. break;
  1612. }
  1613. return channel_weight * (channel>5?255-cc:cc);
  1614. }
  1615. }
  1616. /*
  1617. SCANKER
  1618. */
  1619. class SCANKER extends Shader {
  1620. int mode;
  1621. SCANKER() {
  1622. name = "fxScanker";
  1623. params.add(new Param ("detail level 1", FLOATVAL, 0.001, 1000, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  1624. params.add(new Param ("detail level 2", FLOATVAL, -50, 50, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  1625. params.add(new Param ("detail level 3", FLOATVAL, -5, 5, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  1626. params.add(new Param ("mode", INTVAL, 0, 1, new int[]{RANDOM, SQUAR}));
  1627. params.add(new Param("direction", INTVAL, 0, 3, new int[]{RANDOM}));
  1628. directionParamIndex = 4;
  1629. }
  1630. void apply() {
  1631. mode = (int)params.get(3).value;
  1632. canvas.beginDraw();
  1633. canvas.loadPixels();
  1634. float factor = params.get(0).value + params.get(1).value + params.get(2).value;
  1635. if (mode == 0) {
  1636. for (int i = 0; i < canvas.width*canvas.height; i++) {
  1637. // canvas.pixels[i] = canvas.pixels[i]+((i/1000)*scankMulti);
  1638. canvas.pixels[i] = canvas.pixels[i]-int(map(i, 0, canvas.width*canvas.height, 0, source.width*source.height)/10*factor);
  1639. }
  1640. } else if (mode == 1) {
  1641. for (int i = 0; i < canvas.width*canvas.height; i++) {
  1642. // canvas.pixels[i] = canvas.pixels[i]+((i/1000)*scankMulti);
  1643. canvas.pixels[i] = canvas.pixels[i]+int(map(i, 0, canvas.width*canvas.height, 0, source.width*source.height)/10*factor);
  1644. }
  1645. }
  1646. canvas.updatePixels();
  1647. canvas.endDraw();
  1648. }
  1649. }
  1650. /*
  1651. MASK
  1652. */
  1653. class MASK extends Shader {
  1654. int backgroundLayer, maskLayer, bandwidth, val, chan, shaderListLength, invert, blend_mode;
  1655. boolean do_blend;
  1656. PImage mask;
  1657. PImage background;
  1658. PImage foreground;
  1659. MASK() {
  1660. name = "mask";
  1661. shaderListLength = gui.shaderList.size();
  1662. params.add(new Param("target layer", INTVAL, 0, shaderListLength-2, new int[]{RANDOM}));
  1663. params.add(new Param("mask layer", INTVAL, 0, shaderListLength-1, new int[]{RANDOM}));
  1664. params.add(new Param("invert", INTVAL, 0, 1, new int[]{RANDOM, SQUAR}));
  1665. params.add(new Param("bandwidth", INTVAL, 0, 255, new int[]{TRIANG, SINE}));
  1666. params.add(new Param("value", INTVAL, 1, 255, new int[]{TRIANG, SINE}));
  1667. params.add(new Param("channel (R/G/B/H/S/V", INTVAL, 0, 5, new int[]{RANDOM}));
  1668. params.add(new Param("do blend", INTVAL, 0, 1, new int[]{RANDOM}));
  1669. params.add(new Param("blend mode", INTVAL, 0, blends.length-1, new int[]{RANDOM}));
  1670. background = createImage(canvas.width, canvas.height, ARGB);
  1671. mask = createImage(canvas.width, canvas.height, ARGB);
  1672. foreground = createImage(canvas.width, canvas.height, ARGB);
  1673. }
  1674. void apply() {
  1675. if (shaderListLength != gui.shaderList.size()) {
  1676. shaderListLength = gui.shaderList.size();
  1677. changeParam(0, new Param("target layer", INTVAL, 0, shaderListLength-2, new int[]{RANDOM}));
  1678. changeParam(1, new Param("mask layer", INTVAL, 0, shaderListLength-1, new int[]{RANDOM}));
  1679. }
  1680. if (mask.width != canvas.width || mask.height != canvas.height) mask.resize(canvas.width, canvas.height);
  1681. if (background.width != canvas.width || background.height != canvas.height) background.resize(canvas.width, canvas.height);
  1682. if (foreground.width != canvas.width || foreground.height != canvas.height) foreground.resize(canvas.width, canvas.height);
  1683. backgroundLayer = (int)params.get(0).value;
  1684. maskLayer = (int)params.get(1).value;
  1685. invert = (int)params.get(2).value;
  1686. bandwidth = (int)params.get(3).value;
  1687. val = (int)params.get(4).value;
  1688. chan = (int)params.get(5).value;
  1689. do_blend = boolean((int)params.get(6).value);
  1690. blend_mode = blends[(int)params.get(7).value];
  1691. if (backgroundLayer <= 0) {
  1692. background.resize(source.width, source.height);
  1693. background = source.get();
  1694. background.resize(canvas.width, canvas.height);
  1695. } else background = gui.shaderList.get(backgroundLayer-1).result.get();
  1696. if (maskLayer <= 0) {
  1697. mask.resize(source.width, source.height);
  1698. mask = source.get();
  1699. mask.resize(canvas.width, canvas.height);
  1700. } else mask = gui.shaderList.get(maskLayer-1).result.get();
  1701. canvas.beginDraw();
  1702. canvas.imageMode(CORNER);
  1703. mask.loadPixels();
  1704. foreground.loadPixels();
  1705. canvas.loadPixels();
  1706. if (boolean(invert)) {
  1707. for (int i = 0; i < canvas.width * canvas.height; i++) {
  1708. if (!thresh(color(mask.pixels[i])))
  1709. foreground.pixels[i] = canvas.pixels[i];
  1710. else
  1711. foreground.pixels[i] = background.pixels[i];
  1712. }
  1713. } else {
  1714. for (int i = 0; i < canvas.width * canvas.height; i++) {
  1715. if (thresh(color(mask.pixels[i])))
  1716. foreground.pixels[i] = canvas.pixels[i];
  1717. else
  1718. foreground.pixels[i] = background.pixels[i];
  1719. }
  1720. }
  1721. canvas.updatePixels();
  1722. foreground.updatePixels();
  1723. mask.updatePixels();
  1724. if (do_blend)
  1725. canvas.blend(foreground, 0, 0, foreground.width, foreground.height, 0, 0, canvas.width, canvas.height, blend_mode);
  1726. else
  1727. canvas.image(foreground, 0, 0, canvas.width, canvas.height);
  1728. canvas.endDraw();
  1729. }
  1730. boolean thresh(color c) {
  1731. switch(chan) {
  1732. case(0):
  1733. if (red(c) > val - bandwidth && red(c) < val + bandwidth)
  1734. return(true);
  1735. else
  1736. return(false);
  1737. case(1):
  1738. if (green(c) > val - bandwidth && green(c) < val + bandwidth)
  1739. return(true);
  1740. else
  1741. return(false);
  1742. case(2):
  1743. if (blue(c) > val - bandwidth && blue(c) < val + bandwidth)
  1744. return(true);
  1745. else
  1746. return(false);
  1747. case(3):
  1748. if (hue(c) > val - bandwidth && hue(c) < val + bandwidth)
  1749. return(true);
  1750. else
  1751. return(false);
  1752. case(4):
  1753. if (saturation(c) > val - bandwidth && saturation(c) < val + bandwidth)
  1754. return(true);
  1755. else
  1756. return(false);
  1757. case(5):
  1758. if (brightness(c) > val - bandwidth && brightness(c) < val + bandwidth)
  1759. return(true);
  1760. else
  1761. return(false);
  1762. }
  1763. return(false);
  1764. }
  1765. }
  1766. class DRAWSTROKES extends Shader {
  1767. int stat_type = ABSDIST2; // type of diff calculation: fast: ABSDIST, DIST, slow: HUE, SATURATION, BRIGHTNESS
  1768. int stroke_len = 3; // length of the stroke, values: 1 and above
  1769. int angles_no = 30; // number of directions stroke can be drew, 2 and above
  1770. int segments = 500; // number of segments of single thread
  1771. float stroke_width = 1; // width of the stroke, 0.5 - 3
  1772. int stroke_alpha = 100; // alpha channel of the stroke: 30 - 200
  1773. color background_color = color(255, 255, 255); // RGB
  1774. boolean interactive = false;
  1775. int max_display_size = 800; // viewing window size (regardless image size)
  1776. int len;
  1777. // working buffer
  1778. PGraphics buffer;
  1779. int currx, curry;
  1780. int[] sintab, costab;
  1781. int sqwidth;
  1782. int iterations;
  1783. int calcDiff(PImage img1, PImage img2) {
  1784. int err = 0;
  1785. for (int i=0; i<img1.pixels.length; i++)
  1786. err += getStat(img1.pixels[i], img2.pixels[i]);
  1787. return err;
  1788. }
  1789. DRAWSTROKES() {
  1790. name = "fxDrawStrokes";
  1791. 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
  1792. params.add(new Param ("stroke length", INTVAL, 1, 10, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  1793. params.add(new Param ("amount of angles", INTVAL, 2, 30, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  1794. params.add(new Param ("amount of segments", INTVAL, 50, 1500, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  1795. params.add(new Param ("stroke width", FLOATVAL, 0.5, 5, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  1796. params.add(new Param ("stroke transparency", INTVAL, 30, 220, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  1797. params.add(new Param ("iterations", INTVAL, 1, 500, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  1798. len = (renderer.width<renderer.height?renderer.width:renderer.height)/3;
  1799. buffer = createGraphics(renderer.width, renderer.height);
  1800. buffer.smooth(2);
  1801. buffer.beginDraw();
  1802. buffer.strokeWeight(stroke_width);
  1803. buffer.noFill();
  1804. buffer.endDraw();
  1805. rw = renderer.width;
  1806. rh = renderer.height;
  1807. }
  1808. int rw, rh;
  1809. void apply() {
  1810. stat_type = (int)params.get(0).value;
  1811. stroke_len = (int)params.get(1).value;
  1812. angles_no = (int)params.get(2).value;
  1813. segments = (int)params.get(3).value;
  1814. stroke_width = params.get(4).value;
  1815. stroke_alpha = (int)params.get(5).value;
  1816. iterations = (int)params.get(6).value;
  1817. if (rw != canvas.width || rh != canvas.height) { //doesnt account image swap
  1818. len = (canvas.width<canvas.height?canvas.width:canvas.height)/3;
  1819. rw = canvas.width;
  1820. rh = canvas.height;
  1821. PGraphics save = createGraphics(canvas.width, canvas.height);
  1822. save.beginDraw();
  1823. save.image(buffer, 0, 0, save.width, save.height);
  1824. save.endDraw();
  1825. buffer.setSize(canvas.width, canvas.height);
  1826. buffer.beginDraw();
  1827. buffer.image(save, 0, 0, buffer.width, buffer.height); // ????
  1828. buffer.endDraw();
  1829. }
  1830. for (int j = 0; j < iterations; j++) {
  1831. currx = (int)random(canvas.width);
  1832. curry = (int)random(canvas.height);
  1833. sintab = new int[angles_no];
  1834. costab = new int[angles_no];
  1835. for (int i=0; i<angles_no; i++) {
  1836. sintab[i] = (int)(stroke_len * sin(TWO_PI*i/(float)angles_no));
  1837. costab[i] = (int)(stroke_len * cos(TWO_PI*i/(float)angles_no));
  1838. }
  1839. sqwidth = stroke_len * 2 + 4;
  1840. buffer.beginDraw();
  1841. buffer.strokeWeight(stroke_width);
  1842. //draw whole segment using current color
  1843. buffer.stroke(canvas.get(currx, curry), stroke_alpha);
  1844. for (int iter=0; iter<segments; iter++) {
  1845. // corners of square containing new strokes
  1846. int corx = currx-stroke_len-2;
  1847. int cory = curry-stroke_len-2;
  1848. // take square from image and current screen
  1849. PImage imgpart = canvas.get(corx, cory, sqwidth, sqwidth);
  1850. PImage mypart = buffer.get(corx, cory, sqwidth, sqwidth);
  1851. imgpart.loadPixels();
  1852. mypart.loadPixels();
  1853. // calc current diff
  1854. float localerr = calcDiff(imgpart, mypart);
  1855. // chosen stroke will be here
  1856. PImage destpart = null;
  1857. int _nx=currx, _ny=curry;
  1858. // start with random angle
  1859. int i = (int)random(angles_no);
  1860. int iterangles = angles_no;
  1861. while (iterangles-- > 0) {
  1862. // take end points
  1863. int nx = currx + costab[i];
  1864. int ny = curry + sintab[i];
  1865. // if not out of the screen
  1866. if (nx>=0 && nx<canvas.width-1 && ny>=0 && ny<canvas.height-1) {
  1867. // clean region and draw line
  1868. buffer.image(mypart, corx, cory);
  1869. buffer.line(currx, curry, nx, ny);
  1870. // take region with line and calc diff
  1871. PImage curr = buffer.get(corx, cory, sqwidth, sqwidth);
  1872. curr.loadPixels();
  1873. int currerr = calcDiff(imgpart, curr);
  1874. // if better, remember this region and line endpoint
  1875. if (currerr < localerr) {
  1876. destpart = curr;
  1877. _nx = nx;
  1878. _ny = ny;
  1879. localerr = currerr;
  1880. }
  1881. }
  1882. // next angle
  1883. i = (i+1)%angles_no;
  1884. }
  1885. // if we have new stroke, draw it
  1886. if (destpart != null) {
  1887. buffer.image(destpart, corx, cory);
  1888. currx = _nx;
  1889. curry = _ny;
  1890. } else {
  1891. break; // skip
  1892. }
  1893. }
  1894. buffer.endDraw();
  1895. }
  1896. canvas.beginDraw();
  1897. canvas.image(buffer, canvas.width/2, canvas.height/2);
  1898. canvas.endDraw();
  1899. }
  1900. final static int DIST = 0;
  1901. final static int HUE = 1;
  1902. final static int BRIGHTNESS = 2;
  1903. final static int SATURATION = 3;
  1904. final static int ABSDIST = 4;
  1905. final static int ABSDIST2 = 5;
  1906. final float getStat(color c1, color c2) {
  1907. switch(stat_type) {
  1908. case HUE:
  1909. abs(hue(c1)-hue(c2));
  1910. case BRIGHTNESS:
  1911. abs(brightness(c1)-brightness(c2));
  1912. case SATURATION:
  1913. abs(saturation(c1)-saturation(c2));
  1914. case ABSDIST:
  1915. return abs(red(c1)-red(c2))+abs(green(c1)-green(c2))+abs(blue(c1)-blue(c2));
  1916. case ABSDIST2:
  1917. return abs( (red(c1)+blue(c1)+green(c1)) - (red(c2)+blue(c2)+green(c2)) );
  1918. default:
  1919. return sq(red(c1)-red(c2)) + sq(green(c1)-green(c2)) + sq(blue(c1)-blue(c2));
  1920. }
  1921. }
  1922. }
  1923. /*
  1924. DRAWGENERATIVE
  1925. */
  1926. class DRAWGENERATIVE extends Shader {
  1927. // choose channel
  1928. int channel = HUE;
  1929. // run, after 30 iterations result will be saved automatically
  1930. // or press SPACE
  1931. // channels to work with
  1932. final static int RED = 0;
  1933. final static int GREEN = 1;
  1934. final static int BLUE = 2;
  1935. final static int HUE = 3;
  1936. final static int SATURATION = 4;
  1937. final static int BRIGHTNESS = 5;
  1938. final static int NRED = 6;
  1939. final static int NGREEN = 7;
  1940. final static int NBLUE = 8;
  1941. final static int NHUE = 9;
  1942. final static int NSATURATION = 10;
  1943. final static int NBRIGHTNESS = 11;
  1944. int n=2000;
  1945. float [] cx=new float[n];
  1946. float [] cy=new float[n];
  1947. int len;
  1948. // working buffer
  1949. PGraphics buffer;
  1950. int tick = 0;
  1951. DRAWGENERATIVE() {
  1952. name = "fxDrawGenerative";
  1953. 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
  1954. buffer = createGraphics(renderer.width, renderer.height);
  1955. buffer.noFill();
  1956. buffer.beginDraw();
  1957. //buffer.background(0); //ENABLE THIS TO DRAW FROM BLANK
  1958. buffer.endDraw();
  1959. rw = canvas.width;
  1960. rh = canvas.height;
  1961. len = (canvas.width<canvas.height?canvas.width:canvas.height)/6;
  1962. for (int i=0; i<n; i++) {
  1963. cx[i]=random(canvas.width);
  1964. cy[i]=random(canvas.height);
  1965. }
  1966. }
  1967. int rw, rh;
  1968. void apply() {
  1969. if (rw != canvas.width || rh != canvas.height) {
  1970. rw = canvas.width;
  1971. rh = canvas.height;
  1972. PGraphics save = createGraphics(canvas.width, canvas.height);
  1973. save.beginDraw();
  1974. save.image(buffer, 0, 0, save.width, save.height);
  1975. save.endDraw();
  1976. buffer.setSize(canvas.width, canvas.height);
  1977. buffer.beginDraw();
  1978. buffer.image(save, 0, 0, buffer.width, buffer.height);
  1979. buffer.endDraw();
  1980. }
  1981. buffer.beginDraw();
  1982. buffer.strokeWeight(params.get(0).value);
  1983. for (int i=1; i<n; i++) {
  1984. color c = canvas.get((int)cx[i], (int)cy[i]);
  1985. buffer.stroke(c);
  1986. buffer.point(cx[i], cy[i]);
  1987. // you can choose channels: red(c), blue(c), green(c), hue(c), saturation(c) or brightness(c)
  1988. cy[i]+=sin(map(getChannel(c), 0, 255, 0, TWO_PI));
  1989. cx[i]+=cos(map(getChannel(c), 0, 255, 0, TWO_PI));
  1990. }
  1991. if (frameCount>len) {
  1992. frameCount=0;
  1993. //println("iteration: " + tick++);
  1994. for (int i=0; i<n; i++) {
  1995. cx[i]=random(canvas.width); //same problem as in slitscan here
  1996. cy[i]=random(canvas.height);
  1997. }
  1998. }
  1999. buffer.endDraw();
  2000. canvas.beginDraw();
  2001. canvas.image(buffer, canvas.width/2, canvas.height/2);
  2002. canvas.endDraw();
  2003. }
  2004. float getChannel(color c) {
  2005. int ch = channel>5?channel-6:channel;
  2006. float cc;
  2007. switch(ch) {
  2008. case RED:
  2009. cc = red(c);
  2010. break;
  2011. case GREEN:
  2012. cc = green(c);
  2013. break;
  2014. case BLUE:
  2015. cc = blue(c);
  2016. break;
  2017. case HUE:
  2018. cc = hue(c);
  2019. break;
  2020. case SATURATION:
  2021. cc = saturation(c);
  2022. break;
  2023. default:
  2024. cc= brightness(c);
  2025. break;
  2026. }
  2027. return channel>5?255-cc:cc;
  2028. }
  2029. }
  2030. /*
  2031. PIXELDRIFTER
  2032. */
  2033. class PIXELDRIFTER extends Shader {
  2034. int channel = HUE; // channel data used for shift
  2035. float channel_off = 60; // channel value offset
  2036. int iteration_no = 50; // number of iterations 1-100
  2037. int max_iter = iteration_no;
  2038. int direction = UP; // UP, DOWN, LEFT, RIGHT
  2039. boolean automate_channel_offset = false; // if true, change channel_offset every iteration
  2040. float scale = 0.03; // 0.01 - 0.1, step size (0.01: 2px, 0.1:25px)
  2041. float feedback = 0.9; // 0.9 - 0.999 ; blend ratio with original image
  2042. boolean do_blend = false; // blend image after process
  2043. int blend_mode = OVERLAY; // blend type
  2044. // working buffer
  2045. PGraphics buffer;
  2046. // image
  2047. PImage imgb;
  2048. PImage img;
  2049. String sessionid;
  2050. float acho_step;
  2051. int rw, rh;
  2052. PIXELDRIFTER() {
  2053. name = "fxPixelDrifter";
  2054. params.add(new Param ("channel offset", FLOATVAL, 0, 1, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  2055. params.add(new Param ("iterations", INTVAL, 1, 100, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  2056. params.add(new Param ("step size", FLOATVAL, 0.01, 0.1, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  2057. params.add(new Param ("feedback", FLOATVAL, 0.1, 1, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  2058. params.add(new Param ("direction", INTVAL, 37, 40, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  2059. params.add(new Param ("do blend", INTVAL, 0, 1, new int[]{RANDOM, SQUAR}));
  2060. params.add(new Param ("blend mode", INTVAL, 0, blends.length-1, new int[]{RANDOM}));
  2061. params.add(new Param ("channel", INTVAL, 0, 1, new int[]{SQUAR, RANDOM}));
  2062. params.add(new Param ("automate channel offset", INTVAL, 0, 1, new int[]{SQUAR, RANDOM}));
  2063. rw = canvas.width;
  2064. rh = canvas.height;
  2065. img = createImage(rw, rh, ARGB);
  2066. buffer = createGraphics(rw, rh);
  2067. buffer.beginDraw();
  2068. buffer.noStroke();
  2069. buffer.smooth(8);
  2070. buffer.background(0);
  2071. buffer.image(img, 0, 0);
  2072. buffer.endDraw();
  2073. scale = abs(scale);
  2074. }
  2075. void apply() {
  2076. if (rw != canvas.width || rh != canvas.height) {
  2077. rw = canvas.width;
  2078. rh = canvas.height;
  2079. img.resize(rw, rh);
  2080. buffer = createGraphics(rw, rh);
  2081. }
  2082. channel_off = map(params.get(0).value, 0, 1, 10, max(rw, rh));
  2083. iteration_no = (int)params.get(1).value;
  2084. scale = params.get(2).value;
  2085. feedback = params.get(3).value;
  2086. direction = (int)params.get(4).value;
  2087. do_blend = boolean((int)params.get(5).value);
  2088. blend_mode = blends[(int)params.get(6).value];
  2089. channel = (int)params.get(7).value == 1 ? HUE : RGB;
  2090. automate_channel_offset = boolean((int)params.get(8).value);
  2091. acho_step = 256.0 / iteration_no;
  2092. img = canvas.get();
  2093. // if (iteration_no>0) {
  2094. for (int i = 0; i < iteration_no; i++) {
  2095. processImage();
  2096. }
  2097. //iteration_no--;
  2098. //iteration_no=(iteration_no==0)?max_iter:iteration_no;
  2099. // if (iteration_no == 0)
  2100. // iteration_no = 50;
  2101. // }
  2102. // } else {
  2103. canvas.beginDraw();
  2104. if (do_blend) {
  2105. canvas.blend(img, 0, 0, img.width, img.height, 0, 0, canvas.width, canvas.height, blend_mode);
  2106. } else {
  2107. canvas.image(buffer, canvas.width/2, canvas.height/2, canvas.width, canvas.height);
  2108. }
  2109. canvas.endDraw();
  2110. // canvas.image(img, 0, 0, renderer.width, renderer.height);
  2111. // noLoop();
  2112. // }
  2113. }
  2114. void processImage() {
  2115. buffer.beginDraw();
  2116. for (int x=0; x<img.width; x++) {
  2117. for (int y=0; y<img.height; y++) {
  2118. color c = img.get(x, y);
  2119. color c2;
  2120. if (direction == UP || direction == DOWN) {
  2121. c2 = img.get(x, ((int)(y+img.height+( (channel_off+getChannel(c, channel))%255 )*(direction==DOWN?-1.0:1.0)*scale))%img.height);
  2122. } else {
  2123. c2 = img.get(((int)(x+img.width+( (channel_off+getChannel(c, channel))%255)*(direction==RIGHT?-1.0:1.0)*scale))%img.width, y);
  2124. }
  2125. buffer.set(x, y, lerpColor(c, c2, feedback) );
  2126. }
  2127. }
  2128. buffer.endDraw();
  2129. //canvas.image(buffer, 0, 0, width, height);
  2130. img = buffer.get();
  2131. if (automate_channel_offset) channel_off += acho_step;
  2132. }
  2133. // ALL Channels, Nxxx stand for negative (255-value)
  2134. // channels to work with
  2135. final static int RED = 0;
  2136. final static int GREEN = 1;
  2137. final static int BLUE = 2;
  2138. final static int HUE = 3;
  2139. final static int SATURATION = 4;
  2140. final static int BRIGHTNESS = 5;
  2141. final static int NRED = 6;
  2142. final static int NGREEN = 7;
  2143. final static int NBLUE = 8;
  2144. final static int NHUE = 9;
  2145. final static int NSATURATION = 10;
  2146. final static int NBRIGHTNESS = 11;
  2147. float getChannel(color c, int channel) {
  2148. int ch = channel>5?channel-6:channel;
  2149. float cc;
  2150. switch(ch) {
  2151. case RED:
  2152. cc = red(c);
  2153. break;
  2154. case GREEN:
  2155. cc = green(c);
  2156. break;
  2157. case BLUE:
  2158. cc = blue(c);
  2159. break;
  2160. case HUE:
  2161. cc = hue(c);
  2162. break;
  2163. case SATURATION:
  2164. cc = saturation(c);
  2165. break;
  2166. default:
  2167. cc= brightness(c);
  2168. break;
  2169. }
  2170. return channel>5?255-cc:cc;
  2171. }
  2172. }
  2173. /*
  2174. DRIPDRIP
  2175. */
  2176. class DRIPDRIP extends Shader {
  2177. int maxsteps = 50; //maximum fade length in px
  2178. int minsteps = 2; //minimum fade length in px
  2179. Boolean brightmode = false; //if enabled will fade light over dark
  2180. Boolean autotoggle = true; //switch brightmode at pivot point
  2181. float autoPivot = 0.58; //where on the y axis (0-1) to switch
  2182. int steps[];
  2183. int rw, rh;
  2184. DRIPDRIP() {
  2185. name = "fxDripDrip";
  2186. params.add(new Param ("max steps", FLOATVAL, 0, 1, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  2187. params.add(new Param ("min steps", FLOATVAL, 0, 1, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  2188. params.add(new Param ("bright breakpoint", FLOATVAL, 0, 1, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  2189. //params.add(new Param ("auto toggle", INTVAL, 0, 1, new int[]{SQUAR, RANDOM}));
  2190. params.add(new Param("direction", INTVAL, 0, 3, new int[]{RANDOM}));
  2191. directionParamIndex = 3;
  2192. rw = canvas.width;
  2193. rh = canvas.height;
  2194. steps = new int[canvas.width*canvas.height];
  2195. for (int i = 0; i < canvas.width*canvas.height; i++) {
  2196. steps[i] = (int)map(random(1), 0, 1, minsteps, maxsteps);
  2197. }
  2198. }
  2199. void apply() {
  2200. minsteps = (int)map(params.get(1).value, 0, 1, 1, max(canvas.width, canvas.height)/10);
  2201. maxsteps = (int)map(params.get(0).value, 0, 1, minsteps, max(canvas.width, canvas.height)/10);
  2202. autoPivot = params.get(2).value;
  2203. //brightmode = boolean((int)params.get(3).value);
  2204. //autotoggle = boolean((int)params.get(4).value);
  2205. if (rw != canvas.width || rh != canvas.height) {
  2206. rw = canvas.width;
  2207. rh = canvas.height;
  2208. steps = new int[canvas.width*canvas.height];
  2209. }
  2210. for (int i = 0; i < steps.length; i++) {
  2211. steps[i] = (int)map(random(1), 0, 1, minsteps, maxsteps);
  2212. }
  2213. canvas.beginDraw();
  2214. canvas.loadPixels();
  2215. for ( int x = 0, w = canvas.width; x<w; x++) {
  2216. for ( int h = canvas.height, y = h-1; y>-1; y--) {
  2217. /*
  2218. if ( alternatetoggle ) {
  2219. brightmode = !brightmode;
  2220. } else {
  2221. if ( autotoggle ) {
  2222. brightmode = y > (h*autoPivot);
  2223. }
  2224. }
  2225. */
  2226. //if (autotoggle) {
  2227. brightmode = y > (h*autoPivot);
  2228. //}
  2229. float rat = 1.0;
  2230. int pos = x + y * w;
  2231. color c = canvas.pixels[pos];
  2232. int ty = y;
  2233. while ( rat > 1.0/steps[x*y]*2 ) {
  2234. ty++;
  2235. if ( ty >= h ) break;
  2236. int tpos = x + ty * w;
  2237. color tc = canvas.pixels[tpos];
  2238. if (
  2239. ( !brightmode && brightness(tc) < brightness(c) )
  2240. || ( brightmode && brightness(tc) > brightness(c) )
  2241. ) break;
  2242. canvas.pixels[tpos] = blendC(tc, c, rat);
  2243. rat-= rat/steps[x*y];
  2244. }
  2245. }
  2246. }
  2247. canvas.updatePixels();
  2248. canvas.endDraw();
  2249. }
  2250. color blendC(color tc, color sc, float rat) {
  2251. return color(
  2252. (red(tc)*(1.0-rat))+(red(sc)*rat),
  2253. (green(tc)*(1.0-rat))+(green(sc)*rat),
  2254. (blue(tc)*(1.0-rat))+(blue(sc)*rat)
  2255. );
  2256. }
  2257. }
  2258. /*
  2259. WRONGQSORT
  2260. */
  2261. class WRONGQSORT extends Shader {
  2262. boolean mode = L; // L or R, which sort part is broken
  2263. boolean do_blend = false; // blend image after process
  2264. int blend_mode = OVERLAY; // blend type
  2265. static final boolean L = true;
  2266. static final boolean R = false;
  2267. // working buffer
  2268. PGraphics buffer;
  2269. // image
  2270. PImage img;
  2271. float random_point = 0.5;
  2272. int len;
  2273. int rw, rh;
  2274. WRONGQSORT() {
  2275. name = "fxWrongQSort";
  2276. params.add(new Param ("v", FLOATVAL, 0.1, 1, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  2277. params.add(new Param ("randomize", FLOATVAL, 0.1, 0.9, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  2278. params.add(new Param ("mode", INTVAL, 0, 1, new int[]{RANDOM, SQUAR}));
  2279. params.add(new Param ("do blend", INTVAL, 0, 1, new int[]{RANDOM, SQUAR}));
  2280. params.add(new Param ("blend mode", INTVAL, 0, blends.length-1, new int[]{RANDOM}));
  2281. params.add(new Param ("direction", INTVAL, 0, 3, new int[]{RANDOM}));
  2282. directionParamIndex = 5;
  2283. img = createImage(canvas.width, canvas.height, ARGB);
  2284. img = canvas.get();
  2285. buffer = createGraphics(canvas.width, canvas.height);
  2286. buffer.beginDraw();
  2287. buffer.noStroke();
  2288. buffer.smooth(8);
  2289. buffer.background(0);
  2290. buffer.image(img, 0, 0);
  2291. buffer.endDraw();
  2292. }
  2293. void apply() {
  2294. random_point = params.get(1).value;
  2295. mode = boolean((int)params.get(2).value);
  2296. do_blend = boolean((int)params.get(3).value);
  2297. blend_mode = blends[(int)params.get(4).value];
  2298. if (rw != canvas.width || rh != canvas.height) {
  2299. rw = canvas.width;
  2300. rh = canvas.height;
  2301. img.resize(rw, rh);
  2302. buffer = createGraphics(rw, rh);
  2303. }
  2304. img = canvas.get();
  2305. len = rw * rh;
  2306. int v = (int)map(params.get(0).value, 0, 1, 1, len-1);
  2307. buffer.beginDraw();
  2308. buffer.image(img, 0, 0);
  2309. buffer.endDraw();
  2310. buffer.loadPixels();
  2311. int x = 0;
  2312. while (x<len) {
  2313. if (x+v<len) quicksort(buffer.pixels, x, x+v);
  2314. else quicksort(buffer.pixels, x, len-1);
  2315. x+=v;
  2316. }
  2317. buffer.updatePixels();
  2318. buffer.beginDraw();
  2319. if (do_blend) {
  2320. buffer.blend(img, 0, 0, img.width, img.height, 0, 0, buffer.width, buffer.height, blend_mode);
  2321. }
  2322. buffer.endDraw();
  2323. canvas.beginDraw();
  2324. canvas.image(buffer, canvas.width/2, canvas.height/2);
  2325. canvas.endDraw();
  2326. }
  2327. int partition(int x[], int left, int right) {
  2328. int i = left;
  2329. int j = right;
  2330. int temp;
  2331. int pivot = x [(int)map(random_point, 0, 1, left, right)];
  2332. while (i<= j) {
  2333. while (x[i] < pivot) {
  2334. i++;
  2335. }
  2336. while (x[j] > pivot) {
  2337. j--;
  2338. }
  2339. if (i <= j) {
  2340. temp = x[i];
  2341. x[i] = x [j];
  2342. x[j] = temp;
  2343. i++;
  2344. j--;
  2345. }
  2346. }
  2347. return i;
  2348. }
  2349. void quicksort(int x[], int left, int right) {
  2350. if (left<right) {
  2351. int index = partition(x, left, right);
  2352. if (mode) {
  2353. if (left < index-1) quicksort(x, left, index-1);
  2354. if (right < index) quicksort(x, index, right);
  2355. } else {
  2356. if (left > index-1) quicksort(x, left, index-1);
  2357. if (right > index) quicksort(x, index, right);
  2358. }
  2359. }
  2360. }
  2361. }
  2362. /*
  2363. VHS
  2364. */
  2365. class VHS extends Shader {
  2366. PImage timg;
  2367. int bass, treble, sxl, syl;
  2368. VHS () {
  2369. name = "fxVHS";
  2370. params.add(new Param ("sine x length", INTVAL, 1, 100, new int[]{TRIANG, SINE}));
  2371. params.add(new Param ("sine y length", INTVAL, 1, 100, new int[]{TRIANG, SINE}));
  2372. params.add(new Param ("bass", INTVAL, -15, 15, new int[]{TRIANG, SINE}));
  2373. params.add(new Param ("treble", INTVAL, -15, 15, new int[]{TRIANG, SINE}));
  2374. params.add(new Param ("direction", INTVAL, 0, 3, new int[]{RANDOM}));
  2375. directionParamIndex = 4;
  2376. }
  2377. void apply() {
  2378. sxl = (int)params.get(0).value;
  2379. syl = (int)params.get(1).value;
  2380. bass = (int)params.get(2).value;
  2381. treble = (int)params.get(3).value;
  2382. int virtw = canvas.width;
  2383. int virth = canvas.height;
  2384. PImage timg = createImage(canvas.width, canvas.height, RGB);
  2385. timg = canvas.get();
  2386. PImage hay = sinwav(timg, sxl, syl);
  2387. PImage result = createImage(timg.width, timg.height, RGB);
  2388. result.copy(hay, 0, 0, virtw, virth, 0, 0, result.width, result.height);
  2389. canvas.beginDraw();
  2390. canvas.image(basstreble(result, bass, treble), canvas.width/2, canvas.height/2, canvas.width, canvas.height); //0 to 100
  2391. canvas.endDraw();
  2392. }
  2393. PImage sinwav(PImage img, int xp, int yp) {
  2394. int ctr = 0;
  2395. img.loadPixels();
  2396. float ylength = xp;
  2397. float xlength = yp; // was map (yp, 0,100, 1, 100);
  2398. PImage result = createImage(img.width, img.height, RGB);
  2399. for ( int y =0, h = img.height; y<h; y++) {
  2400. for ( int x = 0, w = img.width; x<w; x++, ctr++) {
  2401. int pos = x + y * w;
  2402. color c = img.pixels[pos];
  2403. int epos = (int)(( x + sin(y/ylength)*xlength)+ y * w);
  2404. if ( epos < result.pixels.length )
  2405. result.pixels[epos] = c;
  2406. else
  2407. result.pixels[pos] = c;
  2408. }
  2409. }
  2410. result.updatePixels();
  2411. return result;
  2412. }
  2413. PImage basstreble(PImage img, int xp, int yp) {
  2414. float dB_bass = xp;
  2415. float dB_treble = yp;
  2416. PImage result = createImage(img.width, img.height, RGB);
  2417. float slope = 0.4;
  2418. double hzBass = 250.0;
  2419. double hzTreble = 4000.0;
  2420. 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;
  2421. double mMax = 0.0;
  2422. double mSampleRate = 44000;
  2423. xn1Bass = xn2Bass = yn1Bass = yn2Bass = 0.0;
  2424. xn1Treble = xn2Treble = yn1Treble = yn2Treble = 0.0;
  2425. float w = (float)(2 * PI * hzBass / mSampleRate);
  2426. float a = exp((float)(log(10.0) * dB_bass / 40));
  2427. float b = sqrt((float)((a * a + 1) / slope - (pow((float)(a - 1), 2))));
  2428. b0Bass = a * ((a + 1) - (a - 1) * cos(w) + b * sin(w));
  2429. b1Bass = 2 * a * ((a - 1) - (a + 1) * cos(w));
  2430. b2Bass = a * ((a + 1) - (a - 1) * cos(w) - b * sin(w));
  2431. a0Bass = ((a + 1) + (a - 1) * cos(w) + b * sin(w));
  2432. a1Bass = -2 * ((a - 1) + (a + 1) * cos(w));
  2433. a2Bass = (a + 1) + (a - 1) * cos(w) - b * sin(w);
  2434. w = (float)(2 * PI * hzTreble / mSampleRate);
  2435. a = exp((float)(log(10.0) * dB_treble / 40));
  2436. b = sqrt((float)((a * a + 1) / slope - (pow((float)(a - 1), 2))));
  2437. b0Treble = a * ((a + 1) + (a - 1) * cos(w) + b * sin(w));
  2438. b1Treble = -2 * a * ((a - 1) + (a + 1) * cos(w));
  2439. b2Treble = a * ((a + 1) + (a - 1) * cos(w) - b * sin(w));
  2440. a0Treble = ((a + 1) - (a - 1) * cos(w) + b * sin(w));
  2441. a1Treble = 2 * ((a - 1) - (a + 1) * cos(w));
  2442. a2Treble = (a + 1) - (a - 1) * cos(w) - b * sin(w);
  2443. img.loadPixels();
  2444. result.loadPixels();
  2445. for ( int i = 0, l = img.pixels.length; i<l; i++) {
  2446. int[] rgb = new int[3];
  2447. rgb[0] = (int)red(img.pixels[i]);
  2448. rgb[1] = (int)green(img.pixels[i]);
  2449. rgb[2] = (int)blue(img.pixels[i]);
  2450. for ( int ri = 0; ri<3; ri++ ) {
  2451. float in = map(rgb[ri], 0, 255, 0, 1);
  2452. float out = (b0Bass * in + b1Bass * xn1Bass + b2Bass * xn2Bass - a1Bass * yn1Bass - a2Bass * yn2Bass ) / a0Bass;
  2453. //println(a0Bass);
  2454. xn2Bass = xn1Bass;
  2455. xn1Bass = in;
  2456. yn2Bass = yn1Bass;
  2457. yn1Bass = out;
  2458. //treble filter
  2459. in = out;
  2460. out = (b0Treble * in + b1Treble * xn1Treble + b2Treble * xn2Treble - a1Treble * yn1Treble - a2Treble * yn2Treble) / a0Treble;
  2461. xn2Treble = xn1Treble;
  2462. xn1Treble = in;
  2463. yn2Treble = yn1Treble;
  2464. yn1Treble = out;
  2465. //retain max value for use in normalization
  2466. if ( mMax < abs(out))
  2467. mMax = abs(out);
  2468. rgb[ri] = (int)map(out, 0, 1, 0, 255);
  2469. }
  2470. result.pixels[i] = color(rgb[0], rgb[1], rgb[2]);
  2471. }
  2472. result.updatePixels();
  2473. return result;
  2474. }
  2475. }
  2476. /*
  2477. LZ7
  2478. */
  2479. class LZ7 extends Shader {
  2480. // choose colorspace
  2481. int colorspace = HSB; // HSB or RGB
  2482. // set compressor attributes for each channel in chosen colorspace
  2483. // first number is length of dictionary in LZ77 - values 100 - 4000
  2484. // second number is length of word (ahead buffer) in LZ77 - about 5% - 50% of dictionary size
  2485. int[][] compressor_attributes = { {2000, 250}, // channel 1 (H or R)
  2486. {50, 10}, // channel 2 (S or G)
  2487. {100, 100} }; // channel 3 (B or B)
  2488. // set number of glitches made for each channel
  2489. // first number is actual number of random change in compressed channel
  2490. // second number is amount of change (values from 0.01 to 4)
  2491. float[][] number_of_glitches = { {5000, 2}, // channel 1
  2492. {500, 1}, // channel 2
  2493. {50, 0.1} }; // channel 3
  2494. // working buffer
  2495. PGraphics buffer;
  2496. // image
  2497. PImage img;
  2498. boolean do_blend = false; // blend image after process
  2499. int blend_mode = OVERLAY; // blend type
  2500. LZ77 comp1, comp2, comp3;
  2501. byte[] cr, cb, cg;
  2502. //red channel dictionary size
  2503. //red channel word size
  2504. //red channel randomness
  2505. //red channel amount of change
  2506. LZ7() {
  2507. name = "fxLZ77";
  2508. params.add(new Param("dictionary size (red/hue)", INTVAL, 100, 3000, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  2509. params.add(new Param("word length (red/hue)", FLOATVAL, 0.05, 0.5, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  2510. params.add(new Param("randomness (red/hue)", INTVAL, 20, 5000, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  2511. params.add(new Param("amount of change (red/hue)", FLOATVAL, 0.01, 4, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  2512. params.add(new Param("dictionary size (green/saturation)", INTVAL, 100, 3000, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  2513. params.add(new Param("word length (green/saturation)", FLOATVAL, 0.05, 0.5, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  2514. params.add(new Param("randomness (green/saturation)", INTVAL, 20, 5000, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  2515. params.add(new Param("amount of change (green/saturation)", FLOATVAL, 0.01, 4, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  2516. params.add(new Param("dictionary size (blue/brightness)", INTVAL, 100, 3000, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  2517. params.add(new Param("word length (blue/brightness)", FLOATVAL, 0.05, 0.5, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  2518. params.add(new Param("randomness (blue/brightness)", INTVAL, 20, 5000, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  2519. params.add(new Param("amount of change (blue/brightness)", FLOATVAL, 0.01, 4, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  2520. params.add(new Param("colorspace (rgb / hsb)", INTVAL, 0, 1, new int[]{RANDOM, SQUAR}));
  2521. params.add(new Param("do blend", INTVAL, 0, 1, new int[]{RANDOM, SQUAR}));
  2522. params.add(new Param("blend mode", INTVAL, 0, blends.length-1, new int[]{RANDOM}));
  2523. params.add(new Param("direction", INTVAL, 0, 3, new int[]{RANDOM}));
  2524. directionParamIndex = 15;
  2525. rw = canvas.width;
  2526. rh = canvas.height;
  2527. buffer = createGraphics(rw, rh);
  2528. buffer.beginDraw();
  2529. buffer.noStroke();
  2530. //buffer.smooth(8);
  2531. buffer.background(0);
  2532. buffer.endDraw();
  2533. img = createImage(canvas.width, canvas.height, RGB);
  2534. cr = new byte[rw*rh];
  2535. cb = new byte[rw*rh];
  2536. cg = new byte[rw*rh];
  2537. }
  2538. int rw, rh;
  2539. void apply() {
  2540. if (rw != canvas.width || rh != canvas.height) {
  2541. rw = canvas.width;
  2542. rh = canvas.height;
  2543. cr = new byte[rw*rh];
  2544. cb = new byte[rw*rh];
  2545. cg = new byte[rw*rh];
  2546. buffer = createGraphics(rw, rh);
  2547. img.resize(rw, rh);
  2548. }
  2549. img = canvas.get();
  2550. colorspace = (int)params.get(12).value == 0 ?RGB:HSB;
  2551. do_blend = boolean((int)params.get(13).value);
  2552. blend_mode = blends[(int)params.get(14).value];
  2553. //red
  2554. compressor_attributes[0][0] = (int)params.get(0).value;
  2555. compressor_attributes[0][1] = (int)(params.get(1).value*compressor_attributes[0][0]);
  2556. number_of_glitches[0][0] = (int)params.get(2).value;
  2557. number_of_glitches[0][1] = params.get(3).value;
  2558. //green
  2559. compressor_attributes[1][0] = (int)params.get(4).value;
  2560. compressor_attributes[1][1] = (int)(params.get(5).value*compressor_attributes[1][0]);
  2561. number_of_glitches[1][0] = (int)params.get(6).value;
  2562. number_of_glitches[1][1] = params.get(7).value;
  2563. //blue
  2564. compressor_attributes[2][0] = (int)params.get(8).value;
  2565. compressor_attributes[2][1] = (int)(params.get(9).value*compressor_attributes[2][0]);
  2566. number_of_glitches[2][0] = (int)params.get(10).value;
  2567. number_of_glitches[2][1] = params.get(11).value;
  2568. comp1 = new LZ77( compressor_attributes[0][0], compressor_attributes[0][1] );
  2569. comp2 = new LZ77( compressor_attributes[1][0], compressor_attributes[1][1] );
  2570. comp3 = new LZ77( compressor_attributes[2][0], compressor_attributes[2][1] );
  2571. buffer.beginDraw();
  2572. print("Preparing... ");
  2573. img.loadPixels();
  2574. int iter=0;
  2575. for (int i=0; i<img.pixels.length; i++) {
  2576. color c = img.pixels[i];
  2577. if (colorspace == HSB) {
  2578. cr[iter]= (byte)hue(c);
  2579. cg[iter]= (byte)saturation(c);
  2580. cb[iter]= (byte)brightness(c);
  2581. } else {
  2582. cr[iter]= (byte)red(c);
  2583. cg[iter]= (byte)green(c);
  2584. cb[iter]= (byte)blue(c);
  2585. }
  2586. iter++;
  2587. }
  2588. println("done");
  2589. print("Glitching channel 1... ");
  2590. comp1.doCompress(cr);
  2591. comp1.glitch( (int)number_of_glitches[0][0], number_of_glitches[0][1] );
  2592. comp1.doDecompress(cr);
  2593. println("done");
  2594. print("Glitching channel 2... ");
  2595. comp2.doCompress(cg);
  2596. comp2.glitch( (int)number_of_glitches[1][0], number_of_glitches[1][1] );
  2597. comp2.doDecompress(cg);
  2598. println("done");
  2599. print("Glitching channel 3... ");
  2600. comp3.doCompress(cb);
  2601. comp3.glitch( (int)number_of_glitches[2][0], number_of_glitches[2][1] );
  2602. comp3.doDecompress(cb);
  2603. println("done");
  2604. for (int i = 0; i < 3; i++) {
  2605. println("Channel "+(i+1)+" = ("+compressor_attributes[i][0]+","+compressor_attributes[i][1]+")"
  2606. + ", glitches = ("+number_of_glitches[i][0]+","+number_of_glitches[i][1]+")");
  2607. }
  2608. buffer.loadPixels();
  2609. if (colorspace == HSB) colorMode(HSB);
  2610. else colorMode(RGB);
  2611. iter=0;
  2612. for (int i=0; i<buffer.pixels.length; i++) {
  2613. float r = cr[iter];
  2614. r = r>=0?r:r+256;
  2615. float g = cg[iter];
  2616. g = g>=0?g:g+256;
  2617. float b = cb[iter];
  2618. b = b>=0?b:b+256;
  2619. buffer.pixels[i] = color(r, g, b);
  2620. iter++;
  2621. }
  2622. buffer.updatePixels();
  2623. if (do_blend)
  2624. buffer.blend(img, 0, 0, img.width, img.height, 0, 0, buffer.width, buffer.height, blend_mode);
  2625. buffer.endDraw();
  2626. canvas.beginDraw();
  2627. canvas.image(buffer, canvas.width/2, canvas.height/2);
  2628. canvas.endDraw();
  2629. }
  2630. }
  2631. class Tuple {
  2632. public int offset, len;
  2633. byte chr;
  2634. public Tuple(int o, int l, byte c) {
  2635. offset = o;
  2636. len = l;
  2637. chr = c;
  2638. }
  2639. }
  2640. class LZ77 {
  2641. int windowWidth;
  2642. int lookAheadWidht;
  2643. public LZ77(int ww, int law) {
  2644. windowWidth = ww;
  2645. lookAheadWidht = law;
  2646. }
  2647. ArrayList<Tuple> clist = new ArrayList<Tuple>();
  2648. public void glitch(int no, float fac) {
  2649. for (int i=0; i<no; i++) {
  2650. Tuple r = clist.get( (int)random(clist.size()));
  2651. int what = (int)random(3);
  2652. switch(what) {
  2653. case 0:
  2654. r.chr = (byte)random(256);
  2655. break;
  2656. case 1:
  2657. r.offset = (int)random(2*windowWidth*fac);
  2658. break;
  2659. default:
  2660. r.len = (int)random(2*lookAheadWidht*fac);
  2661. }
  2662. }
  2663. }
  2664. public void doCompress(byte[] buff) {
  2665. int currByte = 1;
  2666. // first is always byte
  2667. clist.add( new Tuple(0, 0, buff[0]) );
  2668. while (currByte < buff.length) {
  2669. int bend = constrain(currByte-windowWidth, 0, buff.length);
  2670. int boff = 0;
  2671. int blen = 0;
  2672. if (currByte<buff.length-1)
  2673. for (int i = currByte-1; i>=bend; i--) {
  2674. if (buff[currByte] == buff[i]) {
  2675. int tboff = abs(i-currByte);
  2676. int tblen = 1;
  2677. int laEnd = constrain(currByte+lookAheadWidht, 0, buff.length-1);
  2678. int mi = currByte+1;
  2679. while (mi<laEnd && (i+mi-currByte)<currByte) {
  2680. if (buff[mi] == buff[i+mi-currByte]) {
  2681. mi++;
  2682. tblen++;
  2683. } else {
  2684. break;
  2685. }
  2686. }
  2687. if (tblen>blen) {
  2688. blen = tblen;
  2689. boff = tboff;
  2690. }
  2691. }
  2692. }
  2693. currByte +=blen+1;
  2694. // println("currchar = " + (currByte-1)+",blen = " + blen);
  2695. clist.add( new Tuple(boff, blen, buff[currByte-1]) );
  2696. // println(boff + ", " + blen + ", " + buff[currByte-1]);
  2697. }
  2698. //println("clist " + clist.size()*2);
  2699. }
  2700. void doDecompress(byte[] buff) {
  2701. int i = 0;
  2702. for (Tuple t : clist) {
  2703. if (i>=buff.length) break;
  2704. if (t.offset == 0) {
  2705. buff[i++] = t.chr;
  2706. } else {
  2707. int start = i-t.offset;
  2708. int end = start + t.len;
  2709. for (int c = start; c<end; c++) {
  2710. int pos = constrain(c, 0, buff.length-1);
  2711. buff[constrain(i++, 0, buff.length-1)] = buff[pos];
  2712. if (i>=buff.length) break;
  2713. }
  2714. if (i>=buff.length) break;
  2715. buff[i++] = t.chr;
  2716. }
  2717. }
  2718. }
  2719. }
  2720. /*
  2721. LENS
  2722. */
  2723. class LENS extends Shader {
  2724. // parameters
  2725. float bendx = 0.1; // from 0 to 1
  2726. float bendy = 0.1; // from 0 to 1
  2727. float[] power_vals = { 2, 0.5 }; // two values of power from 0.1 to 10, one for x and second for y
  2728. int[] types = { LINEAR, POWER }; // always to types one for x second for y
  2729. int[] channels = { BRIGHTNESS, SATURATION }; // as above
  2730. float[] facts = new float[2];
  2731. //////////////
  2732. PImage img;
  2733. PImage limg;
  2734. int shaderListLength;
  2735. // working buffer
  2736. PGraphics buffer;
  2737. LENS() {
  2738. name = "fxLens";
  2739. shaderListLength = gui.shaderList.size();
  2740. params.add(new Param("lens image layer", INTVAL, 0, shaderListLength-1, new int[]{RANDOM}));
  2741. params.add(new Param("power x", FLOATVAL, 0.1, 10, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  2742. params.add(new Param("power y", FLOATVAL, 0.1, 10, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  2743. params.add(new Param("lens type x", INTVAL, 0, 3, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  2744. params.add(new Param("lens type y", INTVAL, 0, 3, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  2745. params.add(new Param("channel x", INTVAL, 0, 11, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  2746. params.add(new Param("channel y", INTVAL, 0, 11, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  2747. params.add(new Param("curvature factor x", FLOATVAL, 0, 1, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  2748. params.add(new Param("curvature factor y", FLOATVAL, 0, 1, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  2749. params.add(new Param("direction", INTVAL, 0, 3, new int[]{RANDOM}));
  2750. directionParamIndex = 9;
  2751. rw = canvas.width;
  2752. rh = canvas.height;
  2753. img = createImage(rw, rh, ARGB);
  2754. limg = createImage(rw, rh, ARGB);
  2755. buffer = createGraphics(rw, rh);
  2756. buffer.beginDraw();
  2757. buffer.noStroke();
  2758. buffer.endDraw();
  2759. }
  2760. int rw, rh;
  2761. void apply() {
  2762. if (rw != canvas.width || rh != canvas.height) {
  2763. rw = canvas.width;
  2764. rh = canvas.height;
  2765. buffer = createGraphics(rw, rh);
  2766. buffer.beginDraw();
  2767. buffer.noStroke();
  2768. buffer.endDraw();
  2769. img.resize(rw, rh);
  2770. limg.resize(rw, rh);
  2771. }
  2772. if (shaderListLength != gui.shaderList.size()) {
  2773. shaderListLength = gui.shaderList.size();
  2774. changeParam(0, new Param("lens image layer", INTVAL, 0, shaderListLength-1, new int[]{RANDOM}));
  2775. }
  2776. img = canvas.get();
  2777. if ((int)params.get(0).value == pos) {
  2778. limg = canvas.get();
  2779. } else {
  2780. limg = gui.shaderList.get((int)params.get(0).value).canvas.get();
  2781. }
  2782. power_vals[0] = params.get(1).value;
  2783. power_vals[1] = params.get(2).value;
  2784. types[0] = (int)params.get(3).value;
  2785. types[1] = (int)params.get(4).value;
  2786. channels[0] = (int)params.get(5).value;
  2787. channels[1] = (int)params.get(6).value;
  2788. bendx = params.get(7).value;
  2789. bendy = params.get(8).value;
  2790. facts[0] = bendx * img.width;
  2791. facts[1] = bendy * img.height;
  2792. img.loadPixels();
  2793. limg.loadPixels();
  2794. buffer.beginDraw();
  2795. buffer.background(0);
  2796. for (int x=0; x<img.width; x++) {
  2797. int lx = (int)map(x, 0, img.width-1, 0, limg.width-1);
  2798. for (int y=0; y<img.height; y++) {
  2799. int ly = (int)map(y, 0, img.height-1, 0, limg.height-1);
  2800. color c = limg.pixels[lx+ly*limg.width];
  2801. int posx = (x+getShift(c, 0)+2*img.width)%img.width;
  2802. int posy = (y+getShift(c, 1)+2*img.height)%img.height;
  2803. color n = img.pixels[posx+posy*img.width];
  2804. buffer.fill(n);
  2805. // fill(red(c),green(c),blue(n)); // work only on blue channel
  2806. // fill(red(n), abs(green(c)-green(n)), blue(n)); // green channel is blended using difference method
  2807. buffer.rect(x, y, 1, 1);
  2808. }
  2809. }
  2810. buffer.endDraw();
  2811. img.updatePixels();
  2812. limg.updatePixels();
  2813. canvas.beginDraw();
  2814. canvas.image(buffer, canvas.width/2, canvas.height/2);
  2815. canvas.endDraw();
  2816. }
  2817. float getChannel(color c, int channel) {
  2818. int ch = channel>5?channel-6:channel;
  2819. float cc;
  2820. switch(ch) {
  2821. case RED:
  2822. cc = red(c);
  2823. break;
  2824. case GREEN:
  2825. cc = green(c);
  2826. break;
  2827. case BLUE:
  2828. cc = blue(c);
  2829. break;
  2830. case HUE:
  2831. cc = hue(c);
  2832. break;
  2833. case SATURATION:
  2834. cc = saturation(c);
  2835. break;
  2836. default:
  2837. cc= brightness(c);
  2838. break;
  2839. }
  2840. return channel>5?255-cc:cc;
  2841. }
  2842. int getShift(color c, int idx) {
  2843. float cc = getChannel(c, channels[idx]);
  2844. switch(types[idx]) {
  2845. case LINEAR:
  2846. return (int)(facts[idx] * cc/255.0);
  2847. case POWER:
  2848. return (int)(facts[idx]*map(pow(cc/255.0, power_vals[idx]), 0, 1, -1, 1));
  2849. case SINUSOIDAL:
  2850. return (int)(facts[idx]*sin(map(cc, 0, 255, -PI, PI)));
  2851. default:
  2852. { // POLAR
  2853. float c1 = idx==0?cc:getChannel(c, channels[1]);
  2854. float c2 = idx==1?cc:getChannel(c, channels[0]);
  2855. float ang = map(c1, 0, 255, 0, TWO_PI);
  2856. float r = map(c2, 0, 255, 0, facts[0]);
  2857. return (int)(idx==0?r*cos(ang):r*sin(ang));
  2858. }
  2859. }
  2860. }
  2861. }
  2862. // name
  2863. String getColorspaceName(int cs) {
  2864. switch(cs) {
  2865. case OHTA:
  2866. return "OHTA";
  2867. case CMY:
  2868. return "CMY";
  2869. case XYZ:
  2870. return "XYZ";
  2871. case YXY:
  2872. return "YXY";
  2873. case HCL:
  2874. return "HCL";
  2875. case LUV:
  2876. return "LUV";
  2877. case LAB:
  2878. return "LAB";
  2879. case HWB:
  2880. return "HWB";
  2881. case HSB:
  2882. return "HSB";
  2883. case RGGBG:
  2884. return "R-GGB-G";
  2885. case YPbPr:
  2886. return "YPbPr";
  2887. case YCbCr:
  2888. return "YCbCr";
  2889. case YDbDr:
  2890. return "YDbDr";
  2891. case GS:
  2892. return "Greyscale";
  2893. case YUV:
  2894. return "YUV";
  2895. default:
  2896. return "RGB";
  2897. }
  2898. }
  2899. // colorspace converters
  2900. color fromColorspace(color c, int cs) {
  2901. switch(cs) {
  2902. case OHTA:
  2903. return fromOHTA(c);
  2904. case CMY:
  2905. return fromCMY(c);
  2906. case XYZ:
  2907. return fromXYZ(c);
  2908. case YXY:
  2909. return fromYXY(c);
  2910. case HCL:
  2911. return fromHCL(c);
  2912. case LUV:
  2913. return fromLUV(c);
  2914. case LAB:
  2915. return fromLAB(c);
  2916. case HWB:
  2917. return fromHWB(c);
  2918. case HSB:
  2919. return fromHSB(c);
  2920. case RGGBG:
  2921. return fromRGGBG(c);
  2922. case YPbPr:
  2923. return fromYPbPr(c);
  2924. case YCbCr:
  2925. return fromYCbCr(c);
  2926. case YDbDr:
  2927. return fromYDbDr(c);
  2928. case GS:
  2929. return tofromGS(c);
  2930. case YUV:
  2931. return fromYUV(c);
  2932. default:
  2933. return c;
  2934. }
  2935. }
  2936. color toColorspace(color c, int cs) {
  2937. switch(cs) {
  2938. case OHTA:
  2939. return toOHTA(c);
  2940. case CMY:
  2941. return toCMY(c);
  2942. case XYZ:
  2943. return toXYZ(c);
  2944. case YXY:
  2945. return toYXY(c);
  2946. case HCL:
  2947. return toHCL(c);
  2948. case LUV:
  2949. return toLUV(c);
  2950. case LAB:
  2951. return toLAB(c);
  2952. case HWB:
  2953. return toHWB(c);
  2954. case HSB:
  2955. return toHSB(c);
  2956. case RGGBG:
  2957. return toRGGBG(c);
  2958. case YPbPr:
  2959. return toYPbPr(c);
  2960. case YCbCr:
  2961. return toYCbCr(c);
  2962. case YDbDr:
  2963. return toYDbDr(c);
  2964. case YUV:
  2965. return toYUV(c);
  2966. case GS:
  2967. return tofromGS(c);
  2968. default:
  2969. return c;
  2970. }
  2971. }
  2972. // Colorspace converters
  2973. final int getR(color c) {
  2974. return (c & 0xff0000) >> 16;
  2975. }
  2976. final int getG(color c) {
  2977. return (c & 0xff00) >> 8;
  2978. }
  2979. final int getB(color c) {
  2980. return c & 0xff;
  2981. }
  2982. final int getLuma(color c) {
  2983. return constrain((int)(0.2126*getR(c)+0.7152*getG(c)+0.0722*getB(c)), 0, 255);
  2984. }
  2985. int getChannel(color c, int ch) {
  2986. switch(ch) {
  2987. case 0 :
  2988. return getR(c);
  2989. case 1 :
  2990. return getG(c);
  2991. case 2 :
  2992. return getB(c);
  2993. default:
  2994. return 0;
  2995. }
  2996. }
  2997. // normalized versions
  2998. final float getNR(color c) {
  2999. return r255[(c & 0xff0000) >> 16];
  3000. }
  3001. final float getNG(color c) {
  3002. return r255[(c & 0xff00) >> 8];
  3003. }
  3004. final float getNB(color c) {
  3005. return r255[c & 0xff];
  3006. }
  3007. final float getNLuma(color c) {
  3008. return r255[getLuma(c)];
  3009. }
  3010. color blendRGB(color c, int r, int g, int b) {
  3011. return (c & 0xff000000) | (constrain(r, 0, 255) << 16) | (constrain(g, 0, 255) << 8 ) | constrain(b, 0, 255);
  3012. }
  3013. color blendRGB(color c, float r, float g, float b) {
  3014. return blendRGB(c, (int)(r*255), (int)(g*255), (int)(b*255));
  3015. }
  3016. /**************
  3017. * Greyscale
  3018. **************/
  3019. color tofromGS(color c) {
  3020. int l = getLuma(c);
  3021. return blendRGB(c, l, l, l);
  3022. }
  3023. /**************
  3024. * YUV
  3025. **************/
  3026. final static float Umax = 0.436 * 255.0;
  3027. final static float Vmax = 0.615 * 255.0;
  3028. color toYUV(color c) {
  3029. int R = getR(c);
  3030. int G = getG(c);
  3031. int B = getB(c);
  3032. int Y = (int)( 0.299*R+0.587*G+0.114*B);
  3033. int U = (int)map(-0.14713*R-0.28886*G+0.436*B, -Umax, Umax, 0, 255);
  3034. int V = (int)map(0.615*R-0.51499*G-0.10001*B, -Vmax, Vmax, 0, 255);
  3035. return blendRGB(c, Y, U, V);
  3036. }
  3037. color fromYUV(color c) {
  3038. int Y = getR(c);
  3039. float U = map(getG(c), 0, 255, -Umax, Umax);
  3040. float V = map(getB(c), 0, 255, -Vmax, Vmax);
  3041. int R = (int)(Y + 1.13983*V);
  3042. int G = (int)(Y - 0.39465*U - 0.58060*V);
  3043. int B = (int)(Y + 2.03211*U);
  3044. return blendRGB(c, R, G, B);
  3045. }
  3046. /**************
  3047. * YDbDr
  3048. **************/
  3049. color toYDbDr(color c) {
  3050. int R = getR(c);
  3051. int G = getG(c);
  3052. int B = getB(c);
  3053. int Y = (int)( 0.299*R+0.587*G+0.114*B);
  3054. int Db = (int)(127.5+(-0.450*R-0.883*G+1.333*B)/2.666);
  3055. int Dr = (int)(127.5+(-1.333*R+1.116*G+0.217*B)/2.666);
  3056. return blendRGB(c, Y, Db, Dr);
  3057. }
  3058. color fromYDbDr(color c) {
  3059. int Y = getR(c);
  3060. float Db = (getG(c)-127.5)*2.666;
  3061. float Dr = (getB(c)-127.5)*2.666;
  3062. int R = (int)(Y + 9.2303716147657e-05*Db-0.52591263066186533*Dr);
  3063. int G = (int)(Y - 0.12913289889050927*Db+0.26789932820759876*Dr);
  3064. int B = (int)(Y + 0.66467905997895482*Db-7.9202543533108e-05*Dr);
  3065. return blendRGB(c, R, G, B);
  3066. }
  3067. /**************
  3068. * YCbCr
  3069. **************/
  3070. color toYCbCr(color c) {
  3071. int R = getR(c);
  3072. int G = getG(c);
  3073. int B = getB(c);
  3074. int Y = (int)( 0.2988390*R+0.5868110*G+0.1143500*B);
  3075. int Cb = (int)(-0.168736*R-0.3312640*G+0.5000000*B+127.5);
  3076. int Cr = (int)( 0.5000000*R-0.4186880*G-0.0813120*B+127.5);
  3077. return blendRGB(c, Y, Cb, Cr);
  3078. }
  3079. color fromYCbCr(color c) {
  3080. int Y = getR(c);
  3081. float Cb = getG(c) - 127.5;
  3082. float Cr = getB(c) - 127.5;
  3083. int R = (int)(Y + 1.402*Cr)+1; // some fix
  3084. int G = (int)(Y-0.344136*Cb-0.714136*Cr);
  3085. int B = (int)(Y+1.772000*Cb)+1; // some fix
  3086. return blendRGB(c, R, G, B);
  3087. }
  3088. /**************
  3089. * YPbPr
  3090. **************/
  3091. color toYPbPr(color c) {
  3092. int R = getR(c);
  3093. int B = getB(c);
  3094. int Y = getLuma(c);
  3095. int Pb = B - Y;
  3096. int Pr = R - Y;
  3097. if (Pb<0) Pb+=256;
  3098. if (Pr<0) Pr+=256;
  3099. return blendRGB(c, Y, Pb, Pr);
  3100. }
  3101. color fromYPbPr(color c) {
  3102. int Y = getR(c);
  3103. int B = getG(c) + Y;
  3104. int R = getB(c) + Y;
  3105. if (R>255) R-=256;
  3106. if (B>255) B-=256;
  3107. int G = (int)((Y-0.2126*R-0.0722*B)/0.7152);
  3108. return blendRGB(c, R, G, B);
  3109. }
  3110. /**************
  3111. * R-G,G,B-G
  3112. **************/
  3113. color toRGGBG(color c) {
  3114. int G = getG(c);
  3115. int R = getR(c)-G;
  3116. int B = getB(c)-G;
  3117. if (R<0) R+=256;
  3118. if (B<0) B+=256;
  3119. return blendRGB(c, R, G, B);
  3120. }
  3121. color fromRGGBG(color c) {
  3122. int G = getG(c);
  3123. int R = getR(c)+G;
  3124. int B = getB(c)+G;
  3125. if (R>255) R-=256;
  3126. if (B>255) B-=256;
  3127. return blendRGB(c, R, G, B);
  3128. }
  3129. /**************
  3130. * HWB
  3131. **************/
  3132. color toHSB(color c) {
  3133. int R = getR(c);
  3134. int G = getG(c);
  3135. int B = getB(c);
  3136. int _min = min(R, G, B);
  3137. int _max = max(R, G, B);
  3138. float delta = _max-_min;
  3139. float saturation = delta/_max;
  3140. float brightness = r255[_max];
  3141. if (delta == 0.0) return blendRGB(c, 0.0, saturation, brightness);
  3142. float hue = 0;
  3143. if (R == _max) hue = (G-B)/delta;
  3144. else if (G == _max) hue = 2.0 + (B-R)/delta;
  3145. else hue = 4.0 + (R-G)/delta;
  3146. hue /= 6.0;
  3147. if (hue < 0.0) hue += 1.0;
  3148. return blendRGB(c, hue, saturation, brightness);
  3149. }
  3150. color fromHSB(color c) {
  3151. float S = getNG(c);
  3152. float B = getNB(c);
  3153. if (S == 0.0) return blendRGB(c, B, B, B);
  3154. float h = 6.0 * getNR(c);
  3155. float f = h-floor(h);
  3156. float p = B*(1.0-S);
  3157. float q = B*(1.0-S*f);
  3158. float t = B*(1.0-(S*(1.0-f)));
  3159. float r, g, b;
  3160. switch((int)h) {
  3161. case 1:
  3162. r=q;
  3163. g=B;
  3164. b=p;
  3165. break;
  3166. case 2:
  3167. r=p;
  3168. g=B;
  3169. b=t;
  3170. break;
  3171. case 3:
  3172. r=p;
  3173. g=q;
  3174. b=B;
  3175. break;
  3176. case 4:
  3177. r=t;
  3178. g=p;
  3179. b=B;
  3180. break;
  3181. case 5:
  3182. r=B;
  3183. g=p;
  3184. b=q;
  3185. break;
  3186. default:
  3187. r=B;
  3188. g=t;
  3189. b=p;
  3190. break;
  3191. }
  3192. return blendRGB(c, r, g, b);
  3193. }
  3194. /**************
  3195. * HWB
  3196. **************/
  3197. color toHWB(color c) {
  3198. int R = getR(c);
  3199. int G = getG(c);
  3200. int B = getB(c);
  3201. int w = min(R, G, B);
  3202. int v = max(R, G, B);
  3203. int hue;
  3204. if (v == w) hue = 255;
  3205. else {
  3206. float f = ((R == w) ? G-B : ((G == w) ? B-R : R-G));
  3207. float p = (R == w) ? 3.0 : ((G == w) ? 5.0 : 1.0);
  3208. hue = (int)map((p-f/(v-w))/6.0, 0, 1, 0, 254);
  3209. }
  3210. return blendRGB(c, hue, w, 255-v);
  3211. }
  3212. color fromHWB(color c) {
  3213. int H = getR(c);
  3214. int B = 255-getB(c);
  3215. if (H == 255) return blendRGB(c, B, B, B);
  3216. else {
  3217. float hue = map(H, 0, 254, 0, 6);
  3218. float v = r255[B];
  3219. float whiteness = getNG(c);
  3220. int i = (int)floor(hue);
  3221. float f = hue-i;
  3222. if ((i&0x01)!= 0) f=1.0-f;
  3223. float n = whiteness+f*(v-whiteness);
  3224. float r, g, b;
  3225. switch(i) {
  3226. case 1:
  3227. r=n;
  3228. g=v;
  3229. b=whiteness;
  3230. break;
  3231. case 2:
  3232. r=whiteness;
  3233. g=v;
  3234. b=n;
  3235. break;
  3236. case 3:
  3237. r=whiteness;
  3238. g=n;
  3239. b=v;
  3240. break;
  3241. case 4:
  3242. r=n;
  3243. g=whiteness;
  3244. b=v;
  3245. break;
  3246. case 5:
  3247. r=v;
  3248. g=whiteness;
  3249. b=n;
  3250. break;
  3251. default:
  3252. r=v;
  3253. g=n;
  3254. b=whiteness;
  3255. break;
  3256. }
  3257. return blendRGB(c, r, g, b);
  3258. }
  3259. }
  3260. /**************
  3261. * Lab
  3262. **************/
  3263. final static float D65X=0.950456;
  3264. final static float D65Y=1.0;
  3265. final static float D65Z=1.088754;
  3266. final static float CIEEpsilon=(216.0/24389.0);
  3267. final static float CIEK=(24389.0/27.0);
  3268. final static float CIEK2epsilon = CIEK * CIEEpsilon;
  3269. final static float D65FX_4 = 4.0*D65X/(D65X+15.0*D65Y+3.0*D65Z);
  3270. final static float D65FY_9 = 9.0*D65Y/(D65X+15.0*D65Y+3.0*D65Z);
  3271. final static float RANGE_X = 100.0 * (0.4124+0.3576+0.1805);
  3272. final static float RANGE_Y = 100.0;
  3273. final static float RANGE_Z = 100.0 * (0.0193+0.1192+0.9505);
  3274. final static float mepsilon = 1.0e-10;
  3275. final static float corrratio = 1.0/2.4;
  3276. final static float One_Third = 1.0/3.0;
  3277. final static float one_hsixteen = 1.0/116.0;
  3278. color toLAB(color c) {
  3279. PVector xyz = _toXYZ(getNR(c), getNG(c), getNB(c));
  3280. xyz.div(100.0);
  3281. xyz.x /= D65X;
  3282. xyz.y /= D65Y;
  3283. xyz.z /= D65Z;
  3284. float x, y, z;
  3285. if (xyz.x > CIEEpsilon) {
  3286. x = pow(xyz.x, One_Third);
  3287. } else {
  3288. x= (CIEK*xyz.x+16.0)*one_hsixteen;
  3289. }
  3290. if (xyz.y > CIEEpsilon) {
  3291. y = pow(xyz.y, One_Third);
  3292. } else {
  3293. y = (CIEK*xyz.y+16.0)*one_hsixteen;
  3294. }
  3295. if (xyz.z > CIEEpsilon) {
  3296. z = pow(xyz.z, One_Third);
  3297. } else {
  3298. z = (CIEK*xyz.z+16.0)*one_hsixteen;
  3299. }
  3300. float L = 255.0*(((116.0*y)-16.0)*0.01);
  3301. float a = 255.0*(0.5*(x-y)+0.5);
  3302. float b = 255.0*(0.5*(y-z)+0.5);
  3303. return blendRGB(c, round(L), round(a), round(b));
  3304. }
  3305. color fromLAB(color c) {
  3306. float L = 100*getNR(c);
  3307. float a = getNG(c)-0.5;
  3308. float b = getNB(c)-0.5;
  3309. float y = (L+16.0)*one_hsixteen;
  3310. float x = y+a;
  3311. float z = y-b;
  3312. float xxx=x*x*x;
  3313. if (xxx>CIEEpsilon) {
  3314. x = xxx;
  3315. } else {
  3316. x = (116.0*x-16.0)/CIEK;
  3317. }
  3318. float yyy=y*y*y;
  3319. if (yyy>CIEEpsilon) {
  3320. y = yyy;
  3321. } else {
  3322. y = L/CIEK;
  3323. }
  3324. float zzz=z*z*z;
  3325. if (zzz>CIEEpsilon) {
  3326. z = zzz;
  3327. } else {
  3328. z = (116.0*z-16.0)/CIEK;
  3329. }
  3330. return _fromXYZ(c, RANGE_X*x, RANGE_Y*y, RANGE_Z*z);
  3331. }
  3332. /**************
  3333. * Luv
  3334. **************/
  3335. final float PerceptibleReciprocal(float x) {
  3336. float sgn = x < 0.0 ? -1.0 : 1.0;
  3337. if ((sgn * x) >= mepsilon) return (1.0 / x);
  3338. return (sgn/mepsilon);
  3339. }
  3340. color toLUV(color c) {
  3341. PVector xyz = _toXYZ(getNR(c), getNG(c), getNB(c));
  3342. xyz.div(100.0);
  3343. float d = xyz.y; // / D65Y;
  3344. float L;
  3345. if (d > CIEEpsilon) L = 116.0*pow(d, One_Third)-16.0;
  3346. else L = CIEK * d;
  3347. float alpha = PerceptibleReciprocal(xyz.x + 15.0 * xyz.y + 3.0 * xyz.z);
  3348. float L13 = 13.0 * L;
  3349. float u = L13 * ((4.0 * alpha * xyz.x)-D65FX_4);
  3350. float v = L13 * ((9.0 * alpha * xyz.y)-D65FY_9);
  3351. L /= 100.0;
  3352. u=(u+134.0)/354.0;
  3353. v=(v+140.0)/262.0;
  3354. return blendRGB(c, round(L*255), round(u*255), round(v*255));
  3355. }
  3356. color fromLUV(color c) {
  3357. float L = 100.0*getNR(c);
  3358. float u = 354.0*getNG(c)-134.0;
  3359. float v = 262.0*getNB(c)-140.0;
  3360. float X, Y, Z;
  3361. if (L > CIEK2epsilon) Y = pow((L+16.0)*one_hsixteen, 3.0);
  3362. else Y = L/CIEK;
  3363. float L13 = 13.0*L;
  3364. float L52 = 52.0*L;
  3365. float Y5 = 5.0*Y;
  3366. float L13u = L52/(u+L13*D65FX_4);
  3367. X=((Y*((39.0*L/(v+L13*D65FY_9))-5.0))+Y5)/((((L13u)-1.0)/3.0)+One_Third);
  3368. Z=(X*(((L13u)-1.0)/3.0))-Y5;
  3369. return _fromXYZ(c, 100*X, 100*Y, 100*Z);
  3370. }
  3371. /**************
  3372. * HCL
  3373. **************/
  3374. color toHCL(color c) {
  3375. float r = getNR(c);
  3376. float g = getNG(c);
  3377. float b = getNB(c);
  3378. float max = max(r, max(g, b));
  3379. float chr = max - min(r, min(g, b));
  3380. float h = 0.0;
  3381. if ( chr != 0) {
  3382. if (r == max) {
  3383. h = ((g-b)/chr+6.0) % 6.0;
  3384. } else if (g == max) {
  3385. h = (b-r)/chr + 2.0;
  3386. } else {
  3387. h = (r-g)/chr + 4.0;
  3388. }
  3389. }
  3390. return blendRGB(c, round((h/6.0)*255), round(chr*255), round(255*(0.298839*r+0.586811*g+0.114350*b)));
  3391. }
  3392. color fromHCL(color c) {
  3393. float h = 6.0*getNR(c);
  3394. float chr = getNG(c);
  3395. float l = getNB(c);
  3396. float x = chr*(1.0-abs((h%2.0)-1.0));
  3397. float r = 0.0;
  3398. float g = 0.0;
  3399. float b = 0.0;
  3400. if ((0.0 <= h) && (h < 1.0)) {
  3401. r=chr;
  3402. g=x;
  3403. } else if ((1.0 <= h) && (h < 2.0)) {
  3404. r=x;
  3405. g=chr;
  3406. } else if ((2.0 <= h) && (h < 3.0)) {
  3407. g=chr;
  3408. b=x;
  3409. } else if ((3.0 <= h) && (h < 4.0)) {
  3410. g=x;
  3411. b=chr;
  3412. } else if ((4.0 <= h) && (h < 5.0)) {
  3413. r=x;
  3414. b=chr;
  3415. } else {//if ((5.0 <= h) && (h < 6.0)) {
  3416. r=chr;
  3417. b=x;
  3418. }
  3419. float m = l - (0.298839*r+0.586811*g+0.114350*b);
  3420. return blendRGB(c, round(255*(r+m)), round(255*(g+m)), round(255*(b+m)));
  3421. }
  3422. /**************
  3423. * Yxy
  3424. **************/
  3425. color toYXY(color c) {
  3426. PVector xyz = _toXYZ(getNR(c), getNG(c), getNB(c));
  3427. float sum = xyz.x + xyz.y + xyz.z;
  3428. float x = xyz.x > 0 ? xyz.x / sum : 0.0;
  3429. float y = xyz.y > 0 ? xyz.y / sum : 0.0;
  3430. return blendRGB(c,
  3431. (int)map(xyz.y, 0, RANGE_Y, 0, 255),
  3432. (int)map(x, 0.0, 1.0, 0, 255),
  3433. (int)map(y, 0.0, 1.0, 0, 255));
  3434. }
  3435. color fromYXY(color c) {
  3436. float Y = map(getR(c), 0, 255, 0, RANGE_Y);
  3437. float x = map(getG(c), 0, 255, 0, 1.0);
  3438. float y = map(getB(c), 0, 255, 0, 1.0);
  3439. float divy = Y / (y>0 ? y : 1.0e-6);
  3440. return _fromXYZ(c, x * divy, Y, (1-x-y)*divy);
  3441. }
  3442. /**************
  3443. * XYZ
  3444. **************/
  3445. // FIXME: range from 0 to 1
  3446. float correctionxyz(float n) {
  3447. return (n > 0.04045 ? pow((n + 0.055) / 1.055, 2.4) : n / 12.92) * 100.0;
  3448. }
  3449. PVector _toXYZ(float rr, float gg, float bb) {
  3450. float r = correctionxyz(rr);
  3451. float g = correctionxyz(gg);
  3452. float b = correctionxyz(bb);
  3453. return new PVector(r * 0.4124 + g * 0.3576 + b * 0.1805,
  3454. r * 0.2126 + g * 0.7152 + b * 0.0722,
  3455. r * 0.0193 + g * 0.1192 + b * 0.9505);
  3456. }
  3457. color toXYZ(color c) {
  3458. PVector xyz = _toXYZ(getNR(c), getNG(c), getNB(c));
  3459. return blendRGB(c,
  3460. (int)map(xyz.x, 0, RANGE_X, 0, 255),
  3461. (int)map(xyz.y, 0, RANGE_Y, 0, 255),
  3462. (int)map(xyz.z, 0, RANGE_Z, 0, 255));
  3463. }
  3464. float recorrectionxyz(float n) {
  3465. return n > 0.0031308 ? 1.055 * pow(n, corrratio) - 0.055 : 12.92 * n;
  3466. }
  3467. // FIXME: range from 0 to 1
  3468. color _fromXYZ(color c, float xx, float yy, float zz) {
  3469. float x = xx/100.0;
  3470. float y = yy/100.0;
  3471. float z = zz/100.0;
  3472. int r = round(255.0*recorrectionxyz(x * 3.2406 + y * -1.5372 + z * -0.4986));
  3473. int g = round(255.0*recorrectionxyz(x * -0.9689 + y * 1.8758 + z * 0.0415));
  3474. int b = round(255.0*recorrectionxyz(x * 0.0557 + y * -0.2040 + z * 1.0570));
  3475. return blendRGB(c, r, g, b);
  3476. }
  3477. color fromXYZ(color c) {
  3478. float x = map(getR(c), 0, 255, 0, RANGE_X);
  3479. float y = map(getG(c), 0, 255, 0, RANGE_Y);
  3480. float z = map(getB(c), 0, 255, 0, RANGE_Z);
  3481. return _fromXYZ(c, x, y, z);
  3482. }
  3483. /**************
  3484. * CMY
  3485. **************/
  3486. color toCMY(color c) {
  3487. return blendRGB(c, 255-getR(c), 255-getG(c), 255-getB(c));
  3488. }
  3489. color fromCMY(color c) {
  3490. return toCMY(c);
  3491. }
  3492. /**************
  3493. * OHTA
  3494. **************/
  3495. color fromOHTA(color c) {
  3496. int I1 = getR(c);
  3497. float I2 = map(getG(c), 0, 255, -127.5, 127.5);
  3498. float I3 = map(getB(c), 0, 255, -127.5, 127.5);
  3499. int R = (int)(I1+1.00000*I2-0.66668*I3);
  3500. int G = (int)(I1+1.33333*I3);
  3501. int B = (int)(I1-1.00000*I2-0.66668*I3);
  3502. return blendRGB(c, R, G, B);
  3503. }
  3504. color toOHTA(color c) {
  3505. int R = getR(c);
  3506. int G = getG(c);
  3507. int B = getB(c);
  3508. int I1 = (int)(0.33333*R+0.33334*G+0.33333*B);
  3509. int I2 = (int)map(0.5*(R-B), -127.5, 127.5, 0, 255);
  3510. int I3 = (int)map(-0.25000*R+0.50000*G-0.25000*B, -127.5, 127.5, 0, 255);
  3511. return blendRGB(c, I1, I2, I3);
  3512. }
  3513. ////
  3514. // 1/n table for n=0..255 - to speed up color conversions things
  3515. final static float[] r255 = {
  3516. 0.0, 0.003921569, 0.007843138, 0.011764706, 0.015686275, 0.019607844, 0.023529412, 0.02745098, 0.03137255, 0.03529412, 0.039215688,
  3517. 0.043137256, 0.047058824, 0.050980393, 0.05490196, 0.05882353, 0.0627451, 0.06666667, 0.07058824, 0.07450981, 0.078431375, 0.08235294,
  3518. 0.08627451, 0.09019608, 0.09411765, 0.09803922, 0.101960786, 0.105882354, 0.10980392, 0.11372549, 0.11764706, 0.12156863, 0.1254902,
  3519. 0.12941177, 0.13333334, 0.13725491, 0.14117648, 0.14509805, 0.14901961, 0.15294118, 0.15686275, 0.16078432, 0.16470589, 0.16862746,
  3520. 0.17254902, 0.1764706, 0.18039216, 0.18431373, 0.1882353, 0.19215687, 0.19607843, 0.2, 0.20392157, 0.20784314, 0.21176471, 0.21568628,
  3521. 0.21960784, 0.22352941, 0.22745098, 0.23137255, 0.23529412, 0.23921569, 0.24313726, 0.24705882, 0.2509804, 0.25490198, 0.25882354,
  3522. 0.2627451, 0.26666668, 0.27058825, 0.27450982, 0.2784314, 0.28235295, 0.28627452, 0.2901961, 0.29411766, 0.29803923, 0.3019608, 0.30588236,
  3523. 0.30980393, 0.3137255, 0.31764707, 0.32156864, 0.3254902, 0.32941177, 0.33333334, 0.3372549, 0.34117648, 0.34509805, 0.34901962, 0.3529412,
  3524. 0.35686275, 0.36078432, 0.3647059, 0.36862746, 0.37254903, 0.3764706, 0.38039216, 0.38431373, 0.3882353, 0.39215687, 0.39607844, 0.4,
  3525. 0.40392157, 0.40784314, 0.4117647, 0.41568628, 0.41960785, 0.42352942, 0.42745098, 0.43137255, 0.43529412, 0.4392157, 0.44313726,
  3526. 0.44705883, 0.4509804, 0.45490196, 0.45882353, 0.4627451, 0.46666667, 0.47058824, 0.4745098, 0.47843137, 0.48235294, 0.4862745, 0.49019608,
  3527. 0.49411765, 0.49803922, 0.5019608, 0.5058824, 0.50980395, 0.5137255, 0.5176471, 0.52156866, 0.5254902, 0.5294118, 0.53333336, 0.5372549,
  3528. 0.5411765, 0.54509807, 0.54901963, 0.5529412, 0.5568628, 0.56078434, 0.5647059, 0.5686275, 0.57254905, 0.5764706, 0.5803922, 0.58431375,
  3529. 0.5882353, 0.5921569, 0.59607846, 0.6, 0.6039216, 0.60784316, 0.6117647, 0.6156863, 0.61960787, 0.62352943, 0.627451, 0.6313726, 0.63529414,
  3530. 0.6392157, 0.6431373, 0.64705884, 0.6509804, 0.654902, 0.65882355, 0.6627451, 0.6666667, 0.67058825, 0.6745098, 0.6784314, 0.68235296,
  3531. 0.6862745, 0.6901961, 0.69411767, 0.69803923, 0.7019608, 0.7058824, 0.70980394, 0.7137255, 0.7176471, 0.72156864, 0.7254902, 0.7294118,
  3532. 0.73333335, 0.7372549, 0.7411765, 0.74509805, 0.7490196, 0.7529412, 0.75686276, 0.7607843, 0.7647059, 0.76862746, 0.77254903, 0.7764706,
  3533. 0.78039217, 0.78431374, 0.7882353, 0.7921569, 0.79607844, 0.8, 0.8039216, 0.80784315, 0.8117647, 0.8156863, 0.81960785, 0.8235294, 0.827451,
  3534. 0.83137256, 0.8352941, 0.8392157, 0.84313726, 0.84705883, 0.8509804, 0.85490197, 0.85882354, 0.8627451, 0.8666667, 0.87058824, 0.8745098,
  3535. 0.8784314, 0.88235295, 0.8862745, 0.8901961, 0.89411765, 0.8980392, 0.9019608, 0.90588236, 0.9098039, 0.9137255, 0.91764706, 0.92156863,
  3536. 0.9254902, 0.92941177, 0.93333334, 0.9372549, 0.9411765, 0.94509804, 0.9490196, 0.9529412, 0.95686275, 0.9607843, 0.9647059, 0.96862745,
  3537. 0.972549, 0.9764706, 0.98039216, 0.9843137, 0.9882353, 0.99215686, 0.99607843, 1.0
  3538. };