Joe Maller: Joe's Filters: Building Joe's RGB Desaturate

How I used FXScript to build my RGB Desaturation filter for Final Cut Pro.

Visit the New FXScript Reference and Joe's Filters sites. These pages will be phased out soon and may already be out of date.

Joe's Filters
FXScript Reference

This page describes the FXScript concepts behind Joe's RGB Desaturate. If you're looking for the page about how to use the filter, click here.


filter page which The biggest challenge in Joe's RGB Desaturate was figuring out how to move three of the values in the 3x3 matrix towards one amount while moving the other six values towards zero. Some testing showed that the matrix totals needed to equal one to maintain the balance of the original image. Setting any mix of the three color output channels to 1/3 produced grey. The tricky part was not just to assign that value but to get there gradually based on the desaturation slider value.

How it works

The solution I came up with is based on this formula:

Current - (Current - Target) * Desaturate

Current = current value
Target = Target value (0.33)
Desaturate = Desaturation amount from slider

That simple statement does the following: The Target value is subtracted from the Current value, resulting in the distance that must be travelled. That distance is then multiplied by the Desaturate value, which is a precentage between 0 and 100. The percentage of the distance is then subtracted from the Current value, resulting in the new value.

The Matrix

The basic matrix is defined via nine variables. Partly I did this because it's easier for me to work with, but mostly because I don't fully understand 3x3 matrix math yet. The page for Joe's 3x3 RGB Matrix Tester contains for a more detailed explanation of how the 3x3 RGB matrix works.

rr = 1; rg = 0; rb = 0
gr = 0; gg = 1; gb = 0
br = 0; bg = 0; bb = 1

After changing the values around, those values are transferred into an array with this statement:

mat = {rr, rg, rb, gr, gg, gb, br, bg, bb}

That matrix is then used as the source of a ColorTransform function:

colorTransform(Src1, Dest, mat, offset0, offset0);

(Offset0 is an empty placeholder array).

The Desaturation Value

Desaturation is set by a slider between zero and 100. This value is reversed early in the script:


The compound operator /= is a compound operator which would be the same as :

desat = desat/100

A listing of Compound Operators is on the FXScript Variables page.

Desaturate to Red

Each of the three colors uses a similar desaturation routine this is the code to desaturate to Red. The variable desat is a value decimal value between zero and one (a percentage):

gdif = (gg - rg)*desat
bdif = (bb - rb)*desat

gg = gdif
bb = bdif

rg = 1 - desat
rb = 1 - desat

mat = {rr, rg, rb, gr, gg, gb, br, bg, bb}

The first set of statements evaluate the difference between the target color and the current color value for each of the non-red primaries. The difference is then multiplied by the desat variable.

The second set transfers this value into the color primaries. I'm not sure why I didn't just compress these four lines into two, which would have the same effect:

gg = (gg - rg)*desat
bb = (bb - rb)*desat

The third set of lines sets the Red to Green (rg) and Red to Blue (rb) variables to the inverse of the desat variable. When desat equals zero, gg and bb also equal zero and rg and rb equal 1.


The complete FXScript source code for Joe's RGB Desaturate is included with the paid version of Joe's Filters.

Buy Joe's Filters Download the Free Trial

page last modified: October 23, 2017
Copyright © 1996-2003 Joe Maller