blog

home > blog >

Shaders in sketches — Step

— 5 min read

Welcome to a small series of short posts where I thought of sharing how my brain works when it tries to explain to me some of the GLSL built-in functions I use when I make pixel shaders.

Shaders can be a rather complex and intimidating computer program to explore when one's new to it, but maybe it's all about perspective and how one can interpret the program pieces to make them work.

Maybe so far everything you've read or watched hasn't triggered your aha moment. Maybe your thoughts haven't been able to put the puzzle pieces together yet —— don't give up! Maybe these short posts might share a little light in the tunnel.

Understanding what exactly some of the GLSL standard functions do, has helped me in my quest to understand and write pixel shaders. Perhaps my way of understanding can help others too.

By the way, I'm starting a newsletter. If you prefer to skip this post, go to the newsletter section directly.

Step function

To get started, let's travel through the step() function, which takes two parameters to compare:

  step(edge, x)  

The links in the references below give us a description for this GLSL function:
0.0 is returned if x < edge, and 1.0 is returned otherwise.

But what does that mean? In my head, seeing a mathematical graph wasn't enough. My aha moment arrived, once I visualized the function as a tall wall separating two sides with solid colors.

ilithya's sketch of a wall in the y coordinate
Shader sketch of GLSL step function: x = y
© ilithya

The two colors are black and white. Black when getting 0.0, and white when getting 1.0. In a pixel shader or better known as a fragment shader, the color outputted in your screen comes from a vector with four values — vec4().

That vec4() is the returned value of gl_FragColor which takes the first three values as an RGB color model and the last value as an alpha value for transparency. By focusing on a vec3() inside that vec4() containing three values, we can guess the color appearing in the screen — vec3(R, G, B):

  • 1 value for R (red channel)
  • 1 value for G (green channel)
  • 1 value for B (blue channel)

For this exemplification, if step() results in 0.0, we can assign that value to all of those three values from the RGB color model as a vec3(0.0, 0.0, 0.0), which in GLSL it can also be declared as a vec3(0.0).

If we dig deep into the RGB color model, colors can be expressed in different ways. One is as a percentage, where the black color is represented with three values (0%, 0%, 0%), and another one is the regular 8-bit (0, 0, 0).

The white color in the 8-bit expression is (255, 255, 255), while as a percentage (going from 0%-100%) is (100%, 100%, 100%), which in GLSL translates as a vec3() with three floating-point numbers as values — vec3(1.0, 1.0, 1.0) = vec3(1.0).

No matter if x is a linear coordinate or a distance between two or more points in a plane, build an imaginary wall splitting two colors. As long as I visualize such a wall growing from the edge whenever I use this function, I can make a clear picture of what that code will draw.

ilithya's sketch of a wall surrounding a circle in a plane
Shader sketch of GLSL step function: x = length()
© ilithya

References:

Newsletter

I'm starting a tiny newsletter where I intend to share the rest of this series of posts with sketches.

I'll probably still post them eventually here on my blog, but if you prefer to receive them in your mailbox, subscribe!

It might be possible I'll also share other news about personal projects, art + tech topics, and whatnot.

You can expect no schedule and no spam. I imagine the most frequently I could write would be weekly or biweekly. Maybe once a month or every couple of months. It all depends on the flow and feel + life. ✌🏽