Sunday, May 25, 2025

How to create a rotating 3D Menger sponge in p5.js using the WEBGL renderer

How to create a rotating 3D Menger sponge in p5.js using the WEBGL renderer, complete with color gradients, an orbiting light, and specular shine effects. I'll provide a complete solution with explanations and the full code.

Overview

We'll create a level 1 Menger sponge, which is a cube divided into a 3x3x3 grid (27 smaller cubes), with the center cube and the center of each face removed, leaving 20 smaller cubes. The sponge will rotate, have a color gradient across its cubes, be illuminated by an orbiting light, and feature a shiny surface.

Steps

  1. Setup the Canvas:
    • Use p5.js in WEBGL mode for 3D rendering.
  2. Draw the Menger Sponge:
    • Position 20 smaller cubes where at least two coordinates are non-zero (±1), excluding face centers and the central cube.
  3. Add Color Gradients:
    • Interpolate colors across the sponge based on cube positions.
  4. Rotate the Sponge:
    • Apply continuous rotation around the X and Y axes.
  5. Create an Orbiting Light:
    • Position a point light that circles the sponge.
  6. Apply Specular Shine:
    • Use specular material to make the cubes reflective.



Solution Code

<!DOCTYPE html>
<html>
<head>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.2/p5.min.js"></script>
</head>
<body>
<script>
function setup() {
  createCanvas(400, 400, WEBGL);
}

function draw() {
  background(0);
 
  // Rotate the sponge
  rotateX(frameCount * 0.01);
  rotateY(frameCount * 0.01);
 
  // Orbiting light
  let lightX = sin(frameCount * 0.02) * 200;
  let lightY = cos(frameCount * 0.02) * 200;
  pointLight(255, 255, 255, lightX, lightY, 200);
 
  // Draw Menger sponge
  for (let i = -1; i <= 1; i++) {
    for (let j = -1; j <= 1; j++) {
      for (let k = -1; k <= 1; k++) {
        let zeros = (i === 0 ? 1 : 0) + (j === 0 ? 1 : 0) + (k === 0 ? 1 : 0);
        if (zeros < 2) {
          push();
          translate(i * 20, j * 20, k * 20);
          let t = map(i, -1, 1, 0, 1);
          let c = lerpColor(color(255, 0, 0), color(0, 0, 255), t);
          specularMaterial(c);
          shininess(20);
          box(20);
          pop();
        }
      }
    }
  }
}
</script>
</body>
</html>


Explanation

  • Setup:
    • A 400x400 pixel canvas is created with WEBGL mode, enabling 3D graphics.
  • Draw Loop:
    • Background: Cleared to black each frame.
    • Rotation: The sponge rotates around the X and Y axes, with the rotation angle based on frameCount for smooth animation.
    • Orbiting Light: A white point light orbits in the XY plane at a radius of 200 units, using sin() and cos() for circular motion.
    • Menger Sponge:
      • Loops iterate over a 3x3x3 grid (i, j, k from -1 to 1).
      • Cubes are drawn only where fewer than 2 coordinates are zero, resulting in 20 cubes (8 corners and 12 edge centers).
      • Each cube is 20 units wide, positioned at multiples of 20 (e.g., -20, 0, 20).
      • Color Gradient: Colors transition from red (255, 0, 0) to blue (0, 0, 255) based on the X-coordinate using lerpColor().
      • Specular Shine: specularMaterial() applies the color with reflectivity, and shininess(20) enhances the shine effect under the light.

Visual Result

  • The sponge appears as a 3D structure with 20 cubes forming a hollowed-out pattern.
  • It rotates continuously, showing all sides.
  • The color shifts from red on the left to blue on the right.
  • A white light orbits around it, casting highlights that emphasize the specular shine.

This solution provides a dynamic and visually engaging 3D Menger sponge in p5.js WEBGL, meeting all specified requirements. You can copy the code into an HTML file and open it in a browser to see it in action!

No comments:

virtual representations of physical objects or systems.

Digital Twins - Virtual Replicas of Cities, Factories, or Human Organs for Simulations How virtual copies are revolutionizing the phys...