Creating a Procedural Marble Texture in GLSL
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.
What Makes Marble Look Like Marble?
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.
Starting with the Coordinates
We'll begin with ordinary UV coordinates.
vec2 uv = vUv;
Everything else will build on these coordinates.
Creating a Wave Pattern
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.
Adding Noise
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.
Distorting 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.
Making the Distortion Stronger
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.
Complete Shader
#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.
Adding Marble Colours
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.
Creating Blue Marble
vec3(0.8,0.9,1.0)
vec3(0.2,0.3,0.5)
The result resembles polished blue stone.
Creating Green Marble
vec3(0.8,0.9,0.8)
vec3(0.2,0.4,0.2)
The veins begin to resemble natural jade.
Animating the Texture
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.
Increasing the Detail
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.
Where Are Procedural Marble Textures Used?
Procedural marble appears in many applications.
- Floor materials.
- Kitchen countertops.
- Architecture.
- Video games.
- Product visualization.
- Motion graphics.
- Decorative backgrounds.
- Interior design.
- Digital sculpture.
- Procedural artwork.
Because the texture is generated mathematically, it never becomes blurry.
Try These Experiments
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.
A Small Challenge
Can you create these effects?
- White marble.
- Black marble with gold veins.
- Blue decorative stone.
- Green jade.
- A polished fantasy crystal.
Every variation starts from the same mathematical idea.
Leave Creating a Procedural Marble Texture in GLSL to:
Read more #coding posts
Best Posts From hey2d
We have not curated any of hey2d's posts yet. But you can encourage our curation team to review posts by visiting them regularly and by referring other readers. Because we give priority to frequently read content.
More Posts From hey2d
- Fragment Shaders Made Simple: What gl-FragColor Does
- Understanding gl-Position: My First Real Vertex Shader
- Creating Procedural Galaxies and Nebulas in GLSL
- Creating a Procedural Night Sky and Stars in GLSL
- Creating Procedural Clouds in GLSL
- Adding Reflections and Highlights to Procedural Water in GLSL
- Creating Procedural Water in GLSL
- Creating Procedural Smoke in GLSL
- Creating Procedural Fire in GLSL
- Creating Procedural Wood Grain in GLSL
- Creating a Procedural Marble Texture in GLSL
- Domain Warping in GLSL: Distorting Noise to Create Organic Worlds
- Fractal Brownian Motion in GLSL: Building Rich Procedural Noise
- Understanding Gradient Noise in GLSL
- Creating Smooth Value Noise in GLSL
- Creating Random Values in GLSL: The Building Blocks of Procedural Graphics
- Combining Translation, Rotation, and Scaling in GLSL
- Scaling Shapes in GLSL: Making Procedural Graphics Grow and Shrink
- Rotating Shapes in GLSL: Understanding Coordinate Rotation
- Moving Shapes in GLSL: Understanding Coordinate Translation