Walk through an old building made from marble and you'll notice something interesting.
No two pieces look exactly alike.
Every slab contains flowing veins.
Some areas are bright.
Others are dark.
The lines twist naturally without repeating.
Most of these patterns can be recreated entirely with mathematics.
No image textures are required.
Marble is made from three simple ingredients.
Long flowing stripes.
Smooth variation.
Small irregular distortions.
We already know how to create all three.
Sine waves create repeating bands.
FBM creates natural variation.
Domain warping bends everything into flowing curves.
When combined, they produce something that looks surprisingly realistic.
We'll begin with ordinary UV coordinates.
vec2 uv = vUv;
Everything else will build on these coordinates.
A sine wave forms the base of the marble.
float stripes =
sin(
uv.x * 12.0
);
At the moment the lines are perfectly straight.
Real marble doesn't look like this.
Let's sample FBM.
float n = fbm(uv * 3.0);
The result changes smoothly across the surface.
Instead of displaying it directly, we'll use it to bend the stripes.
Add the noise to the sine wave.
float marble =
sin(
uv.x * 12.0 +
n * 5.0
);
Now the lines begin to twist naturally.
Instead of perfectly straight bands, they resemble stone veins.
Increase the multiplier.
n * 8.0
The veins become much more dramatic.
Reduce it.
n * 2.0
The marble appears calmer.
This single value controls the overall character of the material.
#ifdef GL_ES
precision mediump float;
#endif
uniform float uTime;
varying vec2 vUv;
void main(){
vec2 uv = vUv;
float n = fbm(uv * 3.0);
float marble =
sin(
uv.x * 12.0 +
n * 5.0
);
marble = marble * 0.5 + 0.5;
gl_FragColor = vec4(vec3(marble),1.0);
}
Even without colors, the pattern already resembles polished stone.
Marble becomes much more convincing with subtle colors.
vec3 color = mix(
vec3(0.85,0.85,0.88),
vec3(0.35,0.35,0.40),
marble
);
Light gray and dark gray create classic white marble.
Try different combinations for completely different stones.
vec3(0.8,0.9,1.0)
vec3(0.2,0.3,0.5)
The result resembles polished blue stone.
vec3(0.8,0.9,0.8)
vec3(0.2,0.4,0.2)
The veins begin to resemble natural jade.
Although marble itself doesn't move, animation helps visualize the pattern.
uv.x +=
uTime * 0.1;
The veins slowly flow across the screen.
This is useful while experimenting with different settings.
Use more FBM layers.
Increase the sine frequency.
Increase the domain warp strength.
Each adjustment creates a completely different stone surface.
Professional materials often combine several noise functions to produce even richer details.
Procedural marble appears in many applications.
Because the texture is generated mathematically, it never becomes blurry.
Create black marble.
Create green marble.
Create blue marble.
Increase the stripe frequency.
Decrease the distortion.
Animate the texture.
Try adding domain warping before generating the stripes.
Observe how each adjustment changes the appearance.
Can you create these effects?
Every variation starts from the same mathematical idea.