SDF Rectangle

11 / 18
Practice core GLSL math building blocks used across shaders.

The rectangle signed distance function (SDF) computes each pixel's distance to the nearest box edge in a single call:

Let's break it down.


What is an SDF?

An SDF (Signed Distance Field) gives every pixel a signed distance value:

  • Negative: inside the shape
  • Zero: exactly on the boundary
  • Positive: outside the shape

With this single number, one smoothstep call is enough to draw a shape with smooth edges — no complex rasterization needed.


How sdBox works

p is the pixel position relative to the box center. b is the half-extent of the box — e.g. vec2(0.2, 0.12) means a box that's 0.4 wide and 0.24 tall.

abs(p) - b exploits symmetry so only the first quadrant matters:

  • Negative result → pixel's x or y is inside the box
  • Positive result → pixel extends past the box

length(max(d, 0.0)) handles the outer corner distance; min(max(d.x, d.y), 0.0) handles the interior and edge regions. Adding them gives the complete signed distance.


Turn the distance into a mask

  • d < 0 (inside) → smoothstep = 0 → mask = 1 (white)
  • d > 0.01 (outside) → smoothstep = 1 → mask = 0 (black)
  • 0 to 0.01 → smooth transition

The 0.01 controls edge softness — smaller is sharper.


Try changing it

ChangeEffect
Change vec2(0.2, 0.12) to vec2(0.3, 0.3)Perfect square
Change vec2(0.2, 0.12) to vec2(0.4, 0.05)Thin horizontal bar
Change 0.01 to 0.05Softer, blurrier edge
Change to smoothstep(-0.01, 0.01, d)Wider softening zone at the edge

Exercise

Call sdBox(p, vec2(0.2, 0.12)) to compute the distance d, and display a white rectangle on a black background.

Answer Breakdown

p = vUv - 0.5 moves the origin to screen center. sdBox computes the signed distance from each pixel to a box centered at origin with half-extents (0.2, 0.12). 1.0 - smoothstep(0.0, 0.01, d) converts negative values (inside) to 1 (white) and positive values (outside) to 0 (black), with a 0.01-wide soft transition at the edge.

The exercise starts with float d = 0.0, which puts every pixel exactly at the boundary — the mask result is uniform. Replace it with the correct sdBox call to see the rectangle appear.

Try vec2(0.1, 0.25) to see a tall vertical bar instead.

GLSL Code Editor

Correct Code Preview

Current Code Preview