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

effects.pde 91KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417
  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. rw = canvas.width;
  2063. rh = canvas.height;
  2064. img = createImage(rw, rh, ARGB);
  2065. buffer = createGraphics(rw, rh);
  2066. buffer.beginDraw();
  2067. buffer.noStroke();
  2068. buffer.smooth(8);
  2069. buffer.background(0);
  2070. buffer.image(img, 0, 0);
  2071. buffer.endDraw();
  2072. scale = abs(scale);
  2073. acho_step = 256.0 / iteration_no;
  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. img = canvas.get();
  2091. // if (iteration_no>0) {
  2092. for (int i = 0; i < iteration_no; i++) {
  2093. processImage();
  2094. }
  2095. //iteration_no--;
  2096. //iteration_no=(iteration_no==0)?max_iter:iteration_no;
  2097. // if (iteration_no == 0)
  2098. // iteration_no = 50;
  2099. // }
  2100. // } else {
  2101. canvas.beginDraw();
  2102. if (do_blend) {
  2103. canvas.blend(img, 0, 0, img.width, img.height, 0, 0, canvas.width, canvas.height, blend_mode);
  2104. } else {
  2105. canvas.image(buffer, canvas.width/2, canvas.height/2, canvas.width, canvas.height);
  2106. }
  2107. canvas.endDraw();
  2108. // canvas.image(img, 0, 0, renderer.width, renderer.height);
  2109. // noLoop();
  2110. // }
  2111. }
  2112. void processImage() {
  2113. buffer.beginDraw();
  2114. for (int x=0; x<img.width; x++) {
  2115. for (int y=0; y<img.height; y++) {
  2116. color c = img.get(x, y);
  2117. color c2;
  2118. if (direction == UP || direction == DOWN) {
  2119. c2 = img.get(x, ((int)(y+img.height+( (channel_off+getChannel(c, channel))%255 )*(direction==DOWN?-1.0:1.0)*scale))%img.height);
  2120. } else {
  2121. c2 = img.get(((int)(x+img.width+( (channel_off+getChannel(c, channel))%255)*(direction==RIGHT?-1.0:1.0)*scale))%img.width, y);
  2122. }
  2123. buffer.set(x, y, lerpColor(c, c2, feedback) );
  2124. }
  2125. }
  2126. buffer.endDraw();
  2127. //canvas.image(buffer, 0, 0, width, height);
  2128. img = buffer.get();
  2129. if (automate_channel_offset) channel_off += acho_step;
  2130. }
  2131. // ALL Channels, Nxxx stand for negative (255-value)
  2132. // channels to work with
  2133. final static int RED = 0;
  2134. final static int GREEN = 1;
  2135. final static int BLUE = 2;
  2136. final static int HUE = 3;
  2137. final static int SATURATION = 4;
  2138. final static int BRIGHTNESS = 5;
  2139. final static int NRED = 6;
  2140. final static int NGREEN = 7;
  2141. final static int NBLUE = 8;
  2142. final static int NHUE = 9;
  2143. final static int NSATURATION = 10;
  2144. final static int NBRIGHTNESS = 11;
  2145. float getChannel(color c, int channel) {
  2146. int ch = channel>5?channel-6:channel;
  2147. float cc;
  2148. switch(ch) {
  2149. case RED:
  2150. cc = red(c);
  2151. break;
  2152. case GREEN:
  2153. cc = green(c);
  2154. break;
  2155. case BLUE:
  2156. cc = blue(c);
  2157. break;
  2158. case HUE:
  2159. cc = hue(c);
  2160. break;
  2161. case SATURATION:
  2162. cc = saturation(c);
  2163. break;
  2164. default:
  2165. cc= brightness(c);
  2166. break;
  2167. }
  2168. return channel>5?255-cc:cc;
  2169. }
  2170. }
  2171. // name
  2172. String getColorspaceName(int cs) {
  2173. switch(cs) {
  2174. case OHTA:
  2175. return "OHTA";
  2176. case CMY:
  2177. return "CMY";
  2178. case XYZ:
  2179. return "XYZ";
  2180. case YXY:
  2181. return "YXY";
  2182. case HCL:
  2183. return "HCL";
  2184. case LUV:
  2185. return "LUV";
  2186. case LAB:
  2187. return "LAB";
  2188. case HWB:
  2189. return "HWB";
  2190. case HSB:
  2191. return "HSB";
  2192. case RGGBG:
  2193. return "R-GGB-G";
  2194. case YPbPr:
  2195. return "YPbPr";
  2196. case YCbCr:
  2197. return "YCbCr";
  2198. case YDbDr:
  2199. return "YDbDr";
  2200. case GS:
  2201. return "Greyscale";
  2202. case YUV:
  2203. return "YUV";
  2204. default:
  2205. return "RGB";
  2206. }
  2207. }
  2208. // colorspace converters
  2209. color fromColorspace(color c, int cs) {
  2210. switch(cs) {
  2211. case OHTA:
  2212. return fromOHTA(c);
  2213. case CMY:
  2214. return fromCMY(c);
  2215. case XYZ:
  2216. return fromXYZ(c);
  2217. case YXY:
  2218. return fromYXY(c);
  2219. case HCL:
  2220. return fromHCL(c);
  2221. case LUV:
  2222. return fromLUV(c);
  2223. case LAB:
  2224. return fromLAB(c);
  2225. case HWB:
  2226. return fromHWB(c);
  2227. case HSB:
  2228. return fromHSB(c);
  2229. case RGGBG:
  2230. return fromRGGBG(c);
  2231. case YPbPr:
  2232. return fromYPbPr(c);
  2233. case YCbCr:
  2234. return fromYCbCr(c);
  2235. case YDbDr:
  2236. return fromYDbDr(c);
  2237. case GS:
  2238. return tofromGS(c);
  2239. case YUV:
  2240. return fromYUV(c);
  2241. default:
  2242. return c;
  2243. }
  2244. }
  2245. color toColorspace(color c, int cs) {
  2246. switch(cs) {
  2247. case OHTA:
  2248. return toOHTA(c);
  2249. case CMY:
  2250. return toCMY(c);
  2251. case XYZ:
  2252. return toXYZ(c);
  2253. case YXY:
  2254. return toYXY(c);
  2255. case HCL:
  2256. return toHCL(c);
  2257. case LUV:
  2258. return toLUV(c);
  2259. case LAB:
  2260. return toLAB(c);
  2261. case HWB:
  2262. return toHWB(c);
  2263. case HSB:
  2264. return toHSB(c);
  2265. case RGGBG:
  2266. return toRGGBG(c);
  2267. case YPbPr:
  2268. return toYPbPr(c);
  2269. case YCbCr:
  2270. return toYCbCr(c);
  2271. case YDbDr:
  2272. return toYDbDr(c);
  2273. case YUV:
  2274. return toYUV(c);
  2275. case GS:
  2276. return tofromGS(c);
  2277. default:
  2278. return c;
  2279. }
  2280. }
  2281. // Colorspace converters
  2282. final int getR(color c) {
  2283. return (c & 0xff0000) >> 16;
  2284. }
  2285. final int getG(color c) {
  2286. return (c & 0xff00) >> 8;
  2287. }
  2288. final int getB(color c) {
  2289. return c & 0xff;
  2290. }
  2291. final int getLuma(color c) {
  2292. return constrain((int)(0.2126*getR(c)+0.7152*getG(c)+0.0722*getB(c)), 0, 255);
  2293. }
  2294. int getChannel(color c, int ch) {
  2295. switch(ch) {
  2296. case 0 :
  2297. return getR(c);
  2298. case 1 :
  2299. return getG(c);
  2300. case 2 :
  2301. return getB(c);
  2302. default:
  2303. return 0;
  2304. }
  2305. }
  2306. // normalized versions
  2307. final float getNR(color c) {
  2308. return r255[(c & 0xff0000) >> 16];
  2309. }
  2310. final float getNG(color c) {
  2311. return r255[(c & 0xff00) >> 8];
  2312. }
  2313. final float getNB(color c) {
  2314. return r255[c & 0xff];
  2315. }
  2316. final float getNLuma(color c) {
  2317. return r255[getLuma(c)];
  2318. }
  2319. color blendRGB(color c, int r, int g, int b) {
  2320. return (c & 0xff000000) | (constrain(r, 0, 255) << 16) | (constrain(g, 0, 255) << 8 ) | constrain(b, 0, 255);
  2321. }
  2322. color blendRGB(color c, float r, float g, float b) {
  2323. return blendRGB(c, (int)(r*255), (int)(g*255), (int)(b*255));
  2324. }
  2325. /**************
  2326. * Greyscale
  2327. **************/
  2328. color tofromGS(color c) {
  2329. int l = getLuma(c);
  2330. return blendRGB(c, l, l, l);
  2331. }
  2332. /**************
  2333. * YUV
  2334. **************/
  2335. final static float Umax = 0.436 * 255.0;
  2336. final static float Vmax = 0.615 * 255.0;
  2337. color toYUV(color c) {
  2338. int R = getR(c);
  2339. int G = getG(c);
  2340. int B = getB(c);
  2341. int Y = (int)( 0.299*R+0.587*G+0.114*B);
  2342. int U = (int)map(-0.14713*R-0.28886*G+0.436*B, -Umax, Umax, 0, 255);
  2343. int V = (int)map(0.615*R-0.51499*G-0.10001*B, -Vmax, Vmax, 0, 255);
  2344. return blendRGB(c, Y, U, V);
  2345. }
  2346. color fromYUV(color c) {
  2347. int Y = getR(c);
  2348. float U = map(getG(c), 0, 255, -Umax, Umax);
  2349. float V = map(getB(c), 0, 255, -Vmax, Vmax);
  2350. int R = (int)(Y + 1.13983*V);
  2351. int G = (int)(Y - 0.39465*U - 0.58060*V);
  2352. int B = (int)(Y + 2.03211*U);
  2353. return blendRGB(c, R, G, B);
  2354. }
  2355. /**************
  2356. * YDbDr
  2357. **************/
  2358. color toYDbDr(color c) {
  2359. int R = getR(c);
  2360. int G = getG(c);
  2361. int B = getB(c);
  2362. int Y = (int)( 0.299*R+0.587*G+0.114*B);
  2363. int Db = (int)(127.5+(-0.450*R-0.883*G+1.333*B)/2.666);
  2364. int Dr = (int)(127.5+(-1.333*R+1.116*G+0.217*B)/2.666);
  2365. return blendRGB(c, Y, Db, Dr);
  2366. }
  2367. color fromYDbDr(color c) {
  2368. int Y = getR(c);
  2369. float Db = (getG(c)-127.5)*2.666;
  2370. float Dr = (getB(c)-127.5)*2.666;
  2371. int R = (int)(Y + 9.2303716147657e-05*Db-0.52591263066186533*Dr);
  2372. int G = (int)(Y - 0.12913289889050927*Db+0.26789932820759876*Dr);
  2373. int B = (int)(Y + 0.66467905997895482*Db-7.9202543533108e-05*Dr);
  2374. return blendRGB(c, R, G, B);
  2375. }
  2376. /**************
  2377. * YCbCr
  2378. **************/
  2379. color toYCbCr(color c) {
  2380. int R = getR(c);
  2381. int G = getG(c);
  2382. int B = getB(c);
  2383. int Y = (int)( 0.2988390*R+0.5868110*G+0.1143500*B);
  2384. int Cb = (int)(-0.168736*R-0.3312640*G+0.5000000*B+127.5);
  2385. int Cr = (int)( 0.5000000*R-0.4186880*G-0.0813120*B+127.5);
  2386. return blendRGB(c, Y, Cb, Cr);
  2387. }
  2388. color fromYCbCr(color c) {
  2389. int Y = getR(c);
  2390. float Cb = getG(c) - 127.5;
  2391. float Cr = getB(c) - 127.5;
  2392. int R = (int)(Y + 1.402*Cr)+1; // some fix
  2393. int G = (int)(Y-0.344136*Cb-0.714136*Cr);
  2394. int B = (int)(Y+1.772000*Cb)+1; // some fix
  2395. return blendRGB(c, R, G, B);
  2396. }
  2397. /**************
  2398. * YPbPr
  2399. **************/
  2400. color toYPbPr(color c) {
  2401. int R = getR(c);
  2402. int B = getB(c);
  2403. int Y = getLuma(c);
  2404. int Pb = B - Y;
  2405. int Pr = R - Y;
  2406. if (Pb<0) Pb+=256;
  2407. if (Pr<0) Pr+=256;
  2408. return blendRGB(c, Y, Pb, Pr);
  2409. }
  2410. color fromYPbPr(color c) {
  2411. int Y = getR(c);
  2412. int B = getG(c) + Y;
  2413. int R = getB(c) + Y;
  2414. if (R>255) R-=256;
  2415. if (B>255) B-=256;
  2416. int G = (int)((Y-0.2126*R-0.0722*B)/0.7152);
  2417. return blendRGB(c, R, G, B);
  2418. }
  2419. /**************
  2420. * R-G,G,B-G
  2421. **************/
  2422. color toRGGBG(color c) {
  2423. int G = getG(c);
  2424. int R = getR(c)-G;
  2425. int B = getB(c)-G;
  2426. if (R<0) R+=256;
  2427. if (B<0) B+=256;
  2428. return blendRGB(c, R, G, B);
  2429. }
  2430. color fromRGGBG(color c) {
  2431. int G = getG(c);
  2432. int R = getR(c)+G;
  2433. int B = getB(c)+G;
  2434. if (R>255) R-=256;
  2435. if (B>255) B-=256;
  2436. return blendRGB(c, R, G, B);
  2437. }
  2438. /**************
  2439. * HWB
  2440. **************/
  2441. color toHSB(color c) {
  2442. int R = getR(c);
  2443. int G = getG(c);
  2444. int B = getB(c);
  2445. int _min = min(R, G, B);
  2446. int _max = max(R, G, B);
  2447. float delta = _max-_min;
  2448. float saturation = delta/_max;
  2449. float brightness = r255[_max];
  2450. if (delta == 0.0) return blendRGB(c, 0.0, saturation, brightness);
  2451. float hue = 0;
  2452. if (R == _max) hue = (G-B)/delta;
  2453. else if (G == _max) hue = 2.0 + (B-R)/delta;
  2454. else hue = 4.0 + (R-G)/delta;
  2455. hue /= 6.0;
  2456. if (hue < 0.0) hue += 1.0;
  2457. return blendRGB(c, hue, saturation, brightness);
  2458. }
  2459. color fromHSB(color c) {
  2460. float S = getNG(c);
  2461. float B = getNB(c);
  2462. if (S == 0.0) return blendRGB(c, B, B, B);
  2463. float h = 6.0 * getNR(c);
  2464. float f = h-floor(h);
  2465. float p = B*(1.0-S);
  2466. float q = B*(1.0-S*f);
  2467. float t = B*(1.0-(S*(1.0-f)));
  2468. float r, g, b;
  2469. switch((int)h) {
  2470. case 1:
  2471. r=q;
  2472. g=B;
  2473. b=p;
  2474. break;
  2475. case 2:
  2476. r=p;
  2477. g=B;
  2478. b=t;
  2479. break;
  2480. case 3:
  2481. r=p;
  2482. g=q;
  2483. b=B;
  2484. break;
  2485. case 4:
  2486. r=t;
  2487. g=p;
  2488. b=B;
  2489. break;
  2490. case 5:
  2491. r=B;
  2492. g=p;
  2493. b=q;
  2494. break;
  2495. default:
  2496. r=B;
  2497. g=t;
  2498. b=p;
  2499. break;
  2500. }
  2501. return blendRGB(c, r, g, b);
  2502. }
  2503. /**************
  2504. * HWB
  2505. **************/
  2506. color toHWB(color c) {
  2507. int R = getR(c);
  2508. int G = getG(c);
  2509. int B = getB(c);
  2510. int w = min(R, G, B);
  2511. int v = max(R, G, B);
  2512. int hue;
  2513. if (v == w) hue = 255;
  2514. else {
  2515. float f = ((R == w) ? G-B : ((G == w) ? B-R : R-G));
  2516. float p = (R == w) ? 3.0 : ((G == w) ? 5.0 : 1.0);
  2517. hue = (int)map((p-f/(v-w))/6.0, 0, 1, 0, 254);
  2518. }
  2519. return blendRGB(c, hue, w, 255-v);
  2520. }
  2521. color fromHWB(color c) {
  2522. int H = getR(c);
  2523. int B = 255-getB(c);
  2524. if (H == 255) return blendRGB(c, B, B, B);
  2525. else {
  2526. float hue = map(H, 0, 254, 0, 6);
  2527. float v = r255[B];
  2528. float whiteness = getNG(c);
  2529. int i = (int)floor(hue);
  2530. float f = hue-i;
  2531. if ((i&0x01)!= 0) f=1.0-f;
  2532. float n = whiteness+f*(v-whiteness);
  2533. float r, g, b;
  2534. switch(i) {
  2535. case 1:
  2536. r=n;
  2537. g=v;
  2538. b=whiteness;
  2539. break;
  2540. case 2:
  2541. r=whiteness;
  2542. g=v;
  2543. b=n;
  2544. break;
  2545. case 3:
  2546. r=whiteness;
  2547. g=n;
  2548. b=v;
  2549. break;
  2550. case 4:
  2551. r=n;
  2552. g=whiteness;
  2553. b=v;
  2554. break;
  2555. case 5:
  2556. r=v;
  2557. g=whiteness;
  2558. b=n;
  2559. break;
  2560. default:
  2561. r=v;
  2562. g=n;
  2563. b=whiteness;
  2564. break;
  2565. }
  2566. return blendRGB(c, r, g, b);
  2567. }
  2568. }
  2569. /**************
  2570. * Lab
  2571. **************/
  2572. final static float D65X=0.950456;
  2573. final static float D65Y=1.0;
  2574. final static float D65Z=1.088754;
  2575. final static float CIEEpsilon=(216.0/24389.0);
  2576. final static float CIEK=(24389.0/27.0);
  2577. final static float CIEK2epsilon = CIEK * CIEEpsilon;
  2578. final static float D65FX_4 = 4.0*D65X/(D65X+15.0*D65Y+3.0*D65Z);
  2579. final static float D65FY_9 = 9.0*D65Y/(D65X+15.0*D65Y+3.0*D65Z);
  2580. final static float RANGE_X = 100.0 * (0.4124+0.3576+0.1805);
  2581. final static float RANGE_Y = 100.0;
  2582. final static float RANGE_Z = 100.0 * (0.0193+0.1192+0.9505);
  2583. final static float mepsilon = 1.0e-10;
  2584. final static float corrratio = 1.0/2.4;
  2585. final static float One_Third = 1.0/3.0;
  2586. final static float one_hsixteen = 1.0/116.0;
  2587. color toLAB(color c) {
  2588. PVector xyz = _toXYZ(getNR(c), getNG(c), getNB(c));
  2589. xyz.div(100.0);
  2590. xyz.x /= D65X;
  2591. xyz.y /= D65Y;
  2592. xyz.z /= D65Z;
  2593. float x, y, z;
  2594. if (xyz.x > CIEEpsilon) {
  2595. x = pow(xyz.x, One_Third);
  2596. } else {
  2597. x= (CIEK*xyz.x+16.0)*one_hsixteen;
  2598. }
  2599. if (xyz.y > CIEEpsilon) {
  2600. y = pow(xyz.y, One_Third);
  2601. } else {
  2602. y = (CIEK*xyz.y+16.0)*one_hsixteen;
  2603. }
  2604. if (xyz.z > CIEEpsilon) {
  2605. z = pow(xyz.z, One_Third);
  2606. } else {
  2607. z = (CIEK*xyz.z+16.0)*one_hsixteen;
  2608. }
  2609. float L = 255.0*(((116.0*y)-16.0)*0.01);
  2610. float a = 255.0*(0.5*(x-y)+0.5);
  2611. float b = 255.0*(0.5*(y-z)+0.5);
  2612. return blendRGB(c, round(L), round(a), round(b));
  2613. }
  2614. color fromLAB(color c) {
  2615. float L = 100*getNR(c);
  2616. float a = getNG(c)-0.5;
  2617. float b = getNB(c)-0.5;
  2618. float y = (L+16.0)*one_hsixteen;
  2619. float x = y+a;
  2620. float z = y-b;
  2621. float xxx=x*x*x;
  2622. if (xxx>CIEEpsilon) {
  2623. x = xxx;
  2624. } else {
  2625. x = (116.0*x-16.0)/CIEK;
  2626. }
  2627. float yyy=y*y*y;
  2628. if (yyy>CIEEpsilon) {
  2629. y = yyy;
  2630. } else {
  2631. y = L/CIEK;
  2632. }
  2633. float zzz=z*z*z;
  2634. if (zzz>CIEEpsilon) {
  2635. z = zzz;
  2636. } else {
  2637. z = (116.0*z-16.0)/CIEK;
  2638. }
  2639. return _fromXYZ(c, RANGE_X*x, RANGE_Y*y, RANGE_Z*z);
  2640. }
  2641. /**************
  2642. * Luv
  2643. **************/
  2644. final float PerceptibleReciprocal(float x) {
  2645. float sgn = x < 0.0 ? -1.0 : 1.0;
  2646. if ((sgn * x) >= mepsilon) return (1.0 / x);
  2647. return (sgn/mepsilon);
  2648. }
  2649. color toLUV(color c) {
  2650. PVector xyz = _toXYZ(getNR(c), getNG(c), getNB(c));
  2651. xyz.div(100.0);
  2652. float d = xyz.y; // / D65Y;
  2653. float L;
  2654. if (d > CIEEpsilon) L = 116.0*pow(d, One_Third)-16.0;
  2655. else L = CIEK * d;
  2656. float alpha = PerceptibleReciprocal(xyz.x + 15.0 * xyz.y + 3.0 * xyz.z);
  2657. float L13 = 13.0 * L;
  2658. float u = L13 * ((4.0 * alpha * xyz.x)-D65FX_4);
  2659. float v = L13 * ((9.0 * alpha * xyz.y)-D65FY_9);
  2660. L /= 100.0;
  2661. u=(u+134.0)/354.0;
  2662. v=(v+140.0)/262.0;
  2663. return blendRGB(c, round(L*255), round(u*255), round(v*255));
  2664. }
  2665. color fromLUV(color c) {
  2666. float L = 100.0*getNR(c);
  2667. float u = 354.0*getNG(c)-134.0;
  2668. float v = 262.0*getNB(c)-140.0;
  2669. float X, Y, Z;
  2670. if (L > CIEK2epsilon) Y = pow((L+16.0)*one_hsixteen, 3.0);
  2671. else Y = L/CIEK;
  2672. float L13 = 13.0*L;
  2673. float L52 = 52.0*L;
  2674. float Y5 = 5.0*Y;
  2675. float L13u = L52/(u+L13*D65FX_4);
  2676. X=((Y*((39.0*L/(v+L13*D65FY_9))-5.0))+Y5)/((((L13u)-1.0)/3.0)+One_Third);
  2677. Z=(X*(((L13u)-1.0)/3.0))-Y5;
  2678. return _fromXYZ(c, 100*X, 100*Y, 100*Z);
  2679. }
  2680. /**************
  2681. * HCL
  2682. **************/
  2683. color toHCL(color c) {
  2684. float r = getNR(c);
  2685. float g = getNG(c);
  2686. float b = getNB(c);
  2687. float max = max(r, max(g, b));
  2688. float chr = max - min(r, min(g, b));
  2689. float h = 0.0;
  2690. if ( chr != 0) {
  2691. if (r == max) {
  2692. h = ((g-b)/chr+6.0) % 6.0;
  2693. } else if (g == max) {
  2694. h = (b-r)/chr + 2.0;
  2695. } else {
  2696. h = (r-g)/chr + 4.0;
  2697. }
  2698. }
  2699. return blendRGB(c, round((h/6.0)*255), round(chr*255), round(255*(0.298839*r+0.586811*g+0.114350*b)));
  2700. }
  2701. color fromHCL(color c) {
  2702. float h = 6.0*getNR(c);
  2703. float chr = getNG(c);
  2704. float l = getNB(c);
  2705. float x = chr*(1.0-abs((h%2.0)-1.0));
  2706. float r = 0.0;
  2707. float g = 0.0;
  2708. float b = 0.0;
  2709. if ((0.0 <= h) && (h < 1.0)) {
  2710. r=chr;
  2711. g=x;
  2712. } else if ((1.0 <= h) && (h < 2.0)) {
  2713. r=x;
  2714. g=chr;
  2715. } else if ((2.0 <= h) && (h < 3.0)) {
  2716. g=chr;
  2717. b=x;
  2718. } else if ((3.0 <= h) && (h < 4.0)) {
  2719. g=x;
  2720. b=chr;
  2721. } else if ((4.0 <= h) && (h < 5.0)) {
  2722. r=x;
  2723. b=chr;
  2724. } else {//if ((5.0 <= h) && (h < 6.0)) {
  2725. r=chr;
  2726. b=x;
  2727. }
  2728. float m = l - (0.298839*r+0.586811*g+0.114350*b);
  2729. return blendRGB(c, round(255*(r+m)), round(255*(g+m)), round(255*(b+m)));
  2730. }
  2731. /**************
  2732. * Yxy
  2733. **************/
  2734. color toYXY(color c) {
  2735. PVector xyz = _toXYZ(getNR(c), getNG(c), getNB(c));
  2736. float sum = xyz.x + xyz.y + xyz.z;
  2737. float x = xyz.x > 0 ? xyz.x / sum : 0.0;
  2738. float y = xyz.y > 0 ? xyz.y / sum : 0.0;
  2739. return blendRGB(c,
  2740. (int)map(xyz.y, 0, RANGE_Y, 0, 255),
  2741. (int)map(x, 0.0, 1.0, 0, 255),
  2742. (int)map(y, 0.0, 1.0, 0, 255));
  2743. }
  2744. color fromYXY(color c) {
  2745. float Y = map(getR(c), 0, 255, 0, RANGE_Y);
  2746. float x = map(getG(c), 0, 255, 0, 1.0);
  2747. float y = map(getB(c), 0, 255, 0, 1.0);
  2748. float divy = Y / (y>0 ? y : 1.0e-6);
  2749. return _fromXYZ(c, x * divy, Y, (1-x-y)*divy);
  2750. }
  2751. /**************
  2752. * XYZ
  2753. **************/
  2754. // FIXME: range from 0 to 1
  2755. float correctionxyz(float n) {
  2756. return (n > 0.04045 ? pow((n + 0.055) / 1.055, 2.4) : n / 12.92) * 100.0;
  2757. }
  2758. PVector _toXYZ(float rr, float gg, float bb) {
  2759. float r = correctionxyz(rr);
  2760. float g = correctionxyz(gg);
  2761. float b = correctionxyz(bb);
  2762. return new PVector(r * 0.4124 + g * 0.3576 + b * 0.1805,
  2763. r * 0.2126 + g * 0.7152 + b * 0.0722,
  2764. r * 0.0193 + g * 0.1192 + b * 0.9505);
  2765. }
  2766. color toXYZ(color c) {
  2767. PVector xyz = _toXYZ(getNR(c), getNG(c), getNB(c));
  2768. return blendRGB(c,
  2769. (int)map(xyz.x, 0, RANGE_X, 0, 255),
  2770. (int)map(xyz.y, 0, RANGE_Y, 0, 255),
  2771. (int)map(xyz.z, 0, RANGE_Z, 0, 255));
  2772. }
  2773. float recorrectionxyz(float n) {
  2774. return n > 0.0031308 ? 1.055 * pow(n, corrratio) - 0.055 : 12.92 * n;
  2775. }
  2776. // FIXME: range from 0 to 1
  2777. color _fromXYZ(color c, float xx, float yy, float zz) {
  2778. float x = xx/100.0;
  2779. float y = yy/100.0;
  2780. float z = zz/100.0;
  2781. int r = round(255.0*recorrectionxyz(x * 3.2406 + y * -1.5372 + z * -0.4986));
  2782. int g = round(255.0*recorrectionxyz(x * -0.9689 + y * 1.8758 + z * 0.0415));
  2783. int b = round(255.0*recorrectionxyz(x * 0.0557 + y * -0.2040 + z * 1.0570));
  2784. return blendRGB(c, r, g, b);
  2785. }
  2786. color fromXYZ(color c) {
  2787. float x = map(getR(c), 0, 255, 0, RANGE_X);
  2788. float y = map(getG(c), 0, 255, 0, RANGE_Y);
  2789. float z = map(getB(c), 0, 255, 0, RANGE_Z);
  2790. return _fromXYZ(c, x, y, z);
  2791. }
  2792. /**************
  2793. * CMY
  2794. **************/
  2795. color toCMY(color c) {
  2796. return blendRGB(c, 255-getR(c), 255-getG(c), 255-getB(c));
  2797. }
  2798. color fromCMY(color c) {
  2799. return toCMY(c);
  2800. }
  2801. /**************
  2802. * OHTA
  2803. **************/
  2804. color fromOHTA(color c) {
  2805. int I1 = getR(c);
  2806. float I2 = map(getG(c), 0, 255, -127.5, 127.5);
  2807. float I3 = map(getB(c), 0, 255, -127.5, 127.5);
  2808. int R = (int)(I1+1.00000*I2-0.66668*I3);
  2809. int G = (int)(I1+1.33333*I3);
  2810. int B = (int)(I1-1.00000*I2-0.66668*I3);
  2811. return blendRGB(c, R, G, B);
  2812. }
  2813. color toOHTA(color c) {
  2814. int R = getR(c);
  2815. int G = getG(c);
  2816. int B = getB(c);
  2817. int I1 = (int)(0.33333*R+0.33334*G+0.33333*B);
  2818. int I2 = (int)map(0.5*(R-B), -127.5, 127.5, 0, 255);
  2819. int I3 = (int)map(-0.25000*R+0.50000*G-0.25000*B, -127.5, 127.5, 0, 255);
  2820. return blendRGB(c, I1, I2, I3);
  2821. }
  2822. ////
  2823. // 1/n table for n=0..255 - to speed up color conversions things
  2824. final static float[] r255 = {
  2825. 0.0, 0.003921569, 0.007843138, 0.011764706, 0.015686275, 0.019607844, 0.023529412, 0.02745098, 0.03137255, 0.03529412, 0.039215688,
  2826. 0.043137256, 0.047058824, 0.050980393, 0.05490196, 0.05882353, 0.0627451, 0.06666667, 0.07058824, 0.07450981, 0.078431375, 0.08235294,
  2827. 0.08627451, 0.09019608, 0.09411765, 0.09803922, 0.101960786, 0.105882354, 0.10980392, 0.11372549, 0.11764706, 0.12156863, 0.1254902,
  2828. 0.12941177, 0.13333334, 0.13725491, 0.14117648, 0.14509805, 0.14901961, 0.15294118, 0.15686275, 0.16078432, 0.16470589, 0.16862746,
  2829. 0.17254902, 0.1764706, 0.18039216, 0.18431373, 0.1882353, 0.19215687, 0.19607843, 0.2, 0.20392157, 0.20784314, 0.21176471, 0.21568628,
  2830. 0.21960784, 0.22352941, 0.22745098, 0.23137255, 0.23529412, 0.23921569, 0.24313726, 0.24705882, 0.2509804, 0.25490198, 0.25882354,
  2831. 0.2627451, 0.26666668, 0.27058825, 0.27450982, 0.2784314, 0.28235295, 0.28627452, 0.2901961, 0.29411766, 0.29803923, 0.3019608, 0.30588236,
  2832. 0.30980393, 0.3137255, 0.31764707, 0.32156864, 0.3254902, 0.32941177, 0.33333334, 0.3372549, 0.34117648, 0.34509805, 0.34901962, 0.3529412,
  2833. 0.35686275, 0.36078432, 0.3647059, 0.36862746, 0.37254903, 0.3764706, 0.38039216, 0.38431373, 0.3882353, 0.39215687, 0.39607844, 0.4,
  2834. 0.40392157, 0.40784314, 0.4117647, 0.41568628, 0.41960785, 0.42352942, 0.42745098, 0.43137255, 0.43529412, 0.4392157, 0.44313726,
  2835. 0.44705883, 0.4509804, 0.45490196, 0.45882353, 0.4627451, 0.46666667, 0.47058824, 0.4745098, 0.47843137, 0.48235294, 0.4862745, 0.49019608,
  2836. 0.49411765, 0.49803922, 0.5019608, 0.5058824, 0.50980395, 0.5137255, 0.5176471, 0.52156866, 0.5254902, 0.5294118, 0.53333336, 0.5372549,
  2837. 0.5411765, 0.54509807, 0.54901963, 0.5529412, 0.5568628, 0.56078434, 0.5647059, 0.5686275, 0.57254905, 0.5764706, 0.5803922, 0.58431375,
  2838. 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,
  2839. 0.6392157, 0.6431373, 0.64705884, 0.6509804, 0.654902, 0.65882355, 0.6627451, 0.6666667, 0.67058825, 0.6745098, 0.6784314, 0.68235296,
  2840. 0.6862745, 0.6901961, 0.69411767, 0.69803923, 0.7019608, 0.7058824, 0.70980394, 0.7137255, 0.7176471, 0.72156864, 0.7254902, 0.7294118,
  2841. 0.73333335, 0.7372549, 0.7411765, 0.74509805, 0.7490196, 0.7529412, 0.75686276, 0.7607843, 0.7647059, 0.76862746, 0.77254903, 0.7764706,
  2842. 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,
  2843. 0.83137256, 0.8352941, 0.8392157, 0.84313726, 0.84705883, 0.8509804, 0.85490197, 0.85882354, 0.8627451, 0.8666667, 0.87058824, 0.8745098,
  2844. 0.8784314, 0.88235295, 0.8862745, 0.8901961, 0.89411765, 0.8980392, 0.9019608, 0.90588236, 0.9098039, 0.9137255, 0.91764706, 0.92156863,
  2845. 0.9254902, 0.92941177, 0.93333334, 0.9372549, 0.9411765, 0.94509804, 0.9490196, 0.9529412, 0.95686275, 0.9607843, 0.9647059, 0.96862745,
  2846. 0.972549, 0.9764706, 0.98039216, 0.9843137, 0.9882353, 0.99215686, 0.99607843, 1.0
  2847. };