Discard - Built-in functions - Shader Learning

Built-in functions

Discard

Task

You are given a 3D cube with each face mapped using UV coordinates ranging from (0.0, 0.0) in the bottom-left to (1.0, 1.0) in the top-right corner of each face. Your task is to create a visual circular hole in the center of each face, with a radius of 0.25 in UV space.

Theory

The discard statement in GLSL/HLSL instructs the GPU to completely discard the current fragment, meaning it won’t be drawn or participate in further operations like depth testing or blending.


In a fragment shader, you can write:

if (alpha < 0.1)
    discard;

This tells the GPU: “don’t draw this fragment if it’s mostly transparent.” The fragment is skipped entirely - it produces no color, no depth, no stencil output.


Use discard in fragment shaders when you need binary visibility - for example, cutting out parts of textures (like alpha-masked leaves or fences), procedural holes, or stylized effects where fragments should either fully render or not render at all. It's especially useful for hard-edged transparency or selectively skipping fragments based on custom logic.


Early Z-Testing


In the GPU’s rendering pipeline, early Z-testing (also called early depth testing) allows the GPU to reject fragments before they enter the expensive fragment shader stage - based on whether they’ll be visible or hidden behind other geometry.


This optimization saves time by avoiding work on pixels that won’t be seen anyway.


How discard breaks Early Z


Once you use discard in your fragment shader, the GPU can’t know in advance whether a fragment will be discarded - because that decision now depends on shader logic.


As a result:

  • early Z is disabled

  • late Z-testing is used after fragment shading

That means every fragment is fully shaded, regardless of whether it ends up being visible. If you’re drawing lots of geometry with alpha-masked transparency (like grass, hair, or foliage), this can drastically increase fragment shader workload.