Part 1: Fragment Shaders: Beginner's Guide
Fragment Shaders: The Foundation of Graphics
Fragment shaders are tiny programs that run on your GPU, determining the color of every single pixel on the screen. If you've ever marveled at computer-generated art, glowing effects, or wild procedural visuals, chances are fragment shaders made it possible.
How Fragment Shaders Work
The GPU graphics pipeline works by drawing geometry (shapes made of triangles) to the screen. Here's what happens:
- Vertex Processing: Your vertices (corner points of triangles) are processed and positioned
- Rasterization: The GPU figures out which pixels are covered by each triangle
- Fragment Shader: For each pixel covered by geometry, the fragment shader runs to determine that pixel's color
The fragment shader is a function that runs once for every pixel covered by your geometry. It receives information about the pixel's position, time, textures, and other data called uniforms, then outputs a color.
Coloring Different Shapes
Fragment shaders can color any shape—spheres, cubes, complex models—as long as that shape is made of triangles (which everything is in 3D graphics). Each pixel that falls inside a triangle gets processed by your fragment shader.
Two Triangles That Fill the Screen
For this series, we'll use the simplest possible geometry: two triangles arranged to fill the entire screen. This is perfect for learning because:
- Every pixel on screen runs through our shader
- We don't need to worry about 3D math or camera transforms
- All the visual complexity comes from the shader code itself
Think of it like having a blank canvas where we can paint anything using math. The triangles are just the surface—what we draw on them is up to us.
Basic Example: Gradient
Here's a simple shader that creates a gradient based on pixel position:
#version 300 es
precision highp float;
out vec4 fragColor;
uniform vec2 u_resolution;
void main() {
// Normalize pixel coordinates (0.0 to 1.0)
vec2 uv = gl_FragCoord.xy / u_resolution;
// Use UV coordinates as colors (red increases left to right, green bottom to top)
vec3 col = vec3(uv, 0.0);
fragColor = vec4(col, 1.0);
}
Try it out below—notice how the color changes based on position:
Visualizing the Two Triangles
Normally you'd never see the triangles themselves—they're just a surface for the shader to run on. But here's what they look like with outlined edges:
Key Concepts
- gl_FragCoord: The pixel coordinate being processed.
- uniforms: Values sent in from the CPU, like time (
u_time) or resolution (u_resolution). - vecN: A vector of N floats (e.g.,
vec2,vec3,vec4) used for positions and colors. - Math functions: Use functions like
sin,cos, andmixto generate patterns and animations.
What's Next?
In later posts, we'll build on this knowledge to:
- Make glowing shapes and gradients
- Simulate lighting and 3D with just math
- Combine multiple shaders into a single effect
- React to mouse input and audio
Whether you're making games, interactive art, or generative graphics, mastering fragment shaders is the first step. Happy shading!