Why Procedural Granite Reads as Fake: Worley Noise Has the Wrong Statistics

Key Takeaways
- Worley and Voronoi noise assume every crystal nucleates at the same instant, which is not how granite forms.
- Granite's grains carry a shape hierarchy set by growth order, early crystals well-formed and late ones filling the gaps.
- Poisson-Voronoi cell sizes fit an approximate gamma distribution while real crystal sizes fall off log-linearly, two measurably different statistics.
- Sequencing grains by crystallization order beats stacking noise octaves; in a shader that costs a wider cell search.
You have stacked three Worley noises at different scales, warped them, layered grunge on top, and pushed the roughness variation until your eyes water. The granite still looks like a texture laid over a surface, not a rock. Every breakdown gives the same next step: add another octave, another layer of micro-variation, more detail from macro scale down to micro. That treats the problem as a detail budget. It is aimed at the wrong thing.
The ceiling is not noise quality. It is the model sitting underneath the noise. Worley noise, and the Voronoi partition it is built on, is a snapshot of crystals that all appeared at the same instant. Granite did not form that way, and the gap between those two facts is what your eye keeps catching.
What Worley noise quietly assumes
Voronoi partitioning drops a set of seed points and assigns every location to its nearest seed. Steven Worley's 1996 cellular texture basis function, the node most texture artists reach for, is built directly on that idea (Worley, SIGGRAPH '96). The construction carries consequences you cannot tune away. Every boundary sits exactly halfway between two seeds, so it comes out straight. Every cell is convex. Every seed has equal standing, and nothing in the definition ranks one cell above another.
Read geologically, that is a strong claim: all of these crystals nucleated at once and grew into each other at the same time. A Voronoi field commits you to simultaneous nucleation. This is why domain warp never rescues it. Warping bends the boundaries and breaks the obvious grid, but it cannot introduce an order among the grains, because there is no order in the underlying data to expose. The distortion moves the grains around and leaves each one exactly the status it started with.
How granite actually forms: a hierarchy written in time
Granite crystallizes slowly, and the order in which minerals freeze out of the melt leaves a permanent, visible record. Plagioclase and biotite come first. They grow into liquid melt with room on every side, so they form well-shaped crystals with their own flat faces, euhedral to subhedral in petrology's terms. Quartz and alkali feldspar crystallize last. By then the early crystals have taken the space, so the latecomers solidify into whatever gaps remain, filling the interstices as shapeless anhedral grains (UBC EOSC 321 felsic petrology lab).
Petrology has a single word for the resulting texture: hypidiomorphic granular. Some grains are well-formed, some fill the space between them, and which is which is set by crystallization order. That is a shape hierarchy, and it is the specific thing a Voronoi field cannot contain. Kenneth Perlin's original solid-texture work demonstrated marble and rock back in 1985 (Perlin, SIGGRAPH '85). Four decades of noise research later, procedural stone still lacks this ordering.

Between 5.4 and 9.9x10⁻¹¹ cm/s in a cooling Hawaiian lava lake (Cashman & Marsh, 1988). Crystals freeze out of a melt in sequence, over time, not all in one instant.
Source: Cashman & Marsh (1988), Springer - as of
Porphyritic granite: one rock, two grain sizes
Consider porphyritic granite. Large alkali-feldspar phenocrysts sit in a much finer groundmass, sometimes close to ten times the size of the grains around them, all inside one rock. Two grain populations of very different size, formed at different stages of the same cooling history. Poisson-Voronoi cells cluster tightly around a single characteristic size, so one field will never hand you a cell ten times its neighbours while staying one field. You can jitter the seed density and it does not help. Porphyritic granite holds two size classes from a single crystallization sequence, and a Voronoi field has only one.

