Vertex Shaders

A waving flag looks as if thousands of pixels are moving. They are not. A vertex shader does not change pixels: it moves the corner points of a shape, and the graphics card fills in everything between them. Learn how vertices and UV addresses work, bend a banner into a waving flag, pass data from the corners to the…

8:49 video10 min readWatch on YouTube

Vertex Shaders

A waving flag looks as if thousands of pixels are moving. They are not. A vertex shader does not change pixels: it moves the corner points of a shape, and the graphics card fills in everything between them. Learn how vertices and UV addresses work, bend a banner into a waving flag, pass data from the corners to the pixels, and see what goes wrong. Part of a series on Godot shaders. Liam, in for Bear, narrates.

Chapters 0:00 Opening 0:08 The question 0:22 Key terms 0:38 I · Corners 2:26 II · More Corners 4:17 III · A Waving Flag 5:19 IV · Passing Data Forward 6:51 V · When It Looks Wrong 7:57 Recap 8:17 Your turn

Your turn. Paste this into Claude: Write a Godot canvas item shader for a waving banner. Draw it with a MeshInstance two D and a quad mesh cut thirty-one by seven. In vertex, move the corners up and down with a sine of the address across and the time. Make amplitude, frequency and speed float uniforms, and pin the left edge. Then tell me how many vertices the mesh has. Then check two things yourself.

  • Check: the left edge never moves while the rest ripples.
  • Check: the vertex count matches thirty-three by nine.

Sources

  • Godot 4.7 documentation, read 2026-10-13: introduction to shaders, canvas item shaders, shading language, and the Polygon2D, MeshInstance2D and QuadMesh class references (docs.godotengine.org/en/stable).
  • 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 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:22 — Key terms
  • 0:38 — I · Corners
  • 2:26 — II · More Corners
  • 4:17 — III · A Waving Flag
  • 5:19 — IV · Passing Data Forward
  • 6:51 — V · When It Looks Wrong
  • 7:57 — 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] Vertex shaders, learn how a shader moves the corner points of a shape and how to give a shape enough corners to bend. By the end, you can build a waving flag.

The question

[0:08] Hello, this is Liam in for Bear. A waving flag looks as if thousands of pixels are moving. They are not. A vertex shader does not change pixels. It moves the corner points of a shape and the graphics card fills in everything between them.

Key terms

[0:22] Five terms. A shader is a small program the graphics card runs to decide how something is drawn. A pixel is one dot of the picture. A vertex is a corner point of a shape. A polygon is a shape made of straight edges between points. To interpolate is to blend smoothly between two known values. This flag is

I · Corners

[0:39] Waving and not one pixel in it was told to move. One line of code moves its corner points and the graphics card fills in everything between them. That line lives in a function called vertex. A shape is built from corner points, its vertices. The engine calls vertex once for each one and asks a single question, where does this corner go? The engine hands you the corner's position in a built-in, a value it gives your function. Its name is vertex two in capital letters. Whatever you leave in it is where the corner goes. It counts in pixels from the middle of the sprite. A sprite 128 pixels wide has corners at minus 64 and 64. The Y axis points down, so the top corners are the minus ones. Change the number and the corner moves. Add 40 to X and every corner moves 40 pixels to the right. The whole square slides because the graphics card fills in the shape between the moved corners. The 40

Is in the node's own pixels, counted before the node is scaled. Here the right-hand square is scaled to twice its size, so the same 40 carries it 80 pixels across the screen. Multiply and the corners move toward or away from the middle. Here, one and a half times wider and half as tall, the square stretches and flattens. Still only four corners are moving. To treat corners differently, tell them apart. The engine gives each corner an address, too, called UV, zero to one across, zero to one down. Top left is zero zero, bottom right is one one. Now scale and move by the address. Add 50 times the vertical address to X. The top corners add nothing because their address is zero. The bottom corners add 50. The square leans. Only four corners moved. In between the card fills the shape in even steps. We measured the left edge 50 pixels over 128 rows on a straight line to within half a pixel. Remember that straight

II · More Corners

[2:26] Line. A slide, a squash, a lean, four corners are enough when the whole shape moves as one. A bend is different. Watch what a ripple does to a flag with four corners. A ripple is the sign of the address across scaled and added to Y. On this flag nothing ripples. The right end drops and every edge stays straight. Why vertex can only move the vertices that exist. Between two corners the card draws a straight line. A curve needs corners along the way for vertex to push up and down. So give the shape more vertices. Here are two ways in Godot. A polygon node where you place the points yourself or a mesh node which draws a mesh, the vertices and triangles that make a shape. A mesh instance 2D node draws a mesh. Give it a quad mesh, a flat rectangle you can cut into a grid. Subdivide width and subdivide depth say how many extra cuts to make across and down. Count them. Cut a quad mesh 3 by 3

