Simulate Soap Bubbles with Three.js Iridescence

This article explains how to use the iridescence properties in Three.js to simulate thin-film interference, the optical phenomenon responsible for the shifting rainbow colors seen on soap bubbles, oil slicks, and camera lenses. You will learn about the physics behind this effect, the specific properties of MeshPhysicalMaterial that control it, and how to implement it in your 3D scenes.

What is Thin-Film Interference?

Thin-film interference occurs when light waves reflect off both the upper and lower boundaries of a microscopic thin film. Because the film is extremely thin—comparable to the wavelength of visible light—the two reflected waves interfere with one another.

Depending on the film’s thickness, the refractive index, and the viewer’s angle of observation, certain light wavelengths (colors) amplify each other (constructive interference) while others cancel each other out (destructive interference). As the viewing angle or film thickness changes, the perceived color shifts, creating the classic iridescent rainbow effect.

Implementing Iridescence in Three.js

Three.js simulates this complex wave-theory physics using the MeshPhysicalMaterial class. To create an iridescent effect like a soap bubble, you must configure several specific properties:

1. iridescence

This property controls the intensity of the iridescence effect. It is a float value, typically ranging from 0.0 (no iridescence) to 1.0 (maximum iridescence).

2. iridescenceIOR

This represents the Index of Refraction (IOR) of the thin-film layer itself. It determines how sharply light bends when entering the film, which alters the interference wavelengths. Common values range between 1.2 and 1.7 (water/soap is roughly 1.33).

3. iridescenceThicknessRange

This is an array of two numbers, [minimum, maximum], defining the thickness of the thin film in nanometers (nm). Visible light waves range from roughly 380 nm to 750 nm. Altering these limits changes which colors are constructive or destructive, thereby shifting the color palette of the gradient. A standard range for a soap bubble is [100, 400] or [100, 800].

4. iridescenceThicknessMap

To prevent the colors from looking static and uniform, you can supply a grayscale texture to this property. The texture’s pixel values (0 to 1) map to the minimum and maximum values defined in iridescenceThicknessRange. This variation simulates natural thickness differences in a soap bubble, creating a swirling, organic color pattern.


Code Example: Creating a Soap Bubble

To make a realistic soap bubble, you must combine iridescence with high transmission (transparency) and low roughness.

import * as THREE from 'three';

// Create the geometry
const geometry = new THREE.SphereGeometry(1, 64, 64);

// Create the iridescent physical material
const bubbleMaterial = new THREE.MeshPhysicalMaterial({
    roughness: 0.05,            // Bubbles are highly reflective and smooth
    transmission: 0.95,         // High transmission allows light to pass through
    ior: 1.1,                  // Low base IOR to minimize default glass reflection
    transparent: true,
    opacity: 1.0,
    
    // Iridescence settings
    iridescence: 1.0,                     // Maximize the effect
    iridescenceIOR: 1.33,                 // Soap/water refractive index
    iridescenceThicknessRange: [100, 400] // Limits in nanometers for color shifting
});

// Create and add the mesh to the scene
const bubble = new THREE.Mesh(geometry, bubbleMaterial);
scene.add(bubble);

How the Shader Calculates the Effect

Under the hood, the Three.js fragment shader calculates the optical path difference based on: 1. The angle between the camera’s view vector and the surface normal (the Fresnel effect). 2. The thickness value of the film at that specific fragment. 3. The specified iridescenceIOR.

Using these inputs, the renderer dynamically computes an interference color shift and layers it on top of the material’s base diffuse reflections and specular highlights. Consequently, as the camera or the bubble rotates, the colors naturally shift and flow across the surface.