Recently I came across an absolutely gorgeous game called Totem Teller. On their Tigsource thread, they described how they achieved certain visual effects in Unity, including using a gradient map to tint their levels. This left me wondering if I could achieve the same effect in Construct 2, and after some experimentation, I discovered how.
Creating the Gradient Map Object
Creating a gradient map on a singular object is fairly simple, but we want to use this to tint our entire level, not just one sprite. To do this, we need one large object above all other objects. I like to use a Sprite (which I have called Ramp), but a tiled background could also work, and I like to put this object on a layer called Effects, which goes above all the layers I want the object to affect.
We need a multitude of Construct 2 Effects on this object. Unfortunately, you won’t be able to do this in the free version because it exceeds the Effects limit, but for those with either the Personal or Business license, gradient maps can be achieved using the Effects that come with Construct 2 – no external downloads required!
The effects we need on the Ramp object, in this order, are as follows:
- Grayscale
- Color
- Replace Color
- Replace Color
- Replace Color
The grayscale Effect is fairly self-explanatory. It remove all color from the sprite. This may or may not be required – for me, removing the effect would occasionally cause a visual glitch, so I kept it. You may just be able to use a black sprite instead. Its intensity parameter should be set at 100.
The next effect, Color, applies the values of the background to the Ramp object. This effectively turns the whole level grayscale (since the sprite is grayscale), but also preps the next three effects to work. This needs to come before the next effect, otherwise you’re applying a gradient map to the individual sprite and not the level. There are no parameters on this effect.
The final three effects are the same effect – Replace Color. You’ll notice I named them “blacks” “grays” and “whites” though I prefer the terms “darks” “mids” and “lights” respectively (it’s a pain to rename them now).
The parameters on these effects vary and will be discussed below.
The blend mode should be set to normal. You may also want to delete the object at runtime if WebGL effects are disabled.
Creating the Gradient Map
Each of the Replace Color effects replaces one color (Source) with another (Replace). We’ll use these to replace the dark, middle, and light values each with a color, creating a gradient between the three. You’ll need a color ramp of three colors – one you want to replace dark values, one to replace medium values, and one to replace light values. You’ll also need
On the Replace Color – Darks effect, R Source, G Source, and B Source should all be 0. Tolerance should be 100
On the Replace Color – Mids effect, R Source, G Source, and B Source should all be 128. Tolerance should be 50
On the Replace Color – Lights effect, R Source, G Source, and B Source should all be 255. Tolerance should be 100.
On all effects, all of the Replace parameters will vary depending on the colors in the color ramp you made earlier. R, G, and B Replace should be the R G and B values for each color, respectively.
If you want, you can end here – you’ve successfully created a gradient map. Remember to keep this object on top, preferably on a separate layer.
You can also change the colors at runtime, which opens up a world of possibilities.
Changing Gradients at Runtime
Now that you have your object set up, we’ll need to code a little bit.
Right now I’m just using some code to change the gradient’s colors at the start of the layout, so I can assign each gradient a name and not have to apply the gradient to each room manually. You can do many more complicated things with this, like changing the gradient based on certain conditions, or perhaps even fading from one gradient to another.
Right now I’ll show you what the code looks like for assigning all of the colors to one gradient. This base bit of code can be altered to fit whatever needs you have.
In the Event Sheet, add a blank event, then add an Action to the Ramp object. The Action we will be adding is “Set Effect Parameter” under Appearance. You’ll remember that each value (R, G, and B) is a separate parameter, so we’ll need nine of these Actions – three Actions for each of the three effects.
Change the Effect dropdown for three of these Actions to the Darks Effect, three to the Mids Effect, and three to the Lights Effect.
Then within Darks, change one Parameter Index value to effect Parameter 3 (this one changes the R value), one to effect Parameter 4 (G), and one to effect Parameter 5 (B). Do the same for the actions affecting Mids and Lights – change the Parameter Index values so each has one effecting Parameter 3, 4, and 5.
Then for each, set the Value to the R, G, and B values for the gradient colors in your color ramps, just like when setting up the object in the first place.
Now that you have a blank event that changes the gradient values to the colors you want, you can make that event trigger with any condition you want. I have mine at the start of layout; yours can trigger on a button press, when the player steps on an object, or whatever suits your needs.
And that’s about it! Now we have a level tinted by a gradient map!
Some (probably-going-to-be) Frequently Asked Questions:
Does this cause performance issues?
- It might on some devices, but on the ones I’ve tested on (my desktop, my Surface Pro, and my nearly-six-year-old laptop) my game has run fairly well. I attempted to reduce any performance snags by applying the effects to only one object. I can’t say I’d recommend this setup for a game intended for mobile, but modern PCs should have no problem.
Can you add more colors?
- Maybe. Any time I try to add more, the colors begin to blend together. You can reduce the Tolerance on each effect, but I can’t figure out a good ratio to get it to look good. Let me know if you do!
Can you just assign colors directly from a color palette, instead of manually typing the numbers?
- While that would be so much easier, in Construct 2 there appears to be no “GetRGB” expression, which would be required to read the values from a color ramp. According to Scirra, “Getting pixels is generally not a good idea since it involves a very slow process of halting rendering and copying data from the GPU back to the CPU. … I prefer not to implement features like this, because if mis-used it absolutely kills the performance (and probably means people coming to the forum wondering why their game is slow).” (source)
If you’d like access to my .capx, I’ve uploaded it as a $10 reward on Patreon, as well as a tool that lets you type the RGB values and preview the gradient map. Subscribe to my Patreon for access to this and much more!