shadcn.io is not affiliated with official shadcn/ui
Simplex Truchet Weave Shader lays cords on a hidden grid of triangles. Every corner of the grid has a ring of cord around it, each triangle holds three arcs of those rings, and each triangle stacks its arcs in a random order, so the cords cross over and under one another and run in S-curves, loops and knots. Each cord is shaded round, wound with a fine twist, edged in gold and outlined, with a soft drop shadow on whatever lies below; the cords warm toward terracotta at the lower right. A WGSL fragment shader on WebGPU draws every pixel each frame while the weave drifts up and to the left.
Use it behind a brand, textile, craft or luxury page that wants a tactile, ornamental pattern. For flat, colorful geometry, use Truchet Shader; for black-and-white line art with depth, Truchet Kaleidoscope Shader. It runs only while it's on screen, holds a still frame with reduced motion, and shows a CSS lattice of rings in the same colors in browsers without WebGPU.
Installation
Usage
import {
SimplexTruchetWeaveShader,
} from "@/components/ui/simplex-truchet-weave-shader";<SimplexTruchetWeaveShader className="flex min-h-[32rem] items-center justify-center">
<div className="rounded-xl bg-[#0e2329]/80 px-8 py-6">
<h1 className="text-5xl font-semibold text-white">Ship faster</h1>
</div>
</SimplexTruchetWeaveShader>Simplex Truchet Weave Shader is a container: your content sits on top of the weave, in normal flow. It fills its own box, so give it a height or content. For a backdrop behind the whole page, render it empty with className="fixed inset-0 -z-10". The light cords and the dark ground alternate everywhere, so put copy on a panel: one in the ground's color at 80%, like the one above, keeps white text above 8.5:1, and bg-black/60 above 5.7:1.
Demos
Stacked
shape="hexagon" bends each cord around a hexagon instead of a circle, and weave={false} turns the crossings off: each ring lies wholly above or below its neighbors, the lower ones darker, like a scatter of washers. shape also takes "dodecagon", a twelve-sided ring between the two.
In a card
The cords keep their size in CSS pixels, so a small box shows fewer of them: scale={9} fits nine triangle edges in 750 pixels, for a finer weave at card size. tubeColor, rimColor, backgroundColor and accentColor recolor the cords, their edging, the ground and the tint toward the lower right, here coral and cream on navy, warming to gold.
Performance
About 0.4 ms of GPU time a frame at 1280×720 on an M2 Max laptop: three arcs per pixel, each with its shadow, outline, rims and shading. Slower GPUs take several times longer. It keeps full quality: the outlines and edging are thin and go soft at half resolution. The animation stops when the shader scrolls out of view, and the browser pauses it in a hidden tab. Every shader on a page shares one GPU device and one frame loop, and vgpu (about 50 KB gzipped) loads only when the first one mounts.
Browser support
The shader needs WebGPU: Chrome and Edge, Safari 26 and later, and Firefox on Windows and macOS. Elsewhere, and until the first frame, the box shows a CSS lattice of rings in the same colors, so the layout never jumps. data-state on the root reads unsupported there, if you want to style around it. See Shader Canvas.
Accessibility
The weave is decoration: it's hidden from assistive tech and lets every click through to your content. With reduced motion it draws one still frame and stops. Nothing flashes: the weave only drifts, one triangle edge every ten seconds. Light cords on a dark ground make a busy, high-contrast pattern, so never set text on it bare: a panel in the ground's color at 80% keeps white text above 8.5:1.
FAQ
What is a simplex Truchet weave?
Truchet tiles are tiles whose patterns join up however each one is turned. Here the tiles are the triangles of a simplex grid, the grid simplex noise is built on: each triangle carries three arcs of cord, one around each corner, and the arcs join their neighbors' into rings. Drawing each triangle's three arcs in a random order makes the cords cross over and under, so the rings read as woven knotwork.
Which shapes are there?
shape bends the cords around a "circle" (the default), a "hexagon" or a "dodecagon", a twelve-sided polygon between the two. The hexagon gives straight runs and sharp corners, like a honeycomb of cord.
What does turning the weave off do?
With weave={false} the crossings stop alternating: every ring lies wholly above or below its neighbors, and the lower rings are shaded darker, so the pattern reads as a pile of stacked rings rather than a weave.
Can I show the grid?
Yes: grid draws the hidden triangle grid in thin lines of the rim color, over the cords. It's handy to see how the pattern is built, or for a more technical look.
Can I change the colors?
Yes: tubeColor is the cords, rimColor their edging (and the grid), backgroundColor the ground in the holes, and accentColor the tint the cords take on toward the lower right; set it to tubeColor for none. They take any CSS color, var(--primary) included, and follow a theme switch.
Credits
Inspired by a simplex Truchet weave (opens in a new tab) by Shane on Shadertoy, through shadcn.io's version. This is a new shader written from the idea, not a port: the over-and-under order resolved per triangle stays, while the cord shading, the twist, the edging, the stacked mode, the drift and the colors are ours. The hash is lowbias32 by Chris Wellons, in the public domain.
API Reference
SimplexTruchetWeaveShader
data-slot="simplex-truchet-weave-shader"
accentColor?string
The tint the cords take on toward the lower right. Any CSS color. @default "#e0805f".
- Default
"#e0805f"
backgroundColor?string
The ground that shows through the holes. Any CSS color. @default "#0e2329".
- Default
"#0e2329"
fallback?string
What shows until the first frame and in browsers without WebGPU: a CSS
background value (gradients, sizes, a colour) that looks like the
shader. It can use the colour props' --shader-<field> variables.
grid?boolean
Draws the hidden triangle grid the cords are laid on. @default false.
- Default
false
interactive?boolean
Whether u.pointer follows the pointer. @default false.
paused?boolean
Holds the current frame. @default false.
quality?number
Render scale, from 0.25 to 1, of the screen's pixels (capped at 2×). @default 1.
rimColor?string
The thin edging along both sides of each cord. Any CSS color. @default "#c8963e".
- Default
"#c8963e"
scale?number
How many triangle edges fit 750 CSS pixels, from 3 (big, bold cords) to 12. @default 7.
- Default
7
shape?keyof typeof SHAPES
The shape each cord bends around. @default "circle".
- Default
"circle"
speed?number
Animation speed: 1 is normal, 0 holds the frame. @default 1.
time?number
A fixed moment, in seconds: draws it and doesn't animate.
tubeColor?string
The cords themselves. Any CSS color. @default "#ebe0cc".
- Default
"#ebe0cc"
weave?boolean
Crosses the cords over and under at random; off stacks whole rings, the lower ones darker. @default true.
- Default
true
render?ReactElement | ((props: object, state: object) => ReactElement)
Replace the host element or compose it with another component.
- Type
ReactElement | ((props: object, state: object) => ReactElement)
className?string
Forwarded to the part.
Related
- Pro


Truchet Shader
Patterns & tilingsFlat, colorful folded tiles
- Pro


Truchet Kaleidoscope Shader
Patterns & tilingsBlack-and-white line art with depth
- Pro


Guilloche Shader
GeometryInterlaced hairlines, gold on emerald
- Pro


Marbling Shader
Ink, smoke & fireAnother crafted surface, inked paper
- Pro


Drapery Shader
Flow & gradientsRich fabric for a textile page
- Pro


Hexagon Grid Pattern Shader
Patterns & tilingsBlocks tucked into pinwheels