UV Coordinates

Your map of the screen

The Screen as a Canvas

Every pixel needs to know where it is. In shader programming, we use UV coordinates to give each pixel a unique address. Think of UV coordinates as a map of the screen, where every location has a two-number identifier.

The convention is straightforward: the bottom-left corner is (0, 0) and the top-right corner is (1, 1). The U coordinate (horizontal) increases as you move right. The V coordinate (vertical) increases as you move up.

Interactive: Move your mouse to see UV coordinates

U: 0.500V: 0.500

Move your mouse across the canvas

Notice how the values always stay between 0 and 1, regardless of the actual screen resolution. This normalization is powerful because it makes your shaders resolution-independent. A shader written for a 100x100 canvas will produce the same visual result on a 4K display.

Computing UV Coordinates

In GLSL, we compute UV coordinates by dividing the fragment position by the resolution:

vec2 uv = gl_FragCoord.xy / u_resolution;
glsl

gl_FragCoord gives us the pixel position in actual screen coordinates. If your canvas is 400 pixels wide, a pixel at the center has gl_FragCoord.x of 200. Dividing by u_resolution normalizes this to 0.5.

Visualizing UVs as Color

Here is a trick that will become your best debugging tool: you can visualize UV coordinates directly as colors. Set the red channel to the U coordinate and the green channel to the V coordinate:

void main() {
  vec2 uv = gl_FragCoord.xy / u_resolution;
  gl_FragColor = vec4(uv.x, uv.y, 0.0, 1.0);
}
glsl

UV Coordinates as Color

Bottom-left: (0, 0)
Bottom-right: (1, 0)
Top-left: (0, 1)
Top-right: (1, 1)

The result is a gradient that reveals the coordinate system visually. The bottom-left is black (0, 0). The bottom-right is pure red (1, 0). The top-left is pure green (0, 1). The top-right is yellow (1, 1), where red and green combine.

This pattern is so recognizable that experienced shader programmers instantly know when something has gone wrong with UV calculations just by looking at the color distribution.

Centering the Coordinate System

The 0-to-1 range is useful, but often we want the center of the screen to be our origin. We can transform our coordinates with a simple operation:

vec2 centered = uv * 2.0 - 1.0;
glsl

This maps our (0, 0) to (-1, -1) and our (1, 1) to (+1, +1). The center of the screen becomes (0, 0).

Compare: Standard vs Centered Coordinates

Origin at corner: (0, 0) to (1, 1)

uv=gl_FragCoord.xy/u_resolutionuv = \text{gl\_FragCoord.xy} / \text{u\_resolution}

Breaking down the math: multiplying by 2 expands the range from [0, 1] to [0, 2]. Subtracting 1 shifts it to [-1, 1]. The transformation is reversible: (centered + 1.0) / 2.0 returns you to standard UV coordinates.

Why Centering Matters

Centered coordinates unlock several capabilities that would be awkward or impossible with 0-to-1 coordinates.

Symmetry becomes natural. When you want something to be symmetric around the center of the screen, having (0, 0) at the center means you can use the same math for all four quadrants.

Distance from center is just length. With centered coordinates, calculating how far a pixel is from the center is simply length(centered). This is the foundation for drawing circles.

Rotation works correctly. When we rotate coordinates in the next chapters, we rotate around the origin. If your origin is at the corner, everything spins around the corner. If your origin is at the center, everything spins around the center.

Interactive: Centered Coordinate Explorer

Distance from center creates perfect circles

Notice how the distance visualization creates perfect concentric circles. This is only possible because our coordinate system has its origin at the center.

Aspect Ratio

There is one subtlety we have glossed over. If your canvas is not square, the coordinate system gets stretched. A value of 0.5 in U might represent 200 pixels horizontally, while 0.5 in V represents 300 pixels vertically.

To correct for this, we can multiply one axis by the aspect ratio:

vec2 uv = gl_FragCoord.xy / u_resolution;
uv.x *= u_resolution.x / u_resolution.y;
glsl

This ensures that a circle drawn using length(uv) actually looks circular rather than elliptical. We will use aspect ratio correction throughout the course whenever geometric accuracy matters.

Looking Ahead

UV coordinates are your canvas. In the next chapter, we will learn how to transform this canvas: moving it, scaling it, and bending it to create complex effects from simple math.

Key Takeaways

  • UV coordinates map every pixel to a value between 0 and 1
  • The bottom-left is (0, 0), the top-right is (1, 1)
  • Visualizing UVs as red and green is a powerful debugging technique
  • Centering with uv * 2.0 - 1.0 moves the origin to the screen center
  • Centered coordinates make distance, symmetry, and rotation calculations natural
  • Aspect ratio correction keeps circles circular on non-square canvases