Creating a Realistic Bubble Shader in Three.js

Introduction

Bubbles add a whimsical and ethereal touch to 3D scenes, often seen in underwater environments or playful animations. This article explains how to create a realistic bubble shader in Three.js, incorporating refraction, iridescence, and dynamic movement to simulate real-life bubble behavior.

Key Characteristics of a Bubble

A bubble is defined by:

  1. Transparency: A bubble is mostly see-through.
  2. Refraction: Light bends as it passes through the bubble’s surface.
  3. Iridescence: A rainbow-like effect caused by thin-film interference.
  4. Dynamic Shape: Slight deformations give a natural look.

Vertex Shader: Adding Subtle Deformations

Purpose

The vertex shader manipulates the shape of the bubble to simulate slight distortions caused by internal forces.

Code Explanation

uniform float time;  // Animation time  
varying vec3 vPosition;  // Pass vertex position to the fragment shader  

float noise(vec3 p) {
    return sin(p.x * 3.0 + time) * 0.5 + 0.5;
    // Generate noise for subtle vertex displacement  
}

void main() {
    vec3 pos = position;
    pos += normal * noise(pos + time) * 0.05;  
    // Apply noise-based distortion along the surface normal  

    vPosition = pos;  
    gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0);
}

Key Features

  1. Dynamic Surface Deformation: Adds realism to the bubble’s shape.
  2. Time-Based Animation: Continuous motion simulates real-life behavior.

Fragment Shader: Simulating Bubble Properties

Purpose

The fragment shader handles the bubble’s visual aspects, including transparency, refraction, and iridescence.

Code Explanation

uniform float time;  
varying vec3 vPosition;  

void main() {
    float refraction = sin(vPosition.x * 5.0 + time) * 0.1;  
    // Simulate light refraction with sine wave distortion  

    vec3 baseColor = vec3(0.7, 0.9, 1.0);  
    // Light blue as the base bubble color  

    vec3 iridescence = vec3(sin(vPosition.x * 10.0 + time), 
                            cos(vPosition.y * 10.0 + time), 
                            sin(vPosition.z * 10.0 - time));  
    // Add iridescence with color-shifting effects  

    vec3 finalColor = mix(baseColor, iridescence, 0.5);  
    // Blend base color with iridescence  

    gl_FragColor = vec4(finalColor, 0.3);  
    // Apply transparency to simulate a bubble's translucent nature  
}

Key Features

  1. Refraction: Simulates light bending.
  2. Iridescence: Adds a rainbow-like effect with time-based color shifts.
  3. Transparency: Achieved through a low alpha value.

Implementing the Shader in Three.js

  1. Geometry: Use a sphere geometry for the bubble’s shape.
  2. Material: Create a custom ShaderMaterial with the above shaders.
  3. Animation: Continuously update the time uniform for dynamic effects.
const bubbleMaterial = new THREE.ShaderMaterial({
    uniforms: {
        time: { value: 0.0 }
    },
    vertexShader: `...`,  // Vertex shader code here  
    fragmentShader: `...`,  // Fragment shader code here  
    transparent: true  
});

const bubbleGeometry = new THREE.SphereGeometry(1, 64, 64);
const bubbleMesh = new THREE.Mesh(bubbleGeometry, bubbleMaterial);
scene.add(bubbleMesh);

Enhancing the Bubble

To make the bubble even more dynamic:

  1. Scale Animation: Use GSAP or Three.js’ animation loop to make the bubble pulsate.
  2. Multiple Bubbles: Create a group of bubbles with slight variations in size and movement.
  3. Post-Processing: Add bloom effects to enhance the bubble’s iridescence.

Applications

  • Underwater Scenes: Create a school of bubbles to enhance underwater realism.
  • Playful Animations: Add bubbles in a whimsical game or interactive experience.
  • Physics Simulations: Combine with physics libraries like Cannon.js for realistic bubble motion.

Conclusion

By leveraging dynamic shaders in Three.js, you can create realistic and captivating bubble effects. Experimenting with parameters like refraction strength, color gradients, and motion speed can lead to a variety of bubble designs. Integrate these shaders into your scenes to bring them to life with an enchanting visual appeal!

Leave a comment

Your email address will not be published. Required fields are marked *