Posts

Going Further with `cos()`: Building More Natural Animations

0 comments·0 reblogs
hey2d
25
·
0 views
·
min-read

In the previous tutorial, we learned how to use the sin() function to animate shaders. By combining it with uTime, we created moving gradients, pulsing colors, and our first procedural waves.

The sin() function is one half of a pair that appears everywhere in computer graphics.

The other half is cos().

At first glance they look almost identical, and in many ways they are. The difference is not how they move, but when they move.

That small difference allows us to create circular motion, phase shifted animations, and much more natural procedural effects.

Before You Continue

This tutorial builds on the previous lessons.

Part 1: Your First Shader: Painting the Entire Screen One Color

Part 2: Understanding UV Coordinates: The Secret Behind Every Shader

Part 3: Your First Gradient: Using UV Coordinates to Paint Space

Part 4: Mixing Colors with mix(): Creating Smooth Color Transitions

Part 5: Keeping Values Under Control with clamp()

Part 6: Adding Contrast with pow(): Making Gradients More Interesting

Part 7: Repeating Patterns with fract(): Creating Infinite Tiles

Part 8: Drawing Sharp and Smooth Edges with step() and smoothstep()

Part 9: Bringing Shaders to Life with Time

Part 10: Creating Waves with sin(): Your First Animated Shader

Now we are going to expand on those ideas with cos().
Image from thread

What Is cos()?

The cos() function behaves very much like sin().

Its syntax is almost identical.

cos(value) 

Like sin(), the result always stays between

-1.0 
 
and 
 
1.0 

It rises and falls forever.

The difference is where the animation begins.

Comparing sin() and cos()

Let's compare the two.

sin(0.0) 

returns

0.0 

Now try

cos(0.0) 

The result is

1.0 

That means cos() starts at the top of the wave while sin() starts in the middle.

They have the same shape.

They simply begin at different positions.

Visualizing the Difference

Imagine two people running around the same circular track.

One starts at the top.

The other starts a quarter of the way around.

Both travel at exactly the same speed.

They are following the same path, but they are never standing in the same place.

That is exactly how sin() and cos() behave.

Creating Your First Cosine Animation

Let's animate brightness.

float value = cos(uTime); 
 
value = value * 0.5 + 0.5; 
 
gl_FragColor = vec4(vec3(value), 1.0); 

Just like the previous tutorial, the screen gently pulses.

The only difference is that the animation begins at full brightness instead of halfway.

Why Does This Matter?

Starting at a different point might not seem important.

However, once you combine multiple animations, it becomes extremely useful.

For example, imagine two lights.

float lightA = sin(uTime); 
 
float lightB = cos(uTime); 

While one light reaches maximum brightness, the other is already changing.

This creates much more interesting movement than using two identical animations.

Creating Circular Motion

One of the most famous uses of sin() and cos() is creating circles.

Look at this code.

vec2 position = vec2( 
 
    cos(uTime), 
 
    sin(uTime) 
 
); 

Instead of moving in a straight line, the point moves in a perfect circle.

Why?

The horizontal position follows a cosine wave.

The vertical position follows a sine wave.

Together they trace a circular path.

This technique appears everywhere in computer graphics.

Moving a Circle

Suppose you already know how to draw a circle.

Instead of placing it at the center, you can animate its position.

vec2 center = vec2( 
 
    0.5 + cos(uTime) * 0.2, 
 
    0.5 + sin(uTime) * 0.2 
 
); 

Now the circle orbits around the middle of the screen.

Changing only two numbers creates smooth circular movement.

Creating More Organic Motion

Nothing says both waves must have the same speed.

Try this.

vec2 motion = vec2( 
 
    cos(uTime), 
 
    sin(uTime * 0.5) 
 
); 

Now the movement becomes much less predictable.

Small differences like this often make animations feel more natural.

Combining sin() and cos() with Colors

Let's animate two color channels independently.

float red = sin(uTime) * 0.5 + 0.5; 
 
float blue = cos(uTime) * 0.5 + 0.5; 
 
gl_FragColor = vec4(red, 0.2, blue, 1.0); 

The red and blue channels now pulse at different stages.

Instead of flashing together, they smoothly exchange brightness.

Mixing with mix()

We can even animate the blend value.

float t = cos(uTime) * 0.5 + 0.5; 
 
vec3 color = mix( 
 
    vec3(0.1, 0.4, 1.0), 
 
    vec3(1.0, 0.2, 0.5), 
 
    t 
 
); 
 
gl_FragColor = vec4(color, 1.0); 

The transition feels continuous because the cosine wave never suddenly changes direction.

Combining with UV Coordinates

Now combine UV space with cosine.

float wave = cos(vUv.x * 12.0 + uTime); 
 
wave = wave * 0.5 + 0.5; 
 
gl_FragColor = vec4(vec3(wave), 1.0); 

The result is a moving wave travelling across the screen.

Notice how similar it is to the sine wave from the previous lesson.

The animation simply begins at a different point.

Where Are sin() and cos() Used?

These two functions appear in countless shaders.

Some common examples include

  • Water surfaces
  • Floating objects
  • Audio visualizers
  • Circular motion
  • Camera shake
  • Neon signs
  • Pulsing lights
  • Smoke
  • Clouds
  • User interface animations

Whenever you see smooth repeating movement, there is a good chance one of these functions is involved.

Try These Experiments

Animate brightness.

cos(uTime) 

Move faster.

cos(uTime * 3.0) 

Move more slowly.

cos(uTime * 0.4) 

Create a moving wave.

cos(vUv.x * 8.0 + uTime) 

Create circular movement.

vec2( 
 
cos(uTime), 
 
sin(uTime) 
 
) 

Change the speed, multiply the waves, and combine them with the techniques from previous tutorials.

A Small Challenge

Can you create these animations?

  • A circle moving around the center of the screen.
  • Two colors that pulse at different times.
  • Waves moving from left to right.
  • Slow floating motion.
  • A shader that combines sin() and cos() in the same animation.

Try solving them before reading the next tutorial.

The more you experiment, the more comfortable these functions become.

What We Learned

The cos() function behaves almost exactly like sin(), but it begins at a different point in the wave.

That simple difference allows us to create phase shifted animations and combine multiple waves without everything moving together.

When sin() and cos() work as a pair, they become one of the most powerful tools in procedural animation.

Posted Using INLEO