Mango Media - Luminosity 3D

Luminosity 3D


Reflecting light off 3D objects with Three.js with an interactive GUI.

Three.js is a cross-browser JavaScript library + application programming interface (API) used to create + display animated 3D computer graphics in a web browser using WebGL.

There are multiple types of lights that we can use in Three.js, this project is a demonstration of all the different classes that can be manipulated using the GUI.
This project was inspired by the course Three.js Journey by Bruno Simon a creative developer based in Paris.






The Universe


Interaction, 3D, Creative Coding


Three.js + Javascript

Setting the scene

A scene is set up complete with a rotating sphere, cube, doughnut + a plane as the floor.
Since I am using lights I have used a material that reacts to lights - in this case, the texture of the objects is set as MeshStandardMaterial. The rotation exacerbates the luminosity of an object by the measure of its intrinsic brightness + is defined as the amount of energy the object emits in a fixed time.

Explaining the code

 * Lights - This code generates 6 different types of light demonstrating each method we can reflect on 3D objects.

// Ambient Light - 
// The AmbientLight applies omnidirectional lighting on all geometries of the scene.
// The first parameter is the color + the second parameter is the intensity.
// As for the materials, you can set the properties directly when instantiating or you can change them after:
const ambientLight = new THREE.AmbientLight() // Ambient Light is a class within the Three.js libary.
ambientLight.color = new THREE.Color(0xffffff) // Declare the colour
ambientLight.intensity = 0.5 // Declare the Intensity
scene.add(ambientLight) // Need to always add elements to the scene
gui.add(ambientLight, 'intensity').min(0).max(1).step(0.01).name('Ambient Light Intensity') // With dat.gui we can easily manipulate attributes in the frontend

// Directional Light - 
// The DirectionalLight will have a sun-like effect as if the sun rays were traveling in parallel.
//The first parameter is the color + the second parameter is the intensity:
const directionalLightColour = { //We are globally declaring the colour so we can use this in different functions
    color: 0x46ff97,
const directionalLight = new THREE.DirectionalLight()
directionalLight.color = new THREE.Color({ color: directionalLight.color })
directionalLight.intensity = 0.3
directionalLight.position.set(1, 0.25, 0) // Position of the light is required to make sure the light is projecting on top
.addColor(directionalLightColour, 'color') 
.name('Directional Light Colour')
.onChange(() => // On change function checks if a user has changed the colour value + adjusts the light colour accordingly

//Hemisphere Light -
// The HemisphereLight is similar to the AmbientLight but with a different color from the sky than the color coming from the ground.
//Faces facing the sky will be lit by one color while another color will lit faces facing the ground.
const hemisphereLight = new THREE.HemisphereLight(0xff0000, 0x0000ff, .2)
const hemisphereLightColour = { // The first parameter is the color corresponding to the sky color.
    color: 0xff0000,
.addColor(hemisphereLightColour, 'color') 
.name('Hemisphere Light Colour')
.onChange(() =>
    hemisphereLight.color.set(hemisphereLightColour.color) // The second parameter is the groundColor.
const hemisphereLightGroundColour = {
    color: 0x0000ff,
.addColor(hemisphereLightGroundColour, 'color') 
.name('Hemisphere Light Ground Colour')
.onChange(() =>

// PointLight -
// The PointLight is almost like a lighter. 
// The light source is infinitely small, and the light spreads uniformly in every direction.
// The first parameter is the colour and the second parameter is the intensity:
const pointLight = new THREE.PointLight(0xff900, 0.6)
//pointLight.decay = 10
//pointLight.distance = 2
pointLight.position.set(1, -0.5, 1)
gui.add(pointLight, 'intensity').min(0).max(1).step(0.01).name('Point Light Intensity')
const pointLightColour = {
    color: 0xff900,
.addColor(pointLightColour, 'color') 
.name('PointLight Colour')
.onChange(() =>

// RectAreaLight -
// The RectAreaLight works like the big rectangle lights you can see on the photoshoot set.
// It's a mix between a directional light and a diffuse light.
// The first parameter is the color, the second parameter is the intensity, the third parameter is width of the rectangle, and the fourth parameter is its height:
const rectAreaLight = new THREE.RectAreaLight(0x4e00ff, 2, 1, 1)
rectAreaLight.position.set(-1.5, 0, 1.5)
rectAreaLight.lookAt(new THREE.Vector3())
gui.add(rectAreaLight, 'intensity').min(0).max(5).step(0.01).name('Rectarea Intensity')
const rectAreaColour = {
    color: 0x4e00ff,
.addColor(rectAreaColour, 'color') 
.name('Rectarea Colour')
.onChange(() =>

// SpotLight
//The SpotLight works like a flashlight.
//It's a cone of light starting at a point and oriented in a direction.
const spotLight = new THREE.SpotLight(0xffd100, 1, 6, Math.PI * 0.1, 0.25, 1) // Colour, intensity, distance, angle, penumbra(how diffused is the contour of the beam), decay(how fast the light dims)
spotLight.position.set(0, 2, 3)
scene.add(spotLight) = 0
gui.add(spotLight, 'intensity').min(0).max(2).step(0.01).name('Spotlight Intensity')
const spotLightColour = {
    color: 0xffd100,
.addColor(spotLightColour, 'color') 
.name('SpotLight Colour')
.onChange(() =>
See Project

Related Projects

Let's start creating your award winning website today!

Anything is possible,
Let's make your dreams a reality.

Get in touch!