Creative Coding With DCTL: Part 3

July 2, 2021

In part 3 of this ongoing series, with foundational knowledge in place, start coding your first DCTL a colorist Cullen Kelly guides you step by step.


Getting Hands-On With Our First DCTL

With the foundation we laid in the first and second installments of this series, we’re ready to code our first DCTL: a tool that applies programmer-specified amounts of lift, gamma, gain and offset.

Along the way, we’ll cover the following:

  • The importance of conceptualizing tools before we begin building them, and my method for doing so
  • The RGB color model
  • Basic image math
  • Using a DCTL template
  • Common syntax errors when coding DCTL

Today’s DCTL may not have much practical application, but after this Insight, we’ll be rapidly graduating to creating more complex and useful tools. Let’s dive in!

Concept First, Code Second

As we’ll do throughout this series, we’re going to begin our development process by writing out a brief summary of the proposed functionality of our tool. Even with simple tools like this one, creating this summary is a vital step in our process. Why?

Because in order to code effectively and efficiently, we need a simple, unambiguous concept to guide us, and the best way to confirm we have one is to write it out.

Think of it this way: if it’s at all difficult or time-consuming to describe your tool’s behavior in plain English, how much more trouble do you think you’ll have when you have to articulate it with non-intuitive code?

This tool, called LGGO, will apply a programmer-specified amount of gamma to the green channel, followed by a programmer-specified amount of offset to all three RGB channels of the image, followed by a programmer-specified amount of lift to the blue channel, followed by a programmer-specified amount of gain to the red channel.

As you can see, there’s nothing special about this summary except that it’s concise and easy to understand. We now have something to refer back to if we get lost, and which we can easily revise as we contemplate adding features or changing functionality.

The RGB Color Model

Throughout this series, we’ll be coding within the RGB color model, which specifies colors using a triplet comprised of a red value, a green value, and a blue value, each ranging from 0 to 1. Every DCTL we build will start with an input RGB triplet and will return an output RGB triplet.

I’ll often refer to the red, green, and/or blue values within our image as channels.

Basic Image Math

Since our LGGO tool will be applying offset, gamma, gain, and lift, it’s time to understand the mathematical operations that drive these behaviors. Thankfully, they’re very simple, and they’re always the same!

  • Offset is applied with addition. When we add to the value of one or more channels, every part of the channel(s) increases equally in value (or decreases if we add a negative number). Expressed in pseudo-code, we apply offset with the following formula: output = input + offset_factor
  • Gain is applied with multiplication. When we multiply the value of one or more channels by a number greater than 1, the higher values increase more rapidly than the lower values, and by the time we’re at zero, nothing happens at all, because zero times anything is still zero. With a gain factor of less than 1, our original values decrease rather than increase. Expressed in pseudo-code, we apply gain with the following formula: output = input * gain_factor
  • Lift can be thought of as the opposite of gain. Where gain has the greatest influence on the highest values in the signal, lift has the greatest influence on the lowest values. Expressed in pseudo-code, we apply lift with the following formula: output = input * (1 – lift_factor) + lift_factor
  • Gamma is a power function that affects the values between 0 and 1, while leaving 0 and 1 themselves unchanged (0 to the power of anything is 0, and 1 to the power of anything is 1). Expressed in pseudo-code, we apply gamma with the following formula: output = input ^ (1 / gamma_factor)
  • Note the use of two special characters in the pseudo-code for gamma: a carat, which can be read as ‘to the power of’ and a slash, which can be read as ‘divided by’.

Creating A Template DCTL

As we discussed in Part 1, all DCTLs must have at least one function in order to run, and this core function must be named ‘transform’ and be declared with specific input variables. Since this is a requirement for any DCTL we’re going to build, it makes sense to create a template DCTL that includes the function declaration as well as the input and return of an RGB triplet in the form of a float3.

1. __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 = {p_R, p_G, p_B};
return rgb;

You can copy and paste this code from your browser into your text editor, or you can use it as your starting point by opening and saving a copy of the Template.dctl I’ve published to my Gitfront (see the link at the end of this post).

Member Content

Sorry... the rest of this content is for members only. You'll need to login or Join Now to continue (we hope you do!).

Need more information about our memberships? Click to learn more.

Membership options
Member Login

Are you using our app? For the best experience, please login using the app's launch screen

1,200+ Tutorials, Articles, and Webinars To Explore

Get 7-day access to our library of over 1,200+ tutorials - for $5!
Do you like what you see? Maintain access for less than $5 per month.

Start Your Test Drive!