QR Codes for 3D Printing
A 3D-printed QR code has no ink, so it has no contrast — which means the whole job is to manufacture a light and dark that a camera can tell apart out of nothing but geometry and shadow.
The contrast problem
Every decoder starts by converting the camera image to greyscale and deciding, point by point, what is dark and what is light. On paper that is trivial. On a single-colour print there is no colour difference at all, and the only thing separating a module from its neighbour is how light falls on it.
So a printed-in-one-colour QR code works entirely through shadow, and shadow depends on the lighting in the room. That is why these codes read beautifully on the bench under a lamp and fail in the customer's hallway.
The fix, wherever possible, is real colour contrast — which on an FDM printer means a filament change partway up the print.
Raised, engraved, or two-colour
| Approach | How it reads | Verdict |
|---|---|---|
| Two-colour, flat | True black-on-white contrast | Best by a distance |
| Raised (embossed) | Shadow at the module edges | Good, with side lighting |
| Engraved (debossed) | Shadow inside the recesses | Worst — recesses fill with shadow unevenly |
| Painted or ink-filled | True contrast, extra step | Excellent if you will do the work |
Two-colour is the answer if your printer can pause. Print the plate in white or a light filament, insert an M600 filament-change command at the layer where the code begins, and continue in black. The code becomes a genuinely printed black-on-white symbol and behaves like one. Every slicer supports this, usually as "colour change at layer".
Raised beats engraved when a single colour is all you have. Raised modules catch light on top and cast a shadow beside them, producing an edge. Engraved modules are recesses that fill with shadow depending entirely on the angle of the light, and at some angles the whole code goes uniformly dark. If you engrave, expect it to be temperamental.
Module size and the nozzle
Here the printer's resolution sets the floor, exactly as a laser printer's does on paper. With a standard 0.4 mm nozzle, a single extruded line is about 0.42–0.45 mm wide, and a module needs at least three or four of them side by side to come out square rather than as a blob.
Do the arithmetic before you design the part. A 25-module code at 2 mm per module is a 50 mm square, plus a quiet zone of four modules on each side, which is 66 mm overall. That is a substantial feature on a small object, and it is why the payload has to be short — see below.
Slicer settings that matter
- Layer height 0.2 mm or finer. Coarser layers make the module edges ragged in the vertical direction.
- Two or three top layers minimum over the code surface, so the pattern is not printing over infill voids.
- Turn on ironing for the top surface of a two-colour code. It smooths the dark surface and makes it read as a flat block of colour rather than a set of visible lines.
- Concentric or monotonic top infill rather than lines at 45°, which can create a directional sheen that confuses the camera.
- No supports. If the code needs supports you have oriented the part wrongly.
Orientation and surface finish
Print the code face up on the top surface of the part, flat on the bed if you can. Two reasons: top surfaces get the smoothest finish, and a code printed on a vertical wall inherits the layer lines as a horizontal stripe pattern, which is a periodic texture across a code made of periodic squares. That is not a helpful combination.
A glossy filament will produce specular highlights that behave exactly like the reflections that break laminated printed codes. Matt filament reads better.
Curved surfaces are harder here than on paper, because you cannot rely on ink to stay uniform. Keep a code on a curve well under a third of the circumference, and expect to make it bigger than the flat equivalent.
Keep the payload tiny
Since every module costs two millimetres of physical space, payload length translates directly into object size:
| Payload | Symbol at level M | Physical size at 2 mm/module |
|---|---|---|
example.com/a (13 chars) | 21 × 21 | 42 mm + quiet zone |
| A 30-character URL | 29 × 29 | 58 mm + quiet zone |
| A 60-character URL | 37 × 37 | 74 mm + quiet zone |
| A minimal vCard | 57 × 57 | 114 mm + quiet zone |
A short redirect on your own domain is not a nicety here, it is the difference between a code that fits on the object and one that does not. Static versus dynamic QR codes explains how to get a short static link you can re-point later.
Level M is the right choice for a printed object: the surface is not going to be scratched the way a carton is, and the extra modules from level H cost real millimetres.
Written by Manuel Llovet, who builds and maintains QR Code Free Forever. Published 2026-08-31, last checked 2026-09-08. Figures and measurements on this page were produced for this site; the method is described in each caption.