Bloom Glow

HDR bloom post-processing effect with threshold and intensity controls.

What this code does

- EffectComposer: post-processing pipeline that applies bloom after scene rendering.
- UnrealBloomPass: realistic HDR bloom with threshold, strength, and radius controls.
- Emissive Materials: self-illuminating objects that contribute to bloom effect.
- Tone Mapping: HDR tone mapping options affect bloom appearance and intensity.
- Interactive Controls: real-time adjustment of bloom parameters and tone mapping.
- Glowing Spheres: animated emissive objects demonstrate bloom on moving light sources.

JavaScript (plain)

const scene = new THREE.Scene()
scene.background = new THREE.Color(0x000511)
const camera = new THREE.PerspectiveCamera(75, width / height, 0.1, 1000)
camera.position.set(0, 0, 5)

const renderer = new THREE.WebGLRenderer({ antialias: true })
renderer.setSize(width, height)

renderer.toneMapping = THREE.ReinhardToneMapping
document.querySelector('#app').appendChild(renderer.domElement)

// Setup post-processing
const composer = new EffectComposer(renderer)
const renderPass = new RenderPass(scene, camera)
composer.addPass(renderPass)

const bloomPass = new UnrealBloomPass(new THREE.Vector2(width, height), 1.5, 0.4, 0.85)
bloomPass.threshold = 0.2
bloomPass.strength = 1.5
bloomPass.radius = 0.4
composer.addPass(bloomPass)

// Create glowing spheres
const geometry = new THREE.IcosahedronGeometry(1, 1)
const spheres = []

for (let i = 0; i < 5; i++) {
  const material = new THREE.MeshStandardMaterial({
    color: new THREE.Color().setHSL(i / 5, 1.0, 0.6),
    emissive: new THREE.Color().setHSL(i / 5, 1.0, 0.3),
    emissiveIntensity: 0.5
  })

  const sphere = new THREE.Mesh(geometry, material)
  sphere.position.x = (i - 2) * 2
  sphere.position.y = Math.sin(i) * 1.5
  spheres.push(sphere)
  scene.add(sphere)

}

// Add lights
const ambientLight = new THREE.AmbientLight(0x404040, 0.1)
scene.add(ambientLight)

const pointLight = new THREE.PointLight(0xffffff, 1, 100)
pointLight.position.set(0, 10, 10)
scene.add(pointLight)

function animate() {
  requestAnimationFrame(animate)

  const time = Date.now() * 0.001
  spheres.forEach((sphere, i) => {
    sphere.position.y = Math.sin(i) * 1.5 + Math.sin(time * 2 + i * Math.PI * 0.4) * 0.5
    sphere.rotation.x = time * 0.5
    sphere.rotation.y = time * 0.3

    const intensity = 0.3 + Math.sin(time * 3 + i * Math.PI * 0.4) * 0.2
    sphere.material.emissiveIntensity = intensity
  })

  composer.render()
}

animate()