Richard Mattka focuses on generative colour animations and light effects
Shaders enable a wide range of effects by working directly with the graphics hardware of devices. In previous articles, we learned what shaders are and created our first ones. We also learned about post-processing, making greyscale and sepia tones, water animation effects and blurs, all with just a few lines of code.
This tutorial will explore some very powerful generative effects that can be created with colour and intensity. They are excellent examples of how little code is required to create incredible effects using GLSL. We’re just scratching the surface of what can be done but it will give you something practical you can use. My goal is to remove some of the mystery around shaders and get you inspired. I want to get you creating your own effects as soon as possible.
Generative colour and lights
Efficient, simple code loops, iterating over pixels demonstrate the power of GLSL. In previous tutorials we looked at colours and how easily gradients can be generated based on distances from a point. Beyond linear or radial gradients, we can use a variety of functions to help us create shapes and patterns, such as modulo, fraction, floor, ceiling, min and max. These can effectively constrain the values passed through the function. For example, we will use Modulo ( mod ), which returns the remainder of the first value divided by the second. You can visualise this as a linear slope until it hits the limit and then it repeats. Combining shaping functions with sin, cos, tan can create easing visually and in motion.
colour intensity distance shader
In previous tutorials we produced some cool effects with images and colour. This first shader shows you how simple shaping functions and distances can create beautiful generative effects. Let’s get started and make this effect.
In order to see our shader, we need to render it. As in previous articles we’ll make use of a WebGL rendering tool, such as Shadertoy. It gives us a nice code window to practice in and a render window to see our work.
To get started, open https://www.shadertoy.com/ new in a browser that supports WebGL. You’ll see a sample shader code all ready to go for you in the code window. Delete it, so we can write our own.
Type in this new code and press the black play icon at the bottom of the window. This will execute the shader code. You should now see a series of red animating rings of light. The pattern feels organic, as it flows smoothly between states. This technique is inspired from a mathematical approach by Danguafer/Silexar ( https:// www.shadertoy.com/view/XsXXDn). It is not only simple but also elegant, essentially based on two lines of code.
So what what’s going on in the code? To start, we follow our usual approach of normalising, centring and adjusting for aspect ratio. First, we get the fragCoord value, then normalise them by dividing by the screen iResolution. We use a variable to hold the colour and call it col . We also keep track of the length of p , which is effectively a distance from centre. Then we calculate the relationship of the current pixel ( p ) as a percent of the overall length ( p/l ) then multiply that out by a factor using time ( t ) so we see it animate over time.
We are effectively using a principle of diminishing return as the distance increases. Light works in this way, as its intensity decreases over the distance from its source. This is often represented by the inverse square law in the form: float lightness = 1.0/(dist*dist) . We are using a variation of this concept in these two lines (second and third last lines) combined with the division again of col by length ( l ) in the last line. Effectively we have divided the colour by l twice or (
l*l ) where l is the distance.
colour separation shader
We applied the effect previously to the red “channel” of the rgb array using col.r . But, using a simple loop, we can apply the same effect to each of the colour channels, with a little separation to generate a really beautiful effect.
Give the code here a try: You should now see a dynamic generative effect using all three colours. The colours are additive, which creates an interaction between the various lights and shapes. What is impressive is how little code is required to create an animation that can
play while constantly changing over time. The use of the iTime uniform enables the time to affect the animation changing continuously. Let it play for a while and you’ll see how it works.
We added a variable for intensity, which you can adjust for overall light strength. We also set up a simple for loop to iterate over the colour channels. This created a little separation, on each iteration between the colours.
liquid metal rings shader
The shader we made is colourful and dynamic and by adjusting values, you can see how easy it is to create your own variations. With a few tweaks we can desaturate this and create a more intentional pattern, like these metallic rings.
Try this new code out: You should see smooth, shaded rings, reflecting light to give the illusion of a metallic surface.
We updated our additive uv function to this: p/l*(sin(t)-1.)*(sin(l*20.)) . This is a reworking of the function to now use two sin functions and the 20. to intensify the affect of distance ( l ).
We can improve this further. By applying better colour separation and some lighting distances we can really make this animation stand out.
Here’s how the new code looks: Now we have something that looks pretty cool. It has a realistic metallic smooth look, with lighting and an interesting pattern between the rings.
We set up another speed variable, which we can adjust easier outside the loop and added an offset to start it further ahead in time. We moved uv and distance calculations outside the loop in order to stabilise the shape, which means that only the colours and lighting fluctuate.
This could make a nice landing page concept or piece of standalone generative art. Set some music with it and it could work as an introduction to a project. So have fun experimenting with this one.
Above A simple red, glowing light, circular animation
Far left Colour separation and more dynamics in this mesmerising generative animation Middle A metallic looking animation, desaturated and shaded Above right A stabilised, colourised pattern of metallic rings