Sunrise-to-Sunset
Animate sky and sun color/intensity over a day-night cycle.
What this code does
- Dynamic Sky: scene background color interpolates between day (sky blue) and night (dark blue).
- Sun Position: directional light moves in circular arc based on time of day.
- Color Temperature: light color shifts from warm (sun) to cool (moon) tones.
- Intensity Variation: light intensity peaks at noon and dims during night.
- Ambient Fill: ambient light adjusts to simulate atmospheric scattering.
- Interactive Controls: scrub timeline, play/pause animation, or jump to presets.
JavaScript (plain)
import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
const scene = new THREE.Scene()
scene.background = new THREE.Color(0x87ceeb)
const camera = new THREE.PerspectiveCamera(70, width / height, 0.1, 200)
camera.position.set(0, 2, 6)
const renderer = new THREE.WebGLRenderer({ antialias: true })
renderer.setSize(width, height)
document.querySelector('#app').appendChild(renderer.domElement)
const controls = new OrbitControls(camera, renderer.domElement)
controls.target.set(0, 0.5, 0)
controls.update()
const ground = new THREE.Mesh(
new THREE.PlaneGeometry(50, 50),
new THREE.MeshStandardMaterial({ color: 0x226622, roughness: 0.9 })
)
ground.rotation.x = -Math.PI / 2
ground.position.y = 0
scene.add(ground)
const sphere = new THREE.Mesh(
new THREE.SphereGeometry(0.6, 32, 32),
new THREE.MeshStandardMaterial({
color: 0xffffff,
roughness: 0.2,
metalness: 0
})
)
sphere.position.set(0, 0.6, 0)
scene.add(sphere)
const sun = new THREE.DirectionalLight(0xffeeaa, 2)
sun.position.set(5, 10, 2)
scene.add(sun)
const ambient = new THREE.AmbientLight(0xffffff, 0.2)
scene.add(ambient)
let timeOfDay = 0.25
function updateLighting() {
const t = timeOfDay
const theta = t * Math.PI * 2
const y = Math.sin(theta)
const x = Math.cos(theta)
sun.position.set(5 * x, 8 * Math.max(0.1, y), 2)
const dayColor = new THREE.Color(0x87ceeb)
const nightColor = new THREE.Color(0x0b1020)
scene.background = dayColor.clone().lerp(nightColor, 1 - Math.max(0, y))
const sunWarm = new THREE.Color(0xffe0a0)
const moonBlue = new THREE.Color(0xaaccff)
sun.color = sunWarm.clone().lerp(moonBlue, y < 0 ? 1 : 0)
sun.intensity = y > 0 ? 2 * y : 0.2
ambient.intensity = 0.1 + 0.4 * Math.max(0, y)
}
function animate() {
requestAnimationFrame(animate)
timeOfDay = (timeOfDay + 0.0015) % 1
updateLighting()
controls.update()
renderer.render(scene, camera)
}
animate()