Skip to main content
GameDev.net gamedev.net

Understanding UV Coordinates

by GameDev.net · GLSL ES 3.00 (WebGL2) · 25 Aug 2026

Use in your engine

Run the shader to adjust these controls.

What it demonstrates

This shader makes normalized UV coordinates visible as color. Horizontal position becomes red, vertical position becomes green, and blue stays at zero. The View mode stepper can isolate either axis in grayscale, turning an abstract pair of numbers into a practical coordinate debugging view.

Source Revision 1

Author notes are linked to specific lines.

Shader inputs

void mainImage(out vec4 fragColor, in vec2 fragCoord)

Called once per pixel. Write the colour to fragColor.

iResolution vec3
Viewport size in pixels (z is the pixel aspect ratio).
iTime float
Seconds since the shader started.
iTimeDelta float
Seconds since the previous frame.
iFrameRate float
Frames per second, smoothed.
iFrame int
Frames rendered since the start.
iMouse vec4
Mouse position: xy while held, zw of the last click.
iDate vec4
Year, month, day, and seconds within the day.
iChannel0 sampler2D
Texture bound to channel 0.
iChannel1 sampler2D
Texture bound to channel 1.
iChannel2 sampler2D
Texture bound to channel 2.
iChannel3 sampler2D
Texture bound to channel 3.
iChannelResolution vec3[4]
Pixel size of each bound channel texture.
iChannelTime float[4]
Playback time of each channel, in seconds.
iSampleRate float
Audio sample rate, always 44100.
Main Image5
1 uniform int uViewMode; // @param 0..2 = 0 "View mode"
2
3 void mainImage(out vec4 fragColor, in vec2 fragCoord) {
4 vec2 uv = fragCoord / iResolution.xy;
5 vec3 coordinateColor = vec3(uv, 0.0);
6
7 if (uViewMode == 1) {
8 coordinateColor = vec3(uv.x);
9 } else if (uViewMode == 2) {
10 coordinateColor = vec3(uv.y);
11 }
12
13 fragColor = vec4(coordinateColor, 1.0);
14 }
15

Learn from this shader

How it works

fragCoord arrives in pixels, so its range changes with the viewport. Dividing by iResolution.xy produces a vec2 whose components run from approximately zero at the lower-left to one at the upper-right. Those values already fit the normal display color range. In combined mode, placing the two components in red and green creates yellow where both are high. The other modes copy one component into all three color channels, making that axis easy to inspect. The output alpha remains fully opaque.

Try changing

Switch among all three View modes and identify which edge represents zero for each axis. In a fork, reverse an axis with 1.0 - uv.x, swap the components with uv.yx, or center the coordinates by subtracting 0.5. Notice that centered negative values cannot be displayed directly without remapping them back into zero-to-one color space.

Using it in a game

UV visualization is a useful debug material for meshes, sprites, full-screen effects, and generated geometry. It reveals flipped axes, seams, stretching, and unexpected coordinate ranges. Engines supply UVs through different inputs, but encoding coordinates as color remains a portable diagnostic technique.

Explore the techniques

Continue with curated explanations and progressively related examples.

LicenseMIT
Views1
Forks0

Discussion

Loading comments...