Old 12-03-2018, 08:40 AM   #1
Justin
Administrator
 
Justin's Avatar
 
Join Date: Jan 2005
Location: NYC
Posts: 15,721
Default Color correction WIP thread

Here's an RGB script that allows you to tweak RGB values for blacks/shadows/midtones/hilight/whites:
Code:
// Shadow/midtone/highlight RGB adjust
//@param 1:fade 'alpha' 1

//@param 2:black.r 'black R' 0 -256 256 0 1
//@param 3:black.g 'black G' 0 -256 256 0 1
//@param 4:black.b 'black B' 0 -256 256 0 1

//@param 5:shadow.r 'shadow R' 0 -256 256 0 1
//@param 6:shadow.g 'shadow G' 0 -256 256 0 1
//@param 7:shadow.b 'shadow B' 0 -256 256 0 1

//@param 8:midtone.r 'midtone R' 0 -256 256 0 1
//@param 9:midtone.g 'midtone G' 0 -256 256 0 1
//@param 10:midtone.b 'midtone B' 0 -256 256 0 1

//@param 11:highlight.r 'highlight R' 0 -256 256 0 1
//@param 12:highlight.g 'highlight G' 0 -256 256 0 1
//@param 13:highlight.b 'highlight B' 0 -256 256 0 1

//@param 14:white.r 'white R' 0 -256 256 0 1
//@param 15:white.g 'white G' 0 -256 256 0 1
//@param 16:white.b 'white B' 0 -256 256 0 1

black.pos = 0;
shadow.pos = 64;
midtone.pos = 128;
highlight.pos = 192;
white.pos = 256;

function mk(i, low*, hi*) local (idx) (
  idx=i*3;
  i = (i - low.pos) / (hi.pos - low.pos);
  idx[0] = (i * hi.r + (1-i)*low.r)*fade;
  idx[1] = (i * hi.g + (1-i)*low.g)*fade;
  idx[2] = (i * hi.b + (1-i)*low.b)*fade;
);

