Creating Random Values in GLSL: The Building Blocks of Procedural Graphics
Look closely at the world around you.
Clouds are never identical.
Mountains all have different shapes.
Stone, wood, sand, and water all contain tiny imperfections.
Nature is full of randomness.
If every pixel had exactly the same value, everything would look perfectly smooth and artificial.
Shaders become much more interesting when we introduce controlled randomness.
Is GLSL Really Random?
The short answer is no.
GLSL cannot generate truly random numbers.
Instead, it creates pseudo random numbers.
That means the same input always produces the same output.
For procedural graphics, this is actually an advantage.
Every frame remains stable while still appearing random.
A Simple Random Function
One of the most common random functions looks like this.
float random(vec2 st){
return fract(
sin(
dot(st, vec2(12.9898,78.233))
)
* 43758.5453123
);
}
You will see versions of this function in countless shaders.
Let's understand what each part does.
Step One: Combining Two Numbers
The first operation uses dot().
dot(st, vec2(12.9898,78.233))
The dot product converts the two dimensional coordinate into a single number.
Different coordinates produce different values.
Step Two: Passing Through sin()
Next comes
sin(...)
The sine function scrambles the values into a repeating wave.
By itself, the result is still predictable.
Step Three: Multiplying by a Large Number
Now multiply the value.
43758.5453123
The exact number isn't important.
Large values help scatter the decimal places into a more random looking pattern.
Step Four: Keeping Only the Decimal Part
Finally,
fract(...)
keeps only the decimal portion.
The final result always stays between
0.0
and
1.0
Every UV coordinate now receives its own random value.
Using the Random Function
Generating a random number is easy.
float r = random(vUv);
You can display it directly.
gl_FragColor = vec4(vec3(r),1.0);
Instead of a smooth gradient, the screen fills with scattered grayscale values.
Complete Shader
#ifdef GL_ES
precision mediump float;
#endif
varying vec2 vUv;
float random(vec2 st){
return fract(
sin(
dot(st, vec2(12.9898,78.233))
)
* 43758.5453123
);
}
void main(){
float r = random(vUv);
gl_FragColor = vec4(vec3(r),1.0);
}
Although the image looks noisy, every pixel is generated mathematically.
No texture is being sampled.
Why Doesn't It Change Every Frame?
Because the UV coordinates stay the same.
The same input produces the same output.
If you want animation, include time.
float r = random(
vUv + uTime
);
Now the values constantly change.
Creating Random Tiles
Randomness becomes much more useful when combined with fract().
vec2 tile = floor(vUv * 10.0);
float r = random(tile);
Instead of every pixel being different, each square receives one random value.
This technique is used in procedural maps, terrain generation, and pixel art.
Adding Random Colour
Random values don't have to remain grayscale.
vec3 color = vec3(
r,
r * 0.5,
1.0 - r
);
Every tile now receives its own colour.
Where Is Randomness Used?
Random values appear almost everywhere.
- Procedural textures.
- Terrain generation.
- Fire.
- Clouds.
- Rain.
- Snow.
- Particle systems.
- Pixel art.
- Noise generation.
- Visual effects.
Almost every advanced shader starts with a simple random function.
Try These Experiments
Display random grayscale values.
Animate the randomness.
Create larger tiles.
Create smaller tiles.
Colour each random value differently.
Try combining random numbers with circles or rectangles.
Notice how quickly procedural graphics become more interesting.
A Small Challenge
Can you create these effects?
- A colourful mosaic.
- Random glowing squares.
- A flickering display.
- Animated static.
- A field of randomly coloured circles.
Everything begins with the same small random function.
Leave Creating Random Values in GLSL: The Building Blocks of Procedural Graphics to:
Read more #glsl 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