DCTLs and Resolve OFX

The division tries to map 8-bit 0 to 255 int onto 0 to 1 float format, but code values in Resolve are already in 0 to 1 float format.
So how would you suggest i re-write the formulas provided by Tobias for converting to CMYK and back to RGB ? Or do you have an alternative formula that can be properly inverted ?
 
I think it should look something like:

Code:
        k = 1 - max(max(p.r, p.g), p.b);
        if (k == 1) {
            o.r = 0;
            o.g = 0;
            o.b = 0;
        } else {
            o.r = (1 - p.r - k) / (1 - k);
            o.g = (1 - p.g - k) / (1 - k);
            o.b = (1 - p.b - k) / (1 - k);
        }

where p is the input rgb structure and o the output rgb (=cmy) structure.

You might want to consider clamping the code values at 1 first (i.e. o.r = min(o.r, 1.0f; and so on))
 
These are probably obvious questions, apologies if I missed this info somewhere:
  1. Can DCTLs operate spatially (i.e. can one pixel be influenced by the values in a different pixel in the frame)
    This would be useful for doing things like custom blurs / glow / halation etc
  2. Can DCTLs operate temporally (i.e. can one pixel in the current frame be influenced by the values in an adjacent frame)
I've had a recurring thought about building some custom tools to suit my workflow but don't know if these things are possible. If they are, I'd be very grateful for links to any reference materials. Maybe the DCTL library from Paul Dore contains examples of these? Looking at / playing with working code is a great learning tool.

Thanks!!
 
These are probably obvious questions, apologies if I missed this info somewhere:
  1. Can DCTLs operate spatially (i.e. can one pixel be influenced by the values in a different pixel in the frame)
    This would be useful for doing things like custom blurs / glow / halation etc
  2. Can DCTLs operate temporally (i.e. can one pixel in the current frame be influenced by the values in an adjacent frame)
I've had a recurring thought about building some custom tools to suit my workflow but don't know if these things are possible. If they are, I'd be very grateful for links to any reference materials. Maybe the DCTL library from Paul Dore contains examples of these? Looking at / playing with working code is a great learning tool.

Thanks!!


Kye,

On Mixinglight.com there is an in depth DCTL tutorial series by Cullen Kelly.
 
Hi,
can you help me fix this Contrast DCTL @Paul Dore ? When I run the DCTL, it produces artifacts. It clips bright and out-of-gamut colors.
(created by paul dore)

/ Contrast OFX DCTL

DEFINE_UI_PARAMS(TYPE, Type, DCTLUI_COMBO_BOX, 0, { S_CURVE, LINEAR }, { S-Curve Contrast, Linear Contrast} )
DEFINE_UI_PARAMS(CURVE, Contrast, DCTLUI_SLIDER_FLOAT, 0, -1, 1, 0.001)
DEFINE_UI_PARAMS(PIVOT, Pivot, DCTLUI_SLIDER_FLOAT, 0.5, 0, 1, 0.001)

__DEVICE__ float3 transform(int p_Width, int p_Height, int p_X, int p_Y, float p_R, float p_G, float p_B)
{
float3 RGB = make_float3(p_R, p_G, p_B);
CURVE = CURVE > 0.0f ? CURVE * 2.0f : CURVE;
CURVE += 1.0f;

if(TYPE == S_CURVE) {
RGB.x = RGB.x <= PIVOT ? _powf(RGB.x / PIVOT, CURVE) * PIVOT : (1.0f - _powf(1.0f - (RGB.x - PIVOT) / (1.0f - PIVOT), CURVE)) * (1.0f - PIVOT) + PIVOT;
RGB.y = RGB.y <= PIVOT ? _powf(RGB.y / PIVOT, CURVE) * PIVOT : (1.0f - _powf(1.0f - (RGB.y - PIVOT) / (1.0f - PIVOT), CURVE)) * (1.0f - PIVOT) + PIVOT;
RGB.z = RGB.z <= PIVOT ? _powf(RGB.z / PIVOT, CURVE) * PIVOT : (1.0f - _powf(1.0f - (RGB.z - PIVOT) / (1.0f - PIVOT), CURVE)) * (1.0f - PIVOT) + PIVOT;
} else {
RGB.x = (RGB.x - PIVOT) * CURVE + PIVOT;
RGB.y = (RGB.y - PIVOT) * CURVE + PIVOT;
RGB.z = (RGB.z - PIVOT) * CURVE + PIVOT;
}

return RGB;
}
 
