Three.js Sky, Clouds and Fog

Three.js scenes get a sky one of three ways: a static skybox/environment map for the fastest setup, the built-in procedural Sky addon for a physically-inspired dynamic day/sunset sky with no texture needed, or a custom shader for full stylistic control. THREE.Fog/FogExp2 adds depth cues and atmosphere on top of any of them for almost no cost.

Last updated . Verified against three.js r181.

Read the FAQJump to code

Skybox vs procedural sky

Skybox / environment map: a cubemap or equirectangular HDRI texture set as scene.background (and often scene.environment for lighting too). Fastest to set up, looks as good as the source photo/render, and doubles as realistic image-based lighting if it's an HDRI. The tradeoff: it's static, so there's no time-of-day change without swapping textures or blending between two.

Procedural sky (Sky addon): Three.js ships a physically-inspired atmospheric scattering sky shader in the examples/addons. Tunable sun position, turbidity and Rayleigh scattering produce a continuously adjustable sky, useful for a day/night cycle or a sunset that shifts in real time, something a static texture can't do without swapping assets.

Custom shader: full control for a stylized (non-physical) sky: a gradient, animated stars, a painterly look. Worth it specifically when the built-in options' physically-inspired look doesn't match your art direction.

Cloud techniques

Clouds in real-time rendering are almost always an approximation rather than true volumetric simulation, layered by cost:

  • Billboard/sprite clouds: flat, camera-facing textured planes (cloud puff textures) scattered in the sky. Cheap, looks reasonable from a distance, breaks down under close inspection or when the camera moves through them.
  • Layered noise on a sky dome: procedural noise (often multiple octaves scrolling at different speeds) sampled on the inside of a sky sphere or dome, for a stylized moving-cloud look without discrete billboard shapes.
  • True volumetric clouds: raymarched noise through a 3D volume, the technique behind the most convincing real-time clouds (and behind most AAA game skies). More expensive; usually only worth it when clouds are a genuine focal point of the scene rather than background atmosphere.

Fog for depth and atmosphere

THREE.Fog (linear, fades between a near and far distance) and THREE.FogExp2 (exponential falloff, generally looks more natural) both blend distant objects toward a fog color, which does real work beyond atmosphere: it hides the far clipping plane's hard edge, gives depth cues for free, and can mask level-of-detail pop-in at a distance.

Set scene.fog, and make sure the fog color matches (or complements) your sky/background color. Mismatched fog and sky color is one of the most common "why does my scene look wrong" issues in outdoor Three.js scenes, since the horizon line becomes visibly discontinuous.

Tools and libraries

Code

Procedural Sky + fog (r181)
1import { Sky } from 'three/examples/jsm/objects/Sky.js'
2
3const sky = new Sky()
4sky.scale.setScalar(450000)
5scene.add(sky)
6
7const sun = new THREE.Vector3()
8const elevation = 10, azimuth = 180
9const phi = THREE.MathUtils.degToRad(90 - elevation)
10const theta = THREE.MathUtils.degToRad(azimuth)
11sun.setFromSphericalCoords(1, phi, theta)
12sky.material.uniforms.sunPosition.value.copy(sun)
13
14// Match fog color to the horizon so the transition isn't visible
15scene.fog = new THREE.FogExp2(0xbfd1e5, 0.008)
Skybox from an equirectangular HDRI
1import { RGBELoader } from 'three/examples/jsm/loaders/RGBELoader.js'
2
3new RGBELoader().load('/hdri/sky.hdr', (texture) => {
4 texture.mapping = THREE.EquirectangularReflectionMapping
5 scene.background = texture // static sky
6 scene.environment = texture // also lights the scene realistically (IBL)
7})

Learn this properly

Learn Practical TSL

Your First Node Material

Node materials are useful for building a custom stylized sky shader.

Start the lesson (6 minutes)

Frequently asked questions

How do I add a sky to a Three.js scene?

Fastest: set scene.background to an equirectangular HDRI or cubemap texture. For a dynamic, adjustable day/sunset sky with no texture, use Three.js's built-in Sky addon. For a fully custom stylized look, write a shader.

How do you make realistic clouds in Three.js?

Billboard/sprite clouds are the cheapest approach and look fine from a distance. Layered scrolling noise on a sky dome gives a more dynamic stylized look. True volumetric raymarched clouds look best but are more expensive: reserve them for scenes where clouds are a genuine focal point.

Why does fog look wrong in my Three.js scene?

The most common cause is a fog color that doesn't match the sky/background color, which creates a visible seam at the horizon. Set scene.fog's color to match your sky.

Keep reading