The correct generalization is Johnson-Mehl
There is a clean mathematical fix for the assumption Voronoi bakes in. Voronoi is the special case where every nucleus appears at the same moment. Let the nuclei appear over time instead, each growing from the instant it forms, and you get the Johnson-Mehl tessellation. Its boundaries curve. Its grains can be non-convex. That already looks far more like rock, and it comes from letting the seeds appear at staggered moments.
Staggered nucleation changes the model; more octaves only change the detail sitting on top of it. This is a different claim from the familiar one that photorealism is art direction rather than resolution, or that atmosphere is what closes the sale. Those posts are about perception in the round. This one points at a single structural mechanism: grains ranked by when they froze, an ordering a Voronoi field has no way to hold.
In production this only bites at close range, on the stone a buyer actually stands next to. From across a room, extra detail hides everything. Up close, the grain ordering is the whole read, and no octave count fills in for it.
Crystal size distributions: gamma versus log-linear
There is a quantitative version of this argument. The sizes of Poisson-Voronoi cells fit an approximate gamma distribution; Ferenc and Néda derive a compact form whose shape and rate parameters are both (3d+1)/2 in d dimensions, and they are careful to call it an approximation rather than an exact law (Ferenc & Néda, Physica A, 2007). Real igneous crystal size distributions follow a different shape: a population-balance law, n = n₀ - exp(-L/Gτ), that plots as a straight line against log population density (Marsh, 1988). An approximate gamma and a log-linear falloff are measurably different families of curve. "Is my procedural granite the right statistics" has a published answer that graphics work rarely stops to check.
A Voronoi cell-volume distribution and a crystal size distribution's per-unit-volume population density measure different quantities. To read the gamma-versus-log-linear contrast as a proof, you would need a careful volume-to-population conversion this post does not attempt. Take it instead as a strong, checkable pointer that the two models carry different statistics, and say so in the open. Owning that limit is itself part of the argument.

Why there is no Johnson-Mehl node in your shader graph
Cellular noise is cheap because it treats every seed as equal, and that same assumption is what makes it wrong about granite. The speed and the error are one design decision.
Open any Worley noise shader and it is the same three steps. Hash the lattice cell the pixel sits in, loop the neighbouring cells, keep the smallest distance. Unity publishes the generated HLSL for its Voronoi node, and it is exactly that: a 3x3 loop with if (d < res.x) inside it (Unity Shader Graph docs).
That loop is exact only because no seed outranks another. When seeds compete on raw distance alone, the winner is guaranteed to sit in an adjacent cell, so a fixed ring gives the right answer rather than an approximation of it. Simultaneous nucleation is what buys that guarantee. The geological error and the speed come from the same assumption.
Unreal prices it out in the open. The quality setting on its Noise node is nothing but the number of cells searched: Quality 1 searches 8 cells at about 160 instructions per octave, Quality 4 searches 32 at about 640, against roughly 100 for a typical material (Brucks, Epic Games, 2016). Six octaves at Quality 4 lands near 3,800 instructions, about thirty times an ordinary material. Divide each quality level by the cells it searches and the rate is identical every time: 20 instructions per cell. Cellular noise costs exactly what its neighbourhood costs.

What Blender, Unity and Unreal actually expose
No shipped node gives you a per-seed weight, which is worth checking before a breakdown claims otherwise. Blender's Voronoi Texture node takes Scale, Detail, Roughness, Lacunarity, Smoothness, Exponent and Randomness, with F1, F2, Smooth F1, Distance to Edge and N-Sphere Radius as its features (Blender manual). Randomness moves a seed around inside its own cell; it does not rank one seed above another. Unity's Voronoi node takes UV, Angle Offset and Cell Density. Unreal's takes quality, octaves and tiling. Every knob on all three changes where the seeds are or how many there are, never when they started growing.
Crystallization order has to be built by hand, then. The code for it is shorter than the workaround most breakdowns reach for.
What staggered nucleation looks like in a shader
Give every seed a birth time and let it grow at a fixed rate. A point belongs to whichever crystal reaches it first, so the test becomes birth time plus travel time rather than distance alone:
// Worley: every seed competes on raw distance.
float d = length(seed - p);
// Johnson-Mehl: a late seed is pushed back by how late it was, which is the
// same as giving the early ones a head start.
float d = length(seed - p) + birth * spread; // birth in [0,1), spread in cells
Call the added quantity the head start, because that is what it does: an early seed gets its distance discounted and takes ground a later seed would otherwise have won. spread sets how big the largest head start is allowed to be, measured in cells of growth, and it is the only new number an artist has to choose.
Geometry has a name for the result. Weight the seeds additively like this and the partition becomes the additively weighted Voronoi diagram, also called the hyperbolic Dirichlet tessellation. The second name is literal: the boundaries stop being straight bisectors and become arcs of hyperbolas (Weighted Voronoi diagram). Curved boundaries and non-convex grains, which is the shape granite has and Voronoi cannot reach, follow from that one line of arithmetic.
What a head start costs: the cell search goes cubic
A head start breaks the fixed ring the loop depends on. Seeds no longer reach a point in order of distance, so the nearest one can lose: a seed two cells away that started early arrives before the neighbour next door that started late. The 3x3 block stops containing the winner, and the search that was exact becomes a guess. The error shows up as seams along cell edges, the same artifact Stefan Gustavson's 2x2 shortcut accepts in exchange for speed (The Book of Shaders, chapter 12).
Staying exact means searching as far as the largest head start can reach. With a spread of W cells, a discounted seed can win from W cells beyond the usual ring, so the ring grows from radius 1 to radius 1+W and the block from 3^3 cells to (3+2W)^3. The head start is one multiply in the inner loop; paying for it is cubic.