fade > 0 ? (
  i = 0;
  loop(256,
    i <= shadow.pos ? mk(i,black,shadow) :
     i <= midtone.pos ? mk(i,shadow,midtone) :
       i <= highlight.pos ? mk(i,midtone,highlight) :
         mk(i,highlight,white);
    i+=1;
  );

  input_info(0,project_w,project_h);
  gfx_blit(0);
  colorspace='RGBA';
  gfx_evalrect(0,0,project_w,project_h,"
    _1 = floor(0.299*r + 0.587*g + 0.114*b+0.5)*3;
    r = min(max(r+_1[0],0),255);
    g = min(max(g+_1[1],0),255);
    b = min(max(b+_1[2],0),255);
  ");
);
(OK maybe it's time to increase the maximum parameter count from 16...)

Last edited by Justin; 12-03-2018 at 08:51 AM. Reason: Cleanup style slightly
Justin is offline   Reply With Quote
Old 12-03-2018, 08:48 AM   #2
Eliseat
Human being with feelings
 
Eliseat's Avatar
 
Join Date: Mar 2018
Location: Cologne
Posts: 1,362
Default

Holy ...!

AWESOME!

No time for the kids. Must test new preset!

Many thanks
Eliseat is offline   Reply With Quote
Old 12-03-2018, 09:26 AM   #3
EpicSounds
Human being with feelings
 
EpicSounds's Avatar
 
Join Date: Jul 2009
Posts: 7,568
Default

(OK maybe it's time to increase the maximum parameter count from 16...)

yes, or a real UI by v6.0
maybe allow typing parameter values in the meantime?

Only quickly tested but I'd say this works quite nicely!
Pretty choppy on my iphone video I tested with but I kinda expect that.

I think it could be split into a couple simpler tools as well.

One could just be to desaturate black with controls for threshold and strength (rgb on one knob).

another could be Black, shadow, midtone, highlight, white balance. just 5 knobs.

I don't think you can give us too many presets
__________________
REAPER Video Tutorials, Tips & Tricks and more at The REAPER Blog
EpicSounds is online now   Reply With Quote
Old 12-03-2018, 11:20 AM   #4
Justin
Administrator
 
Justin's Avatar
 
Join Date: Jan 2005
Location: NYC
Posts: 15,721
Default

Hmm desaturate black would be easy to do in YUV space, mmm...
Justin is offline   Reply With Quote
Old 12-03-2018, 03:44 PM   #5
X-Raym
Human being with feelings
 
X-Raym's Avatar
 
Join Date: Apr 2013
Location: France
Posts: 9,875
Default

Very nice to have these features !



It's a bit intensive on the CPU for videos from my camera (50 Mb/s), so there is drop frames but it is smooth on video from my smartphone.


Though, this doesn't behave like a usual RGB slider


Here is a demo on the influence area:




As you can see, there is clearly defined area (which can be when the point is shift, sometimes there isn't even gradient anymore between non colored and colored on the screenshot)

A usual RGB slider would behaves more like this



(slider is for dark tones, mid tones and then high tones)

As you can see, every slider affects the whole specturm of the image.

Here is an exemple of influence curve in Filmlight Baselight (one of the only representation I found)


(in this exemple, shadows and highlights curve have some easing but it could simply be linear)

As you can see, adjusting shadows or highlights will influence the whole specturm (but more shadows/highlight obviously). This prevent having banding effects or artefacts, it is smoother on live footage.


EDIT: exemple from Magic bullet

See the influence curve at the bottom. Each "bands" affects the whole color spectrum.

Last edited by X-Raym; 12-03-2018 at 04:10 PM.
X-Raym is offline   Reply With Quote
Old 12-03-2018, 04:15 PM   #6
EpicSounds
Human being with feelings
 
EpicSounds's Avatar
 
Join Date: Jul 2009
Posts: 7,568
Default

Justin I think this needs some overlap between bands. Don't know how much but there should be a slight transition between shadow and midtones etc.
__________________
REAPER Video Tutorials, Tips & Tricks and more at The REAPER Blog
EpicSounds is online now   Reply With Quote
Old 12-03-2018, 04:20 PM   #7
X-Raym
Human being with feelings
 
X-Raym's Avatar
 
Join Date: Apr 2013
Location: France
Posts: 9,875
Default

From the great Color Correction Handbook by Alexis Van Hurkman:




So in fact it doesn't behaves like strict bands, each pixels is influence by every slider (shadows/midtones/highlights).
X-Raym is offline   Reply With Quote
Old 12-03-2018, 05:34 PM   #8
Justin
Administrator
 
Justin's Avatar
 
Join Date: Jan 2005
Location: NYC
Posts: 15,721
Default

awesome thank you, that's very helpful! I'm going to do some tweaks

(edit) here you go:
Code:
// Shadow/midtone/highlight RGB adjust
//@param 1:fade 'alpha' 1

//@param 3:r.shadow 'shadow R' 0 -256 256 0 1
//@param 4:g.shadow 'shadow G' 0 -256 256 0 1
//@param 5:b.shadow 'shadow B' 0 -256 256 0 1

//@param 6:r.midtone 'midtone R' 0 -256 256 0 1
//@param 7:g.midtone 'midtone G' 0 -256 256 0 1
//@param 8:b.midtone 'midtone B' 0 -256 256 0 1

//@param 9:r.highlight 'highlight R' 0 -256 256 0 1
//@param 10:g.highlight 'highlight G' 0 -256 256 0 1
//@param 11:b.highlight 'highlight B' 0 -256 256 0 1

//@param 13:showc 'show curves' 0 0 1 0.5 1
//@param 14:shadow_curve 'shadow steepness' 1 .5 4 1 .01
//@param 15:midtone_curve 'midtone steepness' 1 .25 4 1 .01
//@param 16:highlight_curve 'highlight steepness' 1 .5 4 1 .01

function curve(w, i) (
  w==2?(i/256)^highlight_curve:
  w==1?sin(i*$pi/256)^midtone_curve:
  w==0?(1-i/256)^shadow_curve;
);

function mk(i, chan*) (
  curve(0,i)*chan.shadow +
  curve(1,i)*chan.midtone +
  curve(2,i)*chan.highlight;
);

fade > 0 || showc ? (
  input_info(0,project_w,project_h);
  gfx_blit(0);
  fade > 0 ? (
    i = v = 0;
    loop(256,
      i[0] = mk(v,r)*fade;
      i[1] = mk(v,g)*fade;
      i[2] = mk(v,b)*fade;
      v+=1; i+=3;
    );  
    colorspace='RGBA';
    gfx_evalrect(0,0,project_w,project_h,"
      _1 = floor(0.299*r + 0.587*g + 0.114*b+0.5)*3;
      r = min(max(r+_1[0],0),255);
      g = min(max(g+_1[1],0),255);
      b = min(max(b+_1[2],0),255);
    ");
  );
  showc ? (
    x = 32; y = 32;
    ysz = 200;
    gfx_set(0,0,0,0.85);
    gfx_fillrect(x,y,512,ysz);
    p=0;
    loop(3,
      i=0;
      gfx_set(.25+.5*p);
      gfx_a=0.3;
      loop(256,
        v=curve(p,i)*ysz;
        gfx_fillrect(x+i*2,y+ysz-v,2,v);
        i+=1;
      );
      p+=1;
    );
  );
);

Last edited by Justin; 12-03-2018 at 07:14 PM. Reason: oops that was completely broken, and more gbugixesf
Justin is offline   Reply With Quote
Old 12-03-2018, 07:57 PM   #9
Justin
Administrator
 
Justin's Avatar
 
Join Date: Jan 2005
Location: NYC
Posts: 15,721
Default

Here's one that does YV12-based shadow/midtone/highlight, giving luminance, saturation, and hue controls for each.

Code:
// Shadow/midtone/highlight lum/hue/saturation adjust
//@param 1:fade 'alpha' 1

//@param 3:y.shadow 'shadow lum' 0 -256 256 0 1
//@param 4:h.shadow 'shadow hue' 0 -360 360 0 1
//@param 5:s.shadow 'shadow sat' 1 0 8 2 .01

//@param 6:y.midtone 'midtone lum' 0 -256 256 0 1
//@param 7:h.midtone 'midtone hue' 0 -360 360 0 1
//@param 8:s.midtone 'midtone sat' 1 0 8 2 .01

//@param 9:y.highlight 'highlight lum' 0 -256 256 0 1
//@param 10:h.highlight 'highlight hue' 0 -360 360 0 1
//@param 11:s.highlight 'highlight sat'1 0 8 2 .01

//@param 13:showc 'show curves' 0 0 1 0.5 1
//@param 14:shadow_curve 'shadow steepness' 1 .5 4 1 .01
//@param 15:midtone_curve 'midtone steepness' 1 .25 4 1 .01
//@param 16:highlight_curve 'highlight steepness' 1 .5 4 1 .01

function curve(w, i) (
  w==2?(i/256)^highlight_curve:
  w==1?sin(i*$pi/256)^midtone_curve:
  w==0?(1-i/256)^shadow_curve;
);

function mk(i, chan*) (
  curve(0,i)*chan.shadow +
  curve(1,i)*chan.midtone +
  curve(2,i)*chan.highlight;
);

fade > 0 || showc ? (
  input_info(0,project_w,project_h);
  gfx_blit(0);
  fade > 0 ? (
    i = v = 0;
    has_y=has_h=has_v=0;
    loop(256,
      (i[0] = mk(v,y)*fade) != 0 ? has_y = 1;
      (i[1] = mk(v,h)*fade * $pi/180) != 0 ? has_h=1;
      (i[2] = (mk(v,s)*fade + 1-fade)) != 1 ? has_s=1;
      v+=1; i+=4;
    );  
    colorspace='YV12';
    #code = "";
    has_h || has_s ? (
      has_h ? (
        sprintf(#code, "%s
          _2=atan2(u-128,v-128) + (_1=(y1+y2+y3+y4)&-4)[1];
          _3=sqrt(sqr(u-128)+sqr(v-128)) %s;
          u=min(max(sin(_2)*_3+128,0),255);
          v=min(max(cos(_2)*_3+128,0),255);
        ",#code,has_s ? " * _1[2]" : "");
      ) : #code += "
        _3=((y1+y2+y3+y4)&-4)[2];
        u=min(max((u-128)*_3+128,0),255);
        v=min(max((v-128)*_3+128,0),255);
      ";      
    );
    has_y ? #code += 
     "y1 = min(max(y1+(y1*4)[],0),255);
      y2 = min(max(y2+(y2*4)[],0),255);
      y3 = min(max(y3+(y3*4)[],0),255);
      y4 = min(max(y4+(y4*4)[],0),255);";
    
    gfx_evalrect(0,0,project_w,project_h,#code);
  );
  showc ? (
    x = 32; y = 32;
    ysz = 200;
    gfx_set(0,0,0,0.85);
    gfx_fillrect(x,y,512,ysz);
    p=0;
    loop(3,
      i=0;
      gfx_set(.75);
      gfx_a=0.4;
      loop(256,
        v=curve(p,i)*ysz;
        gfx_fillrect(x+i*2,y+ysz-v,2,v);
        i+=1;
      );
      p+=1;
    );
  );
);
It's reasonably fast (still slow) when doing luminance changes, slower when also changing saturation, and very, very slow when changing hue.

I'm 100% sure this would be better implemented using matrices...

Last edited by Justin; 12-03-2018 at 08:42 PM.
Justin is offline   Reply With Quote
Old 12-03-2018, 09:43 PM   #10
Justin
Administrator
 
Justin's Avatar
 
Join Date: Jan 2005
Location: NYC
Posts: 15,721
Default

...err it's actually a nice subset of matrix math that's even easier. Here's we go:
Code:
// Shadow/midtone/highlight hue/saturation/luminance adjust
//@param 1:fade 'fade' 1

//@param 3:h.shadow 'shadow hue' 0 -360 360 0 1
//@param 4:s.shadow 'shadow saturation' 1 0 8 1 .01
//@param 5:y.shadow 'shadow luminance' 0 -256 256 0 1

//@param 6:h.midtone 'midtone hue' 0 -360 360 0 1
//@param 7:s.midtone 'midtone saturation' 1 0 8 1 .01
//@param 8:y.midtone 'midtone luminance' 0 -256 256 0 1

//@param 9:h.highlight 'highlight hue' 0 -360 360 0 1
//@param 10:s.highlight 'highlight saturation'1 0 8 1 .01
//@param 11:y.highlight 'highlight luminance' 0 -256 256 0 1

//@param 13:showc 'show curves' 0 0 1 0.5 1
//@param 14:shadow_curve 'shadow steepness' 1 .5 8 1 .01
//@param 15:midtone_curve 'midtone steepness' 1 .125 8 1 .01
//@param 16:highlight_curve 'highlight steepness' 1 .5 8 1 .01

function curve(w, i) (
  w==2?(i/256)^highlight_curve:
  w==1?sin(i*$pi/256)^midtone_curve:
  w==0?(1-i/256)^shadow_curve;
);

fade > 0 || showc ? (
  input_info(0,project_w,project_h);
  gfx_blit(0);
  fade > 0 ? (
    i = v = 0;
    colorspace='YV12';

    loop(256,
      i[0] = fade * (curve(0,v)*y.shadow + curve(1,v)*y.midtone + curve(2,v)*y.highlight);

      i[1] = sat = 1 + fade*(
            (1 + curve(0,v) * (s.shadow - 1)) *
            (1 + curve(1,v) * (s.midtone - 1)) *
            (1 + curve(2,v) * (s.highlight - 1)) - 1);

      ang = (curve(0,v)*h.shadow + curve(1,v)*h.midtone + curve(2,v)*h.highlight) * $pi/180 * fade;
      i[2] = cos(ang)*sat;
      i[3] = sin(ang)*sat;
      v+=1; i+=4;
    );
    #code = "";

    h.shadow || h.midtone || h.highlight ? (
      #code += "
        _1=((y1+y2+y3+y4)&-4);
        u=min(max((_4=(u-128))*(_2=_1[2])+(v-128)*(_3=_1[3])+128,0),255);
        v=min(max((v-128)*_2-_4*_3+128,0),255);
      ";
    ) : s.shadow!=1 || s.midtone!=1 || s.highlight!=1 ? (
      #code += "
        _3=((y1+y2+y3+y4)&-4)[1];
        u=min(max((u-128)*_3+128,0),255);
        v=min(max((v-128)*_3+128,0),255);
      ";
    );

    y.shadow || y.midtone || y.highlight ? #code +=
     "y1 = min(max(y1+(y1*4)[],0),255);
      y2 = min(max(y2+(y2*4)[],0),255);
      y3 = min(max(y3+(y3*4)[],0),255);
      y4 = min(max(y4+(y4*4)[],0),255);";

    gfx_evalrect(0,0,project_w,project_h,#code);
  );
  showc ? (
    x = 32; y = 32;
    ysz = 200;
    gfx_set(0,0,0,0.85);
    gfx_fillrect(x,y,512,ysz);
    p=0;
    loop(3,
      i=0;
      gfx_set(.75);
      gfx_a=0.4;
      loop(256,
        v=curve(p,i)*ysz;
        gfx_fillrect(x+i*2,y+ysz-v,2,v);
        i+=1;
      );
      p+=1;
    );
  );
);
(still slow at times, but give that a go?)

Last edited by Justin; 12-04-2018 at 09:12 AM. Reason: a few minor tweaks to knobs
Justin is offline   Reply With Quote
Old 12-04-2018, 02:41 AM   #11
Eliseat
Human being with feelings
 
Eliseat's Avatar
 
Join Date: Mar 2018
Location: Cologne
Posts: 1,362
Default

Can't believe whats going on.

This is very promising. Video in Reaper gets more and more fun. And with presets like that it also gets more and more serious.

Many thanks.

BTW: Would it be possible to make the video processor buttons react to the mouse wheel? Like the project tempo adjustment some versions ago? (That was awesome!)
Eliseat is offline   Reply With Quote
Old 12-04-2018, 04:19 AM   #12
X-Raym
Human being with feelings
 
X-Raym's Avatar
 
Join Date: Apr 2013
Location: France
Posts: 9,875
Default

Shadow/midtone/highlight RGB adjust gives way more good results, very nice

Shadow/midtone/highlight, giving luminance, saturation v1, and hue is good but it isn't neutral with default default values. Simply putting in on an image will increase the saturation, which isn't expected.

The v2 had good default behavior, but I'm not sure the influence are good,
As you can see, changing shadows hues also changes highlights hues drastically (it should rotate highlights hue also, but less, as shown on the influence curve).
https://i.imgur.com/dcErTJX.gifv

Here is on Premiere Pro Lumetri:
Link.

As you can see, Shadows influence (and other 'bands') are less extreme on the others. It does influence though.

Quote:
Originally Posted by Eliseat
BTW: Would it be possible to make the video processor buttons react to the mouse wheel? Like the project tempo adjustment some versions ago?
+1 !
X-Raym is offline   Reply With Quote
Old 12-04-2018, 08:24 AM   #13
Justin
Administrator
 
Justin's Avatar
 
Join Date: Jan 2005
Location: NYC
Posts: 15,721
Default

Quote:
Originally Posted by X-Raym View Post
Shadow/midtone/highlight RGB adjust gives way more good results, very nice

Shadow/midtone/highlight, giving luminance, saturation v1, and hue is good but it isn't neutral with default default values. Simply putting in on an image will increase the saturation, which isn't expected.

The v2 had good default behavior, but I'm not sure the influence are good,
As you can see, changing shadows hues also changes highlights hues drastically (it should rotate highlights hue also, but less, as shown on the influence curve).
https://i.imgur.com/dcErTJX.gifv

Here is on Premiere Pro Lumetri:
Link.

As you can see, Shadows influence (and other 'bands') are less extreme on the others. It does influence though.



+1 !
Hmm it might be part of the issue that you are applying *really* big hue adjustments -- if you adjust the shadow hue by 180 degrees, the few percent of that which ends up being applied to the mid/hi areas is still quite a lot... Try smaller hue adjustments, and also try steepening the shadow curve?

Last edited by Justin; 12-04-2018 at 09:08 AM.
Justin is offline   Reply With Quote
Old 12-04-2018, 09:21 AM   #14
Justin
Administrator
 
Justin's Avatar
 
Join Date: Jan 2005
Location: NYC
Posts: 15,721
Default

Hmm using sine curves for the shadow/highlight also improves things, I think:
Code:
// Shadow/midtone/highlight hue/saturation/luminance adjust
//@param 1:fade 'fade' 1

//@param 3:h.shadow 'shadow hue' 0 -360 360 0 1
//@param 4:s.shadow 'shadow saturation' 1 0 8 1 .01
//@param 5:y.shadow 'shadow luminance' 0 -256 256 0 1

//@param 6:h.midtone 'midtone hue' 0 -360 360 0 1
//@param 7:s.midtone 'midtone saturation' 1 0 8 1 .01
//@param 8:y.midtone 'midtone luminance' 0 -256 256 0 1

//@param 9:h.highlight 'highlight hue' 0 -360 360 0 1
//@param 10:s.highlight 'highlight saturation'1 0 8 1 .01
//@param 11:y.highlight 'highlight luminance' 0 -256 256 0 1

//@param 13:showc 'show curves' 0 0 1 0.5 1
//@param 14:shadow_curve 'shadow steepness' 1 .5 8 1 .01
//@param 15:midtone_curve 'midtone steepness' 1 .125 8 1 .01
//@param 16:highlight_curve 'highlight steepness' 1 .5 8 1 .01

function curve(w, i) (
  w==2?(cos((256-i)/256*$pi)*.5+.5)^highlight_curve:
  w==1?sin(i*$pi/256)^midtone_curve:
  w==0?(cos(i/256*$pi)*.5+.5)^shadow_curve;
);

fade > 0 || showc ? (
  input_info(0,project_w,project_h);
  gfx_blit(0);
  fade > 0 ? (
    i = v = 0;
    colorspace='YV12';

    loop(256,
      i[0] = fade * (curve(0,v)*y.shadow + curve(1,v)*y.midtone + curve(2,v)*y.highlight);

      i[1] = sat = 1 + fade*(
            (1 + curve(0,v) * (s.shadow - 1)) *
            (1 + curve(1,v) * (s.midtone - 1)) *
            (1 + curve(2,v) * (s.highlight - 1)) - 1);

      ang = (curve(0,v)*h.shadow + curve(1,v)*h.midtone + curve(2,v)*h.highlight) * $pi/180 * fade;
      i[2] = cos(ang)*sat;
      i[3] = sin(ang)*sat;
      v+=1; i+=4;
    );
    
    #code = "";

    h.shadow || h.midtone || h.highlight ? (
      #code += "
        _1=((y1+y2+y3+y4)&-4);
        u=min(max((_4=(u-128))*(_2=_1[2])+(v-128)*(_3=_1[3])+128,0),255);
        v=min(max((v-128)*_2-_4*_3+128,0),255);
      ";
    ) : s.shadow!=1 || s.midtone!=1 || s.highlight!=1 ? (
      #code += "
        _3=((y1+y2+y3+y4)&-4)[1];
        u=min(max((u-128)*_3+128,0),255);
        v=min(max((v-128)*_3+128,0),255);
      ";
    );

    y.shadow || y.midtone || y.highlight ? #code +=
     "y1 = min(max(y1+(y1*4)[],0),255);
      y2 = min(max(y2+(y2*4)[],0),255);
      y3 = min(max(y3+(y3*4)[],0),255);
      y4 = min(max(y4+(y4*4)[],0),255);";

    gfx_evalrect(0,0,project_w,project_h,#code);
  );
  showc ? (
    x = 32; y = 32;
    ysz = 200;
    gfx_set(0,0,0,0.85);
    gfx_fillrect(x,y,512,ysz);
    p=0;
    loop(3,
      i=0;
      gfx_set(.75);
      gfx_a=0.4;
      loop(256,
        v=curve(p,i)*ysz;
        gfx_fillrect(x+i*2,y+ysz-v,2,v);
        i+=1;
      );
      p+=1;
    );
  );
);
Edit: not really, makes other things less usable. hmmmmm

Last edited by Justin; 12-04-2018 at 10:14 AM.
Justin is offline   Reply With Quote
Old 12-04-2018, 10:43 AM   #15
Justin
Administrator
 
Justin's Avatar
 
Join Date: Jan 2005
Location: NYC
Posts: 15,721
Default

Here's some tweaks to the curves (can go between linear and sine-based):

Code:
// Shadow/midtone/highlight hue/saturation/luminance adjust
//@param 1:fade 'fade' 1

//@param 3:h.shadow 'shadow hue' 0 -360 360 0 1
//@param 4:s.shadow 'shadow saturation' 1 0 8 1 .01
//@param 5:y.shadow 'shadow luminance' 0 -256 256 0 1

//@param 6:h.midtone 'midtone hue' 0 -360 360 0 1
//@param 7:s.midtone 'midtone saturation' 1 0 8 1 .01
//@param 8:y.midtone 'midtone luminance' 0 -256 256 0 1

//@param 9:h.highlight 'highlight hue' 0 -360 360 0 1
//@param 10:s.highlight 'highlight saturation'1 0 8 1 .01
//@param 11:y.highlight 'highlight luminance' 0 -256 256 0 1

//@param 13:showc 'show curves' 0 0 1 0.5 1
//@param 14:shadow_curve 'shadow steepness' 1 0 8 1 .01
//@param 15:midtone_curve 'midtone steepness' 1 .125 8 1 .01
//@param 16:highlight_curve 'highlight steepness' 1 0 8 1 .01

function scurve(i) local(t) ( 
  t = (cos(i*$pi)*.5+.5)^shadow_curve;
  shadow_curve < 1 ? shadow_curve*t + (1-i)*(1-shadow_curve): t;
);
function hcurve(i) ( 
  t = (cos((1-i)*$pi)*.5+.5)^highlight_curve;
  highlight_curve < 1 ? highlight_curve*t + i*(1-highlight_curve): t;
);
function mcurve(i) ( sin(i*$pi)^midtone_curve );

fade > 0 || showc ? (
  input_info(0,project_w,project_h);
  gfx_blit(0);
  fade > 0 ? (
    i = vv = 0;
    colorspace='YV12';

    loop(256,
      v = min(max((vv-16)/224,0),1);
      i[0] = fade * (scurve(v)*y.shadow + mcurve(v)*y.midtone + hcurve(v)*y.highlight);

      i[1] = sat = 1 + fade*(
            (1 + scurve(v) * (s.shadow - 1)) *
            (1 + mcurve(v) * (s.midtone - 1)) *
            (1 + hcurve(v) * (s.highlight - 1)) - 1);

      ang = (scurve(v)*h.shadow + mcurve(v)*h.midtone + hcurve(v)*h.highlight) * $pi/180 * fade;
      i[2] = cos(ang)*sat;
      i[3] = sin(ang)*sat;
      i+=4;
      vv+=1;     
    );
    #code = "";

    h.shadow || h.midtone || h.highlight ? (
      #code += "
        _1=((y1+y2+y3+y4)&-4);
        u=min(max((_4=(u-128))*(_2=_1[2])+(v-128)*(_3=_1[3])+128,0),255);
        v=min(max((v-128)*_2-_4*_3+128,0),255);
      ";
    ) : s.shadow!=1 || s.midtone!=1 || s.highlight!=1 ? (
      #code += "
        _3=((y1+y2+y3+y4)&-4)[1];
        u=min(max((u-128)*_3+128,0),255);
        v=min(max((v-128)*_3+128,0),255);
      ";
    );

    y.shadow || y.midtone || y.highlight ? #code +=
     "y1 = min(max(y1+(y1*4)[],0),255);
      y2 = min(max(y2+(y2*4)[],0),255);
      y3 = min(max(y3+(y3*4)[],0),255);
      y4 = min(max(y4+(y4*4)[],0),255);";

    gfx_evalrect(0,0,project_w,project_h,#code);
  );
  showc ? (
    x = 32; y = 32;
    ysz = 200;
    gfx_set(0,0,0,0.85);
    gfx_fillrect(x,y,512,ysz);
    gfx_set(.75);
    gfx_a=0.4;
    i=0; loop(256, v=ysz*scurve(i/256); gfx_fillrect(x+i*2,y+ysz-v,2,v); i+=1; );
    i=0; loop(256, v=ysz*mcurve(i/256); gfx_fillrect(x+i*2,y+ysz-v,2,v); i+=1; );
    i=0; loop(256, v=ysz*hcurve(i/256); gfx_fillrect(x+i*2,y+ysz-v,2,v); i+=1; );
  );
);
Edit: also made it use 16-240 as the Y range (since that's what video is ultimately encoded in in YV12).

Last edited by Justin; 12-04-2018 at 05:04 PM.
Justin is offline   Reply With Quote
Old 12-04-2018, 03:52 PM   #16
X-Raym
Human being with feelings
 
X-Raym's Avatar
 
Join Date: Apr 2013
Location: France
Posts: 9,875
Default

@Justin
Curve steepness is cool !


For hues, considering the cyclic nature of this parameter, I would expect -360 to give the same results as +360, but it is not the case with previous presets.


How come ?
X-Raym is offline   Reply With Quote
Old 12-04-2018, 05:27 PM   #17
Justin
Administrator
 
Justin's Avatar
 
Join Date: Jan 2005
Location: NYC
Posts: 15,721
Default

Quote:
Originally Posted by X-Raym View Post
@Justin
Curve steepness is cool !


For hues, considering the cyclic nature of this parameter, I would expect -360 to give the same results as +360, but it is not the case with previous presets.


How come ?
It is the same when it is at -360, but the path it takes when fading back to 0 (as you get less and less influence) is different (backwards)
Justin is offline   Reply With Quote
Old 12-04-2018, 06:11 PM   #18
Philbo King
Human being with feelings
 
Philbo King's Avatar
 
Join Date: May 2017
Posts: 3,201
Default

Wow, quite cool!

Have you considered a gamma curve control?
(Yeah, I know, pretty of bells & whistles on this already... Just thought I'd ask)
__________________
Tangent Studio - Philbo King
www.soundclick.com/philboking - Audio streams
Philbo King is offline   Reply With Quote
Old 12-04-2018, 07:51 PM   #19
Justin
Administrator
 
Justin's Avatar
 
Join Date: Jan 2005
Location: NYC
Posts: 15,721
Default

Here's the HSL one with gamma correction (you can adjust the gamma curve for the image, and for the S/M/H separately):

Code:
// Shadow/midtone/highlight hue/saturation/luminance adjust
//@param 1:fade 'fade' 1
//@param 2:gamma 'gamma correct' 1 .1 4 1 .01

//@param 3:h.shadow 'shadow hue' 0 -360 360 0 1
//@param 4:s.shadow 'shadow saturation' 1 0 8 1 .01
//@param 5:y.shadow 'shadow luminance' 0 -256 256 0 1

//@param 6:h.midtone 'midtone hue' 0 -360 360 0 1
//@param 7:s.midtone 'midtone saturation' 1 0 8 1 .01
//@param 8:y.midtone 'midtone luminance' 0 -256 256 0 1

//@param 9:h.highlight 'highlight hue' 0 -360 360 0 1
//@param 10:s.highlight 'highlight saturation'1 0 8 1 .01
//@param 11:y.highlight 'highlight luminance' 0 -256 256 0 1

//@param 12:showc 'show curves' 0 0 1 0.5 1
//@param 13:cgamma 'curve gamma' 1 .1 4 1 .01
//@param 14:shadow_curve 'shadow steepness' 1 0 8 1 .01
//@param 15:midtone_curve 'midtone steepness' 1 .125 8 1 .01
//@param 16:highlight_curve 'highlight steepness' 1 0 8 1 .01

function scurve(i) local(t) ( 
  i^=cgamma;
  t = (cos(i*$pi)*.5+.5)^shadow_curve;
  shadow_curve < 1 ? shadow_curve*t + (1-i)*(1-shadow_curve): t;
);
function hcurve(i) ( 
  i^=cgamma;
  t = (cos((1-i)*$pi)*.5+.5)^highlight_curve;
  highlight_curve < 1 ? highlight_curve*t + i*(1-highlight_curve): t;
);
function mcurve(i) ( sin((i^cgamma)*$pi)^midtone_curve );

fade > 0 || showc ? (
  input_info(0,project_w,project_h);
  gfx_blit(0);
  fade > 0 ? (
    i = vv = 0;
    colorspace='YV12';

    loop(256,
      v = min(max((vv-16)/224,0),1);
      i[0] = fade * (scurve(v)*y.shadow + mcurve(v)*y.midtone + hcurve(v)*y.highlight);

      i[1] = sat = 1 + fade*(
            (1 + scurve(v) * (s.shadow - 1)) *
            (1 + mcurve(v) * (s.midtone - 1)) *
            (1 + hcurve(v) * (s.highlight - 1)) - 1);

      ang = (scurve(v)*h.shadow + mcurve(v)*h.midtone + hcurve(v)*h.highlight) * $pi/180 * fade;
      i[2] = cos(ang)*sat;
      i[3] = sin(ang)*sat;
      i+=4;
      vv[1024] = 256 * (vv/256)^gamma;
      vv+=1;   
    );
    #code = "";

    h.shadow || h.midtone || h.highlight ? (
      #code += "
        _1=((y1+y2+y3+y4)&-4);
        u=min(max((_4=(u-128))*(_2=_1[2])+(v-128)*(_3=_1[3])+128,0),255);
        v=min(max((v-128)*_2-_4*_3+128,0),255);
      ";
    ) : s.shadow!=1 || s.midtone!=1 || s.highlight!=1 ? (
      #code += "
        _3=((y1+y2+y3+y4)&-4)[1];
        u=min(max((u-128)*_3+128,0),255);
        v=min(max((v-128)*_3+128,0),255);
      ";
    );
    gstr = gamma != 1.0 ? "[1024]" : "";
    y.shadow || y.midtone || y.highlight ? #code += sprintf(#,
       "y1 = min(max(y1%s+(y1*4)[],0),255);
        y2 = min(max(y2%s+(y2*4)[],0),255);
        y3 = min(max(y3%s+(y3*4)[],0),255);
        y4 = min(max(y4%s+(y4*4)[],0),255);",gstr,gstr,gstr,gstr) :
      gamma!=1.0 ? #code += "y1 = y1[1024]; y2=y2[1024]; y3=y3[1024]; y4=y4[1024];";
       

    gfx_evalrect(0,0,project_w,project_h,#code);
  );
  showc ? (
    x = 32; y = 32;
    ysz = 200;
    gfx_set(0,0,0,0.85);
    gfx_fillrect(x,y,512,ysz);
    gfx_set(.75);
    gfx_a=0.4;
    i=0; loop(256, v=ysz*scurve(i/256); gfx_fillrect(x+i*2,y+ysz-v,2,v); i+=1; );
    i=0; loop(256, v=ysz*mcurve(i/256); gfx_fillrect(x+i*2,y+ysz-v,2,v); i+=1; );
    i=0; loop(256, v=ysz*hcurve(i/256); gfx_fillrect(x+i*2,y+ysz-v,2,v); i+=1; );
  );
);
Justin is offline   Reply With Quote
Old 12-04-2018, 11:58 PM   #20
X-Raym
Human being with feelings
 
X-Raym's Avatar
 
Join Date: Apr 2013
Location: France
Posts: 9,875
Default

I'm starting to wonder if it is not the use of the YUV space which leads to difference I see between this presets and other video software I'm comparing too.



For eg the new gamma slider,
Per definition it should not affect pure black and pur white pixel, just pixel inbetween,


Source image:


Though we can see on last preset that white isn't pure white anymore:


And here the influence of the Gamma level in DaVinci Resolve when we also set to lowest value:



And here is in premiere pro, Gamma Correction set to maximum

Closer to DaVinci resolve than last video processor preset (as you can see white are also preserved) (it just seems more intense, but doesn't seem to process differently).
X-Raym is offline   Reply With Quote
Old 12-05-2018, 06:18 AM   #21
Bri1
Banned
 
Join Date: Dec 2016
Location: England
Posts: 2,432
Default

ello->



um- seriously think devs need to reconsider some options after viewing this next video-please take notice!!!

this was 1st realised a few years ago by the blender and colour management communities-> solutions are being resolved in the next stable blender updates!!

cheerz.



go aces/filmic plz!

Last edited by Bri1; 12-05-2018 at 06:34 AM. Reason: 1xtra
Bri1 is offline   Reply With Quote
Old 12-05-2018, 08:50 AM   #22
Philbo King
Human being with feelings
 
Philbo King's Avatar
 
Join Date: May 2017
Posts: 3,201
Default

Quote:
Originally Posted by Bri1 View Post
ello->



um- seriously think devs need to reconsider some options after viewing this next video-please take notice!!!

this was 1st realised a few years ago by the blender and colour management communities-> solutions are being resolved in the next stable blender updates!!

cheerz.



go aces/filmic plz!
[Edit - Sorry for this rambling and thread derailing post. I got inspired by Bri's video... ]

This is a very technical (and application specific) video, but it addresses stuff that I've struggled with in the past in a very interesting way.

One example (related only to intensity, not color): In the '90s I was tasked with designing a circuit board for measuring the ambient light in a Boeing 777 cockpit. It sounds trivial but wasn't. The light varies by an amazing amount, from flying over the ocean in an overcast night with no moon to flying with the sun shining directly into the pilots eyes. This represents a huge dynamic range of about 50000:1 (just shy of 100 dB), which had to be measured with a precision of 12 bits at all light levels. The sensor output was a current ranging from a few picoamps to tens of milliamps. It took me about 2 months to come up with with a way to do this electronically, including automatically range switching the gains of linear op amps without any loss in precision. It isn't the toughest problem I encountered, but it's in the top 10...

The eye handles this with pupils, giving a log curve to its brightness response that allows it to easily handle exponentially varying light levels. Electronic optics (like displays and cameras) are inherently linear. This leads to all the color, hue, and brightness transform functions required in software to convincingly map the display dynamic range capability to the much vaster response of the eye.

It's certainly a nontrivial job, as illustrated by the video. And a huge knowledge rabbithole a person could disappear into for several months... Thanks for sharing it Bri.
__________________
Tangent Studio - Philbo King
www.soundclick.com/philboking - Audio streams

Last edited by Philbo King; 12-06-2018 at 08:52 AM.
Philbo King is offline   Reply With Quote
Old 12-05-2018, 09:00 AM   #23
Bri1
Banned
 
Join Date: Dec 2016
Location: England
Posts: 2,432
Default

all are welcomed always-knowledge is for all to be empowered by!
use it,or not!
am making ground breaking realizations almost daily.

some are most shocking,horrific or truly glorious ->but intriguing+compelling all are!
take the ufo (uap) phenomenon for eg: =fascinating.
Bri1 is offline   Reply With Quote
Old 12-05-2018, 09:17 AM   #24
wwwmaze
Human being with feelings
 
Join Date: Oct 2009
Posts: 99
Default

Quote:
Originally Posted by Bri1 View Post
ello->



um- seriously think devs need to reconsider some options after viewing this next video-please take notice!!!

this was 1st realised a few years ago by the blender and colour management communities-> solutions are being resolved in the next stable blender updates!!

cheerz.

***

go aces/filmic plz!
I don't understand the point of this post. The video is about synthesizing photo-realistic images in Blender. Reaper doesn't have that functionality, not at all.

(there's a bit of misinformation in the video too, so maybe better read the original here if you're interested https://blender.stackexchange.com/qu...oking-im/46940)
wwwmaze is offline   Reply With Quote
Old 12-05-2018, 09:19 AM   #25
karbomusic
Human being with feelings
 
karbomusic's Avatar
 
Join Date: May 2009
Posts: 29,260
Default

Quote:
Originally Posted by wwwmaze View Post
I don't understand the point of this post. The video is about synthesizing photo-realistic images in Blender.
Being a Blender user and already familiar with the video above because of it, I was going to say the same thing. I'm not seeing Reaper as needing to be involved in color science in a professional "film-making" capacity and if the video is captured properly and all the information is there, it can be graded properly.
__________________
Music is what feelings sound like.
karbomusic is offline   Reply With Quote
Old 12-05-2018, 09:38 AM   #26
Bri1
Banned
 
Join Date: Dec 2016
Location: England
Posts: 2,432
Default

all's good- i'm not knocking anything-as all are options available..
totally appreciate what cockos and every contributor of any kind do-but why settle for less?
imaging also suffers from clippings and other distortions-- why use old methods which were clearly not intended for modern systems when better is available now?
as for knowledge,i truly appreciate it all:
like Philbo King's input here-- how could anyone else possibly know that particular set of informations unless they had not shared it?! great info=thanx4sharing!
the point of correction is just that-why do it the way it always was,when that seems 'incorrect'?

people still want cathode rays?? when there is plasma and sun rays to be experienced!!
carry on...
Bri1 is offline   Reply With Quote
Old 12-05-2018, 12:23 PM   #27
Bri1
Banned
 
Join Date: Dec 2016
Location: England
Posts: 2,432
Default

Quote:
Being a Blender user and already familiar with the video above

ello-ok so which version are you using? because if you know blender you might already know it has it's own set of fairly decent histograms-it has a clipping radar..so try your colour corrections in reaper--make some renders and check out the data..
it's like seriously,i think some people here do not want reaper to improve ! >?

if 1980's computing is the new thing-then we got it good here..right?
i flipping detest little white rectangles with numbers in them.... it's far from inspirational by both imaginative or coding capabilities imo.....
but hey-- i am being that guy! - the 1 who dares-seeker of greater truth/knowledge...creations.


reaper is a hack of ideas and functions.
maybe it is time for more progressive,forwarded,thinking.
heh-some say "if you pay peanuts,you get monkies"
how about bigfoot?

Last edited by Bri1; 12-05-2018 at 12:32 PM. Reason: 1xtra
Bri1 is offline   Reply With Quote
Old 12-05-2018, 01:12 PM   #28
karbomusic
Human being with feelings
 
karbomusic's Avatar
 
Join Date: May 2009
Posts: 29,260
Default

Quote:
Originally Posted by Bri1 View Post
ello-ok so which version are you using? because if you know blender you might already know it has it's own set of fairly decent histograms-it has a clipping radar
I also use Davinci Resolve (it's my main video app) which pretty much has the most advanced color correction in the business, including full LUT support, parade, waveform, histogram, radar support etc. - but I don't expect/assume/think that should be available in Reaper. Now, if Justin wanted some inspiration for color related stuff he is already doing, Resolve is a great place to draw it from. Davinci also has audio editing but guess what, since it's primary objective is Video, it's audio editing pales (no contest) in comparison to Reaper, just like Reaper's primary objective is audio.

__________________
Music is what feelings sound like.

Last edited by karbomusic; 12-05-2018 at 01:31 PM.
karbomusic is offline   Reply With Quote
Old 12-05-2018, 02:01 PM   #29
Bri1
Banned
 
Join Date: Dec 2016
Location: England
Posts: 2,432
Default

Quote:
like Reaper's primary objective is audio.

yep-i thought so-but that's not the case apparently more time+efforts spent on old video systems--that's fine by me--only helping pay the rent.
expect a change in what you once thought you knew as fact.
each new generation brings this awareness.^
Bri1 is offline   Reply With Quote
Old 12-05-2018, 04:12 PM   #30
Justin
Administrator
 
Justin's Avatar
 
Join Date: Jan 2005
Location: NYC
Posts: 15,721
Default

I know, there are all sorts of things that aren't "correct" about REAPER's video processing. We don't gamma-correct images before resizing them, for example. Bad stuff. But the name of this forum is "REAPER for Video Editing/Mangling", perhaps the Mangling should be listed before Editing?

Edit: also, REAPER's for audio, not video, the video stuff is a bonus playtoy thing

Last edited by Justin; 12-05-2018 at 05:27 PM.
Justin is offline   Reply With Quote
Old 12-05-2018, 04:49 PM   #31
karbomusic
Human being with feelings
 
karbomusic's Avatar
 
Join Date: May 2009
Posts: 29,260
Default

Quote:
Originally Posted by Justin View Post
But the name of this forum is "REAPER for Video Editing/Mangling", perhaps the Mangling should be listed before Editing?
LOL, fine by me.
__________________
Music is what feelings sound like.
karbomusic is offline   Reply With Quote
Old 12-05-2018, 04:52 PM   #32
Tod
Human being with feelings
 
Tod's Avatar
 
Join Date: Jan 2010
Location: Kalispell
Posts: 14,745
Default

Quote:
Originally Posted by Justin View Post
I know, there are all sorts of things that aren't "correct" about REAPER's video processing. We don't gamma-correct images before resizing them, for example. Bad stuff. But the name of this forum is "REAPER for Video Editing/Mangling", perhaps the Mangling should be listed before Editing?
Well it's still great and getting better all the time.

I just hope somewhere along the line some directions for dummies like me will come about for all this stuff.
Tod is offline   Reply With Quote
Old 12-05-2018, 05:40 PM   #33
X-Raym
Human being with feelings
 
X-Raym's Avatar
 
Join Date: Apr 2013
Location: France
Posts: 9,875
Default

@Justin
It's a pretty serious toy already, and thanks to your code nsippet,we are close to have a good basic toolkit of color correction ! How cool is that ! :P

Some users don't just use the essential video display capabilities but are doing all their video editing with it (like Jon from ReaperBlog).



But yes sure, we all know REAPER is an audio software, and none of that will replace the fancy features of a video editors (like GPU acceleration for ultra fast render, advanced compositing etc).
X-Raym is offline   Reply With Quote
Old 12-06-2018, 12:08 AM   #34
Eliseat
Human being with feelings
 
Eliseat's Avatar
 
Join Date: Mar 2018
Location: Cologne
Posts: 1,362
Default

No, its not a toy, Justin. Its only not about being the best video software out there. (Not yet ) Reapers video concept is cool and fits exactly the editing behavior of audio users. People who are used to work with audio got a great potential to work with video without learning a new software or different editing concepts. And this is a strength others don't have.

Time is also relevant. Reaper doesn't need to get the perfect video tool over night. This is something that grows and gets better like all the other stuff in Reaper. It did it over time. And we are all happy about the actual progress. That also implements that you don't only see the video abilities as a toy rather then a huge playground with endless potential. (Be honest, its fun to play there as we all saw in your subtract video. )

But how much potential has the audio part still in relation of whats possible? I don't see that really big step further in general. Maybe some new instruments, effects, ARA, beat detection ... but then? Its a good idea to don't let the video section sleep behind the thorn hedge. And I'm thankful for that.

Many thanks
Eliseat is offline   Reply With Quote
Old 12-06-2018, 04:42 AM   #35
Bri1
Banned
 
Join Date: Dec 2016
Location: England
Posts: 2,432
Default

heh =)
@ karbomusic-lol you remind me of nasa. never as straight answer!!
+yeah-i do not think reaper is going to be geared towards fuller industry style editing-all is well though eh.
it's great to have anything like this in reaper.


@ Justin -just out of curiousity,do you have an actual *final goal for reaper* in total?
it may be usefull to know,going forward,if any further investments will occur.
thanx! for all you peoples do.
Bri1 is offline   Reply With Quote
Old 12-06-2018, 09:48 PM   #36
Philbo King
Human being with feelings
 
Philbo King's Avatar
 
Join Date: May 2017
Posts: 3,201
Default

Thank you sir!


Quote:
Originally Posted by Justin View Post
Here's the HSL one with gamma correction (you can adjust the gamma curve for the image, and for the S/M/H separately):
__________________
Tangent Studio - Philbo King
www.soundclick.com/philboking - Audio streams
Philbo King is offline   Reply With Quote
Old 06-19-2023, 05:14 AM   #37
nub
Human being with feelings
 
Join Date: Oct 2021
Posts: 4
Default

Could anyone make a simpler version of this with a SINGLE slider for shadows, midtone, highlight, black and white?

I'm not sure how easy this would be, but, if could be expended, maybe one with temperature and tint?
nub is offline   Reply With Quote
Old 06-19-2023, 09:47 AM   #38
papagirafe
Human being with feelings
 
papagirafe's Avatar
 
Join Date: Aug 2020
Location: Brasil
Posts: 679
Default

Quote:
Originally Posted by nub View Post
Could anyone make a simpler version of this with a SINGLE slider for shadows, midtone, highlight, black and white?

I'm not sure how easy this would be, but, if could be expended, maybe one with temperature and tint?
I'm not sure what you mean by "single slider". Do you have any app (outside of REaper) that already does similar things to what you're looking for? As for color temperature, the mathematical formulas behind that take some time to digest...

Last edited by papagirafe; 06-19-2023 at 05:57 PM. Reason: rewording
papagirafe is offline   Reply With Quote
Old 10-27-2023, 01:15 PM   #39
nub
Human being with feelings
 
Join Date: Oct 2021
Posts: 4
Default

Quote:
Originally Posted by papagirafe View Post
I'm not sure what you mean by "single slider". Do you have any app (outside of REaper) that already does similar things to what you're looking for? As for color temperature, the mathematical formulas behind that take some time to digest...
Really sorry for the late response.

I mean a single parameter, instead of the RGB version in the JS presets.

You could think of any major DAW like Premiere, there is a single parameter/slider for shadows, highlights, whites, blacks, etc.

The main idea is just to have more control to color correction and integrate as much as possible thoses missing parameters/functions.

As a reference, in Premiere, just take a look at the controls in Lumetri Color, Creative, etc).
nub is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -7. The time now is 08:40 AM.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.