ANIMATED WHITE
CLOUD PARTICLES
Create soft, drifting clouds in the browser with Three.js — built from layered smoke sprites that face the camera and slowly rotate.
LIVE DEMO
The soft clouds drifting behind this page are the live demo. Use the buttons to pause and resume the animation.
Introduction
Realistic clouds are surprisingly easy in Three.js. Instead of a complex GPU particle simulation, this free tutorial layers about 25 flat planes, each mapped with a soft, semi-transparent smoke texture. Scatter them through space, make each one face the camera, and rotate them slowly — the overlapping transparency blends into soft, volumetric-looking clouds.
It runs fast, looks great, and the whole effect is only a few dozen lines of code. Copy it below and drop it into any page.
Frequently Asked Questions
How do you make clouds in Three.js?
The simplest realistic cloud effect uses many flat planes, each mapped with a soft semi-transparent smoke texture. Scatter the planes through space, make each face the camera, and slowly rotate them. Overlapping transparent sprites blend into soft, volumetric-looking clouds.
Why use textured planes instead of real particles for clouds?
A soft smoke texture on a plane already looks like a puff of cloud. Layering 25 to 50 of these transparent, camera-facing planes and rotating them gives a convincing volumetric look for a tiny performance cost, without a complex GPU particle system.
How do you make a plane always face the camera in Three.js?
Call mesh.lookAt(camera.position) so the plane's normal points at the camera. This billboarding keeps each flat smoke sprite facing the viewer no matter where the camera moves, which is what sells the cloud illusion.
Is this Three.js cloud tutorial free?
Yes. This is a completely free tutorial. The full source code is shown on the page, you can copy it, and there is a live cloud demo running in the background. No sign-in or membership is required.
How To Add The Code
Follow these steps to get the cloud effect running on your own page. You need a plain HTML file, a soft smoke PNG texture, and Three.js from a CDN.
- 1Create an HTML file. Make a new file called
index.htmlwith the standard<!DOCTYPE html>,<head>, and<body>tags. - 2Get a smoke texture. Save a soft, semi-transparent smoke PNG next to your HTML (e.g.
smoke.png). A white puff on a transparent background works best. - 3Load Three.js from a CDN. Just before your closing
</body>tag, add the Three.js script soTHREEis available. - 4Add the cloud script. Below the Three.js tag, paste the full script shown below. It builds the scene, camera, renderer, and lighting.
- 5Load the texture. Use
TextureLoaderto load your smoke PNG so it can be applied to each plane. - 6Create the cloud planes. In a loop, make ~25 transparent
PlaneGeometrymeshes at random positions, calllookAt(camera.position)so each faces the camera, and give each a random rotation speed. - 7Animate and handle resize. Rotate every plane a little each frame inside
requestAnimationFrame, and update the camera when the window resizes. - 8Open it in your browser. Serve the folder locally (so the PNG loads) and you will see soft clouds drifting and turning.
Tip: browsers block local file textures over file://. Run a quick local server, e.g. python -m http.server, then open http://localhost:8000.
The Full Code
Paste this into index.html, put a smoke.png beside it, and serve the folder.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Three.js Animated Cloud Particle System</title>
<style> body { margin: 0; background: #0a0b0f; } </style>
</head>
<body>
<!-- 1. Load Three.js from a CDN -->
<script src="https://cdn.jsdelivr.net/npm/three@latest/build/three.min.js"></script>
<!-- 2. The cloud system -->
<script>
// Scene, camera, renderer
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(
100, window.innerWidth / window.innerHeight, 1, 4000
);
const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor(0x0a0b0f, 1);
document.body.appendChild(renderer.domElement);
// Light so the smoke material is visible
const ambient = new THREE.AmbientLight(0xffffff, 5);
scene.add(ambient);
// Load a soft smoke texture (put smoke.png next to this file)
const smokeTexture = new THREE.TextureLoader().load('smoke.png');
// Build ~25 camera-facing smoke planes
const planes = [];
for (let i = 0; i < 25; i++) {
const geometry = new THREE.PlaneGeometry(15, 15);
const material = new THREE.MeshPhongMaterial({
map: smokeTexture,
transparent: true,
opacity: 1,
depthTest: false
});
const plane = new THREE.Mesh(geometry, material);
// Random position in space
plane.position.set(
Math.random() * 30 - 15,
Math.random() * 30 - 15,
-2
);
// Face the camera (billboard)
plane.lookAt(camera.position);
// Give each plane its own slow spin
plane.userData.speed = Math.random() * 0.3;
scene.add(plane);
planes.push(plane);
}
// Animation loop
const clock = new THREE.Clock();
function animate() {
requestAnimationFrame(animate);
const delta = clock.getDelta();
for (const plane of planes) {
plane.rotateOnAxis(new THREE.Vector3(0, 0, 1), plane.userData.speed * delta);
}
renderer.render(scene, camera);
}
animate();
// Keep it sharp on resize
window.addEventListener('resize', () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
});
</script>
</body>
</html>
What To Try Next
- Increase the loop count to 50+ planes for denser, fuller clouds.
- Tint the
MeshPhongMaterialwith acolorfor stormy grey or sunset orange clouds. - Lower each plane's
opacity(e.g. 0.4) so overlaps blend more softly. - Slowly drift the whole cloud group along X for a windswept sky.
- Add colored lights that move to make the clouds shift hue over time.
SEE 3D AND 2D BROWSER GAMES IN ACTION
Built with Three.js and JavaScript — free, no download, plays right in your browser.
Super Soldier Battle
Free 3D multiplayer FPS built with Three.js and WebGL. Destroy the enemy bots and turrets, climb the leaderboard.
Play now →
AI Tic-Tac-Toe
Play the classic game against an AI opponent right in your browser. Free, no download, with an online leaderboard.
Play now →
Zombie Attack
Survive waves of zombies in this free 3D browser shooter built with Three.js. No download, plays instantly.
Play now →
Space Wow
Blast through space in this free 3D Three.js arcade shooter. Free, no download, plays right in your browser.
Play now →