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

effects.pde 68KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646
  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. }
  10. int previousMode;
  11. void apply() {
  12. if (previousMode != int(params.get(1).value)) {
  13. if (params.get(1).value == 0) changeParam(0, new Param("black", INTVAL, -17000000, -2000000, new int[]{SINE, SAWTOOTH, RAMPUPDOWN, TAN, TANINVERSE, TRIANG}));
  14. if (params.get(1).value == 1) changeParam(0, new Param("brightness", INTVAL, 0, 200, new int[]{SINE, SAWTOOTH, RAMPUPDOWN, TAN, TANINVERSE, TRIANG}));
  15. if (params.get(1).value == 2) changeParam(0, new Param("white", INTVAL, -15000000, -700000, new int[]{SINE, SAWTOOTH, RAMPUPDOWN, TAN, TANINVERSE, TRIANG}));
  16. }
  17. previousMode = int(params.get(1).value);
  18. row = 0;
  19. column = 0;
  20. renderer.beginDraw();
  21. renderer.colorMode(RGB);
  22. colorMode(RGB);
  23. while (column < renderer.width-1) {
  24. renderer.loadPixels();
  25. sortColumn();
  26. column++;
  27. renderer.updatePixels();
  28. }
  29. while (row < renderer.height-1) {
  30. renderer.loadPixels();
  31. sortRow();
  32. row++;
  33. renderer.updatePixels();
  34. }
  35. renderer.endDraw();
  36. }
  37. int row = 0;
  38. int column = 0;
  39. void sortRow() {
  40. int x = 0;
  41. int y = row;
  42. int xend = 0;
  43. while (xend < renderer.width-1) {
  44. switch((int)params.get(1).value) {
  45. case 0:
  46. x = getFirstNotBlackX(x, y);
  47. xend = getNextBlackX(x, y);
  48. break;
  49. case 1:
  50. x = getFirstBrightX(x, y);
  51. xend = getNextDarkX(x, y);
  52. break;
  53. case 2:
  54. x = getFirstNotWhiteX(x, y);
  55. xend = getNextWhiteX(x, y);
  56. break;
  57. default:
  58. break;
  59. }
  60. if (x < 0) break;
  61. int sortLength = xend-x;
  62. color[] unsorted = new color[sortLength];
  63. color[] sorted = new color[sortLength];
  64. for (int i=0; i<sortLength; i++) {
  65. unsorted[i] = renderer.pixels[x + i + y * renderer.width];
  66. }
  67. sorted = sort(unsorted);
  68. for (int i=0; i<sortLength; i++) {
  69. renderer.pixels[x + i + y * renderer.width] = sorted[i];
  70. }
  71. x = xend+1;
  72. }
  73. }
  74. void sortColumn() {
  75. int x = column;
  76. int y = 0;
  77. int yend = 0;
  78. while (yend < renderer.height-1) {
  79. switch((int)params.get(1).value) {
  80. case 0:
  81. y = getFirstNotBlackY(x, y);
  82. yend = getNextBlackY(x, y);
  83. break;
  84. case 1:
  85. y = getFirstBrightY(x, y);
  86. yend = getNextDarkY(x, y);
  87. break;
  88. case 2:
  89. y = getFirstNotWhiteY(x, y);
  90. yend = getNextWhiteY(x, y);
  91. break;
  92. default:
  93. break;
  94. }
  95. if (y < 0) break;
  96. int sortLength = yend-y;
  97. color[] unsorted = new color[sortLength];
  98. color[] sorted = new color[sortLength];
  99. for (int i=0; i<sortLength; i++) {
  100. unsorted[i] = renderer.pixels[x + (y+i) * renderer.width];
  101. }
  102. sorted = sort(unsorted);
  103. for (int i=0; i<sortLength; i++) {
  104. renderer.pixels[x + (y+i) * renderer.width] = sorted[i];
  105. }
  106. y = yend+1;
  107. }
  108. }
  109. //BLACK
  110. int getFirstNotBlackX(int _x, int _y) {
  111. int x = _x;
  112. int y = _y;
  113. color c;
  114. while ( (c = renderer.pixels[x + y * renderer.width]) < params.get(0).value) {
  115. x++;
  116. if (x >= renderer.width) return -1;
  117. }
  118. return x;
  119. }
  120. int getNextBlackX(int _x, int _y) {
  121. int x = _x+1;
  122. int y = _y;
  123. color c;
  124. while ( (c = renderer.pixels[x + y * renderer.width]) > params.get(0).value) {
  125. x++;
  126. if (x >= renderer.width) return renderer.width-1;
  127. }
  128. return x-1;
  129. }
  130. //BRIGHTNESS
  131. int getFirstBrightX(int _x, int _y) {
  132. int x = _x;
  133. int y = _y;
  134. color c;
  135. while (brightness (c = renderer.pixels[x + y * renderer.width]) < params.get(0).value) {
  136. x++;
  137. if (x >= renderer.width) return -1;
  138. }
  139. return x;
  140. }
  141. int getNextDarkX(int _x, int _y) {
  142. int x = _x+1;
  143. int y = _y;
  144. color c;
  145. while (brightness (c = renderer.pixels[x + y * renderer.width]) > params.get(0).value) {
  146. x++;
  147. if (x >= renderer.width) return renderer.width-1;
  148. }
  149. return x-1;
  150. }
  151. //WHITE
  152. int getFirstNotWhiteX(int _x, int _y) {
  153. int x = _x;
  154. int y = _y;
  155. color c;
  156. while ( (c = renderer.pixels[x + y * renderer.width]) > params.get(0).value) {
  157. x++;
  158. if (x >= renderer.width) return -1;
  159. }
  160. return x;
  161. }
  162. int getNextWhiteX(int _x, int _y) {
  163. int x = _x+1;
  164. int y = _y;
  165. color c;
  166. while ( (c = renderer.pixels[x + y * renderer.width]) < params.get(0).value) {
  167. x++;
  168. if (x >= renderer.width) return renderer.width-1;
  169. }
  170. return x-1;
  171. }
  172. //BLACK
  173. int getFirstNotBlackY(int _x, int _y) {
  174. int x = _x;
  175. int y = _y;
  176. color c;
  177. if (y < renderer.height) {
  178. while ( (c = renderer.pixels[x + y * renderer.width]) < params.get(0).value) {
  179. y++;
  180. if (y >= renderer.height) return -1;
  181. }
  182. }
  183. return y;
  184. }
  185. int getNextBlackY(int _x, int _y) {
  186. int x = _x;
  187. int y = _y+1;
  188. color c;
  189. if (y < renderer.height) {
  190. while ( (c = renderer.pixels[x + y * renderer.width]) > params.get(0).value) {
  191. y++;
  192. if (y >= renderer.height) return renderer.height-1;
  193. }
  194. }
  195. return y-1;
  196. }
  197. //BRIGHTNESS
  198. int getFirstBrightY(int _x, int _y) {
  199. int x = _x;
  200. int y = _y;
  201. color c;
  202. if (y < renderer.height) {
  203. while (brightness (c = renderer.pixels[x + y * renderer.width]) < params.get(0).value) {
  204. y++;
  205. if (y >= renderer.height) return -1;
  206. }
  207. }
  208. return y;
  209. }
  210. int getNextDarkY(int _x, int _y) {
  211. int x = _x;
  212. int y = _y+1;
  213. color c;
  214. if (y < renderer.height) {
  215. while (brightness (c = renderer.pixels[x + y * renderer.width]) > params.get(0).value) {
  216. y++;
  217. if (y >= renderer.height) return renderer.height-1;
  218. }
  219. }
  220. return y-1;
  221. }
  222. //WHITE
  223. int getFirstNotWhiteY(int _x, int _y) {
  224. int x = _x;
  225. int y = _y;
  226. color c;
  227. if (y < renderer.height) {
  228. while ( (c = renderer.pixels[x + y * renderer.width]) > params.get(0).value) {
  229. y++;
  230. if (y >= renderer.height) return -1;
  231. }
  232. }
  233. return y;
  234. }
  235. int getNextWhiteY(int _x, int _y) {
  236. int x = _x;
  237. int y = _y+1;
  238. color c;
  239. if (y < renderer.height) {
  240. while ( (c = renderer.pixels[x + y * renderer.width]) < params.get(0).value) {
  241. y++;
  242. if (y >= renderer.height) return renderer.height-1;
  243. }
  244. }
  245. return y-1;
  246. }
  247. }
  248. /*
  249. DISTORTER
  250. */
  251. class DISTORTER extends Shader {
  252. boolean do_blend = false; // blend image after process
  253. int blend_mode = OVERLAY; // blend type
  254. int channel = BRIGHTNESS; // channel used in processing (R,G,B) or (H,S,B)
  255. float scalex = 0.05; // from 0.01 to 1
  256. float scaley = 0.1; // from 0.01 to 1
  257. boolean shift_hue = true;
  258. float shift_amt = 0.1; // from 0 to 1
  259. PImage buffer;
  260. 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
  261. int[][] distort = new int[2][distortionMatrixSize];
  262. final static float tick = 1.0/distortionMatrixSize;
  263. int mode = 0;
  264. int initBufferW, initBufferH;
  265. DISTORTER() {
  266. buffer = createImage(renderer.width, renderer.height, ARGB);
  267. initBufferW = buffer.width;
  268. initBufferH = buffer.height;
  269. name = "fxDistorter";
  270. params.add(new Param("width", FLOATVAL, 2, buffer.width/4-1, new int[]{SINE, SAWTOOTH, RAMPUPDOWN, TAN, TANINVERSE, TRIANG}));
  271. params.add(new Param("height", FLOATVAL, 2, buffer.height/4-1, new int[]{SINE, SAWTOOTH, RAMPUPDOWN, TAN, TANINVERSE, TRIANG}));
  272. params.add(new Param("do blend", INTVAL, 0, 1, new int[]{RANDOM, SQUAR}));
  273. params.add(new Param("shift hue amount", FLOATVAL, 0, 1, new int[]{SAWTOOTH, SAWTOOTHINVERSE, TAN, TANINVERSE, RAMP, RAMPINVERSE}));
  274. params.add(new Param("scale x", FLOATVAL, 0.01, 1, new int[]{SINE, SAWTOOTH, RAMPUPDOWN, TAN, TANINVERSE, TRIANG}));
  275. params.add(new Param("scale y", FLOATVAL, 0.01, 1, new int[]{SINE, SAWTOOTH, RAMPUPDOWN, TAN, TANINVERSE, TRIANG}));
  276. params.add(new Param("blend mode", INTVAL, 0, blends.length-1, new int[]{SINE, SAWTOOTH, RAMPUPDOWN, TAN, TANINVERSE, TRIANG}));
  277. params.add(new Param("channel", INTVAL, 0, 12, new int[]{SINE, SAWTOOTH, RAMPUPDOWN, TAN, TANINVERSE, TRIANG}));
  278. // channel, blend_mode
  279. //params.add(new Param("height", FLOATVAL, 1, buffer.height/4-1, new int[]{SINE, SAWTOOTH, RAMPUPDOWN, TAN, TANINVERSE, TRIANG}));
  280. // prepare distortion pattern
  281. for (int i=0; i<distortionMatrixSize; i++) {
  282. distort[0][i] = (int)random(-128, 128);
  283. distort[1][i] = (int)random(-128, 128);
  284. }
  285. }
  286. // ALL Channels, Nxxx stand for negative (255-value)
  287. // channels to work with
  288. final static int RED = 0;
  289. final static int GREEN = 1;
  290. final static int BLUE = 2;
  291. final static int HUE = 3;
  292. final static int SATURATION = 4;
  293. final static int BRIGHTNESS = 5;
  294. final static int NRED = 6;
  295. final static int NGREEN = 7;
  296. final static int NBLUE = 8;
  297. final static int NHUE = 9;
  298. final static int NSATURATION = 10;
  299. final static int NBRIGHTNESS = 11;
  300. void apply() {
  301. //println(buffer.height);
  302. buffer = renderer.get();
  303. buffer.resize(renderer.width, renderer.height);
  304. float neww = map(params.get(0).value, 2, initBufferW-2, 2, buffer.width/4-2);
  305. float newh = map(params.get(1).value, 2, initBufferH-2, 2, buffer.height/4-2);
  306. do_blend = boolean(int(params.get(2).value));
  307. shift_amt = params.get(3).value;
  308. scalex = params.get(4).value;
  309. scaley = params.get(5).value;
  310. blend_mode = blends[(int)params.get(6).value];
  311. channel = (int)params.get(7).value;
  312. float totalnum = neww+newh;
  313. float times = (totalnum/floor(totalnum/neww));
  314. float offx = (totalnum%neww)/times;
  315. float ratiox = neww/buffer.width;
  316. //println(ratiox);
  317. renderer.beginDraw();
  318. renderer.noStroke();
  319. for (int y=0; y<buffer.height; y++) {
  320. float yy = y/(float)buffer.height;
  321. for (int x=0; x<buffer.width; x++) {
  322. float xx = x/(float)buffer.width;
  323. float offy = floor(newh*yy);
  324. float fx = xx*ratiox+offx*offy;
  325. float shift = fx%1.0;
  326. float st = shift/tick;
  327. int no1 = floor(st)%distortionMatrixSize;
  328. int no2 = ceil(st)%distortionMatrixSize ;
  329. float l = st-(float)no1;
  330. float cx = lerp(distort[0][no1], distort[0][no2], l);
  331. float cy = lerp(distort[1][no1], distort[1][no2], l);
  332. float rx =getChannel(buffer.get(x, y), channel);
  333. int sx = (int)((buffer.width+x+cx*rx*scalex*0.1)%buffer.width);
  334. int sy = (int)((buffer.height+y+cy*scaley)%buffer.height);
  335. color c=buffer.get(sx, sy);
  336. if (shift_hue) {
  337. colorMode(HSB, 255);
  338. c = color((hue(c)+shift_amt*255*noise(newh+y))%255.0, constrain(saturation(c)*1.2, 0, 255), constrain(brightness(c), 0, 255));
  339. colorMode(RGB, 255);
  340. }
  341. // buffer.fill(lerpColor(c,img.get(x,y),0.2));
  342. renderer.fill(c); //wärs nich effizienter die pixelmatrix zu ändern ?
  343. renderer.rect(x, y, 1, 1);
  344. }
  345. }
  346. if (do_blend)
  347. renderer.blend(buffer, 0, 0, buffer.width, buffer.height, 0, 0, renderer.width, renderer.height, blend_mode);
  348. renderer.endDraw();
  349. }
  350. float getChannel(color c, int channel) {
  351. int ch = channel>5?channel-6:channel;
  352. float cc;
  353. switch(ch) {
  354. case RED:
  355. cc = red(c);
  356. break;
  357. case GREEN:
  358. cc = green(c);
  359. break;
  360. case BLUE:
  361. cc = blue(c);
  362. break;
  363. case HUE:
  364. cc = hue(c);
  365. break;
  366. case SATURATION:
  367. cc = saturation(c);
  368. break;
  369. default:
  370. cc= brightness(c);
  371. break;
  372. }
  373. return channel>5?255-cc:cc;
  374. }
  375. }
  376. /*
  377. FM
  378. */
  379. class FM extends Shader {
  380. // configuration
  381. int colorspace = RGB;
  382. int quantval = 30; // 0 - off, less - more glitch, more - more precision
  383. boolean do_blend = true; // blend image after process
  384. int blend_mode = OVERLAY; // blend type
  385. //unused parameters (giers):
  386. final static boolean first_channel_only = false; // for L.. or Y.. colorspaces set true to modulate only luma;
  387. final static boolean lowpass1_on = true; // on/off of first low pass filter
  388. final static boolean lowpass2_on = true; // on/off of second low pass filter
  389. final static boolean lowpass3_on = true; // on/off of third low pass filter
  390. // better don't touch it, lowpass filters are run in cascade
  391. float lowpass1_cutoff = 0.25; // percentage of rate
  392. float lowpass2_cutoff = 0.1;
  393. float lowpass3_cutoff = 0.05;
  394. // working buffer
  395. PGraphics buffer;
  396. // local variables
  397. float min_omega, max_omega;
  398. float min_phase_mult=0.05;
  399. float max_phase_mult=50.0;
  400. LowpassFilter lpf1, lpf2, lpf3;
  401. int[][] pxls;
  402. boolean negate = false;
  403. FM() {
  404. name = "fxFM";
  405. params.add(new Param("do blend", INTVAL, 0, 1, new int[]{RANDOM, SQUAR}));
  406. params.add(new Param ("blend_mode", INTVAL, 0, blends.length-1, new int[]{RANDOM}));
  407. params.add(new Param ("omega", FLOATVAL, 0, 1, new int[]{SINE, SAWTOOTH, TRIANG}));
  408. params.add(new Param ("phase", FLOATVAL, 0, 1, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  409. params.add(new Param ("colorspace", INTVAL, 0, 16, new int[]{RANDOM}));
  410. params.add(new Param ("quant", INTVAL, 0, 40, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  411. buffer = createGraphics(renderer.width, renderer.height);
  412. buffer.beginDraw();
  413. buffer.noStroke();
  414. //buffer.smooth(8);
  415. //buffer.background(0);
  416. // buffer.image(renderer, 0, 0);
  417. buffer.endDraw();
  418. //img.loadPixels();
  419. min_omega = TWO_PI/(0.05*renderer.width);
  420. max_omega = TWO_PI/(300.0*renderer.width);
  421. float rate = 100000.0;
  422. lpf1 = new LowpassFilter(rate, lowpass1_cutoff*rate);
  423. lpf2 = new LowpassFilter(rate, lowpass2_cutoff*rate);
  424. lpf3 = new LowpassFilter(rate, lowpass3_cutoff*rate);
  425. rw = renderer.width;
  426. prepareData();
  427. }
  428. void prepareData() {
  429. pxls = new int[3][renderer.pixels.length];
  430. for (int i=0; i<renderer.pixels.length; i++) {
  431. int cl = toColorspace(renderer.pixels[i], colorspace);
  432. pxls[0][i] = (cl >> 16) & 0xff;
  433. pxls[1][i] = (cl >> 8) & 0xff;
  434. pxls[2][i] = (cl) & 0xff;
  435. }
  436. }
  437. float omega, min_phase, max_phase;
  438. int rw, rh;
  439. void apply() {
  440. do_blend = boolean(int(params.get(0).value));
  441. blend_mode = blends[(int)params.get(1).value];
  442. omega = map(sqrt(params.get(2).value), 0, 1, min_omega, max_omega);
  443. float phase = map(sq(params.get(3).value), 0, 1, min_phase_mult, max_phase_mult);
  444. colorspace = (int)params.get(4).value;
  445. quantval = (int) params.get(5).value;
  446. if (rw != renderer.width || rh != renderer.height) {
  447. rw = renderer.width;
  448. rh = renderer.height;
  449. min_omega = TWO_PI/(0.05*renderer.width);
  450. max_omega = TWO_PI/(300.0*renderer.width);
  451. }
  452. prepareData();
  453. buffer.setSize(renderer.width, renderer.height);
  454. //buffer = renderer.get(0, 0, renderer.width, renderer.height);
  455. max_phase = phase * omega;
  456. min_phase = -max_phase;
  457. processImage();
  458. }
  459. void processImage() {
  460. buffer.beginDraw();
  461. buffer.loadPixels();
  462. int [][] dest_pxls = new int[3][renderer.pixels.length];
  463. if (first_channel_only) {
  464. arrayCopy(pxls[1], dest_pxls[1]);
  465. arrayCopy(pxls[2], dest_pxls[2]);
  466. }
  467. for (int i=0; i< (first_channel_only?1:3); i++) {
  468. for (int y=0; y<renderer.height; y++) {
  469. int off = y * renderer.width;
  470. //reset filters each line
  471. lpf1.resetFilter(map(pxls[i][off], 0, 255, min_phase, max_phase));
  472. lpf2.resetFilter(map(pxls[i][off], 0, 255, min_phase, max_phase));
  473. lpf3.resetFilter(map(pxls[i][off], 0, 255, min_phase, max_phase));
  474. float sig_int = 0; // integral of the signal
  475. float pre_m = 0; // previous value of modulated signal
  476. for (int x=0; x<renderer.width; x++) {
  477. /////////////////////////
  478. // FM part starts here
  479. /////////////////////////
  480. float sig = map(pxls[i][x+off], 0, 255, min_phase, max_phase); // current signal value
  481. sig_int += sig; // current value of signal integral
  482. float m = cos(omega * x + sig_int); // modulate signal
  483. if ( quantval > 0) {
  484. m = map((int)map(m, -1, 1, 0, quantval), 0, quantval, -1, 1); // quantize
  485. }
  486. float dem = abs(m-pre_m); // demodulate signal, derivative
  487. pre_m = m; // remember current value
  488. // lowpass filter chain
  489. if (lowpass1_on) dem = lpf1.lowpass(dem);
  490. if (lowpass2_on) dem = lpf2.lowpass(dem);
  491. if (lowpass3_on) dem = lpf3.lowpass(dem);
  492. // remap signal back to channel value
  493. int v = constrain( (int)map(2*(dem-omega), min_phase, max_phase, 0, 255), 0, 255);
  494. //////////////////////
  495. // FM part ends here
  496. //////////////////////
  497. dest_pxls[i][x+off] = negate?255-v:v;
  498. }
  499. }
  500. }
  501. for (int i=0; i<buffer.pixels.length; i++) {
  502. buffer.pixels[i] = fromColorspace(0xff000000 | (dest_pxls[0][i] << 16) | (dest_pxls[1][i] << 8) | (dest_pxls[2][i]), colorspace);
  503. }
  504. buffer.updatePixels();
  505. if (do_blend)
  506. buffer.blend(renderer, 0, 0, renderer.width, renderer.height, 0, 0, buffer.width, buffer.height, blend_mode);
  507. buffer.endDraw();
  508. renderer.beginDraw();
  509. renderer.image(buffer, 0, 0, renderer.width, renderer.height);
  510. renderer.endDraw();
  511. }
  512. class LowpassFilter {
  513. float alpha;
  514. float prev;
  515. public LowpassFilter(float rate, float hz) {
  516. alpha = 0.0;
  517. prev = 0.0;
  518. setFilter(rate, hz);
  519. }
  520. void setFilter(float rate, float hz) {
  521. float timeInterval = 1.0/rate;
  522. float tau = 1.0 / (hz * TWO_PI);
  523. alpha = timeInterval / (tau + timeInterval);
  524. }
  525. void resetFilter(float val) {
  526. prev = val;
  527. }
  528. void resetFilter() {
  529. resetFilter(0);
  530. }
  531. float lowpass(float sample) {
  532. float stage1 = sample * alpha;
  533. float stage2 = prev - (prev * alpha);
  534. prev = (stage1 + stage2);
  535. return prev;
  536. }
  537. float highpass(float sample) {
  538. return sample - lowpass(sample);
  539. }
  540. }
  541. }
  542. /*
  543. WZIP
  544. */
  545. class WZIP extends Shader {
  546. final float sqrt05 = sqrt(0.5);
  547. float[] raw, raw1, raw2, raw3;
  548. float[] in, w, out;
  549. float[] in1, in2, in3, out1, out2, out3;
  550. int n, n2, s;
  551. float scalingfactorin, scalingfactorout;
  552. PImage img;
  553. String sessionid;
  554. WZIP() {
  555. name = "fxWZIP";
  556. params.add(new Param ("scale", FLOATVAL, 0.1, 1000, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  557. params.add(new Param ("factor in", FLOATVAL, 0.01, 1, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  558. params.add(new Param ("factor out", FLOATVAL, 0.01, 1, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  559. params.add(new Param("hsb/rgb", INTVAL, 0, 1, new int[]{RANDOM, SQUAR}));
  560. params.add(new Param("mode", INTVAL, 0, 1, new int[]{RANDOM, SQUAR}));
  561. sessionid = hex((int)random(0xffff), 4);
  562. img = createImage(renderer.width, renderer.height, ARGB);
  563. img = renderer.get(0, 0, renderer.width, renderer.height);
  564. }
  565. void apply() {
  566. // img = createImage(renderer.width, renderer.height, ARGB);
  567. img.resize(renderer.width, renderer.height);
  568. img = renderer.get(0, 0, renderer.width, renderer.height);
  569. s = img.width*img.height;
  570. raw = new float[s*3];
  571. raw1 = new float[s];
  572. raw2 = new float[s];
  573. raw3 = new float[s];
  574. renderer.beginDraw();
  575. renderer.background(0);
  576. renderer.noStroke();
  577. if (boolean((int)params.get(3).value)) { /////////////////////
  578. renderer.colorMode(HSB, 255);
  579. colorMode(HSB, 255);
  580. } else {
  581. renderer.colorMode(RGB, 255);
  582. colorMode(RGB, 255);
  583. }
  584. scalingfactorin = map(params.get(1).value, 0, 1, 0, params.get(0).value); /////////////////////
  585. scalingfactorout = map(params.get(2).value, 0, 1, 0, params.get(0).value); /////////////////////
  586. int iter=0;
  587. int iter2 = 0;
  588. for (int y=0; y<img.height; y++) {
  589. for (int x=0; x<img.width; x++) {
  590. color c = img.get(x, y);
  591. float r, g, b;
  592. if (boolean((int)params.get(3).value)) { /////////////////////
  593. r = hue(c)>127?hue(c)-256:hue(c);
  594. g = saturation(c)>127?saturation(c)-256:saturation(c);
  595. b = brightness(c)>127?brightness(c)-256:brightness(c);
  596. } else {
  597. r = red(c)>127?red(c)-256:red(c);
  598. g = green(c)>127?green(c)-256:green(c);
  599. b = blue(c)>127?blue(c)-256:blue(c);
  600. }
  601. raw[iter++] = r;
  602. raw[iter++] = g;
  603. raw[iter++] = b;
  604. raw1[iter2] = r;
  605. raw2[iter2] = g;
  606. raw3[iter2] = b;
  607. iter2++;
  608. }
  609. }
  610. n = (int)pow(2, ceil(log(s*3)/log(2)));
  611. n2 = (int)pow(2, ceil(log(s)/log(2)));
  612. in = new float[n];
  613. w = new float[n];
  614. out = new float[n];
  615. out1 = new float[n2];
  616. out2 = new float[n2];
  617. out3 = new float[n2];
  618. in1 = new float[n2];
  619. in2 = new float[n2];
  620. in3 = new float[n2];
  621. arrayCopy(raw, 0, in, 0, raw.length);
  622. for (int i=raw.length; i<n; i++) in[i] = raw[raw.length-1];
  623. arrayCopy(raw1, 0, in1, 0, s);
  624. arrayCopy(raw2, 0, in2, 0, s);
  625. arrayCopy(raw3, 0, in3, 0, s);
  626. for (int i=s; i<n2; i++) {
  627. in1[i] = raw1[s-1];
  628. in2[i] = raw2[s-1];
  629. in3[i] = raw3[s-1];
  630. }
  631. if (boolean((int)params.get(4).value)) option1(); /////////////////////
  632. else option2();
  633. renderer.colorMode(RGB);
  634. colorMode(RGB);
  635. renderer.endDraw();
  636. }
  637. // void printOption() {
  638. // String str1, str2;
  639. // if (do_hsb) {
  640. // str1 = "HSBHSBHSB...";
  641. // str2 = "HHH...SSS...BBB...";
  642. // } else {
  643. // str1 = "RGBRGBRGB...";
  644. // str2 = "RRR...GGG...BBB...";
  645. // }
  646. // if (option1) println("channels combined: " + str1);
  647. // else println("channels separated: " + str2);
  648. // }
  649. //
  650. // void printScale() {
  651. // println("Scale: 0.."+sc);
  652. // }
  653. float clamp(float c) {
  654. return(abs(c<0?256+c:c)%255.0);
  655. }
  656. void option2() {
  657. wtrafo(in1, n2);
  658. wbtrafo(out1, n2);
  659. wtrafo(in2, n2);
  660. wbtrafo(out2, n2);
  661. wtrafo(in3, n2);
  662. wbtrafo(out3, n2);
  663. for (int i=0; i<s; i++) {
  664. float r = clamp(out1[i]);
  665. float g = clamp(out2[i]);
  666. float b = clamp(out3[i]);
  667. renderer.fill(r, g, b);
  668. renderer.rect(i%img.width, i/img.width, 1, 1);
  669. }
  670. }
  671. void option1() {
  672. wtrafo(in, n);
  673. wbtrafo(out, n);
  674. float r=0, g=0, b=0;
  675. int state = 0;
  676. for (int i=0; i<raw.length; i++) {
  677. float c = clamp(out[i]);
  678. switch(state) {
  679. case 0:
  680. r = c;
  681. break;
  682. case 1:
  683. g = c;
  684. break;
  685. case 2:
  686. b = c;
  687. break;
  688. default:
  689. {
  690. r = c;
  691. renderer.fill(r, g, b);
  692. renderer.rect(floor(i/3.0)%img.width, floor(i/3.0)/img.width, 1, 1);
  693. state = 0;
  694. }
  695. }
  696. state++;
  697. }
  698. }
  699. void wbtrafo(float[] y, int n) {
  700. float[] d = new float[n];
  701. d[n-2] = w[n-1];
  702. int b1 = n-4;
  703. int b2 = n-2;
  704. int a=1;
  705. while (a<n/2) {
  706. for (int i=0; i<a; i++) {
  707. d[2*i+b1]=(d[i+b2]+w[i+b2])*sqrt05;
  708. d[2*i+1+b1]=(d[i+b2]-w[i+b2])*sqrt05;
  709. }
  710. b2=b1;
  711. b1=b1-4*a;
  712. a*=2;
  713. }
  714. for (int i=0; i<a; i++) {
  715. y[2*i]=(d[i]+w[i])*sqrt05;
  716. y[2*i+1]=(d[i]-w[i])*sqrt05;
  717. }
  718. for (int i=0; i<n; i++) y[i] *= scalingfactorout;
  719. }
  720. void wtrafo(float[] y, int n) {
  721. float[] d = new float[n];
  722. int a = n/2;
  723. for (int i=0; i<a; i++) {
  724. w[i] = (y[2*i]-y[2*i+1])*sqrt05;
  725. d[i] = (y[2*i]+y[2*i+1])*sqrt05;
  726. }
  727. int b1 = 0;
  728. int b2 = a;
  729. a/=2;
  730. while (a>0) {
  731. for (int i=0; i<a; i++) {
  732. w[i+b2]=(d[2*i+b1]-d[2*i+1+b1])*sqrt05;
  733. d[i+b2]=(d[2*i+b1]+d[2*i+1+b1])*sqrt05;
  734. }
  735. b1=b2;
  736. b2=b2+a;
  737. a/=2;
  738. }
  739. w[b2] = d[b1];
  740. for (int i=0; i<n-1; i++) w[i] = (int)(w[i]/scalingfactorin);
  741. if (w[n-1]>0) w[n-1] = (int)(w[n-1]/scalingfactorin+0.5);
  742. else w[n-1] = (int)(w[n-1]/scalingfactorin-0.5);
  743. }
  744. }
  745. /*
  746. AUECHO
  747. */
  748. class AUECHO extends Shader {
  749. final int[] blends = {BLEND, ADD, SUBTRACT, DARKEST, LIGHTEST, DIFFERENCE, EXCLUSION, MULTIPLY, SCREEN, OVERLAY, HARD_LIGHT, SOFT_LIGHT, DODGE, BURN};
  750. AUECHO() {
  751. name = "fxAUecho";
  752. params.add(new Param("mode", INTVAL, 0, 1, new int[]{RANDOM, SQUAR}));
  753. params.add(new Param ("echo", FLOATVAL, 0.001, 1, new int[]{TRIANG, SINE, RAMPUPDOWN, }));
  754. params.add(new Param ("decay", FLOATVAL, 0.001, 1, new int[]{TRIANG, SINE, RAMPUPDOWN }));
  755. params.add(new Param ("blend mode", INTVAL, 0, this.blends.length-1, new int[]{RANDOM }));
  756. }
  757. void apply() {
  758. renderer.beginDraw();
  759. if (boolean((int)params.get(0).value)) {
  760. renderer.colorMode(HSB);
  761. colorMode(HSB);
  762. } else {
  763. renderer.colorMode(RGB);
  764. colorMode(RGB);
  765. }
  766. renderer.loadPixels();
  767. float _delay = params.get(1).value;
  768. float decay = params.get(2).value;
  769. int delay = (int)(renderer.pixels.length * _delay);
  770. color[] history = new color[renderer.pixels.length];
  771. int blendMode =this.blends[(int)params.get(3).value];
  772. for ( int i = 0, l = renderer.pixels.length; i<l; i++) {
  773. history[i] = renderer.pixels[i];
  774. }
  775. for ( int i = 0, l = renderer.pixels.length; i<l; i++) {
  776. int fromPos = i-delay < 0 ? l-abs(i-delay) : i-delay;
  777. color fromColor = history[fromPos];
  778. float r = red(fromColor) * decay;
  779. float g = green(fromColor) * decay;
  780. float b = blue(fromColor) * decay;
  781. color origColor = history[i];
  782. color toColor = color(
  783. r = r + red(origColor) > 255 ? r + red(origColor) - 255 : r + red(origColor), // simulate overflow ;)
  784. g = g + green(origColor) > 255 ? g + green(origColor) - 255 : g + green(origColor),
  785. b = b + blue(origColor) > 255 ? b + blue(origColor) - 255 : b + blue(origColor) );
  786. //renderer.pixels[i] = history[i] = toColor;
  787. renderer.pixels[i] = history[i] = blendColor(origColor, toColor, blendMode);
  788. }
  789. renderer.updatePixels();
  790. if (boolean((int)params.get(0).value)) {
  791. renderer.colorMode(RGB);
  792. colorMode(RGB);
  793. }
  794. renderer.endDraw();
  795. }
  796. }
  797. /*
  798. SLITSCAN
  799. */
  800. class SLITSCAN extends Shader {
  801. int[] fx;
  802. int[] fy;
  803. float[] phx;
  804. float[] phy;
  805. int[] sx, sy;
  806. boolean[] skipfx;
  807. boolean[] skipfy;
  808. boolean dox, doy;
  809. PImage buffer;
  810. float[][] ft = new float[2][32];
  811. int depth; // number of octaves
  812. int fxnum;
  813. int fynum;
  814. SLITSCAN() {
  815. name = "fxSlitSscan";
  816. buffer = createImage(renderer.width, renderer.height, ARGB);
  817. for (int i=0; i<32; i++) {
  818. ft[0][i] = pow(2.0, i);
  819. ft[1][i] = 0.5*1.0/ft[0][i];
  820. }
  821. }
  822. void apply() {
  823. renderer.beginDraw();
  824. renderer.colorMode(RGB);
  825. renderer.noStroke();
  826. colorMode(RGB);
  827. renderer.fill(255);
  828. buffer.resize(renderer.width, renderer.height);
  829. buffer = renderer.get(0, 0, renderer.width, renderer.height);
  830. //int s = buffer.width>buffer.height?buffer.height:buffer.width;
  831. int s = min(buffer.width, buffer.height);
  832. depth = (int)(log(s)/log(2));
  833. fxnum = (int)random(depth); ////
  834. fynum = (int)random(depth); ////
  835. fx = new int[fxnum+1];
  836. fy = new int[fynum+1];
  837. sx = new int[fxnum+1];
  838. sy = new int[fynum+1];
  839. phx = new float[fxnum+1];
  840. phy = new float[fynum+1];
  841. skipfx = new boolean[fxnum+1];
  842. skipfy = new boolean[fynum+1];
  843. for (int i=0; i<fxnum; i++) {
  844. fx[i]=(int)random(6);
  845. phx[i] = random(1);
  846. skipfx[i] = random(1)<0.2;
  847. sx[i] = random(1)<0.2?-1:1;
  848. }
  849. for (int i=0; i<fynum; i++) {
  850. fy[i]=(int)random(6);
  851. phy[i] = random(1);
  852. skipfy[i] = random(1)<0.2;
  853. sy[i] = random(1)<0.2?-1:1;
  854. }
  855. dox = random(1)<0.8;
  856. doy = dox?random(1)<0.8:true;
  857. float v=0;
  858. for (int y=0; y<buffer.height; y++)
  859. for (int x=0; x<buffer.width; x++) {
  860. float iy = map(y, 0, buffer.height, 0, 1);
  861. v=0;
  862. if (doy) for (int i=0; i<fy.length; i++)
  863. if (!skipfy[i]) v+=sy[i]*getValue(fy[i], iy, i, phy[i]);
  864. float ry = 2*iy+v;
  865. float y2 = (3*buffer.height+ry * buffer.height/2)%buffer.height;
  866. float ix = map(x, 0, buffer.width, 0, 1);
  867. v=0;
  868. if (dox) for (int i=0; i<fx.length; i++)
  869. if (!skipfx[i]) v+=sx[i]*getValue(fx[i], ix, i, phx[i]);
  870. float rx = 2*ix+v;
  871. float x2 = (3*buffer.width+rx * buffer.width/2)%buffer.width;
  872. renderer.fill(buffer.get((int)x2, (int)y2));
  873. renderer.rect(x, y, 1, 1);
  874. }
  875. renderer.endDraw();
  876. }
  877. float getValue(int fun, float idx, int freq, float phase) {
  878. switch(fun) {
  879. case 0:
  880. return getSin(idx, freq, phase);
  881. case 1:
  882. return getSaw(idx, freq, phase);
  883. case 2:
  884. return getTriangle(idx, freq, phase);
  885. case 3:
  886. return getCutTriangle(idx, freq, phase);
  887. case 4:
  888. return getSquare(idx, freq, phase);
  889. case 5:
  890. return getNoise(idx, freq, phase);
  891. default:
  892. return getSin(idx, freq, phase);
  893. }
  894. }
  895. float getNoise(float idx, int freq, float phase) {
  896. return 2*ft[1][freq]*(noise((idx+phase)*ft[0][freq])-0.5);
  897. }
  898. float getSin(float idx, int freq, float phase) {
  899. float p = ft[0][freq];
  900. return ft[1][freq] * sin(idx*TWO_PI*p+phase*TWO_PI);
  901. }
  902. float getSaw(float idx, int freq, float phase) {
  903. float p = ft[0][freq];
  904. float rp = 2.0*ft[1][freq];
  905. float p2 = p*((idx+phase+ft[1][freq])%1.0);
  906. return rp*(p2-floor(p2)-0.5);
  907. }
  908. float getSquare(float idx, int freq, float phase) {
  909. float p = ft[0][freq];
  910. float rp = ft[1][freq];
  911. return (((idx*p)+phase)%1.0)<0.5?rp:-rp;
  912. }
  913. float getTriangle(float idx, int freq, float phase) {
  914. return 2*abs(getSaw(idx, freq, phase+0.5*ft[1][freq]))-ft[1][freq];
  915. }
  916. float getCutTriangle(float idx, int freq, float phase) {
  917. return constrain(getTriangle(idx, freq, phase), -ft[1][freq+1], ft[1][freq+1]);
  918. }
  919. }
  920. /*
  921. WAHWAH
  922. */
  923. class WAHWAH extends Shader {
  924. float sequence, lfoskip, xn1, xn2, yn1, yn2, b0, b1, b2, a0, a1, a2, freqofs, freq, freqoff, startsequence, res, depth;
  925. float mCurRate = 0.4, skipcount = 0;
  926. int lfoskipsamples = 0;
  927. float frequency, omega, sn, cs, alpha;
  928. float in, out;
  929. float val;
  930. WAHWAH() {
  931. name = "fxWahWah";
  932. //params.add(new Param("mode", INTVAL, 0, 1, new int[]{RANDOM, SQUAR}));
  933. params.add(new Param ("resolution", FLOATVAL, 1, 100, new int[]{TRIANG, SINE, RAMPUPDOWN, }));
  934. params.add(new Param ("depth", FLOATVAL, 0.0001, 1, new int[]{TRIANG, SINE, RAMPUPDOWN }));
  935. params.add(new Param ("frequency offset", FLOATVAL, 0, 1, new int[]{TRIANG, SINE, RAMPUPDOWN }));
  936. params.add(new Param ("mCurRate", FLOATVAL, 0, 1, new int[]{TRIANG, SINE, RAMPUPDOWN }));
  937. // params.add(new Param ("blend mode", INTVAL, 0, this.blends.length-1, new int[]{RANDOM }));
  938. }
  939. void apply() {
  940. res = params.get(0).value;
  941. depth = params.get(1).value;
  942. freqofs = params.get(2).value;
  943. //res = 12.5
  944. //depth = 0.8;
  945. //freqofs = 0.9;
  946. freq = 1.5;
  947. startsequence = 0.2;
  948. lfoskip = freq * 2 * PI / mCurRate;
  949. skipcount = xn1 = xn2 = yn1 = yn2 = b0 = b1 = b2 = a0 = a1 = a2 = 0;
  950. sequence = startsequence;
  951. renderer.beginDraw();
  952. renderer.colorMode(RGB);
  953. renderer.loadPixels();
  954. float[] rgb = new float[3];
  955. for ( int i = 0, len = renderer.pixels.length; i < len; i++) {
  956. rgb[0] = red(renderer.pixels[i]);
  957. rgb[1] = green(renderer.pixels[i]);
  958. rgb[2] = blue(renderer.pixels[i]);
  959. for ( int ri = 0; ri < 3; ri++ ) {
  960. in = map(rgb[ri], 0, 255, 0, 1);
  961. frequency = (1+cos(skipcount * lfoskip + sequence ))/2;
  962. frequency = frequency * depth * (1-freqofs) + freqofs;
  963. frequency = exp((frequency - 1) * 6 );
  964. omega = PI * frequency;
  965. sn = sin(omega);
  966. cs = cos(omega);
  967. alpha = sn/(2*res);
  968. b0 = (1-cs) /2;
  969. b1 = 1 - cs;
  970. b2 = (1-cs)/2;
  971. a0 = 1 + alpha;
  972. a1 = -2 * cs;
  973. a2 = 1 - alpha;
  974. out = ( b0 * in + b1 * xn1 + b2 * xn2 - a1 * yn1 - a2 * yn2 ) / a0;
  975. xn2 = xn1;
  976. xn1 = in;
  977. yn2 = yn1;
  978. yn1 = out;
  979. rgb[ri] = map(out, 0, 1, 0, 255);
  980. }
  981. renderer.pixels[i] = color(rgb[0], rgb[1], rgb[2]);
  982. }
  983. renderer.updatePixels();
  984. renderer.endDraw();
  985. }
  986. }
  987. /*
  988. PHASER
  989. */
  990. class PHASER extends Shader {
  991. //float samplerate = 92230.0; // try setting this to 44100.0 or 2048.5 for kicks
  992. float samplerate = 44100; // try setting this to 44100.0 or 2048.5 for kicks
  993. int mode;
  994. PHASER() {
  995. name ="fxPhaser";
  996. params.add(new Param("mode", INTVAL, 0, 1, new int[]{RANDOM, SQUAR}));
  997. params.add(new Param ("frequency", FLOATVAL, 0.1, 40.0, new int[]{TRIANG, SINE, RAMPUPDOWN }));
  998. params.add(new Param ("depth", INTVAL, 1, 255, new int[]{TRIANG, SINE, RAMPUPDOWN }));
  999. params.add(new Param ("feedback", INTVAL, -100, 100, new int[]{TRIANG, SINE, RAMPUPDOWN }));
  1000. params.add(new Param ("phase", FLOATVAL, 0, TWO_PI, new int[]{TRIANG, SINE, RAMPUPDOWN }));
  1001. params.add(new Param ("stages", INTVAL, 1, 24, new int[]{TRIANG, SINE, RAMPUPDOWN }));
  1002. params.add(new Param ("sample rate", FLOATVAL, 512, 92230, new int[]{TRIANG, SINE, RAMPUPDOWN }));
  1003. //params.add(new Param ("frequency offset", FLOATVAL, 0, 1, new int[]{TRIANG, SINE, RAMPUPDOWN }));
  1004. }
  1005. /*
  1006. mDepth = (int) map(knobZero, 0, 255, 255, 0);
  1007. mFeedback = (int) map(knobOne, 0, 255, -100, 100);
  1008. // enable these for some more fun :)
  1009. if (mode == 1) {
  1010. mSampleRate = map(knobTwo, 0, 255, 1, 512);
  1011. mStages = (int) ( 2*map(knobThree, 0, 255, 1, 12));
  1012. }
  1013. */
  1014. void apply() {
  1015. mode = (int)params.get(0).value;
  1016. float mFreq = params.get(1).value;
  1017. int mDryWet = 255;
  1018. int mDepth = (int)params.get(2).value;
  1019. int mFeedback = (int)params.get(3).value;
  1020. float mPhase = params.get(4).value;
  1021. //these two are only changed if mode = 1
  1022. int mStages = 2;
  1023. float mSampleRate = samplerate;
  1024. renderer.beginDraw();
  1025. renderer.colorMode(RGB);
  1026. renderer.loadPixels();
  1027. //constants
  1028. float phaserlfoshape = 4.0;
  1029. int lfoskipsamples = 20; //how many samples are processed before recomputing lfo
  1030. int numStages = 24;
  1031. //getParams
  1032. /*
  1033. Phaser Parameters
  1034. mFreq - Phaser's LFO frequency
  1035. mPhase - Phaser's LFO startsequence (radians), needed for stereo Phasers
  1036. mDepth - Phaser depth (0 - no depth, 255 - max depth)
  1037. mStages - Phaser stages (recomanded from 2 to 16-24, and EVEN NUMBER)
  1038. mDryWet - Dry/wet mix, (0 - dry, 128 - dry=wet, 255 - wet)
  1039. mFeedback - Phaser FeedBack (0 - no feedback, 100 = 100% Feedback,
  1040. -100 = -100% FeedBack)
  1041. */
  1042. // enable these for some more fun :)
  1043. if (mode == 1) {
  1044. mStages = (int)params.get(5).value;
  1045. mSampleRate = params.get(6).value;
  1046. }
  1047. //init
  1048. float gain = 0, fbout = 0;
  1049. float lfoskip = mFreq * 2 * PI / mSampleRate;
  1050. float sequence = mPhase * PI / 180;
  1051. float[] old = new float[mStages];
  1052. for ( int j = 0; j < mStages; j++) {
  1053. old[j] = 0.0;
  1054. }
  1055. /* EffectPhaser::ProcessBlock */
  1056. int skipcount = 0;
  1057. float[] rgb = new float[3];
  1058. for ( int i = 0, l = renderer.pixels.length; i<l; i++ ) {
  1059. color c = renderer.pixels[i];
  1060. rgb[0] = map(red(c), 0, 255, 0, 1);
  1061. rgb[1] = map(green(c), 0, 255, 0, 1);
  1062. rgb[2] = map(blue(c), 0, 255, 0, 1);
  1063. for ( int ci = 0; ci < 3; ci++) {
  1064. float in = rgb[ci];
  1065. float m = in + fbout * mFeedback / 100;
  1066. if ( (( skipcount++) % lfoskipsamples ) == 0 ) { //recomopute lfo
  1067. gain = (1.0 + cos(skipcount * lfoskip + sequence)) / 2.0; //compute sine between 0 and 1
  1068. gain = exp(gain * phaserlfoshape) / exp(phaserlfoshape); // change lfo shape
  1069. gain = 1.0 - gain / 255.0 * mDepth; // attenuate the lfo
  1070. }
  1071. //phasing routine
  1072. for ( int j = 0; j<mStages; j++) {
  1073. float tmp = old[j];
  1074. old[j] = gain * tmp + m;
  1075. m = tmp - gain * old[j];
  1076. }
  1077. fbout = m;
  1078. rgb[ci] = (float) (( m * mDryWet + in * (255-mDryWet)) / 255);
  1079. }
  1080. color rc = color(
  1081. map(rgb[0], 0, 1, 0, 255),
  1082. map(rgb[1], 0, 1, 0, 255),
  1083. map(rgb[2], 0, 1, 0, 255));
  1084. renderer.pixels[i] = rc;
  1085. }
  1086. renderer.updatePixels();
  1087. renderer.endDraw();
  1088. }
  1089. }
  1090. /*
  1091. ECHO
  1092. */
  1093. class ECHO extends Shader {
  1094. int mode = 0;
  1095. PImage result;
  1096. ECHO() {
  1097. name = "fxEcho";
  1098. params.add(new Param("mode", INTVAL, 0, 1, new int[]{RANDOM, SQUAR}));
  1099. params.add(new Param ("xp", INTVAL, 0, 100, new int[]{TRIANG, SINE, RAMPUPDOWN }));
  1100. params.add(new Param ("yp", INTVAL, 0, 100, new int[]{TRIANG, SINE, RAMPUPDOWN }));
  1101. result = createImage(renderer.width, renderer.height, RGB);
  1102. }
  1103. void apply() {
  1104. mode = (int)params.get(0).value;
  1105. int xp = (int)params.get(1).value;
  1106. int yp = (int)params.get(2).value;
  1107. renderer.beginDraw();
  1108. renderer.colorMode(RGB);
  1109. colorMode(RGB);
  1110. if (mode == 0) {
  1111. renderer.image(auEcho(renderer, xp, yp), 0, 0);
  1112. } else if (mode == 1) {
  1113. renderer.image(auEchoWTF(renderer, xp, yp), 0, 0);
  1114. }
  1115. renderer.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. renderer.beginDraw();
  1206. renderer.colorMode(HSB);
  1207. colorMode(HSB);
  1208. renderer.loadPixels();
  1209. if (mode == 0) {
  1210. for (int h = 1; h < count+1; h++) {
  1211. for (int i = 0; i < renderer.width*renderer.height; i++) {
  1212. float hue = hue(renderer.pixels[i]);
  1213. float sat = saturation(renderer.pixels[i]);
  1214. float bright = brightness(renderer.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. renderer.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 < renderer.width*renderer.height; i++) {
  1226. float hue = hue(renderer.pixels[i]);
  1227. float sat = saturation(renderer.pixels[i]);
  1228. float bright = brightness(renderer.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. renderer.pixels[i] = c;
  1235. }
  1236. }
  1237. }
  1238. renderer.updatePixels();
  1239. renderer.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. renderer.beginDraw();
  1262. renderer.colorMode(HSB);
  1263. colorMode(HSB);
  1264. renderer.loadPixels();
  1265. for (int i = 0; i < renderer.width*renderer.height; i++) {
  1266. float hue = hue(renderer.pixels[i]);
  1267. float sat = saturation(renderer.pixels[i]);
  1268. float bright = brightness(renderer.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. renderer.pixels[i] = c;
  1275. }
  1276. renderer.colorMode(RGB);
  1277. renderer.updatePixels();
  1278. renderer.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. renderer.beginDraw();
  1298. if (params.get(3).value > 0) colorMode(HSB);
  1299. else {
  1300. colorMode(RGB);
  1301. }
  1302. renderer.loadPixels();
  1303. for (int i = 0; i < renderer.width*renderer.height; i++) {
  1304. float h = hue(renderer.pixels[i]);
  1305. float s = saturation(renderer.pixels[i]);
  1306. float b = brightness(renderer.pixels[i]);
  1307. renderer.pixels[i] = color(h+params.get(0).value, s+params.get(1).value, b+params.get(2).value);
  1308. }
  1309. renderer.updatePixels();
  1310. renderer.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. }
  1327. void apply() {
  1328. renderer.beginDraw();
  1329. if (params.get(3).value > 0) colorMode(HSB);
  1330. else {
  1331. colorMode(RGB);
  1332. }
  1333. renderer.loadPixels();
  1334. float h = params.get(0).value;
  1335. float s = params.get(1).value;
  1336. float b = params.get(2).value;
  1337. for (int i = 0; i < renderer.width*renderer.height; i++) {
  1338. h = hue(renderer.pixels[i])+h;
  1339. if (h > 255) h -= 255;
  1340. s = saturation(renderer.pixels[i])+s;
  1341. if (s > 255) s -= 255;
  1342. b = brightness(renderer.pixels[i])+b;
  1343. if (b > 255) b -= 255;
  1344. renderer.pixels[i] = color(h, s, b);
  1345. }
  1346. renderer.updatePixels();
  1347. renderer.endDraw();
  1348. colorMode(RGB);
  1349. }
  1350. }
  1351. /*
  1352. POSTERIZE
  1353. */
  1354. class POSTER extends Shader {
  1355. POSTER() {
  1356. name = "fxPosterize";
  1357. params.add(new Param("levels", INTVAL, 2, 10, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  1358. }
  1359. void apply() {
  1360. renderer.beginDraw();
  1361. renderer.filter(POSTERIZE, (int)params.get(0).value);
  1362. renderer.endDraw();
  1363. }
  1364. }
  1365. /*
  1366. DUAL
  1367. */
  1368. class DUAL extends Shader {
  1369. PImage buffer;
  1370. int dualColor;
  1371. int dirx = 1;
  1372. int diry = 1;
  1373. DUAL() {
  1374. name = "fxDual";
  1375. params.add(new Param("dual color", INTVAL, 2000000, 15000000, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  1376. params.add(new Param("flip direction", INTVAL, 0, 3, new int[]{RANDOM}));
  1377. params.add(new Param("mode", INTVAL, 0, 1, new int[]{SQUAR, RANDOM}));
  1378. buffer = createImage(renderer.width, renderer.height, ARGB);
  1379. }
  1380. void apply() {
  1381. switch((int)params.get(1).value) {
  1382. case(0):
  1383. dirx = 1;
  1384. diry = 1;
  1385. break;
  1386. case(1):
  1387. dirx = -1;
  1388. diry = 1;
  1389. break;
  1390. case(2):
  1391. dirx = 1;
  1392. diry = -1;
  1393. break;
  1394. case(3):
  1395. dirx = -1;
  1396. diry = -1;
  1397. break;
  1398. }
  1399. dualColor = (int)params.get(0).value;
  1400. buffer.resize(renderer.width, renderer.height);
  1401. renderer.beginDraw();
  1402. renderer.loadPixels();
  1403. buffer.loadPixels();
  1404. if ((int)params.get(2).value > 0) {
  1405. for (int i = 0; i < renderer.width*renderer.height; i++) {
  1406. buffer.pixels[i] = renderer.pixels[i]+dualColor;
  1407. }
  1408. } else {
  1409. for (int i = 0; i < renderer.width*renderer.height; i++) {
  1410. buffer.pixels[i] = renderer.pixels[i]+dualColor;
  1411. buffer.pixels[i] = buffer.pixels[i]+i/10;
  1412. }
  1413. }
  1414. buffer.updatePixels();
  1415. renderer.updatePixels();
  1416. renderer.pushMatrix();
  1417. renderer.scale(dirx, diry);
  1418. renderer.image(buffer, 0, 0, dirx * renderer.width, diry * renderer.height);
  1419. renderer.popMatrix();
  1420. renderer.endDraw();
  1421. }
  1422. }
  1423. /*
  1424. GRAUZONE
  1425. */
  1426. class GRAUZONE extends Shader {
  1427. int nFrames = 20;
  1428. int iWrite = 0, iRead = 1;
  1429. PImage[] buffer;
  1430. PGraphics grauz;
  1431. GRAUZONE() {
  1432. name = "fxGrauzone";
  1433. params.add(new Param("delay (in frames)", INTVAL, 3, 100, new int[]{RANDOM}));
  1434. nFrames = (int)params.get(0).value;
  1435. buffer = new PImage[nFrames];
  1436. }
  1437. int nFramesPrev;
  1438. void apply() {
  1439. nFramesPrev = nFrames;
  1440. if (nFramesPrev != (int)params.get(0).value) {
  1441. iWrite = 0;
  1442. iRead = 1;
  1443. int nFramesOld = nFrames;
  1444. nFrames = (int)params.get(0).value;
  1445. if (nFrames > nFramesOld) {
  1446. buffer = new PImage[nFrames];
  1447. }
  1448. }
  1449. buffer[iWrite] = renderer.get();
  1450. grauz = createGraphics(renderer.width, renderer.height);
  1451. grauz.beginDraw();
  1452. // grauz.resize(renderer.width, renderer.height);
  1453. buffer[iWrite] = renderer.get();
  1454. if (buffer[iRead] != null) {
  1455. grauz.tint(255, 127);
  1456. buffer[iRead].filter(INVERT);
  1457. grauz.image(buffer[iRead], 0, 0, renderer.width, renderer.height);
  1458. grauz.tint(255, 255);
  1459. }
  1460. grauz.endDraw();
  1461. renderer.beginDraw();
  1462. renderer.image(grauz, 0, 0, renderer.width, renderer.height);
  1463. renderer.endDraw();
  1464. iWrite++;
  1465. iRead++;
  1466. if (iRead >= nFrames-1) {
  1467. iRead = 0;
  1468. }
  1469. if (iWrite >= nFrames-1) {
  1470. iWrite = 0;
  1471. }
  1472. }
  1473. }
  1474. /*
  1475. COPYZOOM
  1476. */
  1477. class COPYZOOM extends Shader {
  1478. int coprx, copry, coprw, coprh;
  1479. PImage buffer;
  1480. COPYZOOM() {
  1481. name = "fxCopyZoom";
  1482. params.add(new Param("w", FLOATVAL, 0, 1, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  1483. params.add(new Param("h", FLOATVAL, 0, 1, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  1484. params.add(new Param("x", FLOATVAL, 0, 1, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  1485. params.add(new Param("y", FLOATVAL, 0, 1, new int[]{SAWTOOTH, TRIANG, SINE, TAN, TANINVERSE, RAMPUPDOWN, RAMP, RAMPINVERSE}));
  1486. buffer = createImage(renderer.width, renderer.height, ARGB);
  1487. coprw = int(random(0, renderer.width));
  1488. coprh = int(random(0, renderer.height));
  1489. coprx = int(random(0, renderer.width-coprw));
  1490. copry = int(random(0, renderer.height-coprh));
  1491. }
  1492. void apply() {
  1493. if (buffer.width != renderer.width || buffer.height != renderer.height) buffer.resize(renderer.width, renderer.height);
  1494. buffer = renderer.get();
  1495. coprw = int(map(params.get(0).value, 0, 1, 1, renderer.width));
  1496. coprh = int(map(params.get(1).value, 0, 1, 1, renderer.height));
  1497. coprx = int(map(params.get(2).value, 0, 1, 0, renderer.width-coprw));
  1498. copry = int(map(params.get(3).value, 0, 1, 0, renderer.height-coprh));
  1499. renderer.beginDraw();
  1500. buffer.copy(coprx, copry, coprw, coprh, 0, 0, renderer.width, renderer.height);
  1501. renderer.image(buffer, 0, 0, renderer.width, renderer.height);
  1502. renderer.endDraw();
  1503. }
  1504. }
  1505. /*
  1506. BUFFER
  1507. */
  1508. class BUFFER extends Shader {
  1509. BUFFER() {
  1510. name = "BUFFER";
  1511. }
  1512. }
  1513. // name
  1514. String getColorspaceName(int cs) {
  1515. switch(cs) {
  1516. case OHTA:
  1517. return "OHTA";
  1518. case CMY:
  1519. return "CMY";
  1520. case XYZ:
  1521. return "XYZ";
  1522. case YXY:
  1523. return "YXY";
  1524. case HCL:
  1525. return "HCL";
  1526. case LUV:
  1527. return "LUV";
  1528. case LAB:
  1529. return "LAB";
  1530. case HWB:
  1531. return "HWB";
  1532. case HSB:
  1533. return "HSB";
  1534. case RGGBG:
  1535. return "R-GGB-G";
  1536. case YPbPr:
  1537. return "YPbPr";
  1538. case YCbCr:
  1539. return "YCbCr";
  1540. case YDbDr:
  1541. return "YDbDr";
  1542. case GS:
  1543. return "Greyscale";
  1544. case YUV:
  1545. return "YUV";
  1546. default:
  1547. return "RGB";
  1548. }
  1549. }
  1550. // colorspace converters
  1551. color fromColorspace(color c, int cs) {
  1552. switch(cs) {
  1553. case OHTA:
  1554. return fromOHTA(c);
  1555. case CMY:
  1556. return fromCMY(c);
  1557. case XYZ:
  1558. return fromXYZ(c);
  1559. case YXY:
  1560. return fromYXY(c);
  1561. case HCL:
  1562. return fromHCL(c);
  1563. case LUV:
  1564. return fromLUV(c);
  1565. case LAB:
  1566. return fromLAB(c);
  1567. case HWB:
  1568. return fromHWB(c);
  1569. case HSB:
  1570. return fromHSB(c);
  1571. case RGGBG:
  1572. return fromRGGBG(c);
  1573. case YPbPr:
  1574. return fromYPbPr(c);
  1575. case YCbCr:
  1576. return fromYCbCr(c);
  1577. case YDbDr:
  1578. return fromYDbDr(c);
  1579. case GS:
  1580. return tofromGS(c);
  1581. case YUV:
  1582. return fromYUV(c);
  1583. default:
  1584. return c;
  1585. }
  1586. }
  1587. color toColorspace(color c, int cs) {
  1588. switch(cs) {
  1589. case OHTA:
  1590. return toOHTA(c);
  1591. case CMY:
  1592. return toCMY(c);
  1593. case XYZ:
  1594. return toXYZ(c);
  1595. case YXY:
  1596. return toYXY(c);
  1597. case HCL:
  1598. return toHCL(c);
  1599. case LUV:
  1600. return toLUV(c);
  1601. case LAB:
  1602. return toLAB(c);
  1603. case HWB:
  1604. return toHWB(c);
  1605. case HSB:
  1606. return toHSB(c);
  1607. case RGGBG:
  1608. return toRGGBG(c);
  1609. case YPbPr:
  1610. return toYPbPr(c);
  1611. case YCbCr:
  1612. return toYCbCr(c);
  1613. case YDbDr:
  1614. return toYDbDr(c);
  1615. case YUV:
  1616. return toYUV(c);
  1617. case GS:
  1618. return tofromGS(c);
  1619. default:
  1620. return c;
  1621. }
  1622. }
  1623. // Colorspace converters
  1624. final int getR(color c) {
  1625. return (c & 0xff0000) >> 16;
  1626. }
  1627. final int getG(color c) {
  1628. return (c & 0xff00) >> 8;
  1629. }
  1630. final int getB(color c) {
  1631. return c & 0xff;
  1632. }
  1633. final int getLuma(color c) {
  1634. return constrain((int)(0.2126*getR(c)+0.7152*getG(c)+0.0722*getB(c)), 0, 255);
  1635. }
  1636. int getChannel(color c, int ch) {
  1637. switch(ch) {
  1638. case 0 :
  1639. return getR(c);
  1640. case 1 :
  1641. return getG(c);
  1642. case 2 :
  1643. return getB(c);
  1644. default:
  1645. return 0;
  1646. }
  1647. }
  1648. // normalized versions
  1649. final float getNR(color c) {
  1650. return r255[(c & 0xff0000) >> 16];
  1651. }
  1652. final float getNG(color c) {
  1653. return r255[(c & 0xff00) >> 8];
  1654. }
  1655. final float getNB(color c) {
  1656. return r255[c & 0xff];
  1657. }
  1658. final float getNLuma(color c) {
  1659. return r255[getLuma(c)];
  1660. }
  1661. color blendRGB(color c, int r, int g, int b) {
  1662. return (c & 0xff000000) | (constrain(r, 0, 255) << 16) | (constrain(g, 0, 255) << 8 ) | constrain(b, 0, 255);
  1663. }
  1664. color blendRGB(color c, float r, float g, float b) {
  1665. return blendRGB(c, (int)(r*255), (int)(g*255), (int)(b*255));
  1666. }
  1667. /**************
  1668. * Greyscale
  1669. **************/
  1670. color tofromGS(color c) {
  1671. int l = getLuma(c);
  1672. return blendRGB(c, l, l, l);
  1673. }
  1674. /**************
  1675. * YUV
  1676. **************/
  1677. final static float Umax = 0.436 * 255.0;
  1678. final static float Vmax = 0.615 * 255.0;
  1679. color toYUV(color c) {
  1680. int R = getR(c);
  1681. int G = getG(c);
  1682. int B = getB(c);
  1683. int Y = (int)( 0.299*R+0.587*G+0.114*B);
  1684. int U = (int)map(-0.14713*R-0.28886*G+0.436*B, -Umax, Umax, 0, 255);
  1685. int V = (int)map(0.615*R-0.51499*G-0.10001*B, -Vmax, Vmax, 0, 255);
  1686. return blendRGB(c, Y, U, V);
  1687. }
  1688. color fromYUV(color c) {
  1689. int Y = getR(c);
  1690. float U = map(getG(c), 0, 255, -Umax, Umax);
  1691. float V = map(getB(c), 0, 255, -Vmax, Vmax);
  1692. int R = (int)(Y + 1.13983*V);
  1693. int G = (int)(Y - 0.39465*U - 0.58060*V);
  1694. int B = (int)(Y + 2.03211*U);
  1695. return blendRGB(c, R, G, B);
  1696. }
  1697. /**************
  1698. * YDbDr
  1699. **************/
  1700. color toYDbDr(color c) {
  1701. int R = getR(c);
  1702. int G = getG(c);
  1703. int B = getB(c);
  1704. int Y = (int)( 0.299*R+0.587*G+0.114*B);
  1705. int Db = (int)(127.5+(-0.450*R-0.883*G+1.333*B)/2.666);
  1706. int Dr = (int)(127.5+(-1.333*R+1.116*G+0.217*B)/2.666);
  1707. return blendRGB(c, Y, Db, Dr);
  1708. }
  1709. color fromYDbDr(color c) {
  1710. int Y = getR(c);
  1711. float Db = (getG(c)-127.5)*2.666;
  1712. float Dr = (getB(c)-127.5)*2.666;
  1713. int R = (int)(Y + 9.2303716147657e-05*Db-0.52591263066186533*Dr);
  1714. int G = (int)(Y - 0.12913289889050927*Db+0.26789932820759876*Dr);
  1715. int B = (int)(Y + 0.66467905997895482*Db-7.9202543533108e-05*Dr);
  1716. return blendRGB(c, R, G, B);
  1717. }
  1718. /**************
  1719. * YCbCr
  1720. **************/
  1721. color toYCbCr(color c) {
  1722. int R = getR(c);
  1723. int G = getG(c);
  1724. int B = getB(c);
  1725. int Y = (int)( 0.2988390*R+0.5868110*G+0.1143500*B);
  1726. int Cb = (int)(-0.168736*R-0.3312640*G+0.5000000*B+127.5);
  1727. int Cr = (int)( 0.5000000*R-0.4186880*G-0.0813120*B+127.5);
  1728. return blendRGB(c, Y, Cb, Cr);
  1729. }
  1730. color fromYCbCr(color c) {
  1731. int Y = getR(c);
  1732. float Cb = getG(c) - 127.5;
  1733. float Cr = getB(c) - 127.5;
  1734. int R = (int)(Y + 1.402*Cr)+1; // some fix
  1735. int G = (int)(Y-0.344136*Cb-0.714136*Cr);
  1736. int B = (int)(Y+1.772000*Cb)+1; // some fix
  1737. return blendRGB(c, R, G, B);
  1738. }
  1739. /**************
  1740. * YPbPr
  1741. **************/
  1742. color toYPbPr(color c) {
  1743. int R = getR(c);
  1744. int B = getB(c);
  1745. int Y = getLuma(c);
  1746. int Pb = B - Y;
  1747. int Pr = R - Y;
  1748. if (Pb<0) Pb+=256;
  1749. if (Pr<0) Pr+=256;
  1750. return blendRGB(c, Y, Pb, Pr);
  1751. }
  1752. color fromYPbPr(color c) {
  1753. int Y = getR(c);
  1754. int B = getG(c) + Y;
  1755. int R = getB(c) + Y;
  1756. if (R>255) R-=256;
  1757. if (B>255) B-=256;
  1758. int G = (int)((Y-0.2126*R-0.0722*B)/0.7152);
  1759. return blendRGB(c, R, G, B);
  1760. }
  1761. /**************
  1762. * R-G,G,B-G
  1763. **************/
  1764. color toRGGBG(color c) {
  1765. int G = getG(c);
  1766. int R = getR(c)-G;
  1767. int B = getB(c)-G;
  1768. if (R<0) R+=256;
  1769. if (B<0) B+=256;
  1770. return blendRGB(c, R, G, B);
  1771. }
  1772. color fromRGGBG(color c) {
  1773. int G = getG(c);
  1774. int R = getR(c)+G;
  1775. int B = getB(c)+G;
  1776. if (R>255) R-=256;
  1777. if (B>255) B-=256;
  1778. return blendRGB(c, R, G, B);
  1779. }
  1780. /**************
  1781. * HWB
  1782. **************/
  1783. color toHSB(color c) {
  1784. int R = getR(c);
  1785. int G = getG(c);
  1786. int B = getB(c);
  1787. int _min = min(R, G, B);
  1788. int _max = max(R, G, B);
  1789. float delta = _max-_min;
  1790. float saturation = delta/_max;
  1791. float brightness = r255[_max];
  1792. if (delta == 0.0) return blendRGB(c, 0.0, saturation, brightness);
  1793. float hue = 0;
  1794. if (R == _max) hue = (G-B)/delta;
  1795. else if (G == _max) hue = 2.0 + (B-R)/delta;
  1796. else hue = 4.0 + (R-G)/delta;
  1797. hue /= 6.0;
  1798. if (hue < 0.0) hue += 1.0;
  1799. return blendRGB(c, hue, saturation, brightness);
  1800. }
  1801. color fromHSB(color c) {
  1802. float S = getNG(c);
  1803. float B = getNB(c);
  1804. if (S == 0.0) return blendRGB(c, B, B, B);
  1805. float h = 6.0 * getNR(c);
  1806. float f = h-floor(h);
  1807. float p = B*(1.0-S);
  1808. float q = B*(1.0-S*f);
  1809. float t = B*(1.0-(S*(1.0-f)));
  1810. float r, g, b;
  1811. switch((int)h) {
  1812. case 1:
  1813. r=q;
  1814. g=B;
  1815. b=p;
  1816. break;
  1817. case 2:
  1818. r=p;
  1819. g=B;
  1820. b=t;
  1821. break;
  1822. case 3:
  1823. r=p;
  1824. g=q;
  1825. b=B;
  1826. break;
  1827. case 4:
  1828. r=t;
  1829. g=p;
  1830. b=B;
  1831. break;
  1832. case 5:
  1833. r=B;
  1834. g=p;
  1835. b=q;
  1836. break;
  1837. default:
  1838. r=B;
  1839. g=t;
  1840. b=p;
  1841. break;
  1842. }
  1843. return blendRGB(c, r, g, b);
  1844. }
  1845. /**************
  1846. * HWB
  1847. **************/
  1848. color toHWB(color c) {
  1849. int R = getR(c);
  1850. int G = getG(c);
  1851. int B = getB(c);
  1852. int w = min(R, G, B);
  1853. int v = max(R, G, B);
  1854. int hue;
  1855. if (v == w) hue = 255;
  1856. else {
  1857. float f = ((R == w) ? G-B : ((G == w) ? B-R : R-G));
  1858. float p = (R == w) ? 3.0 : ((G == w) ? 5.0 : 1.0);
  1859. hue = (int)map((p-f/(v-w))/6.0, 0, 1, 0, 254);
  1860. }
  1861. return blendRGB(c, hue, w, 255-v);
  1862. }
  1863. color fromHWB(color c) {
  1864. int H = getR(c);
  1865. int B = 255-getB(c);
  1866. if (H == 255) return blendRGB(c, B, B, B);
  1867. else {
  1868. float hue = map(H, 0, 254, 0, 6);
  1869. float v = r255[B];
  1870. float whiteness = getNG(c);
  1871. int i = (int)floor(hue);
  1872. float f = hue-i;
  1873. if ((i&0x01)!= 0) f=1.0-f;
  1874. float n = whiteness+f*(v-whiteness);
  1875. float r, g, b;
  1876. switch(i) {
  1877. case 1:
  1878. r=n;
  1879. g=v;
  1880. b=whiteness;
  1881. break;
  1882. case 2:
  1883. r=whiteness;
  1884. g=v;
  1885. b=n;
  1886. break;
  1887. case 3:
  1888. r=whiteness;
  1889. g=n;
  1890. b=v;
  1891. break;
  1892. case 4:
  1893. r=n;
  1894. g=whiteness;
  1895. b=v;
  1896. break;
  1897. case 5:
  1898. r=v;
  1899. g=whiteness;
  1900. b=n;
  1901. break;
  1902. default:
  1903. r=v;
  1904. g=n;
  1905. b=whiteness;
  1906. break;
  1907. }
  1908. return blendRGB(c, r, g, b);
  1909. }
  1910. }
  1911. /**************
  1912. * Lab
  1913. **************/
  1914. final static float D65X=0.950456;
  1915. final static float D65Y=1.0;
  1916. final static float D65Z=1.088754;
  1917. final static float CIEEpsilon=(216.0/24389.0);
  1918. final static float CIEK=(24389.0/27.0);
  1919. final static float CIEK2epsilon = CIEK * CIEEpsilon;
  1920. final static float D65FX_4 = 4.0*D65X/(D65X+15.0*D65Y+3.0*D65Z);
  1921. final static float D65FY_9 = 9.0*D65Y/(D65X+15.0*D65Y+3.0*D65Z);
  1922. final static float RANGE_X = 100.0 * (0.4124+0.3576+0.1805);
  1923. final static float RANGE_Y = 100.0;
  1924. final static float RANGE_Z = 100.0 * (0.0193+0.1192+0.9505);
  1925. final static float mepsilon = 1.0e-10;
  1926. final static float corrratio = 1.0/2.4;
  1927. final static float One_Third = 1.0/3.0;
  1928. final static float one_hsixteen = 1.0/116.0;
  1929. color toLAB(color c) {
  1930. PVector xyz = _toXYZ(getNR(c), getNG(c), getNB(c));
  1931. xyz.div(100.0);
  1932. xyz.x /= D65X;
  1933. xyz.y /= D65Y;
  1934. xyz.z /= D65Z;
  1935. float x, y, z;
  1936. if (xyz.x > CIEEpsilon) {
  1937. x = pow(xyz.x, One_Third);
  1938. } else {
  1939. x= (CIEK*xyz.x+16.0)*one_hsixteen;
  1940. }
  1941. if (xyz.y > CIEEpsilon) {
  1942. y = pow(xyz.y, One_Third);
  1943. } else {
  1944. y = (CIEK*xyz.y+16.0)*one_hsixteen;
  1945. }
  1946. if (xyz.z > CIEEpsilon) {
  1947. z = pow(xyz.z, One_Third);
  1948. } else {
  1949. z = (CIEK*xyz.z+16.0)*one_hsixteen;
  1950. }
  1951. float L = 255.0*(((116.0*y)-16.0)*0.01);
  1952. float a = 255.0*(0.5*(x-y)+0.5);
  1953. float b = 255.0*(0.5*(y-z)+0.5);
  1954. return blendRGB(c, round(L), round(a), round(b));
  1955. }
  1956. color fromLAB(color c) {
  1957. float L = 100*getNR(c);
  1958. float a = getNG(c)-0.5;
  1959. float b = getNB(c)-0.5;
  1960. float y = (L+16.0)*one_hsixteen;
  1961. float x = y+a;
  1962. float z = y-b;
  1963. float xxx=x*x*x;
  1964. if (xxx>CIEEpsilon) {
  1965. x = xxx;
  1966. } else {
  1967. x = (116.0*x-16.0)/CIEK;
  1968. }
  1969. float yyy=y*y*y;
  1970. if (yyy>CIEEpsilon) {
  1971. y = yyy;
  1972. } else {
  1973. y = L/CIEK;
  1974. }
  1975. float zzz=z*z*z;
  1976. if (zzz>CIEEpsilon) {
  1977. z = zzz;
  1978. } else {
  1979. z = (116.0*z-16.0)/CIEK;
  1980. }
  1981. return _fromXYZ(c, RANGE_X*x, RANGE_Y*y, RANGE_Z*z);
  1982. }
  1983. /**************
  1984. * Luv
  1985. **************/
  1986. final float PerceptibleReciprocal(float x) {
  1987. float sgn = x < 0.0 ? -1.0 : 1.0;
  1988. if ((sgn * x) >= mepsilon) return (1.0 / x);
  1989. return (sgn/mepsilon);
  1990. }
  1991. color toLUV(color c) {
  1992. PVector xyz = _toXYZ(getNR(c), getNG(c), getNB(c));
  1993. xyz.div(100.0);
  1994. float d = xyz.y; // / D65Y;
  1995. float L;
  1996. if (d > CIEEpsilon) L = 116.0*pow(d, One_Third)-16.0;
  1997. else L = CIEK * d;
  1998. float alpha = PerceptibleReciprocal(xyz.x + 15.0 * xyz.y + 3.0 * xyz.z);
  1999. float L13 = 13.0 * L;
  2000. float u = L13 * ((4.0 * alpha * xyz.x)-D65FX_4);
  2001. float v = L13 * ((9.0 * alpha * xyz.y)-D65FY_9);
  2002. L /= 100.0;
  2003. u=(u+134.0)/354.0;
  2004. v=(v+140.0)/262.0;
  2005. return blendRGB(c, round(L*255), round(u*255), round(v*255));
  2006. }
  2007. color fromLUV(color c) {
  2008. float L = 100.0*getNR(c);
  2009. float u = 354.0*getNG(c)-134.0;
  2010. float v = 262.0*getNB(c)-140.0;
  2011. float X, Y, Z;
  2012. if (L > CIEK2epsilon) Y = pow((L+16.0)*one_hsixteen, 3.0);
  2013. else Y = L/CIEK;
  2014. float L13 = 13.0*L;
  2015. float L52 = 52.0*L;
  2016. float Y5 = 5.0*Y;
  2017. float L13u = L52/(u+L13*D65FX_4);
  2018. X=((Y*((39.0*L/(v+L13*D65FY_9))-5.0))+Y5)/((((L13u)-1.0)/3.0)+One_Third);
  2019. Z=(X*(((L13u)-1.0)/3.0))-Y5;
  2020. return _fromXYZ(c, 100*X, 100*Y, 100*Z);
  2021. }
  2022. /**************
  2023. * HCL
  2024. **************/
  2025. color toHCL(color c) {
  2026. float r = getNR(c);
  2027. float g = getNG(c);
  2028. float b = getNB(c);
  2029. float max = max(r, max(g, b));
  2030. float chr = max - min(r, min(g, b));
  2031. float h = 0.0;
  2032. if ( chr != 0) {
  2033. if (r == max) {
  2034. h = ((g-b)/chr+6.0) % 6.0;
  2035. } else if (g == max) {
  2036. h = (b-r)/chr + 2.0;
  2037. } else {
  2038. h = (r-g)/chr + 4.0;
  2039. }
  2040. }
  2041. return blendRGB(c, round((h/6.0)*255), round(chr*255), round(255*(0.298839*r+0.586811*g+0.114350*b)));
  2042. }
  2043. color fromHCL(color c) {
  2044. float h = 6.0*getNR(c);
  2045. float chr = getNG(c);
  2046. float l = getNB(c);
  2047. float x = chr*(1.0-abs((h%2.0)-1.0));
  2048. float r = 0.0;
  2049. float g = 0.0;
  2050. float b = 0.0;
  2051. if ((0.0 <= h) && (h < 1.0)) {
  2052. r=chr;
  2053. g=x;
  2054. } else if ((1.0 <= h) && (h < 2.0)) {
  2055. r=x;
  2056. g=chr;
  2057. } else if ((2.0 <= h) && (h < 3.0)) {
  2058. g=chr;
  2059. b=x;
  2060. } else if ((3.0 <= h) && (h < 4.0)) {
  2061. g=x;
  2062. b=chr;
  2063. } else if ((4.0 <= h) && (h < 5.0)) {
  2064. r=x;
  2065. b=chr;
  2066. } else {//if ((5.0 <= h) && (h < 6.0)) {
  2067. r=chr;
  2068. b=x;
  2069. }
  2070. float m = l - (0.298839*r+0.586811*g+0.114350*b);
  2071. return blendRGB(c, round(255*(r+m)), round(255*(g+m)), round(255*(b+m)));
  2072. }
  2073. /**************
  2074. * Yxy
  2075. **************/
  2076. color toYXY(color c) {
  2077. PVector xyz = _toXYZ(getNR(c), getNG(c), getNB(c));
  2078. float sum = xyz.x + xyz.y + xyz.z;
  2079. float x = xyz.x > 0 ? xyz.x / sum : 0.0;
  2080. float y = xyz.y > 0 ? xyz.y / sum : 0.0;
  2081. return blendRGB(c,
  2082. (int)map(xyz.y, 0, RANGE_Y, 0, 255),
  2083. (int)map(x, 0.0, 1.0, 0, 255),
  2084. (int)map(y, 0.0, 1.0, 0, 255));
  2085. }
  2086. color fromYXY(color c) {
  2087. float Y = map(getR(c), 0, 255, 0, RANGE_Y);
  2088. float x = map(getG(c), 0, 255, 0, 1.0);
  2089. float y = map(getB(c), 0, 255, 0, 1.0);
  2090. float divy = Y / (y>0 ? y : 1.0e-6);
  2091. return _fromXYZ(c, x * divy, Y, (1-x-y)*divy);
  2092. }
  2093. /**************
  2094. * XYZ
  2095. **************/
  2096. // FIXME: range from 0 to 1
  2097. float correctionxyz(float n) {
  2098. return (n > 0.04045 ? pow((n + 0.055) / 1.055, 2.4) : n / 12.92) * 100.0;
  2099. }
  2100. PVector _toXYZ(float rr, float gg, float bb) {
  2101. float r = correctionxyz(rr);
  2102. float g = correctionxyz(gg);
  2103. float b = correctionxyz(bb);
  2104. return new PVector(r * 0.4124 + g * 0.3576 + b * 0.1805,
  2105. r * 0.2126 + g * 0.7152 + b * 0.0722,
  2106. r * 0.0193 + g * 0.1192 + b * 0.9505);
  2107. }
  2108. color toXYZ(color c) {
  2109. PVector xyz = _toXYZ(getNR(c), getNG(c), getNB(c));
  2110. return blendRGB(c,
  2111. (int)map(xyz.x, 0, RANGE_X, 0, 255),
  2112. (int)map(xyz.y, 0, RANGE_Y, 0, 255),
  2113. (int)map(xyz.z, 0, RANGE_Z, 0, 255));
  2114. }
  2115. float recorrectionxyz(float n) {
  2116. return n > 0.0031308 ? 1.055 * pow(n, corrratio) - 0.055 : 12.92 * n;
  2117. }
  2118. // FIXME: range from 0 to 1
  2119. color _fromXYZ(color c, float xx, float yy, float zz) {
  2120. float x = xx/100.0;
  2121. float y = yy/100.0;
  2122. float z = zz/100.0;
  2123. int r = round(255.0*recorrectionxyz(x * 3.2406 + y * -1.5372 + z * -0.4986));
  2124. int g = round(255.0*recorrectionxyz(x * -0.9689 + y * 1.8758 + z * 0.0415));
  2125. int b = round(255.0*recorrectionxyz(x * 0.0557 + y * -0.2040 + z * 1.0570));
  2126. return blendRGB(c, r, g, b);
  2127. }
  2128. color fromXYZ(color c) {
  2129. float x = map(getR(c), 0, 255, 0, RANGE_X);
  2130. float y = map(getG(c), 0, 255, 0, RANGE_Y);
  2131. float z = map(getB(c), 0, 255, 0, RANGE_Z);
  2132. return _fromXYZ(c, x, y, z);
  2133. }
  2134. /**************
  2135. * CMY
  2136. **************/
  2137. color toCMY(color c) {
  2138. return blendRGB(c, 255-getR(c), 255-getG(c), 255-getB(c));
  2139. }
  2140. color fromCMY(color c) {
  2141. return toCMY(c);
  2142. }
  2143. /**************
  2144. * OHTA
  2145. **************/
  2146. color fromOHTA(color c) {
  2147. int I1 = getR(c);
  2148. float I2 = map(getG(c), 0, 255, -127.5, 127.5);
  2149. float I3 = map(getB(c), 0, 255, -127.5, 127.5);
  2150. int R = (int)(I1+1.00000*I2-0.66668*I3);
  2151. int G = (int)(I1+1.33333*I3);
  2152. int B = (int)(I1-1.00000*I2-0.66668*I3);
  2153. return blendRGB(c, R, G, B);
  2154. }
  2155. color toOHTA(color c) {
  2156. int R = getR(c);
  2157. int G = getG(c);
  2158. int B = getB(c);
  2159. int I1 = (int)(0.33333*R+0.33334*G+0.33333*B);
  2160. int I2 = (int)map(0.5*(R-B), -127.5, 127.5, 0, 255);
  2161. int I3 = (int)map(-0.25000*R+0.50000*G-0.25000*B, -127.5, 127.5, 0, 255);
  2162. return blendRGB(c, I1, I2, I3);
  2163. }
  2164. ////
  2165. // 1/n table for n=0..255 - to speed up color conversions things
  2166. final static float[] r255 = {
  2167. 0.0, 0.003921569, 0.007843138, 0.011764706, 0.015686275, 0.019607844, 0.023529412, 0.02745098, 0.03137255, 0.03529412, 0.039215688,
  2168. 0.043137256, 0.047058824, 0.050980393, 0.05490196, 0.05882353, 0.0627451, 0.06666667, 0.07058824, 0.07450981, 0.078431375, 0.08235294,
  2169. 0.08627451, 0.09019608, 0.09411765, 0.09803922, 0.101960786, 0.105882354, 0.10980392, 0.11372549, 0.11764706, 0.12156863, 0.1254902,
  2170. 0.12941177, 0.13333334, 0.13725491, 0.14117648, 0.14509805, 0.14901961, 0.15294118, 0.15686275, 0.16078432, 0.16470589, 0.16862746,
  2171. 0.17254902, 0.1764706, 0.18039216, 0.18431373, 0.1882353, 0.19215687, 0.19607843, 0.2, 0.20392157, 0.20784314, 0.21176471, 0.21568628,
  2172. 0.21960784, 0.22352941, 0.22745098, 0.23137255, 0.23529412, 0.23921569, 0.24313726, 0.24705882, 0.2509804, 0.25490198, 0.25882354,
  2173. 0.2627451, 0.26666668, 0.27058825, 0.27450982, 0.2784314, 0.28235295, 0.28627452, 0.2901961, 0.29411766, 0.29803923, 0.3019608, 0.30588236,
  2174. 0.30980393, 0.3137255, 0.31764707, 0.32156864, 0.3254902, 0.32941177, 0.33333334, 0.3372549, 0.34117648, 0.34509805, 0.34901962, 0.3529412,
  2175. 0.35686275, 0.36078432, 0.3647059, 0.36862746, 0.37254903, 0.3764706, 0.38039216, 0.38431373, 0.3882353, 0.39215687, 0.39607844, 0.4,
  2176. 0.40392157, 0.40784314, 0.4117647, 0.41568628, 0.41960785, 0.42352942, 0.42745098, 0.43137255, 0.43529412, 0.4392157, 0.44313726,
  2177. 0.44705883, 0.4509804, 0.45490196, 0.45882353, 0.4627451, 0.46666667, 0.47058824, 0.4745098, 0.47843137, 0.48235294, 0.4862745, 0.49019608,
  2178. 0.49411765, 0.49803922, 0.5019608, 0.5058824, 0.50980395, 0.5137255, 0.5176471, 0.52156866, 0.5254902, 0.5294118, 0.53333336, 0.5372549,
  2179. 0.5411765, 0.54509807, 0.54901963, 0.5529412, 0.5568628, 0.56078434, 0.5647059, 0.5686275, 0.57254905, 0.5764706, 0.5803922, 0.58431375,
  2180. 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,
  2181. 0.6392157, 0.6431373, 0.64705884, 0.6509804, 0.654902, 0.65882355, 0.6627451, 0.6666667, 0.67058825, 0.6745098, 0.6784314, 0.68235296,
  2182. 0.6862745, 0.6901961, 0.69411767, 0.69803923, 0.7019608, 0.7058824, 0.70980394, 0.7137255, 0.7176471, 0.72156864, 0.7254902, 0.7294118,
  2183. 0.73333335, 0.7372549, 0.7411765, 0.74509805, 0.7490196, 0.7529412, 0.75686276, 0.7607843, 0.7647059, 0.76862746, 0.77254903, 0.7764706,
  2184. 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,
  2185. 0.83137256, 0.8352941, 0.8392157, 0.84313726, 0.84705883, 0.8509804, 0.85490197, 0.85882354, 0.8627451, 0.8666667, 0.87058824, 0.8745098,
  2186. 0.8784314, 0.88235295, 0.8862745, 0.8901961, 0.89411765, 0.8980392, 0.9019608, 0.90588236, 0.9098039, 0.9137255, 0.91764706, 0.92156863,
  2187. 0.9254902, 0.92941177, 0.93333334, 0.9372549, 0.9411765, 0.94509804, 0.9490196, 0.9529412, 0.95686275, 0.9607843, 0.9647059, 0.96862745,
  2188. 0.972549, 0.9764706, 0.98039216, 0.9843137, 0.9882353, 0.99215686, 0.99607843, 1.0
  2189. };