02-14-2023, 03:57 AM | #1 |
Human being with feelings
Join Date: Mar 2007
Location: Mediterrenean Sea
Posts: 979
|
Rutt Etra video effect
Hi!
I was wondering if somebody did actually try to code a Rutt/Etra video effect. It's a very cool effect that was very used by analog video synth pioneers from the 70's. I'v searched in ReaPack and in the forums but couldn't find anything. and as a video: https://youtu.be/bIrL1fMmm_k Some code I found in javascript that seems to be very related, but looking at the included reaper video fx I cannot seem to understand the logic under these. For ex., how do you iterate through all the pixels in the current frame? Would it be viable to iterate through every pixel, send it to an image buffer and then render via blit? Would it be better to blit directly? can you blit several times per frame? would it have a too big impact on performance? Too many questions, and the documentation is barely inexistent. I'd really apreciate a little bit of help. Kind Regards!
__________________
http://estudi.canreco.com ProTools theme: http://forum.cockos.com/showthread.php?t=9422 Lighter theme: http://forum.cockos.com/showthread.p...653#post109653 Last edited by antiClick; 02-14-2023 at 08:38 AM. |
02-14-2023, 04:41 AM | #2 |
Human being with feelings
Join Date: Aug 2020
Location: Brasil
Posts: 679
|
Cool effect! This is a good candidate for "gfx_evalrect()" that processes code for each pixel. Unfortunately I won't be able to look into this type of effects for a couple of months. Also there is a sharpen filter is in the queue. If you are interested in "gfx_evalrect()" coding you can look at this thread and also to the new functions available since v6.70.
|
02-15-2023, 10:14 AM | #3 | |
Human being with feelings
Join Date: Mar 2007
Location: Mediterrenean Sea
Posts: 979
|
Quote:
Could you please point me some documentation about the subject? Any extra help would also be very appreciated. Maybe some examples I could use as a starting point.... like painting top corner pixels in pink or something like that. Thanks
__________________
http://estudi.canreco.com ProTools theme: http://forum.cockos.com/showthread.php?t=9422 Lighter theme: http://forum.cockos.com/showthread.p...653#post109653 |
|
02-15-2023, 12:58 PM | #4 |
Human being with feelings
Join Date: Sep 2008
Location: Sweden
Posts: 7,417
|
Yeah this looks really cool.
If I understand the Javascript code correctly, a pixel different from the current pixel is changed based on the RGB values of the current pixel. I am not sure that this can be done in gfx_evalrect. If anyone knows how to do that, please let us know. A non-functional skeleton for this that I crafted from the javascript code: Code:
function processRuttEtra(x0, y0, w0, h0, step) ( xx = x0; yy = y0; res = gfx_evalrect(x0, y0, w0, h0, " (yy % step) == 0 ? ( lum = r * 0.34 + g * 0.5 + b * 0.16; // r, g, b are the current pixel's color z = floor(lum/16); // not exactly same as Math.round(), but close newy = max(0, y-z); // Here the pixel (xx, newy) is updated with the RGB values of (xx, yy) // Don't know how to do that... ); r = g = b = 0; // set the current pixel (xx, yy) to black (xx += 1) >= w0 ? (xx = x0; yy += 1); // next pixel ", 1); );
__________________
// MVHMF I never always did the right thing, but all I did wasn't wrong... |
02-15-2023, 01:16 PM | #5 | |
Human being with feelings
Join Date: Aug 2020
Location: Brasil
Posts: 679
|
Quote:
Nevertheless here are simple examples of gfx_evalrect(): Code:
//gfx_evalrect() painting in RGB //@param pr r 0 0 255 128 1 //@param pg g 0 0 255 128 1 //@param pb b 0 0 255 128 1 colorspace='RGBA'; gfx_set(1,1,1,1,0,-1,1); //want 100% solid white for frame buffer gfx_img_resize(-1,400,400,1); //resize frame buffer to 400x400 and clear it with white //lets paint a center square with our chosen color gfx_evalrect(100,100,200,200,"r=pr;g=pg;b=pb",1); //flag=1 means single thread Code:
//gfx_evalrect() invert colors (RGB) src=0; //current video source input# input_info(src,sw,sh)?( //lets make sure we have a source colorspace='RGBA'; //makes variables R G B available gfx_set(0,0,0,1,0,-1,1); //explicitly set all parameters gfx_img_resize(-1,sw,sh); //make sure the frame buffer is same size as source gfx_blit(0); //copy current source in frame buffer gfx_evalrect(0,0,sw,sh,"r=255-r;g=255-g;b=255-b",1); //flag=1 means single thread = better for testing ); Code:
//gfx_evalrect() invert colors (YUY2) src=0; //current video source input# input_info(src,sw,sh)?( //lets make sure we have a source colorspace='YUY2'; //makes variables R G B available gfx_set(0,0,0,1,0,-1,1); //explicitly set all parameters gfx_img_resize(-1,sw,sh); //make sure the frame buffer is same size as source gfx_blit(0); //copy current source in frame buffer gfx_evalrect(0,0,sw,sh,"u=255-u;v=255-v;y1=255-y1;y2=255-y2",1); //flag=1 means single thread = better for testing ); |
|
02-15-2023, 01:35 PM | #6 | |
Human being with feelings
Join Date: Aug 2020
Location: Brasil
Posts: 679
|
Quote:
"r[0]+=1; g[256]+=1; b[512]+=1;seems to suggest that it is possible but I am still not quite sure how to use the vector addressing in this context. "0,256,512,768" are no trivial values but I have no clue what this example does. Last edited by papagirafe; 02-15-2023 at 02:01 PM. Reason: incorrect info |
|
02-15-2023, 05:55 PM | #7 |
Human being with feelings
Join Date: Dec 2012
Posts: 7,272
|
I’ve never understood evalrect, and would love to see some more examples or documentation. The brute force way would be to use getpixel to see each pixel value and then single pixel blits (we don’t have setpixel in VP).
__________________
Lorenzo's Tractor is Everywhere --- Ash's Tube --- Join the Partnership for a Drum Free Amerika Last edited by ashcat_lt; 02-15-2023 at 06:21 PM. |
02-16-2023, 04:21 AM | #8 | |
Human being with feelings
Join Date: Aug 2020
Location: Brasil
Posts: 679
|
Quote:
Code:
//gfx_setpixel() emulation function gfx_setpixel(x,y,r,g,b) global(_spr,_spg,_spb) ( _spr=r;_spg=g;_spb=b; //evalrect can only access globals or thread variables gfx_evalrect(x,y,1,1,"r=_spr;g=_spg;b=_spb"); ); //some testing code... colorspace='RGBA'; gfx_set(0); gfx_img_resize(-1,200,200,1); //400x400 black square bitmap res=gfx_setpixel(100,100,255,0,0); //one red pixel in the middle |
|
02-16-2023, 09:23 AM | #9 |
Human being with feelings
Join Date: Dec 2012
Posts: 7,272
|
I guess when I said “single pixel blit” I meant single pixel _fillrect. (How) Is _evalrect better at that?
__________________
Lorenzo's Tractor is Everywhere --- Ash's Tube --- Join the Partnership for a Drum Free Amerika |
02-16-2023, 10:29 AM | #10 |
Human being with feelings
Join Date: Aug 2020
Location: Brasil
Posts: 679
|
|
02-16-2023, 10:48 AM | #11 | |
Human being with feelings
Join Date: Aug 2020
Location: Brasil
Posts: 679
|
Quote:
In other words, we cannot address other pixel except the current one. The only solution would be to convert the algorythm to multiple phases. |
|
02-16-2023, 11:24 AM | #12 | ||
Human being with feelings
Join Date: Sep 2008
Location: Sweden
Posts: 7,417
|
Quote:
Quote:
__________________
// MVHMF I never always did the right thing, but all I did wasn't wrong... |
||
02-16-2023, 07:48 PM | #13 | |
Human being with feelings
Join Date: Dec 2012
Posts: 7,272
|
Quote:
This seems to do the thing: Code:
//Rutt step = 4; oldCS = colorspace; colorspace = 'RGBA'; pw = project_w; ph = project_h; gfx_set (0, 0, 0, 1, 0, -1 ); x = y = z = newy = lum = r = g = b = 0; while (y < ph) (x = 0; while (x < pw) (y % step == 0 ? (gfx_getpixel (0, x, y, r, g, b); lum = r * 0.34 + g * 0.5 + b * 0.16; z = floor((lum/16) + 0.5); newy = max(0, y-z); gfx_set (r, g, b); gfx_fillrect (x, newy, 1, 1);); gfx_set (0, 0, 0); gfx_fillrect (x, y, 1, 1); z = newy = lum = r = g = b = 0; x += 1;); y += 1;); colorspace = oldCS;
__________________
Lorenzo's Tractor is Everywhere --- Ash's Tube --- Join the Partnership for a Drum Free Amerika |
|
02-17-2023, 04:08 AM | #14 | |
Human being with feelings
Join Date: Aug 2020
Location: Brasil
Posts: 679
|
Quote:
Also with current versions of Reaper (and after numerous confirmations), each new instance of video processor gets its most cucial context variables restored to default/project's values, which mean you don't need to save/restore them. Namely:
|
|
02-17-2023, 10:00 AM | #15 |
Human being with feelings
Join Date: Dec 2012
Posts: 7,272
|
Yeah I suppose I sometimes just like to be explicit. Also, if somebody was to functionize this and put it into a bigger preset, there’s no good way of knowing where things would be set when called, so you might kind of want some of these things to be handled internally. Might do an if/then or something, but…. I really just assigned _w and _h to shorter variables so I didn’t have to type so much.
__________________
Lorenzo's Tractor is Everywhere --- Ash's Tube --- Join the Partnership for a Drum Free Amerika |
02-17-2023, 10:54 AM | #16 | |
Human being with feelings
Join Date: Aug 2020
Location: Brasil
Posts: 679
|
Quote:
|
|
02-17-2023, 11:13 AM | #17 | |
Human being with feelings
Join Date: Sep 2008
Location: Sweden
Posts: 7,417
|
Quote:
A 1x1 rectangle to set a pixel. Of course. Maybe I'm Dunning-Kruger'ing here but... I think there are two things different from Reaper and the Javascript code:
But I guess that will reveal itself when we look at the actual result. Has anyone tried it in the video processor yet? EDIT: OK I tried it in Reaper now, and I do not get the expected results. But my hunches above don't seem to be correct either. There's a nice web page here Rutt-Etra-Izer, and this gets me what I expect when I load the same picture there as I have in Reaper.
__________________
// MVHMF I never always did the right thing, but all I did wasn't wrong... Last edited by Fabian; 02-17-2023 at 12:40 PM. |
|
02-18-2023, 11:40 AM | #18 | |
Human being with feelings
Join Date: Sep 2008
Location: Sweden
Posts: 7,417
|
Quote:
This also explains why it wasn't necessary to scale the lum variable by 255, as I suggested above.
__________________
// MVHMF I never always did the right thing, but all I did wasn't wrong... Last edited by Fabian; 02-18-2023 at 12:10 PM. |
|
02-18-2023, 12:44 PM | #19 |
Human being with feelings
Join Date: Dec 2012
Posts: 7,272
|
Weird. Glad you fingered it out! It’s strangish to me, because I’m working with gfx in JS atm and when I saw your post yesterday I realized I need to scale things coming out of getpixel to work properly, and it does. So I guess that’s another one of those weird little things which are different between JS and VP?!?
__________________
Lorenzo's Tractor is Everywhere --- Ash's Tube --- Join the Partnership for a Drum Free Amerika |
02-18-2023, 12:54 PM | #20 | |
Human being with feelings
Join Date: Sep 2008
Location: Sweden
Posts: 7,417
|
Quote:
Code:
Video processor: gfx_blit(input[,preserve_aspect=0,x,y,w,h,srcx,srcy,srcw,srch]) JSFX: gfx_blit(source, scale, rotation[, srcx, srcy, srcw, srch, destx, desty, destw, desth, rotxoffs, rotyoffs])
__________________
// MVHMF I never always did the right thing, but all I did wasn't wrong... |
|
02-18-2023, 01:32 PM | #21 |
Human being with feelings
Join Date: Dec 2012
Posts: 7,272
|
Yeah I think blit in JS is more like rotoblit, though I haven’t messed with it much. I think I vaguely remember a mismatch when I was passing pixels back and forth via gmem, now that we mention it…
__________________
Lorenzo's Tractor is Everywhere --- Ash's Tube --- Join the Partnership for a Drum Free Amerika |
02-19-2023, 07:50 AM | #22 | |
Human being with feelings
Join Date: Aug 2020
Location: Brasil
Posts: 679
|
Quote:
Code:
gfx_blit( source_input_id, 0, //let me control the output targetXdest, targetYdest,targetWidth,targetHeight, xOffsetInSourceBitmap,YOffsetInSourceBitmap, Width2copyfromSource,Heigth2CopyFromSource ); // or the alternative gfx_img_resize(-1,targetWidth,targetHeight); gfx_blit(source_input); Last edited by papagirafe; 02-19-2023 at 09:33 AM. |
|
Thread Tools | |
Display Modes | |
|
|