Joe Maller: FXScript Reference: Building Joe's Soft Gradients

How I used FXScript to build my Soft Gradients 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 Soft Gradients. If you're looking for the page about how to use the filter, click here.


Joe's Soft Gradients uses the same ideas and basically the same code as described in Joe's Gradients. If you haven't read Building Joe's Gradients, this page might not make much sense. Rather than duplicate everything, the code on this page picks up after the gradient code and just before the colors are corrected for opacity.

Instead of drawing the gradient in color, this filter uses the gradient as the alpha channel for a blurred copy of the source image. This blurred image is then composited back onto the original image.

Blur First

With the exception of a few inputs, Joe's Soft Gradients is the same as Joe Gradients. The code is identical until just before the highlight function. Since this filter uses no color, it replaces the color manipulations with blur commands:

Blur(src1, xbuffer, BlurAmount * zoomfactor, aspectOf(dest));

This statement places a blurred copy of src1 into xbuffer. BlurAmount is a radius value, multiplying it by zoomfactor makes sure that the desktop preview and the video output match up.


The HighLight() function is the same as Joe's Gradients except for the colors. Alpha channels are grayscale images, so the gradient only needs to blend from white to black. The FXScript Constants kBlack and kWhite are used to specify the gradient colors.

Highlight(dest, pointer, (GradAngle +90), GradWidth * zoomfactor, FadeLength/100 * ramplength, DitherCheck, GaussianCheck, kBlack, kWhite, aspectof(dest));

Dest was used as a temporary image buffer for the Highlight gradient, if the script ended here it would show a black and white gradient.

Building the Mask

Since the resulting gradient in dest is gray (all three color channels are identical), any of it's channels can be used as the source of the alpha mask. The following command moves the red channel into the alpha channel of xbuffer.

ChannelCopy(dest, xbuffer, kred, knone, knone, knone)

The ChannelCopy() function assigns source channels into target channels. The last four properties are a key to what goes where, first is Alpha, then Red, Green and Blue. The knone constant tells ChannelCopy() to leave the Red, Green and Blue channels of xbuffer unchanged. As discussed earlier, xbuffer contains a blurred copy of the source image, this operation only affects the alpha channel of this image.


Much like the alpha channel on Joe's Color Glow, the default alpha channel is the reverse of what I thought it should be. The Invert checkbox allows users to reverse the selected area by not inverting the alpha channel. TheSpotInvert checkbox is zero by default, so the alpha channel is inverted unless the user checks the box.

if SpotInvert == 0
   InvertChannel(xbuffer, xbuffer, 1, 0, 0, 0)
end if

Looking back, I should probably have just reversed the color order in the Highlight function. Even though InvertChannel is almost instantaneous, removing extraneous operations makes the filters just that little bit faster. Feel free to correct this on your own, I will do the same in the next version.


My standard set of composting controls merges xbuffer with src1 and places the result into dest.

The complete FXScript source code for Joe's Soft Gradients 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