Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DCTL for Root Polynomial Degree 4? #4

Open
LucasGodzilla opened this issue Dec 28, 2023 · 1 comment
Open

DCTL for Root Polynomial Degree 4? #4

LucasGodzilla opened this issue Dec 28, 2023 · 1 comment

Comments

@LucasGodzilla
Copy link

LucasGodzilla commented Dec 28, 2023

Hello Ethan,

For about half a week now on and off, I have been trying to piece together custom DCTL plugins to apply the matrices generator by your Camera Match library directly inside of Da Vinci Resolve to avoid the use of a LUT.

While I have been successful in implementing a Degree 3 DCTL, I have been stuck at trying to create a Degree 4 DCTL for some reason.

The code itself should be fairly simple going off the Finlayson 2015 documentation I could find from Colour Science, and from my testing, the math should be correct—though I had to manually define my inputs as Constants instead of UI Sliders as DCTL only supported 64 of them.

[[-261346.9106751648 -280938.7950292614 17042.3295917317
  13764445.2638926059 -1314065.8834489791 269142.2770083626
  -14398071.1334277075 1252353.1562157504 -297589.2138827664
  -13474283.1793841682 1419049.9173040469 -239783.8256689388
  -98493.0047027412 6973398.6725546997 113847.0118633829 7701599.0578824533
  -776860.2946374351 158394.1921955326 -644658.1150428661 36050.0813998114
  41174.3347936619 39595.1608919792]

 [-199203.7713849060 -210242.9778685250 3671.1088273078 10204496.3039917685
  -460314.3124146534 131620.9336613363 -10553485.0740822535
  398373.5091930552 -141393.2366282719 -10102808.8260098975
  544158.3457493571 -117884.6268541000 -81224.1256896322 5257524.6216813214
  54390.1047581435 5612822.9510746449 -312224.5900445678 72365.8816136498
  -196912.6681236209 30694.8553637392 33018.7768176074 32557.8780022507]

 [-46950.7510616470 -71661.2046957209 -9804.4149705661 2500437.6548817428
  586857.3693750774 -48938.6547746651 -2606066.7397758248
  -563759.5604125325 47867.1319108658 -2459754.2824597401
  -628580.0843041310 48978.5954363124 17273.9318953632 1277626.8390139220
  -24812.7878715092 1393670.0243389183 341857.5346836292 -23887.3208098403
  290126.7520122456 -6304.5730566768 -7760.0067832336 -6414.3194653750]]
__DEVICE__ float mypowf (float base, float exp)
{
    return _copysignf(_powf(_fabs(base), exp), base);
}

