Shaders are math-heavy and it doesn’t exist a single person who likes math. Hence Shaders are notorious for being difficult. But shaders are unique because they bring all these numbers together to create a color image output.
When we take these numbers out of our heads and into our eyes we find that a lot of them look like gradients. Everyone loves gradients. And while we still need to do the math, gradients are much easier to reason about both visually and verbally.
Here’s some shader code everyone can understand:
uv.x — is an horizontal gradient.
uv.y — is a vertical gradient.
sin(uv.x * 5.) — creates a gradient that repeats 5 times.
step(0.5,uv.x) — makes one side of the gradient white and the other black.
The change in perspective is small, but powerful because gradients are in every shader. We still need math, but now we can visually solve problems and then talk about them in plain english.
Shading boils down to creating a gradient that accurately represents a surface under a light. It usually looks like this:
dot(normal, lightPos) — Creates a gradient based on how directly any point in the object surface is looking at the light
In this case, toon shading, Renaud is taking that gradient and stepping it multiple times with different shades of grey/color.
There are also vertex shaders, which deal with the position of things instead of the colors. Gradients are less obvious, but they are just as relevant.
In this demo, Jaume (TheSpite) uses a diagonal gradient for the rotation and scaling of the hexagons. Over time he moves along the gradient and scales/rotates the hexagons.
In this game, the “squishiness” of the torus is made with a gradient from top to bottom used in two ways:
- Lower the y/height of the cylinder
- Make the x and z wider on the center of the gradient.
When we click on a project on Jesper’s site, we are greeted with two transitions using gradients: color swipe, and a circular image deformation.
Color swipe — step(swipeProgress, uv.y) A gradient from top to bottom (uv.y) slightly bent in the center, stepped along the gradient over time to make it black and white (swipeProgress).
Circular Image Deformation — distance(uv, vec2(0.5)) Creates circular gradient from the center (0.5) and is used to modify the z position.
Image transitions use gradients to mix switch between the images. Black means the firstImage, white means the secondImage, and the gradient in between is the combination of the two images/colors.
Image swipe — mix(firstImage, secondImage, gradient)
That’s the basics, but we can modify our gradient with noise, shaping functions, or the image itself!
If you enjoyed the read or have an interesting particle system to share let me know either by replying to this email or on Twitter!
Until next week,