Trigonometry for Shaders

Most of us met trigonometry as triangles on paper, and forgot it. In a shader it does one job: it turns an angle into a position, and back again. See sine, cosine, radians and the unit circle drive a planet, a moon and a meteor on orbits, then run it backwards with arc tangent to get an angle from a position. Part of…

8:45 video10 min readWatch on YouTube

Trigonometry for Shaders

Most of us met trigonometry as triangles on paper, and forgot it. In a shader it does one job: it turns an angle into a position, and back again. See sine, cosine, radians and the unit circle drive a planet, a moon and a meteor on orbits, then run it backwards with arc tangent to get an angle from a position. Part of a series on Godot shaders. Liam, in for Bear, narrates.

Chapters 0:00 Opening 0:08 The question 0:19 Key terms 0:34 I · One Angle, Two Numbers 1:35 II · Angle In, Position Out 3:30 III · An Orbit 5:16 IV · An Orbit Around an Orbit 6:05 V · Angle from a Position 7:56 Recap 8:17 Your turn

Your turn. Paste this into Claude: Write a Godot canvas item shader for a square Color Rect: a teal planet in the middle and a smaller moon that circles it once every four seconds. Place the moon with cosine and sine of an angle in radians, and point me to the line that sets the speed. Then check two things yourself.

  • Check: the moon completes one lap in about four seconds.
  • Check: it turns clockwise, and negating the angle reverses it.

Sources

  • Godot 4.7 documentation, read 2026-10-13: the Vector2 class reference, canvas item shaders, built-in shader functions, and matrices and transforms (docs.godotengine.org/en/stable).
  • Khronos OpenGL ES 3 reference page for atan (registry.khronos.org/OpenGL-Refpages/es3.0/html/atan.xhtml), read 2026-10-13.
  • Godot 4.7.2 itself: every result on screen is a scripted capture of a real run, with its renderer stated.

Honest notes. The narration is a synthetic voice (Liam, in for Bear) and has not yet been reviewed by ear. The Godot documentation passage shown at 1:59 and 6:24 is a quote card of the docs text, recorded 2026-10-13, not a screenshot of the page. The numbers in the film were run in Godot 4.7.2 on an Apple M4 Pro. The facts have not yet been signed off by Bear. Nobody has watched this film yet.

Made with the brutalist.art toolkit: Manim, Remotion and Kokoro, free and local. An independent educational film.

What this video covers

  • 0:00 — Opening
  • 0:08 — The question
  • 0:19 — Key terms
  • 0:34 — I · One Angle, Two Numbers
  • 1:35 — II · Angle In, Position Out
  • 3:30 — III · An Orbit
  • 5:16 — IV · An Orbit Around an Orbit
  • 6:05 — V · Angle from a Position
  • 7:56 — Recap
  • 8:17 — Your turn

Transcript

A lightly formatted transcript of the video, with timestamps so you can jump to any section on YouTube.

Opening

[0:00] Trigonometry for shaders. Learn what sine and cosine really do, then use them to send a moon around a planet and reveal a picture like a clock hand.

The question

[0:08] Hello, this is Liam in for Bear. Most of us met trigonometry as triangles on paper and forgot it. In a shader, it does one job. It turns an angle into a position.

Key terms

[0:19] Five terms. An angle is an amount of turn. A radian is an angle measured so that a full turn is about 6.28. The hypotenuse is the longest side of a right triangle. A vec 2 is a bundle of two numbers. And UV is a pixel's address, zero to one across and down.

I · One Angle, Two Numbers

[0:34] A moon circles a planet and a meteor circles the moon. Nobody animated it by hand. In the shader, an angle goes in and two numbers come out that say where the moon is. Those numbers come from a triangle. Start with a triangle that has a right angle in one corner. Its longest side is the hypotenuse. Now, pick another corner. The side across from it is the opposite side. The side touching it is the adjacent side. Here is the useful part. Fixed the angle and the ratio of any two sides stays fixed, whatever the size. At 30°, the opposite side is always half the hypotenuse. At 50, about 0.77 of it. Those ratios have names. Opposite over hypotenuse is the sine. Adjacent over hypotenuse is the cosine. Opposite over adjacent is the tangent. The memory trick is SOH CAH TOA. So, sine and cosine are lookups. Hand one an angle and it hands back a ratio. Sine of 30° is 1/2. Cosine Sine of 30° is about 0.87. An angle goes in, a number comes out. Now, put that triangle

II · Angle In, Position Out

[1:36] Inside a circle. Walk out from the middle at your angle until you reach the circle. The triangle's two short sides say where you stand. So far across, so far up. Make the radius one and you have the unit circle. The hypotenuse is one, so dividing by one changes nothing. The opposite side is the sine itself, the adjacent side the cosine itself. The point sits a cosine across, sine up. Godot's own manual says the same. Vector 2 has a function from angle that builds a point from an angle. The manual calls it equivalent to cosine of the angle, sine of the angle. The engine knows the recipe. Want a bigger circle? Multiply by the radius. Want it somewhere else? Add the center. So, center plus radius times cosine and sine puts a point on a circle of any size anywhere. Try one by hand. Radius 0.6, angle 30°. The first number is 0.6 times about 0.52. The second is 0.6 times sine, exactly 0.3. Hold on to those two numbers. One catch,