__DEVICE__ float3 transform(int p_Width, int p_Height, int p_X, int p_Y, float p_R, float p_G, float p_B)
{

    //////
    //  Degree 4 Matrix has too many UI Parameters and must be defined in-code as variables

    ////    Red
    //  1
    const float red_r =         -261346.8614695633      ;
    const float red_g =         -280938.7547033542      ;
    const float red_b =         17042.3139221903        ;
    //  2
    const float red_rt_rg =     13764442.7055367529     ;
    const float red_rt_gb =     -1314065.1009736201     ;
    const float red_rt_rb =     269142.2990315667       ;
    //  3
    const float red_rt_rg2 =    -14398068.4827105850    ;
    const float red_rt_gb2 =    1252352.3805370491      ;
    const float red_rt_rb2 =    -297589.2366363414      ;
    const float red_rt_gr2 =    -13474280.6483757198    ;
    const float red_rt_bg2 =    1419049.1114064993      ;
    const float red_rt_br2 =    -239783.8468399671      ;
    const float red_rt_rgb =    -98492.9954246925       ;
    //  4
    const float red_rt_r3g =    6973397.3557095863      ;
    const float red_rt_r3b =    113847.0223287557       ;
    const float red_rt_g3r =    7701597.6460746182      ;
    const float red_rt_g3b =    -776859.8675437035      ;
    const float red_rt_b3r =    158394.2052652900       ;
    const float red_rt_b3g =    -644657.7096753955      ;
    const float red_rt_r2gb =   36050.0773770861        ;
    const float red_rt_g2rb =   41174.3303323984        ;
    const float red_rt_b2rg =   39595.1565379622        ;

    ////    Green
    //  1
    const float grn_r =         -199203.7582843798      ;
    const float grn_g =         -210242.9650707165      ;
    const float grn_b =         3671.1056783151         ;
    //  2
    const float grn_rt_rg =     10204495.5799025185     ;
    const float grn_rt_gb =     -460314.1208756918      ;
    const float grn_rt_rb =     131620.9456886460       ;
    //  3
    const float grn_rt_rg2 =    -10553484.3228744976    ;
    const float grn_rt_gb2 =    398373.3193960916       ;
    const float grn_rt_rb2 =    -141393.2476468480      ;
    const float grn_rt_gr2 =    -10102808.1077691447    ;
    const float grn_rt_bg2 =    544158.1494033572       ;
    const float grn_rt_br2 =    -117884.6378000051      ;
    const float grn_rt_rgb =    -81224.1245409784       ;
    //  4
    const float grn_rt_r3g =    5257524.2481600670      ;
    const float grn_rt_r3b =    54390.1104690309        ;
    const float grn_rt_g3r =    5612822.5512599843      ;
    const float grn_rt_g3b =    -312224.4872269094      ;
    const float grn_rt_b3r =    72365.8876717333        ;
    const float grn_rt_b3g =    -196912.5696254597      ;
    const float grn_rt_r2gb =   30694.8540255078        ;
    const float grn_rt_g2rb =   33018.7751607543        ;
    const float grn_rt_b2rg =   32557.8765079035        ;

    ////    Blue
    //  1
    const float blu_r =         -46950.6952389541       ;
    const float blu_g =         -71661.1609506553       ;
    const float blu_b =         -9804.4337590240        ;
    //  2
    const float blu_rt_rg =     2500434.7481498034      ;
    const float blu_rt_gb =     586858.3166443132       ;
    const float blu_rt_rb =     -48938.6417227647       ;
    //  3
    const float blu_rt_rg2 =    -2606063.7277709227     ;
    const float blu_rt_gb2 =    -563760.5014380891      ;
    const float blu_rt_rb2 =    47867.1171433433        ;
    const float blu_rt_gr2 =    -2459751.4104897310     ;
    const float blu_rt_bg2 =    -628581.0614164971      ;
    const float blu_rt_br2 =    48978.5827169900        ;
    const float blu_rt_rgb =    17273.9444326147        ;
    //  4
    const float blu_rt_r3g =    1277625.3456099702      ;
    const float blu_rt_r3b =    -24812.7806100923       ;
    const float blu_rt_g3r =    1393668.4202844591      ;
    const float blu_rt_g3b =    341858.0545124854       ;
    const float blu_rt_b3r =    -23887.3120578217       ;
    const float blu_rt_b3g =    290127.2433076900       ;
    const float blu_rt_r2gb =   -6304.5777155657        ;
    const float blu_rt_g2rb =   -7760.0119717876        ;
    const float blu_rt_b2rg =   -6414.3245199491        ;

    //////

    float rFinal =  //  1
                    (p_R * red_r) +
                    (p_G * red_g) +
                    (p_B * red_b) +
                    //  2
                    (mypowf((p_R * p_G), 0.5) * red_rt_rg) +
                    (mypowf((p_G * p_B), 0.5) * red_rt_gb) +
                    (mypowf((p_R * p_B), 0.5) * red_rt_rb) +
                    //  3
                    (mypowf((p_R * p_G * p_G), _frecip(3)) * red_rt_rg2) +
                    (mypowf((p_G * p_B * p_B), _frecip(3)) * red_rt_gb2) +
                    (mypowf((p_R * p_B * p_B), _frecip(3)) * red_rt_rb2) +
                    (mypowf((p_G * p_R * p_R), _frecip(3)) * red_rt_gr2) +
                    (mypowf((p_B * p_G * p_G), _frecip(3)) * red_rt_bg2) +
                    (mypowf((p_B * p_R * p_R), _frecip(3)) * red_rt_br2) +
                    (mypowf((p_R * p_G * p_B), _frecip(3)) * red_rt_rgb) +
                    //  4
                    (mypowf((p_R * p_R * p_R * p_G), 0.25) * red_rt_r3g) +
                    (mypowf((p_R * p_R * p_R * p_B), 0.25) * red_rt_r3b) +
                    (mypowf((p_G * p_G * p_G * p_R), 0.25) * red_rt_g3r) +
                    (mypowf((p_G * p_G * p_G * p_B), 0.25) * red_rt_g3b) +
                    (mypowf((p_B * p_B * p_B * p_R), 0.25) * red_rt_b3r) +
                    (mypowf((p_B * p_B * p_B * p_G), 0.25) * red_rt_b3g) +
                    (mypowf((p_R * p_R * p_G * p_B), 0.25) * red_rt_r2gb) +
                    (mypowf((p_G * p_G * p_R * p_B), 0.25) * red_rt_g2rb) +
                    (mypowf((p_B * p_B * p_R * p_G), 0.25) * red_rt_b2rg);

    float gFinal =  //  1
                    (p_R * grn_r) +
                    (p_G * grn_g) +
                    (p_B * grn_b) +
                    //  2
                    (mypowf((p_R * p_G), 0.5) * grn_rt_rg) +
                    (mypowf((p_G * p_B), 0.5) * grn_rt_gb) +
                    (mypowf((p_R * p_B), 0.5) * grn_rt_rb) +
                    //  3
                    (mypowf((p_R * p_G * p_G), _frecip(3)) * grn_rt_rg2) +
                    (mypowf((p_G * p_B * p_B), _frecip(3)) * grn_rt_gb2) +
                    (mypowf((p_R * p_B * p_B), _frecip(3)) * grn_rt_rb2) +
                    (mypowf((p_G * p_R * p_R), _frecip(3)) * grn_rt_gr2) +
                    (mypowf((p_B * p_G * p_G), _frecip(3)) * grn_rt_bg2) +
                    (mypowf((p_B * p_R * p_R), _frecip(3)) * grn_rt_br2) +
                    (mypowf((p_R * p_G * p_B), _frecip(3)) * grn_rt_rgb) +
                    //  4
                    (mypowf((p_R * p_R * p_R * p_G), 0.25) * grn_rt_r3g) +
                    (mypowf((p_R * p_R * p_R * p_B), 0.25) * grn_rt_r3b) +
                    (mypowf((p_G * p_G * p_G * p_R), 0.25) * grn_rt_g3r) +
                    (mypowf((p_G * p_G * p_G * p_B), 0.25) * grn_rt_g3b) +
                    (mypowf((p_B * p_B * p_B * p_R), 0.25) * grn_rt_b3r) +
                    (mypowf((p_B * p_B * p_B * p_G), 0.25) * grn_rt_b3g) +
                    (mypowf((p_R * p_R * p_G * p_B), 0.25) * grn_rt_r2gb) +
                    (mypowf((p_G * p_G * p_R * p_B), 0.25) * grn_rt_g2rb) +
                    (mypowf((p_B * p_B * p_R * p_G), 0.25) * grn_rt_b2rg);

    float bFinal =  //  1
                    (p_R * blu_r) +
                    (p_G * blu_g) +
                    (p_B * blu_b) +
                    //  2
                    (mypowf((p_R * p_G), 0.5) * blu_rt_rg) +
                    (mypowf((p_G * p_B), 0.5) * blu_rt_gb) +
                    (mypowf((p_R * p_B), 0.5) * blu_rt_rb) +
                    //  3
                    (mypowf((p_R * p_G * p_G), _frecip(3)) * blu_rt_rg2) +
                    (mypowf((p_G * p_B * p_B), _frecip(3)) * blu_rt_gb2) +
                    (mypowf((p_R * p_B * p_B), _frecip(3)) * blu_rt_rb2) +
                    (mypowf((p_G * p_R * p_R), _frecip(3)) * blu_rt_gr2) +
                    (mypowf((p_B * p_G * p_G), _frecip(3)) * blu_rt_bg2) +
                    (mypowf((p_B * p_R * p_R), _frecip(3)) * blu_rt_br2) +
                    (mypowf((p_R * p_G * p_B), _frecip(3)) * blu_rt_rgb) +
                    //  4
                    (mypowf((p_R * p_R * p_R * p_G), 0.25) * blu_rt_r3g) +
                    (mypowf((p_R * p_R * p_R * p_B), 0.25) * blu_rt_r3b) +
                    (mypowf((p_G * p_G * p_G * p_R), 0.25) * blu_rt_g3r) +
                    (mypowf((p_G * p_G * p_G * p_B), 0.25) * blu_rt_g3b) +
                    (mypowf((p_B * p_B * p_B * p_R), 0.25) * blu_rt_b3r) +
                    (mypowf((p_B * p_B * p_B * p_G), 0.25) * blu_rt_b3g) +
                    (mypowf((p_R * p_R * p_G * p_B), 0.25) * blu_rt_r2gb) +
                    (mypowf((p_G * p_G * p_R * p_B), 0.25) * blu_rt_g2rb) +
                    (mypowf((p_B * p_B * p_R * p_G), 0.25) * blu_rt_b2rg);

    return make_float3(rFinal, gFinal, bFinal);
}

But for some reason when I try applying the DCTL in comparison to the LUT in Resolve, I get some really weird results and I have no clue as to why.

LUTvsDCTL

I don't suppose you have any idea what's going wrong here, do you? I'm assuming it's some Resolve limitation but I can't fathom what that would be at the moment.

Thank you in advance and I hope to hear back soon!

@ethan-ou
Copy link
Owner

ethan-ou commented Aug 1, 2024

Apologies for such a long delay! I think I tried to make the 4th degree polynomial work on my end but it became way too difficult to get a good match. It's because it has a lot of variables it's trying to optimise for and the amount of gain you get from those increased variables rarely leads to a better match. I think when I tried it I got results on the 2nd and 3rd degrees that was barely better than the standard linear transform.

Hopefully you get somewhere with this but I couldn't and that's why the DCTL folder in this repo doesn't have a 4th degree polynomial either.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants