What Does the Fragment Shader Do in GLSL?
The primary function of the fragment shader stage in the OpenGL Shading Language (GLSL) is to calculate the final color, depth, and material properties of individual rasterized fragments before they reach the framebuffer. Executing near the end of the programmable rendering pipeline, the fragment shader takes interpolated data from earlier stages and determines exactly how each pixel-sized fragment will appear on screen by evaluating lighting models, sampling textures, handling transparency, and applying visual effects.
The Core Purpose: Determining Fragment Color and Attributes
When 3D primitives such as triangles are projected onto the screen, the GPU's rasterizer converts them into discrete fragments. A fragment is a potential pixel containing spatial coordinates, interpolated vertex attributes, and depth values. The fragment shader runs once for every single fragment produced by the rasterizer, serving as the central engine for pixel-level visual appearance.
Key tasks performed by the fragment shader include:
- Texture Mapping: Sampling 2D, 3D, or cube-map textures using interpolated UV coordinates to map surface detail, normal maps, and roughness maps onto 3D geometry.
- Lighting and Material Shading: Calculating per-pixel illumination using models such as Phong, Blinn-Phong, or Physically Based Rendering (PBR) algorithms to simulate diffuse, specular, and ambient reflections.
- Discarding Unwanted Fragments: Using the
discardkeyword to abort processing for fragments that meet specific conditions, such as alpha testing for cut-out foliage or wireframes. - Procedural Pattern Generation: Generating math-based visual effects directly on surfaces, including noise, gradients, scanlines, or ray-marched geometry.
- Custom Depth Output: Optionally modifying or
writing fragment depth values directly to
gl_FragDepthfor specialized depth-buffer operations.
Position Within the Graphics Pipeline
To understand the role of the fragment shader, it helps to see where it fits inside the standard OpenGL/GLSL pipeline:
- Vertex Shader: Transforms 3D vertex positions and attributes into clip-space coordinates.
- Primitive Assembly & Clipping: Connects vertices into shapes (triangles, lines) and removes geometry outside the view frustum.
- Rasterization: Breaks down primitives into discrete fragments and interpolates vertex outputs smoothly across the surface of the primitive.
- Fragment Shader: Evaluates the interpolated inputs to compute output colors and depth values.
- Per-Sample Operations: Tests the fragment against depth, stencil, and alpha blending configurations before finally committing the color to the framebuffer.
Because rasterization can generate millions of fragments per frame, the fragment shader is typically the most computationally demanding stage in real-time rendering.
Inputs and Outputs in Modern GLSL
Modern GLSL (version 330 and newer) relies on explicit inputs and outputs to communicate with the rest of the graphics pipeline:
- Inputs (
in): Receives smoothly interpolated variables generated by the vertex shader (such as surface normals, texture coordinates, and world-space positions). - Uniforms (
uniform): Accesses global variables set by the CPU application that remain constant across all fragments during a single draw call, such as light sources, camera positions, and texture samplers (sampler2D). - Built-in Inputs: Uses hardware-provided values like
gl_FragCoord(window-relative coordinates of the fragment) andgl_FrontFacing(indicates whether the fragment belongs to a front- or back-facing primitive). - Outputs (
out): Emits the calculated values to the bound framebuffer targets, most commonly avec4representing the RGBA color channels. In Multiple Render Target (MRT) setups used in deferred shading, the fragment shader can output multiple color vectors simultaneously to store position, normal, and albedo data into separate textures (G-Buffers).
By controlling the attributes of every visible fragment, the fragment shader bridges raw geometric data and the photorealistic, styled images displayed on the user's screen.