Neon Glow Text

Emissive neon-style text with adjustable glow intensity.

What this code does

- Emissive Material: MeshStandardMaterial with emissive color simulates self-illuminating neon signs.
- Emissive Intensity: controls brightness of the glow effect independent of scene lighting.
- Color Independence: emissive color adds to the final pixel color regardless of lighting conditions.
- Background Contrast: dark background plane emphasizes the bright neon glow effect.
- Subtle Animation: gentle rotation creates dynamic lighting reflections on surrounding surfaces.
- Interactive Controls: real-time adjustment of emissive color, intensity, and bloom threshold.

JavaScript (plain)

import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
import { FontLoader } from 'three/examples/jsm/loaders/FontLoader.js'
import { TextGeometry } from 'three/examples/jsm/geometries/TextGeometry.js'

const scene = new THREE.Scene()
scene.fog = new THREE.Fog(0x000000, 15, 35)
const camera = new THREE.PerspectiveCamera(60, width / height, 0.1, 200)
camera.position.set(0, 1.5, 6)

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

document.querySelector('#app').appendChild(renderer.domElement)

const controls = new OrbitControls(camera, renderer.domElement)
controls.target.set(0, 1, 0)
controls.update()

const backdrop = new THREE.Mesh(
  new THREE.PlaneGeometry(20, 10),
  new THREE.MeshStandardMaterial({ color: 0x050505 })
)
backdrop.position.z = -2
scene.add(backdrop)

const ambient = new THREE.AmbientLight(0xffffff, 0.1)
scene.add(ambient)

const fill = new THREE.DirectionalLight(0xffffff, 0.4)
fill.position.set(3, 3, 3)
scene.add(fill)

const accent = new THREE.PointLight(0x00ffff, 3, 12, 1.5)
accent.position.set(0, 1.3, 2.5)
scene.add(accent)

const loader = new FontLoader()
loader.load('https://threejs.org/examples/fonts/helvetiker_regular.typeface.json', (font) => {
  const geometry = new TextGeometry('NEON', {
    font,
    size: 0.5,
    height: 0.05,
    depth: 0.1,
    bevelEnabled: true,
    bevelThickness: 0.02,
    bevelSize: 0.008
  })
  geometry.computeBoundingBox()
  const offsetX = -0.5 * (geometry.boundingBox.max.x - geometry.boundingBox.min.x)
  const offsetY = -0.5 * (geometry.boundingBox.max.y - geometry.boundingBox.min.y)
  const material = new THREE.MeshStandardMaterial({
    color: 0x111111,
    emissive: 0x00ffff,
    emissiveIntensity: 2,
    metalness: 0.25,
    roughness: 0.35
  })
  const mesh = new THREE.Mesh(geometry, material)
  mesh.position.set(offsetX, 1 + offsetY, 0)
  scene.add(mesh)

  accent.position.set(offsetX, 1 + offsetY + 0.25, 2.2)
})

function animate () {
  requestAnimationFrame(animate)
  controls.update()
  renderer.render(scene, camera)
}
animate()