Marble
Marble veins are essentially disturbed sine waves — noise shifts the phase of a sine pattern so that what would be straight stripes bends into organic, flowing veins:
Let's break it down.
Noise-perturbed sine wave
Without noise, sin(vUv.x * 6.0 * PI) produces uniform vertical stripes that repeat at even intervals.
Adding n * 2.0 shifts the phase by a different amount at every pixel — some pixels are a little ahead, some behind. The once-straight stripes curve and twist. That is exactly the look of marble veining.
The 2.0 in n * 2.0 controls how far the phase gets pushed. A larger value makes the veins more tortuous; a smaller value keeps them almost straight.
m * 0.5 + 0.5
sin outputs in the range -1 to 1. Multiplying by 0.5 and adding 0.5 maps that to [0, 1] so it can be used directly as a brightness value.
Try changing it
| Change | Effect |
|---|---|
2.0 → 5.0 | Much more chaotic veins, almost like water ripples |
2.0 → 0.5 | Barely curved, nearly straight stripes |
Sine frequency 6.0 → 12.0 | Denser stripes, finer veins |
mix(darkGray, white, m) around the result | Realistic marble appearance |
Exercise
Inside main, use the output of fbm(vUv * 6.0) to perturb a sine wave phase, then map the result to a brightness value and display it.
Answer Breakdown
Replace m = 0.0 with the two-line formula above.
vUv.x * 6.0— generates 6 vertical stripes across the canvas+ n * 2.0— uses noise to shift the stripe phase, bending them into veins* 3.14159265— scales the input so the stripes align to full sine cyclesm * 0.5 + 0.5— remaps [-1, 1] to [0, 1] for grayscale output
The starter has m = 0.0, so the output is solid black. After the change you see curved black-and-white bands — the fundamental shape of marble veining.
Try changing vUv.x * 6.0 to (vUv.x + vUv.y) * 4.0 to make the veins run diagonally.