NatureGL Skyv1.1.0

Start here

Quick start

A working sky in an ordinary three.js scene. It has PBR reflections of the live clouds, a sun that sets on schedule, and cloud shadows sweeping across the ground.

This is the complete examples/basic/ integration, with commentary. Every step is required except where it says optional.

#Set up the renderer with tone mapping

The sky writes linear HDR. Give the renderer a tone mapper, or noon will clip to white.

js
import * as THREE from 'three';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
import { SkySystem } from 'naturegl-sky';

const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setPixelRatio(Math.min(devicePixelRatio, 2));
renderer.setSize(innerWidth, innerHeight);
renderer.toneMapping = THREE.ACESFilmicToneMapping;
renderer.shadowMap.enabled = true;
document.body.appendChild(renderer.domElement);

#Build your scene as usual

NatureGL Sky assumes metres (set metersPerUnit if your world uses other units) and a far plane that can see the horizon, since clouds start around 1–2 km up.

js
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(55, innerWidth / innerHeight, 0.5, 20000);
camera.position.set(0, 6, 22);

const ground = new THREE.Mesh(
  new THREE.CircleGeometry(3000, 96).rotateX(-Math.PI / 2),
  new THREE.MeshStandardMaterial({ color: 0x4f6b3a, roughness: 0.95 }),
);
ground.receiveShadow = true;
scene.add(ground);

const sun = new THREE.DirectionalLight();
sun.castShadow = true;
scene.add(sun, sun.target);

#Create the sky

create() is async. It adds the backdrop mesh to your scene, runs the first bakes and pre-compiles the shaders, so the first frame is complete.

js
const sky = await SkySystem.create({
  renderer, scene, camera,
  quality: 'high',          // low | medium | high | ultra
  preset: 'partlyCloudy',
});

#Wire the outputs into your scene

js
scene.environment = sky.environment;              // PBR ambient + reflections
sky.addEventListener('environmentchange', () => {
  scene.environment = sky.environment;            // new texture after quality changes
});
sky.bindLights(sun);                              // sun by day, moon by night
sky.patchMaterial(ground.material);               // cloud shadows on the ground
sky.clock.running = true;                         // optional: let time pass

#Update, then render

Call update(dt) once per frame after moving the camera. The cloud reconstruction needs this frame's camera matrices.

js
const controls = new OrbitControls(camera, renderer.domElement);
const timer = new THREE.Timer();

renderer.setAnimationLoop(t => {
  timer.update(t);
  controls.update();
  sky.update(timer.getDelta());
  renderer.render(scene, camera);   // a plain render: the sky is a mesh in your scene
});

addEventListener('resize', () => {
  camera.aspect = innerWidth / innerHeight;
  camera.updateProjectionMatrix();
  renderer.setSize(innerWidth, innerHeight);
  sky.resize();
});
The result, with the demo's island for scale: the marine preset, cloud shadows on the sand, and the sky reflected in the chrome sphere through scene.environment.

#Change the weather

js
sky.applyPreset('storm');                 // ease over ~1–2 s
sky.loadPreset('clear');                  // snap, history reset
sky.setParams({ humidity: 0.8, wind: 0.6 }); // partial, eased
sky.setTime(18.25);                       // hours, eases the short way round
sky.sun.setFromAngles(8, 250);            // elevation°, azimuth°

#Keep going