Angle Visualizer
atan(y, x) computes the polar angle of any point around the origin. Normalize it to [0, 1] and you can use it to drive color. The key lines are:
Let’s break down what each step does.
What atan returns
atan(y, x) is the polar angle function. It returns the angle from the positive x-axis (3 o’clock) to the vector (x, y), measured counter-clockwise, in radians:
- Directly right (3 o’clock) → 0
- Directly up (12 o’clock) → +π/2 (≈ 1.57)
- Directly left (9 o’clock) → +π or -π (the seam)
- Directly down (6 o’clock) → -π/2 (≈ -1.57)
The range is [-π, +π], with a jump discontinuity on the left side.
Normalizing to [0, 1]
Adding π shifts the range from [-π, π] to [0, 2π]. Dividing by 2π compresses it to [0, 1]. Now the whole circle maps cleanly:
- 3 o’clock → t = 0.5
- Going counter-clockwise → t increases smoothly from 0 to 1
Using t as a grayscale value produces a smooth angle wheel rotating around the center.
Try changing it
| Change | Effect |
|---|---|
mix(vec3(1,0,0), vec3(0,0,1), t) instead of grayscale | Red-to-blue color wheel |
Change the center offset from 0.5 to 0.3 | Angle wheel shifts off-center |
fract(t * 3.0) | Angle divided into 3 repeating segments |
Add u_time * 0.3 to a before normalizing | Continuous rotation |
Exercise
The exercise has coordinates already centered at p, but a and t are not computed. Fill in both lines so the canvas displays a grayscale angle wheel from 0 to 1.
Answer Breakdown
Without these lines, t is undefined or 0, making the canvas black.
atan(p.y, p.x) returns each pixel’s bearing relative to the canvas center, in the range [-π, π]. Adding π shifts to [0, 2π], dividing by 2π brings it to [0, 1]. Each pixel’s t value represents where it sits around the circle, so the grayscale output is a smooth angular gradient radiating from the center.
Try replacing vec4(vec3(t), 1.0) with vec4(t, 1.0-t, 0.5, 1.0) to see a colorful angle wheel.