And each side gets five corner points, 25 vertices, always two more than the cuts each way. The flag's 31 by 7 makes 33 by 9, 297. Same ripple, same picture. On the left four vertices a tilt, on the right 297 a ripple. Nothing in the shader changed, only how many corners it had to work with. More vertices a smoother wave. Four pieces show every joint, 10 soften them, 32 hide them. A rule of thumb, eight pieces per wave leaves the worst gap near 8% of the the height, 16 leaves about two. Cut only where it bends. This ripple runs along the flag, never up and down, so rows of vertices add nothing. 31 cuts across and none down gives 66 vertices and the picture matches pixel for pixel. A polygon node gives you one vertex per point you place. With points only around the edge, Godot fills the inside with long thin triangles and the picture twists. A grid of points joined into cells fixes it. Now let it travel. Time

III · A Waving Flag

[4:19] Is seconds on one clock shared by the whole game. Subtract it inside the sign and the ripple slides to the right as the seconds pass. But a flag is held at one end. Multiply the ripple by the address across. At the left edge, the address is zero, so nothing is added and that edge stays put like a pole. Three numbers shape the wave: how tall, how many waves fit, how fast. Make each a uniform, a value your game sets from outside the shader, the same for every vertex and pixel. Now the flag has three dials. Raise amplitude and the waves get taller. Raise frequency and more waves fit across. Raise speed and they travel faster. Each one changes only what its name says. Your game can turn the dials while it runs. When the wind picks up, call set shader parameter on the node's material with the dial's name and a new value. The flag answers at once. Read it as one, three dials at the top. In vertex, the wave, the address across minus time through a sign scaled by the dials pinned by the address. Nine lines, one of them moving the flag.

IV · Passing Data Forward

[5:19] The flag moves, but it looks like a flat sheet. Nothing shades the folds. Shading is a job for fragment, the function that colors each pixel the shape covers. But fragment runs later and it never sees the corners. The way across is a varying. In vertex, you set a value at each corner. In fragment, you read it. The graphics card interpolates it across the shape and it flows one way, forward. Four colors, one per corner set in vertex. Fragment only reads them. The result is a smooth blend and an exact one. Halfway along the top edge, red reads 1/2 the average of its two corners. Switch the blending off with flat and each triangle keeps one corner's value. A mesh cut into a grid shows it. The smooth blend breaks into tiles. A rectangle is two triangles and the blending happens inside each

One. The engine does this for you, too. UV is set at the corners and blended, which is why it is a smooth ramp. The color from vertex is passed on the same way and multiplied by the picture. So, light the folds in vertex, work out how the cloth slopes, and pass it as a varying. In fragment, darken the cloth where it slopes away. Now, the folds read as folds. There is a shorter way. The color already travels from vertex to fragment multiplied by the picture. Darken it in vertex and you need no varying and no fragment function. Same picture, pixel for pixel, with the dials back. One limit of varying is only as detailed as your corners. Six stripes computed in vertex vanish on four corners because both ends compute the same number. Computed in fragment at every pixel, the stripes are there.

V · When It Looks Wrong

[6:52] Some mistakes compile and still look wrong. First, in 2D, a quad mesh draws upside down. Give its size a negative Y and it stands up matching a sprite beside it. Second, the word vertex changes meaning. In vertex, it is the corner's position in the node's own pixels. In fragment, it is the pixel's position on the screen. Same word, different numbers. Move the node and you see it. Colored from the corner position, the gradient travels with the sprite. Colored from the pixel's screen position, the sprite slides across a gradient that stays where it is. Third, a polygon node only has UV when it has a texture. A texture is an image a shader can read. Without one, the address is zero everywhere and a wave multiplied by it never starts. Fourth, a vertex shader changes the drawing, not the node. This one draws the sprite 200 pixels away. The node's rectangle and its collision shape stay exactly where they were. We checked both. Last, when nothing waves, count the vertices. Ask a mesh for its vertex array and print the size here, 297. A polygon has one per point. A plane sprite has four and four cannot bend.

Recap

[7:58] Let's recap with Claude. Vertex runs once for each corner and decides where it goes. A shape can only bend where it has vertices. Cut a mesh until each wave has eight pieces or more. A flag is a sign of the address and the time pinned at one end with dials. A varying carries a value from the corners to every pixel. When it looks wrong, count the vertices and check what each position is measured

Your turn

[8:18] From. Your turn. Paste this into Claude. Write a Godot canvas item shader for a waving banner. Draw it with a mesh instance 2D and a quad mesh cut 31 by 7. In vertex, move the corners up and down with a sign of the address across and the time. Make amplitude, frequency, and speed float uniforms and pin the left edge. Then tell me how many vertices the mesh has. Then check two things yourself. Does the left edge stay still while the rest ripples? And does the vertex count match 33 by 9? Vertex shaders at Nick Bear Brown.

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

Nik Bear Brown Poet and Songwriter