I would suggest using a sigmoid function, here is an example that not only creates an s-curve but can also undo an s-curve (but be aware of possible negative code values. Clamping might not always be the correct option (for instance if the noise level is calibrated at 0).

Code:
__DEVICE__ inline float sigmoid(float x, float s, float i) {
  return 1.0f / (1 + _expf(_fabs(s)*(i - x)));
}

__DEVICE__ inline float sigmoid(float x, float s, float i) {
  // Check for zero slope
  if (s == 0)
    return x;
  float sigmin = sigmoid(0, s, i);
  float sigmax = sigmoid(1, s, i);
 // Handling positive s value (standard sigmoid)
  if (s > 0) {  
    float sig = 1 / (1 + exp(-s * (x - i)));
    return (sig - sigmin) / (sigmax - sigmin);
  }
  // Handling negative s value (inverted sigmoid)
  else {  
    float sig = 1 / (1 + exp(s * (x - i)));
    return (sig - sigmin) / (sigmax - sigmin);
  }
}
Where s is the intensity of the curve and i the inflection point

Before you apply the s-curve you might first want to rolloff the video in case there are above 1.0 values or you want to rolloff the data even earlier, for instance:
Code:
__DEVICE__ inline float rolloff(float x, float t) {
    const float threshold = 1.0f;
    const float maxScale = 10.0f; // Adjust as needed for the range of your data

    // Normalize x within the range [0, maxScale]
    float normalizedX = x / maxScale;

    // Apply a continuous curve adjustment
    // The curve is more pronounced for x > threshold and more subtle for x <= threshold
    float adjustedX = normalizedX <= threshold / maxScale ?
                      normalizedX * _powf((threshold / maxScale) / normalizedX, t) :
                      threshold / maxScale + (1 - _powf(1 - (normalizedX - threshold / maxScale) / (1 - threshold / maxScale), t)) * (1 - threshold / maxScale);

    // Scale back to the original range
    return adjustedX * maxScale;
}
 
Last edited:
These are probably obvious questions, apologies if I missed this info somewhere:
  1. Can DCTLs operate spatially (i.e. can one pixel be influenced by the values in a different pixel in the frame)
    This would be useful for doing things like custom blurs / glow / halation etc
  2. Can DCTLs operate temporally (i.e. can one pixel in the current frame be influenced by the values in an adjacent frame)
I've had a recurring thought about building some custom tools to suit my workflow but don't know if these things are possible. If they are, I'd be very grateful for links to any reference materials. Maybe the DCTL library from Paul Dore contains examples of these? Looking at / playing with working code is a great learning tool.

Thanks!!
1. Yes
2. Yes, but use with caution

Check examples of DCTL's and Readme file in "DaVinciCTL" folder (C:\ProgramData\Blackmagic Design\DaVinci Resolve\Support\Developer\DaVinciCTL on Windows). You should know basics of C syntaxis to write a program. Start with Sololearn "C beginners" course (you would not need much more that that), proceed with free tutorial series by Thatcher Freeman. And download Visual Studio Code, it is much better than trying to write something in notepad.

It is a shader language, so you can start with learning shader programming, but there are not that many simple and approachable courses out there.

Some functions are designed specifically for DaVinci Color Transform Language, so check a list in the readme file if you miss something.

Good luck!
 
Last edited:
1. Yes
2. Yes, but use with caution

Check examples of DCTL's and Readme file in "DaVinciCTL" folder (C:\ProgramData\Blackmagic Design\DaVinci Resolve\Support\Developer\DaVinciCTL on Windows). You should know basics of C syntaxis to write a program. Start with Sololearn "C beginners" course (you would not need much more that that), proceed with free tutorial series by Thatcher Freeman. And download Visual Studio Code, it is much better than trying to write something in notepad.

It is a shader language, so you can start with learning shader programming, but there are not that many simple and approachable courses out there.

Some functions are designed specifically for DaVinci Color Transform Language, so check a list in the readme file if you miss something.

Good luck!
Thanks Fedor, that's incredibly useful and the tutorials from Thatcher look absolutely spectacular!
Thanks again.
 
Hi Paul,
I've been trying to install Freqsep on Resolve 18.6.4 running on a Windows 11 machine. It appears in the Video Plugins section of Preferences but has a message, "Failed to load" does this plugin (windows10 resolve 17) work on win 11?
 
Can anyone recommend a free and lightweight code editor for MAC?
I'm currently using TextEdit, which obviously isn't the best tool for the job!
Even if it just did things like colouring the text and showing the companion bracket to the one you're on would be really useful.
 
Also, does anyone know if DCTLs can output through the Key Output of the node? if so, what about having multiple Key Outputs (the way a compound node can have multiples)?
 
Can anyone recommend a free and lightweight code editor for MAC?
I'm currently using TextEdit, which obviously isn't the best tool for the job!
Even if it just did things like colouring the text and showing the companion bracket to the one you're on would be really useful.
I‘m using VScode and/or CodeRunner. Both work great. VScode has a bit more flexibility and options when you want to code Python too
 
Can anyone recommend a free and lightweight code editor for MAC?
I'm currently using TextEdit, which obviously isn't the best tool for the job!
Even if it just did things like colouring the text and showing the companion bracket to the one you're on would be really useful.
VS Code is a no-brainer and there are good plugins to help with syntax for most programming languages out there.
 
I'm writing a DCTL that works in LAB (the output from OKLAB) and wondering how to handle the Luma channel in my Luma-only Lift/Gamma/Gain function.
My code is this (standard) formula:
LAB.x=(_powf(LAB.x,1.0/LumaGamma)+LumaLift*(1.0-LAB.x))*LumaGain;

The challenge is that an image that has a full 0-1 range of luma values on a 709/2.4 output only has values between about 500-850 in the L channel in the LAB output from the OKLAB conversion. OKLAB is designed for AWG input/output so it makes sense that a 709 image wouldn't be the full range within that context.

I can just offset the values in the formula to make it so that it treats the 500-850 range as 0-1, and the Lift and Gain calculations would also work for values outside that 500-850 range, but the Gamma function either wouldn't work outside that range or would do strange things. I can limit the function within that range and do other things outside it, but I'm not sure if that's the right way to proceed.
It occurs to me that values outside this range might be normal in a HDR output pipeline, but I've never worked with them before so I'm not sure.

Any thoughts?

I'm not sure how you'd design a Gamma adjustment that makes sense in the presence of super-whites and super-blacks, or that works for HDR as well as SDR images, or if this question even makes any sense.
 
To convert a given colorspace to L*a*b you need to convert it to a CIE XYZ intermediate first. So for HDR you would first convert Rec.2020 to CIE XYZ and then convert to L*a*b.
 
This brilliant talk and demo of ChromoGen has a lot of features that might be inspiring to the DCTL programmers amongst us.
(I note that a shorter edit was shared on FilmLight's YT channel previously).
I saw from a recent video by a fellow coder that it has already been very inspirational :)

I'm currently developing my own tool and will be contemplating this demo for quite some time I think!
 
I developed a false color DCTL designed to assist with hue consistency in the Lightbox. This tool is based on the YCbCr color space to facilitate hue analysis by displaying neighboring colors spread to a customizable degree. For instance, setting it to ±90 degrees allows you to immediately analyze color drift, while at 120 degrees and ±90 degrees, you can determine if a hue is trending toward green, orange, or purple. Additionally, you can set boundaries for saturation levels.
On the other hand, it will also display shadows and highlights. Color wheels (YCbCr, HSL and HSL-120degree) and luma ramp can be generated to see the extent of the settings.

For more information see:

C:
DEFINE_UI_PARAMS(HueCtrl, Hue, DCTLUI_SLIDER_FLOAT, 123, 0, 360, 1)

DEFINE_UI_PARAMS(HueRangeCtrl , Hue Range     , DCTLUI_SLIDER_FLOAT  , 11.0, 0.0, 45.0, 1.0)
DEFINE_UI_PARAMS(HueOffset    , Hue Offset    , DCTLUI_SLIDER_FLOAT  , 0.0, 90.0, 180.0, 1.0)


DEFINE_UI_PARAMS(SatLow       , Sat Low       , DCTLUI_SLIDER_FLOAT, 0.125, 0.0, 1.0, 0.025)
DEFINE_UI_PARAMS(SatHigh      , Sat High      , DCTLUI_SLIDER_FLOAT, 0.250, 0.0, 1.0, 0.025)

DEFINE_UI_PARAMS(LumaShadow   , Luma Shadow   , DCTLUI_SLIDER_FLOAT, 0.05, 0.0, 1.0, 0.01)
DEFINE_UI_PARAMS(LumaHighlight, Luma Highlight, DCTLUI_SLIDER_FLOAT, 0.95, 0.0, 1.0, 0.01)

DEFINE_UI_PARAMS(BlackWhite   , Black and White, DCTLUI_CHECK_BOX, 0)
DEFINE_UI_PARAMS(IndicatorLuma, Indicator Luma, DCTLUI_SLIDER_FLOAT, 0.5, 0.0, 1.0, 0.01)
DEFINE_UI_PARAMS(WheelType    , Wheel Type     , DCTLUI_COMBO_BOX  , 0, {YCBCR, HSL, HSLCBCR},{YCbCr, HSL, HSL-120})
DEFINE_UI_PARAMS(WheelZoom    , Wheel Zoom     , DCTLUI_SLIDER_FLOAT,  1.0, 1.0, 4.0, 1.0)
DEFINE_UI_PARAMS(WheelSize    , Wheel Size     , DCTLUI_SLIDER_FLOAT, 0.5, 0.0, 1.0, 0.01)





__DEVICE__ float  mod(float a, float b) {return a -  b * _floor(a/b);} // same as  a%b

__DEVICE__ float3 rgb2hsl(float3 RGB) {
    float max = _fmaxf(RGB.x, _fmaxf(RGB.y, RGB.z));
    float min = _fminf(RGB.x, _fminf(RGB.y, RGB.z));
    float h, s, l;
    l = (max + min) / 2.0f;

    if (max == min) {
        h = s = 0.0f; // achromatic
    } else {
        float d = max - min;
        s = l > 0.5f ? d / (2.0f - max - min) : d / (max + min);
        if (max == RGB.x) {
            h = (RGB.y - RGB.z) / d + (RGB.y < RGB.z ? 6.0f : 0.0f);
        } else if (max == RGB.y) {
            h = (RGB.z - RGB.x) / d + 2.0f;
        } else {
            h = (RGB.x - RGB.y) / d + 4.0f;
        }
        h /= 6.0f;
    }
    float3 HSL = make_float3(h, s, l);
    return HSL;
}

__DEVICE__ float3 hsl2rgb(float3 HSL) {
    float3 RGB = {0.0f, 0.0f, 0.0f}; // Initialize RGB to zero

    if (HSL.y == 0.0f) {
        // Achromatic (grey)
        RGB.x = RGB.y = RGB.z = HSL.z;
        return RGB;
    } else {
        float q = HSL.z < 0.5f ? HSL.z * (1.0f + HSL.y) : HSL.z + HSL.y - HSL.z * HSL.y;
        float p = 2.0f * HSL.z - q;
        float hk = HSL.x;

        float t[3];
        t[0] = hk + 1.0f / 3.0f; // Red
        t[1] = hk;               // Green
        t[2] = hk - 1.0f / 3.0f; // Blue

        for (int i = 0; i < 3; i++) {
            if (t[i] < 0.0f) t[i] += 1.0f;
            if (t[i] > 1.0f) t[i] -= 1.0f;

            if (t[i] < 1.0f / 6.0f) {
                t[i] = p + ((q - p) * 6.0f * t[i]);
            } else if (t[i] < 1.0f / 2.0f) {
                t[i] = q;
            } else if (t[i] < 2.0f / 3.0f) {
                t[i] = p + ((q - p) * (2.0f / 3.0f - t[i]) * 6.0f);
            } else {
                t[i] = p;
            }
        }

        RGB.x = t[0];
        RGB.y = t[1];
        RGB.z = t[2];
    }
    return RGB;
}


__DEVICE__ float3 RGBtoYCbCr_Rec709(float3 RGB) {
    float3 YCbCr;
    YCbCr.x = 0.2126f * RGB.x + 0.7152f * RGB.y + 0.0722f * RGB.z;
    YCbCr.y = -0.114572f * RGB.x - 0.385428f * RGB.y + 0.5f * RGB.z;
    YCbCr.z = 0.5f * RGB.x - 0.454153f * RGB.y - 0.045847f * RGB.z;
    return YCbCr;
}

__DEVICE__ float3 YCbCrtoRGB_Rec709(float3 YCbCr) {
    float3 RGB;
    RGB.x = YCbCr.x + 1.5748f   * (YCbCr.z);
    RGB.y = YCbCr.x - 0.187324f * (YCbCr.y) - 0.468124f * (YCbCr.z);
    RGB.z = YCbCr.x + 1.8556f   * (YCbCr.y);
    return RGB;
}



__DEVICE__ float Saturation(float3 YCbCr) {
    float chroma = _sqrtf(((YCbCr.y) * (YCbCr.y) + (YCbCr.z) * (YCbCr.z))/0.5f);
    return chroma;
}

// Function to detect the hue angle in degrees
__DEVICE__  float detectHue(float3 YCbCr) {
    float PI = 3.14159f;
    float hueAngle = _atan2f(YCbCr.z, YCbCr.y);
    hueAngle = hueAngle * (180.0f / PI);
    if (hueAngle < 0.0f) {
        hueAngle += 360.0f;
    }

    return hueAngle;
}

// Function to achieve max saturated RGB colors based on given hue
__DEVICE__  float3 maxSaturatedRGBFromHue(float hueDeg, float Y, float chroma) {
    float PI = 3.14159f;
    float hueRad = hueDeg * (PI / 180.0f);
    float Cb = chroma * _cosf(hueRad);
    float Cr = chroma * _sinf(hueRad);
    float3 RGB = make_float3(1.0f,1.0f,1.0f);
    RGB = YCbCrtoRGB_Rec709(make_float3(Y,Cb,Cr));
    return RGB;
}


__DEVICE__ float3 drawYCbCrCircle(float2 xy, float2 wh, float2 center, float radius,float boolHSV, float angleCtrl, float AngleDelta, float WheelZoom) {
    float PI = 3.14159f;
    // Calculate distance from the center
    float2 dxy = xy/wh.y - make_float2(center.x*wh.x/wh.y,center.x);
    float dist = _sqrtf((dxy.x * dxy.x + dxy.y * dxy.y));
    // Check if the pixel is within the circle
    if (dist < radius) {
    if (_floor(xy.x/8.0f) == _floor(0.5f*wh.y/8.0f)) {return make_float3(0.1f,0.1f,0.1f);}
    if (_floor(xy.y/8.0f) == _floor(0.5f*wh.y/8.0f)) {return make_float3(0.1f,0.1f,0.1f);}
        float dist2 = 0.0f;
        dist2 = dist*2.0f;
        float angle = _atan2f(dxy.y, dxy.x);
        float hue = angle / (2.0f * PI)*360.0f;
        float3 rgb;
        if (boolHSV==0.0f) {rgb = maxSaturatedRGBFromHue(hue+AngleDelta, 1.0f-dist, 1.0f/WheelZoom*dist*_sqrtf(2.0f) );}
        if (boolHSV==1.0f) {rgb = hsl2rgb(make_float3(hue/360.0f+AngleDelta/360.0f,1.0f/WheelZoom*dist*2.65,0.0f+1.0f*(1.0f-dist)));} //Closest to Fusion ColorCorrector Wheel
        if (boolHSV==2.0f) {rgb = hsl2rgb(make_float3(hue/360.0f+240.0f/360.0f,1.0f/WheelZoom*dist*2.65,0.0f+1.0f*(1.0f-dist)));}        
        return make_float3(rgb.x,rgb.y,rgb.z);

    }
    return make_float3(0.0f,0.0f,0.0f);        
}

__DEVICE__ float3 drawLumaRamp(float2 xy, float2 wh, float2 center) {
    float2 dxy = xy/wh;
    float c = 0.05f;
    float d = 0.05f;
    if ((xy.x-c*wh.x > wh.x+d*xy.x) || ((xy.x+c*wh.x < wh.x+d*xy.x) || (xy.y > wh.y))) return make_float3(0.0f,0.0f,0.0f);
    return make_float3(dxy.y,dxy.y,dxy.y);
}

__DEVICE__ float3 transform(int p_Width, int p_Height, int p_X, int p_Y, float p_R, float p_G, float p_B)
{
    float3 iC0  = make_float3(p_R, p_G, p_B);
    //float3 iC0  = make_float3(1.0f, 1.0f, 0.0f);

    float WheelTypeF = 0.0f;
    if (WheelType == HSL   ) {WheelTypeF = 1.0f;}
    if (WheelType == HSLCBCR) {WheelTypeF = 2.0f;}



    float2 wh = make_float2(p_Height, p_Height);
    float2 center = make_float2(0.5f,0.5f);
    float  radius = 0.5f;
    float3 iC1 = make_float3(0.0f,0.0f,0.0f);
    float3 iC2 = make_float3(0.0f,0.0f,0.0f);


    if (WheelSize > 0.1f) {
        iC1 = drawYCbCrCircle(make_float2(p_X,p_Height-p_Y)/WheelSize, wh, center, radius,WheelTypeF,HueCtrl,0.0f,WheelZoom);
        iC2 = drawLumaRamp(make_float2(p_X,p_Height-p_Y)/WheelSize, wh, center);
    }

    if (dot(iC1,make_float3(1.0f,1.0f,1.0f))>0.0f) {iC0=iC1;}
    if (dot(iC2,make_float3(1.0f,1.0f,1.0f))>0.0f) {iC0=iC2;}

 
    // Example RGB values normalized to [0, 1]
    float3 RGB = make_float3(iC0.x,iC0.y,iC0.z);


    // Convert RGB to YCbCr using Rec. 709 coefficients
    float3 YCbCr = RGBtoYCbCr_Rec709(RGB);
    float Sat =  Saturation(YCbCr);
    float hueAngle = detectHue(YCbCr);
 
    float Alternate = 1.0f;
    float ViewType  = 2.0f;

    if ((BlackWhite == 1) && (dot(iC1,make_float3(1.0f,1.0f,1.0f))==0.0f) && Alternate == 1.0f) {iC0 = make_float3(YCbCr.x,YCbCr.x,YCbCr.x);}
 


    if ((Alternate == 1.0f && ViewType == 0.0f) || (ViewType == 2.0f)) {
        float hueAngleX = hueAngle;
        float3 RGBLeft = maxSaturatedRGBFromHue(hueAngle-HueOffset,0.5f,0.5f);
        float3 RGBMid =  maxSaturatedRGBFromHue(hueAngle      ,0.5f,0.5f);
        float3 RGBMid2 = maxSaturatedRGBFromHue(hueAngle      ,0.3f,0.3f);
        float3 RGBRight= maxSaturatedRGBFromHue(hueAngle+HueOffset,0.5f,0.5f);
        if (hueAngleX > (HueCtrl - 2.0f) && hueAngleX < (HueCtrl + 2.0f) && (dot(iC1,make_float3(1.0f,1.0f,1.0f))>0.0f)) {iC0 = RGBMid2;}
        hueAngleX = hueAngle - 360.0f;
        if (hueAngleX > (HueCtrl - 2.0f) && hueAngleX < (HueCtrl + 2.0f) && (dot(iC1,make_float3(1.0f,1.0f,1.0f))>0.0f)) {iC0 = RGBMid2;}
        hueAngleX = hueAngle + 360.0f;
        if (hueAngleX > (HueCtrl - 2.0f) && hueAngleX < (HueCtrl + 2.0f) && (dot(iC1,make_float3(1.0f,1.0f,1.0f))>0.0f)) {iC0 = RGBMid2;}
        if (Sat > SatLow+0.0001 && Sat < SatHigh) {
            hueAngleX = hueAngle;
            if (hueAngleX > (HueCtrl - 3.0f*HueRangeCtrl) && hueAngleX < (HueCtrl -        HueRangeCtrl)) {iC0 = RGBLeft;}
            if (hueAngleX > (HueCtrl -      HueRangeCtrl) && hueAngleX < (HueCtrl +        HueRangeCtrl)) {iC0 = RGBMid;}
            if (hueAngleX > (HueCtrl +      HueRangeCtrl) && hueAngleX < (HueCtrl + 3.0f * HueRangeCtrl)) {iC0 = RGBRight;}
            hueAngleX = hueAngle - 360.0f;
            if (hueAngleX > (HueCtrl - 3.0f*HueRangeCtrl) && hueAngleX < (HueCtrl -        HueRangeCtrl)) {iC0 = RGBLeft;}
            if (hueAngleX > (HueCtrl -      HueRangeCtrl) && hueAngleX < (HueCtrl +        HueRangeCtrl)) {iC0 = RGBMid;}
            if (hueAngleX > (HueCtrl +      HueRangeCtrl) && hueAngleX < (HueCtrl + 3.0f * HueRangeCtrl)) {iC0 = RGBRight;}
            hueAngleX = hueAngle + 360.0f;
            if (hueAngleX > (HueCtrl - 3.0f*HueRangeCtrl) && hueAngleX < (HueCtrl -        HueRangeCtrl)) {iC0 = RGBLeft;}
            if (hueAngleX > (HueCtrl -      HueRangeCtrl) && hueAngleX < (HueCtrl +        HueRangeCtrl)) {iC0 = RGBMid;}
            if (hueAngleX > (HueCtrl +      HueRangeCtrl) && hueAngleX < (HueCtrl + 3.0f * HueRangeCtrl)) {iC0 = RGBRight;}
        }

    }

    if (((Alternate ==1.0f && ViewType == 0.0f) || (ViewType == 2.0f) || (ViewType == 5.0f)) && (dot(iC1,make_float3(1.0f,1.0f,1.0f))==0.0f)) {
        if (YCbCr.x < LumaShadow     ) {iC0 = make_float3(1.0f,0.0f,0.0f);}
        if (YCbCr.x < LumaShadow/2.0f) {iC0 = make_float3(1.0f,1.0f,0.0f);}
        if (YCbCr.x > LumaHighlight  ) {iC0 = make_float3(0.0f,0.0f,1.0f);}
        if (YCbCr.x > LumaHighlight+(1.0f-LumaHighlight)/2.0f ) {iC0 = make_float3(0.0f,1.0f,1.0f);}      
    }

 
    return iC0;
}
 
Back
Top