GlassShatter
A plate of glass broken over a picture, cracked along the stress rather than into a honeycomb.
Options
-
sectors29 -
3 to 48, good: 8 to 20
Radial cracks running out from the impact. A prime number by default and for a reason: with an even count the cracks opposite each other line up through the impact and read as a drawn asterisk rather than as a break.
-
rings9 -
1 to 24, good: 4 to 12
Concentric cracks running round the impact, counted along the square root of the radius, so they come out close together near the impact and further apart as they go out. At 1 you have radial cracks only, which is a smashed pane rather than a struck one.
-
jitter0.7 -
0 to 0.96, good: 0.5 to 0.9
How far a site may sit from the middle of its own cell. At 0 the shards are a perfect polar grid, which is a dartboard. The cap is just under 1 and it is load-bearing: a site that crosses into its neighbour's cell breaks the nine-cell search the whole thing rests on, and the plate tears along the lattice.
-
crack1.3 -
0.2 to 8 px, good: 1 to 3
Width of the dark line, in screen pixels. Thin. A crack in glass is a hairline with light on it, and a fat dark line is a drawing of a crack: that is the single most common way this effect is got wrong.
-
glint0.5 -
0 to 2, good: 0.35 to 0.9
How brightly the fresh edge beside the crack catches the light. The term that does the most work here and the one nobody includes. Set it to 0 once: the cracks stop being cracks and become a grid drawn over the photograph, and no amount of width or refraction brings them back.
-
gap1 -
0 to 4, good: 0.5 to 1.8
How far each shard shifts, outward from the impact plus a little of its own. This slides the picture inside the shard rather than moving the shard, so it has to stay small: past about 2.5 the pieces stop reading as shifted and start reading as the wrong part of the photograph.
-
refract0.6 -
0 to 4, good: 0.6 to 1.8
How much the picture bends at a crack. The bend is strongest at the crack and dies away into the middle of the shard, which is where a wedge of glass is thickest and where it is flat.
-
fringe0.6 -
0 to 4, good: 0.5 to 1.8
How far red and blue come apart as the picture bends. It only happens at the cracks, which is the point: a plate of glass is not a prism, but the wedge at a broken edge is.
-
facet0.16 -
0 to 0.6, good: 0.08 to 0.26
How far a shard may sit out of the plane of the plate, as a share of its brightness. This is what gives the plate thickness: without it the cracks are lines on a flat picture, and with too much of it the shards read as tiles of different colours.
-
reach0.62 -
0.1 to 2, good: 0.45 to 0.95
How far the damage carries from the impact, measured in short edges of the element. A strike does not break the whole pane: there is a region of cracks around the impact and intact glass past it, and without that the frame is webbed edge to edge at an even density, which is half of why the honeycomb version of this effect never convinces. Above about 1.4 the whole element is inside the break and this stops doing anything.
-
arcs0.3 -
0 to 1, good: 0.3 to 0.6
What share of the circumferential cracks actually form. At 1 every one of them is there, and that is the spider web: a Voronoi diagram partitions the plane, so with a radial crack between each pair of neighbours and an arc joining them the architecture is exactly a web, and weighting the arcs down is not enough to fix it. A break is not a partition of the plane, it is a set of curves with ends. At 0 you have radials only, which is a struck pane that has not finished going.
-
impactX0.42 -
0 to 1
Where the plate was struck, across the element. Off centre on purpose: a break centred in the frame reads as a graphic, and the whole argument for a polar lattice is that the break has a place it came from.
-
impactY0.56 -
0 to 1
Where the plate was struck, down the element.
-
impactAt0.5 -
0 to 10 s
Seconds of intact glass before it is struck. Worth having at all: the picture whole for half a second is what makes the break an event rather than a texture.
-
spread0.75 -
0.05 to 6 s, good: 0.4 to 1.2
Seconds for the break to open. Quick. Glass does not ease: the cracks arrive at something like a kilometre a second, and anything above about 1.5 here reads as the picture slowly developing a fault.
-
tint#dbe9ff -
css colour
The colour of the light on a fresh edge. Slightly cool, because a fresh break in glass is a green-blue line: that is the iron in it, and it is why the cut edge of a float-glass pane looks green end on.
-
seed7 -
1 to 9999
Seed for the shards. The same seed gives the same break, which is what makes the take reproducible.
-
maxDpr2 -
1 to 3
Device pixel ratio ceiling. The crack width is in screen pixels, so this changes what the hairlines cost to draw but not how thick they look.
-
reducedMotionTime4 -
0 to 30 s
The single frame shown when the user prefers reduced motion. For a one-shot break this has to be a time after it has opened, so the plate is simply broken. The broken plate is the point; the breaking is how it gets there.
What it needs
- Category
- Surfaces, an effect
- Dependencies
- None at all
- Browser
- WEBGL2
- Frame budget
- ~0.4 ms · 1 context
- Pinned to
- v0.13.0
- Every shattered-glass effect scatters random sites across the plane and gives each pixel to the nearest one. It produces a honeycomb, and a honeycomb is a dry mud flat rather than a broken window
- A plate struck at a point breaks along the stress, and the stress is radial and circumferential: cracks run out from the impact and other cracks run round it, crossing the first set. The pieces come out roughly four-sided, small near the impact and growing with distance, because the radial cracks fan apart as they travel
- So the lattice is polar rather than square. Sites live in cells of angle by radius, the borders fall along radii and around arcs, and the whole character of real glass comes out of the coordinate system rather than out of any extra work
- The radius goes under a square root. A plain radius gives rings of even spacing, and concentric cracks get further apart as they travel; the root also crowds the inner rings together, which is the zone of fine fragments around the impact that any photograph of a broken window has
- The sector index is taken modulo the sector count when it is hashed, so the cell on one side of angle zero is the same cell as the one on the other side. Without that there is a seam running out from the impact that no amount of jitter hides. The position uses the unwrapped index, so the distance stays continuous across the join
- A site is jittered inside its own cell and capped there, which is the assumption the three by three search rests on. Let a site cross into its neighbour and the nearest site can be two cells away, and the plate tears along the lattice instead of along the cracks
- The second nearest site is where the cracks come from. Halfway between two sites the two distances are equal, so their difference falls to zero, and that difference is a distance to the edge for free
- Not every crack is the same crack. In a struck plate the radial cracks go first and go deepest, because the plate is in tension around the impact; the circumferential ones are secondary, forming between radials that have already gone, and they are shorter and shallower. Drawn at equal weight you get a spider web, which is a thing built outward from a centre rather than a thing broken from one. Which kind a border is can be read straight off its own normal: a radial crack runs along the radius, so its normal points round, and a circumferential one is the other way about
- The picture is sampled a little inside its own edge, because the bend and the drift push the lookup outward and a clamped texture asked past its edge hands back the edge column over and over. At the left and right of the frame that came out as horizontal smears of colour, which reads as a fault in the effect rather than as glass
- And not every circumferential crack forms at all. Weighting them down was not enough: a Voronoi diagram partitions the plane, so every cell is ringed by borders and the arcs close into polygons, which is exactly a spider web's architecture and still read as one at a quarter of the weight. Each border is therefore hashed and the circumferential ones only exist if their number comes up. The key is the pair of cells either side of it, taken with a componentwise min and max so both sides agree and a crack does not appear from one shard and not from its neighbour
- What turns a dark line into a crack is the bright line beside it. A broken edge is a fresh face of glass and it catches the light, so a crack in a photograph is a dark line with a glint along it. That one term is the biggest single difference between this and a drawn grid
- The crack width is in screen pixels, got by dividing the border distance by its own gradient. One lattice unit is a few pixels at the impact and a hundred at the edge of the frame, so a width in lattice units comes out as cracks of wildly uneven thickness. Scaling by fwidth was the first attempt and it is the same mistake in a different hat, because fwidth measures how fast the quantity changes rather than how far away the border is: it gave lines eight pixels thick with a white halo, and the thing came out as a spider web
- The picture bends across the crack and the channels come apart as it bends, which is what a wedge of glass does to light passing through it. The bend follows the gradient of the border distance, which points across the crack rather than along it
- The shard drift slides the picture inside the shard rather than moving the shard, so it is kept small. Past a fraction of a cell it stops reading as a piece that has shifted and starts reading as the wrong piece of the photograph
- The <img> stays in the document, hidden. Its alt text is the accessible version of the picture and a page whose script never runs still shows the photograph
- Nine hashes and nine distances per pixel for the polar lattice, then three samples of the picture for the channel split. No list, no sorting, no texture for the sites
- Nothing is allocated per frame and the picture is uploaded once
- One shot. Once the break has opened the frame stops changing, and the runtime stops the loop when the element leaves the screen
Concept credit: Splitting a layer into shards around a set of sites, opening a crack along each border with the next-nearest shard, and bending and colour-splitting the layer across it, from the Shader Effects library's fracture. Their sites are random; the polar lattice here is the answer to what that looks like, by Shader Effects Inc.. The implementation here is written from scratch.