Porphyritic granite needs a wide spread. A phenocryst that dwarfs the groundmass around it is a head start of several cells, which is why the shape your eye is asking for is the one that puts the search in the hundreds of cells per pixel.
Three routes make that search affordable, and they differ in where the cost lands. Bake the field to a texture once and the wide search becomes an offline cost, which is Epic's own advice for expensive Voronoi. Or approximate the hierarchy with two cheap cellular fields at different densities, letting the coarse early population mask the fine late one; that buys the porphyritic two-population read for the price of two plain lookups. Or reach for jump flooding, which resolves a weighted diagram in a handful of passes and hands you a texture to sample.
Where to start in Substance Designer
None of this is a node-by-node graph recipe, and it should not become one. It is a direction. Start from the ordering itself. Give the early, well-formed grains priority, then let a later population settle into the space around them. Even a crude pass at that hierarchy, built with the same cellular node you already have, beats another octave of warp, because it adds the ordering the model never had.
A few tooling details are worth getting right, because getting them wrong is the fastest way a granite breakdown shows it never opened the docs. Adobe documents Substance's Cells nodes as scatter-and-blend operators. It names Voronoi and Perlin explicitly elsewhere when it means them, so writing "Cells equals Worley" claims more than the documentation says. Substance Designer has no erosion node at all; the word "erosion" in tutorials is loose vocabulary for an effect you build by hand. Flood Fill, the node that recovers per-cell identity so you can drive per-grain variation, shipped in version 2017.2, not in a 2018 release. We author and mix materials in Adobe Substance 3D every day, which is why we can be exact about these.
Where scanned libraries win, and where they do not
Because we build and mix materials in Substance and also blend existing library assets, the procedural-versus-scanned tradeoff is something we live with in production, not a matter of theory. Each side wins somewhere, and the split is worth naming plainly.
Scanned library or procedural graph
Reach for a scan
A single hero material under studio lighting, on a deadline, where measured albedo matters more than who controls the library. On pure fidelity, the scan usually wins.
Reach for a graph
Anything you need to own, vary per project, and keep working regardless of a vendor's licensing change. You trade some fidelity for full control over the pipeline.
The control the graph column points at is not abstract. The terms under which you may use a scanned library can change without your say. Epic made Quixel Megascans free to all only through the end of 2024 (CG Channel, Oct 2024), and its own Fab migration documentation states the position plainly (Fab support):
we will not be transferring these Megascans entitlements over to Fab
When your material pipeline leans on a library, a shift like that is out of your hands; when it leans on graphs you author, it stays with you. That is the honest case for keeping procedural capability in the studio. A related tradeoff runs through reality capture, where captured data comes to you measured and synthesized data comes authored; which one you want depends on what you need to control.
Materials also have to survive where they land. Our pre-rendered projects load in about two seconds on a phone, streamed as video rather than computed on the device (our own comparison), and a material earns its place only if it holds at that speed on that hardware. So the next time your granite reads as fake, do not reach for another noise. Open the material and look at how the grains are ordered. Real granite ranks them by the sequence in which they froze; if yours does not, that is your fix.
Building interactive property experiences?
See how we author and stream photoreal materials for real projects.

The launch-day traffic spike: why you're bracing the wrong asset
Before an off-plan drop, everyone stares at the interactive 3D tour and braces for it to crash. It's the wrong worry. On a page built the right way, the biggest visible asset barely feels the crowd, and the fragile part is the small transactional path behind the form. Here is how to split a launch page into its two load profiles and spend your prep where it counts.

The last 20% of units decide whether you hit your pre-sale date
The last units before a pre-sale threshold often carry an objection the launch assets never answer. Show the real outlook before cutting the price.

How to review and approve a property render before it goes live: a sign-off checklist
A render sign-off is a QA gate you run against the spec, not a taste call you make by eye. Three of the checks aren't 'does it look good' but 'does it match what will be built and delivered', and the last of those is an advertising risk, not an aesthetic one. The checklist, and how to end approval as a recorded, versioned state instead of an 'ok, looks great' in an email thread.
