PDF Shading
PDF shading defines a smooth colour transition across an area, used for gradient fills and lighting effects. Shading is specified by a shading dictionary with a shading type (axial, radial, free-form mesh, etc.) and a colour function mapping position coordinates to colour values. Shading can be painted directly with the sh operator or packaged in a shading pattern for use as fill paint.
PDF shading defines a smooth colour gradient across a region of a page — transitioning between two or more colours across a geometric area. Shading is used for background gradients, soft lighting effects, vignettes, and any fill that requires a smooth colour progression rather than a solid colour.
In PDF content streams, shading is invoked with the <code>sh</code> (shading) operator, which paints the current clip region using a specified shading dictionary. Shading can also be wrapped in a Shading Pattern (<code>/PatternType 2</code>) to use it as fill paint with the <code>scn</code> or <code>SCN</code> colour operators, enabling it to be used wherever a colour can be used. Shading is part of the PDF graphics model defined in ISO 32000.
Shading types: the seven shading dictionaries
ISO 32000 defines seven shading types, each with a different geometric model for colour distribution:
<strong>Type 1 — Function-based shading</strong>: Colours are computed by a 2-input function mapping (x,y) coordinates to colour values. The most flexible type but requires a function object. Used for arbitrary colour distributions that cannot be expressed as simple gradients.
<strong>Type 2 — Axial shading</strong>: A linear gradient along an axis between two points. The most common shading type. Defined by two points (<code>/Coords [x0 y0 x1 y1]</code>) and a <code>/Function</code> mapping a 0–1 parameter to colour. Optional <code>/Extend</code> flags control whether the gradient extends beyond the two endpoints.
<strong>Type 3 — Radial shading</strong>: A circular gradient between two circles (which can have different radii and different centre points — the concentric circles case is a special case). Defined by two circles in <code>/Coords [x0 y0 r0 x1 y1 r1]</code>. Used for spotlight and reflective light effects.
<strong>Type 4 — Free-form Gouraud-shaded triangle mesh</strong>: Smooth colour interpolation across triangles defined by a stream of vertices with colour values. Used for complex 3D-like gradient fills.
<strong>Type 5 — Lattice-form Gouraud-shaded triangle mesh</strong>: Like Type 4 but vertices form a regular grid. Slightly more compact for grid-structured data.
<strong>Type 6 — Coons patch mesh</strong>: Curved patches defined by Bézier curves, providing smooth colour transitions across curved surfaces. Used in high-quality illustration for photorealistic gradients.
<strong>Type 7 — Tensor-product patch mesh</strong>: A more general version of Type 6 with additional control points for finer shape control.
In practice, Type 2 (axial) and Type 3 (radial) shadings cover the vast majority of gradient fill needs. Types 4–7 are output from illustration software (Adobe Illustrator mesh gradients) but are rarely authored directly.
Shading and colour functions
All shading types reference a <a href="https://pdftheguide.com/glossary/pdf-function" target="_blank" rel="noopener">PDF function</a> (<code>/Function</code> entry) that maps a position parameter (or coordinates for Type 1) to colour component values. The function's output must match the number of components in the shading's colour space.
<strong>Exponential interpolation (Type 2 function)</strong> — The most common for two-colour gradients: linearly interpolates from colour C0 (at t=0) to colour C1 (at t=1) with an exponent parameter N. For N=1, it is a linear gradient; for other N values, it produces a gamma-like curve. Example: <code><< /FunctionType 2 /Domain [0 1] /C0 [1 0 0] /C1 [0 0 1] /N 1 >></code> produces a linear red-to-blue gradient in DeviceRGB.
<strong>Stitching functions (Type 3)</strong> — For multi-stop gradients (three or more colours), a stitching function combines multiple sub-functions over different intervals of the 0–1 parameter range. Each sub-function handles one colour transition; the bounds array specifies where each transition starts and ends.
<strong>Colour space interaction</strong> — Shading uses the current colour space set by <code>/ColorSpace</code> in the shading dictionary. Any PDF colour space is valid. For accurate colour management in print workflows, ICCBased or DeviceCMYK colour spaces should be used rather than DeviceRGB, ensuring predictable behaviour in RIP processing. See <a href="https://pdftheguide.com/glossary/pdf-color-space" target="_blank" rel="noopener">PDF Colour Space</a> for colour space details.
Transparency, flattening, and PDF/A
Shading interacts with PDF's transparency model and has specific constraints in archiving and print workflows:
<strong>Shading and transparency</strong> — A shading pattern used in a transparency group, or a shading applied while the current alpha is less than 1.0, participates in the normal PDF compositing process. The shading's colour values are multiplied by the current opacity before compositing. This allows fading gradients (transparent at one end) using a shading function that varies opacity — though opacity is typically handled by the soft mask (<a href="https://pdftheguide.com/glossary/pdf-soft-mask" target="_blank" rel="noopener">PDF Soft Mask</a>) rather than by including an alpha channel in the shading function directly.
<strong>Transparency flattening and shadings</strong> — When a shading is involved in a transparency compositing context that must be flattened for a non-transparency-aware RIP, the shading region is rasterised. The resolution of rasterisation depends on the flattener's settings. Gradient bands (visible stepping between colour values) can appear if rasterisation resolution is too low — typically 150 DPI or higher avoids visible banding for most screen-size gradients.
<strong>PDF/A constraints</strong> — Shadings (including shading patterns) are permitted in PDF/A-1 and later. There is no PDF/A restriction on shading types. However, shading that involves transparency (via soft masks or transparency groups) is prohibited in PDF/A-1 (which prohibits all transparency). PDF/A-2 and later allow transparency, including transparent shadings.
Frequently asked questions
What is the difference between an axial and a radial shading?
An axial shading (Type 2) produces a linear gradient along a straight axis between two points. The colour transitions along the perpendicular to that axis — every point at the same distance along the axis has the same colour. Axial shadings are used for simple left-to-right, top-to-bottom, or diagonal colour transitions. A radial shading (Type 3) produces a circular gradient between two circles. The colour transitions concentrically — points at the same radial distance from the circle centres have the same colour. The two circles can be concentric (same centre, different radii — the classic "spotlight" effect) or offset (producing a directional light appearance). Radial shadings with a zero-radius inner circle produce a point-to-circle transition. Both types reference a function that maps the 0–1 gradient parameter to colour values.
Can gradient fills in PDF cause printing problems?
Yes, two common gradient printing problems: (1) Gradient banding — visible stepping between colour values, caused by insufficient tonal resolution in the output device or insufficient steps in the gradient function. Print at high resolution (1200+ DPI for PostScript output) and ensure the gradient covers a sufficient colour range (very subtle gradients band more visibly than strong colour shifts). In PDF/X workflows, gradient banding is more common with low-quality RIPs. (2) Transparency compositing errors — gradients involving transparency that requires flattening can produce colour shifts or tonal breaks at the flattened edge. The fix is to ensure gradients in print PDFs use consistent colour spaces (all CMYK or all RGB with output intent) and avoid mixing gradient colour spaces with the surrounding content. Always proof on the actual output device before high-volume print runs.
How do I create a gradient fill in a PDF programmatically?
In pdf-lib (JavaScript): pdf-lib does not have a built-in gradient API as of the current version — you need to construct the shading dictionary manually using PDFContext objects. In PyMuPDF: PyMuPDF has limited native gradient support; the recommended approach is to create an SVG with a linear or radial gradient and insert it into the PDF page. In iText 7 (Java/C#): use PdfShading.Axial or PdfShading.Radial constructors — iText has a well-developed shading API. In PDFlib: use shfill() with a shading handle created with shade() — PDFlib has comprehensive shading support including all seven types. For simple two-colour gradients without a PDF library, creating a gradient in a vector editor (Illustrator, Inkscape) and embedding the resulting PDF page as a Form XObject into your output PDF is a practical workaround.