Shaders measure angles in radians, not degrees. Lay one radius along the edge of the circle and the angle it covers is a radian. A full turn takes a little over six of them, about 6.28. Godot names the big ones. Pi is half a turn. Tau is a full turn, which is 2 pi. And the function radians converts degrees, so 45° comes out as pi over 4. Skip the conversion and the shader still compiles. That is the trap. 30 radians is almost five full turns, so sine of 30 comes out near minus one. Convert first and sine of 30° is 1/2 again. Why is sine a wave? Plot the point's height against its angle as it goes round. The height climbs to one, falls through zero to minus one, and comes home. That curve is the sine wave. Cosine is the across distance and it draws the same wave a quarter turn earlier. When one is at its peak, the other is at zero. Two waves a quarter turn apart make a circle.

III · An Orbit

[3:30] Now a shader. It runs once for each pixel and UV says where that pixel is. Double it and subtract one and the range becomes minus one to one with zero zero in the middle. Call that P. The planet is a distance test. Length of P is how far a pixel sits from the middle. Under the radius, paint planet color. A circle is every point at one distance from its center. The moon is the same test around another center. That center is .6 * cosine and sine of an angle. Distance measures how far apart two points are. Within .08 of it, a pixel is moon. Run it at 30° across .52 as calculated, but the second number .3 put the moon below the middle, not above. That is the next catch. On paper, up is positive. On a screen, Y counts downward. The formulas stay the same and the picture flips. Down is a quarter turn and a growing angle turns clockwise. Godot's manual agrees. Now, let the angle be time, the

Game's clock in seconds. As time counts up, the angle grows and the moon goes round clockwise. One line changed and nothing is animated by hand. Scale the time and you scale the speed. Time * 2 and the moon goes round twice as fast. The speed of an orbit is how fast the angle grows. An angle names a spot on the circle, so you can add to it. Add a third of a turn, tau over three, and a moon sits a third of the way round. Loop three times and three moons sit evenly spaced. One limit, the shape has been a square. On a wide one, UV still runs zero to one both ways, so circles come out oval. Scale P's X by width over height, passed in as a uniform, and they are round again. That is the whole recipe, a center, a radius, and an angle that grows. The radius sets the size. The center sets the place. The angle speed sets the pace. Change one and the orbit follows.

IV · An Orbit Around an Orbit

[5:16] Now, a meteor around the moon. The moon moves, so the meteor's center moves with it. Take the moon's position and add the meteor's own circle on top. Positions add, so circles can ride on circles. In code, that is one more line. The meteor is the moon plus a small radius times cosine and sine of its own angle. Give that angle time times three, and the meteor outpaces the moon. Watch it run. The meteor laps the moon three times for every lap the moon makes around the planet. Two ordinary circles, one riding on the other. Negate the meteor's angle and it circles the other way while the moon keeps its direction. The minus sign mirrors the point. Same circle, opposite spin. Any depth works. Each level is a center plus a radius times cosine and sine of an angle. Chain two and you have an arm with an elbow. Chain three and you have a tentacle.

V · Angle from a Position

[6:05] So far an angle went in and a position came out. Now run it backwards. A pixel knows where it is. What angle does it sit at seen from the middle? Tangent was opposite over adjacent. Arc tangent undoes it. Give it the two sides and it hands back the angle. For a pixel, the two sides are how far across it sits and how far down. In a shader, arc tangent takes two numbers, Y first then X. Their signs pick the quarter of the circle. So the answer covers the whole turn from minus pi to pi. Godot's reference says exactly that. Zero is straight right. Straight down is half pi, a quarter turn clockwise. Straight left is where it wraps, nearly plus

Pi right below that line, nearly minus pi right above it. Past the wrap, straight up is minus half pi. See it as a picture. Divide by tau and add one half and minus pi to pi becomes zero to one. Then mix from teal at zero to amber at one. The hard edge on the left is the seam. A common slip is passing one number, Y divided by X. Dividing throws away the signs. So opposite directions get the same answer and the left half repeats the right. Pass both numbers. Work one pixel up into the left at minus point three minus point three. Arc tangent says minus three quarters of pi. Divide by tau, minus point three seven five. Add one

Half, point one two five, one eighth. Now compare. A uniform is a number your game sets from outside and this one is called sweep. If a pixel's number is below sweep, show the picture. Raise sweep from zero to one and a clock hand reveals it. That hand starts at 9:00 where the seam is. To start at 12:00, move the seam. Add a quarter turn, point two five, and keep only the part after the decimal point with fract. The angle is a number, so feed it to cosine again. Multiply it by eight and the edge of a circle swells and shrinks eight times as you go round a flower. Subtract time from the angle and the flower turns. Let's recap with

Recap

[7:57] Claude. An angle fixes the ratios of a right triangle, sine, cosine, and tangent. On the unit circle, cosine and sine are the point at an angle. Angle in, position out. Shader angles are radians and a full turn is tau. An orbit is a center, a radius, and an angle that grows. A circle center can itself be on an orbit. Arc tangent runs it backwards. A position gives back its angle. Your

Your turn

[8:18] Turn. Paste this into Claude. Write a go dough canvas item shader for a square color rect, a teal planet in the middle and a smaller moon that circles it once every 4 seconds. Place the moon with cosine and sine of an angle in radians and point me to the line that sets the speed. Then check two things yourself. Does the moon finish a lap in about 4 seconds? And does it turn clockwise so that negating the angle reverses it? Trigonometry for shaders at Nick Bear Brown.

More from CSYE 7270 Virtual Environments and Real-Time 3D

Nik Bear Brown Poet and Songwriter