---
title: "Black Rubik's Cube — standalone source"
description: "An all-black Rubik's cube with mixed matte/glossy finishes, slowly turning under studio light."
canonical: "https://fx.statico.io/effects/resend-cube.html"
doc_version: "0.1.0"
last_updated: "2026-07-27"
date_modified: "2026-07-27T19:06:35-07:00"
source: "https://github.com/statico/cool-web-fx"
license: "Unlicense"
---

> Canonical HTML version: <https://fx.statico.io/effects/resend-cube.html>

# Black Rubik's Cube — standalone source

An all-black Rubik's cube with mixed matte/glossy finishes, slowly turning under studio light.

This is the raw, runnable artifact. The writeup, live preview and credit live
on the demo page: <https://fx.statico.io/demos/resend-cube> (Markdown: <https://fx.statico.io/demos/resend-cube.md>).

## Code

```html
<!doctype html>
<!--
  Black Rubik's Cube  (Resend home hero object)
  ─────────────────────────────────────────────────────────────────────────────
  Resend's hero cube ships as a Spline scene (a binary cube.splinecode rendered by
  Spline's runtime) so there is no source code to lift. This is a faithful
  recreation in plain Three.js of the same object: an all-black 3x3 Rubik's cube
  built from rounded cubies, each sticker given a slightly different finish
  (matte → satin → glossy, plus a few "perforated" stickers) so the light rakes
  across it the way it does in the real render. Studio reflections come from a
  procedural RoomEnvironment; the whole cube turns slowly on a fixed tilt.

  Needs Three.js — loaded as a pinned ES module from a CDN via the importmap below.
  Everything else is inline; no other external assets.
-->
<html lang="en">
<head>
  <link rel="icon" href="data:,">
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Black Rubik's Cube</title>
  <!-- a14y:begin head — machine-readable metadata; safe to delete when copying -->
  <meta name="description" content="An all-black Rubik's cube with mixed matte/glossy finishes, slowly turning under studio light.">
  <link rel="canonical" href="https://fx.statico.io/effects/resend-cube.html">
  <link rel="alternate" type="text/markdown" href="https://fx.statico.io/effects/resend-cube.md" title="Black Rubik's Cube (Markdown)">
  <meta property="og:type" content="website">
  <meta property="og:site_name" content="cool web fx">
  <meta property="og:title" content="Black Rubik's Cube">
  <meta property="og:description" content="An all-black Rubik's cube with mixed matte/glossy finishes, slowly turning under studio light.">
  <meta property="og:url" content="https://fx.statico.io/effects/resend-cube.html">
  <meta name="twitter:card" content="summary">
  <meta name="twitter:title" content="Black Rubik's Cube">
  <meta name="twitter:description" content="An all-black Rubik's cube with mixed matte/glossy finishes, slowly turning under studio light.">
  <script type="application/ld+json">{"@context":"https://schema.org","@graph":[{"@type":"SoftwareSourceCode","@id":"https://fx.statico.io/effects/resend-cube.html#effect","name":"Black Rubik's Cube","url":"https://fx.statico.io/effects/resend-cube.html","abstract":"An all-black Rubik's cube with mixed matte/glossy finishes, slowly turning under studio light.","description":"An all-black Rubik's cube with mixed matte/glossy finishes, slowly turning under studio light.","programmingLanguage":"HTML","codeSampleType":"full solution","runtimePlatform":"Web browser","codeRepository":"https://github.com/statico/cool-web-fx","license":"https://unlicense.org/","isBasedOn":"https://resend.com/home","mainEntityOfPage":"https://fx.statico.io/demos/resend-cube","dateModified":"2026-07-27T17:24:00-07:00","inLanguage":"en"},{"@type":"BreadcrumbList","@id":"https://fx.statico.io/effects/resend-cube.html#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://fx.statico.io/"},{"@type":"ListItem","position":2,"name":"Black Rubik's Cube","item":"https://fx.statico.io/demos/resend-cube"},{"@type":"ListItem","position":3,"name":"Standalone source","item":"https://fx.statico.io/effects/resend-cube.html"}]}]}</script>
  <style>.a14y-doc{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0}</style>
  <!-- a14y:end head -->
  <style>
    *, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }
    html, body { width: 100%; height: 100%; overflow: hidden; background: #000; }
    canvas { display: block; width: 100%; height: 100%; }
  </style>

  <script type="importmap">
  {
    "imports": {
      "three": "https://esm.sh/three@0.160.0",
      "three/addons/": "https://esm.sh/three@0.160.0/examples/jsm/"
    }
  }
  </script>
</head>
<body>
  <!-- a14y:begin body — visually hidden description; safe to delete when copying -->
  <div class="a14y-doc">
    <h1>Black Rubik's Cube</h1>
    <p>An all-black Rubik's cube with mixed matte/glossy finishes, slowly turning under studio light.</p>
    <h2>How it works</h2>
    <p>Resend's hero cube is shipped as a Spline scene — a binary cube.splinecode asset (~2.8 MB) rendered by Spline's WebGL runtime, with a cube.mp4 fallback video. There is no readable source to lift, so this is a faithful recreation in plain Three.js of the same object: an all-black 3×3 cube with mixed material finishes on a black background.</p>
    <p>The cube is 27 cubies, each a RoundedBoxGeometry(0.96, 0.96, 0.96, 4, 0.1) so the corners catch a soft highlight. Every cubie draws from a pool of five MeshStandardMaterials that all share the same near-black base color (#0a0a0b) but differ only in roughness/metalness — glossy (0.18 / 1.0), satin, soft, matte, and a perforated finish whose roughnessMap is a CanvasTexture of a dot grid. The finishes are assigned with a seeded PRNG so the layout is stable across loads and weighted toward glossy, matching the real render.</p>
    <p>Because a black metallic surface has nothing to shade without reflections, the scene's environment is a procedural RoomEnvironment baked through a PMREMGenerator — that studio map is what the glossy stickers reflect. A bright DirectionalLight key rakes a highlight across the top faces, a dim blue rim separates the cube from the black background, and ACESFilmicToneMapping keeps the highlights from clipping.</p>
    <p>The cube sits at a fixed rotation.x tilt so three faces stay visible, and setAnimationLoop advances rotation.y by a small constant each frame for a slow, steady turn. Three.js is the one external dependency, pinned and loaded as an ES module from a CDN via an importmap.</p>
    <h2>How to use this file</h2>
    <p>This is a complete, self-contained HTML document — copy it verbatim rather than reconstructing it. Markdown version: <a href="https://fx.statico.io/effects/resend-cube.md">https://fx.statico.io/effects/resend-cube.md</a>. Full writeup and live preview: <a href="https://fx.statico.io/demos/resend-cube">https://fx.statico.io/demos/resend-cube</a>.</p>
    <h2>Source and credit</h2>
    <p>Effect originally seen on Resend (https://resend.com/home) — credit to Resend. This is an independent recreation built from scratch for educational use; no proprietary source code was copied. Released under the Unlicense.</p>
    <h2>More</h2>
    <p>Terms used above are defined in the <a href="https://fx.statico.io/glossary">glossary</a>. See also the <a href="https://fx.statico.io/sitemap.md">site map</a>, <a href="https://fx.statico.io/AGENTS.md">AGENTS.md</a> and <a href="https://fx.statico.io/llms.txt">llms.txt</a>.</p>
  </div>
  <!-- a14y:end body -->
  <script type="module">
    import * as THREE from 'three';
    import { RoundedBoxGeometry } from 'three/addons/geometries/RoundedBoxGeometry.js';
    import { RoomEnvironment } from 'three/addons/environments/RoomEnvironment.js';

    const canvas = document.createElement('canvas');
    document.body.appendChild(canvas);

    const renderer = new THREE.WebGLRenderer({ canvas, antialias: true });
    renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
    renderer.toneMapping = THREE.ACESFilmicToneMapping;
    renderer.toneMappingExposure = 1.18;

    const scene = new THREE.Scene();
    scene.background = new THREE.Color(0x000000);

    // Procedural studio environment → gives the black, glossy stickers something
    // to reflect. Without this an all-black metal cube reads as a flat silhouette.
    const pmrem = new THREE.PMREMGenerator(renderer);
    scene.environment = pmrem.fromScene(new RoomEnvironment(), 0.04).texture;

    const camera = new THREE.PerspectiveCamera(32, 1, 0.1, 100);
    camera.position.set(4.2, 3.4, 5.6);
    camera.lookAt(0, 0, 0);

    // Key carves a highlight across the top; a fill keeps the shadow side from
    // going pure-black (so cubies stay visible against the black background); a
    // cool rim traces the silhouette edges.
    const key = new THREE.DirectionalLight(0xffffff, 2.0);
    key.position.set(5, 8, 6);
    scene.add(key);
    const fill = new THREE.DirectionalLight(0xffffff, 0.7);
    fill.position.set(-6, 1, 4);
    scene.add(fill);
    const rim = new THREE.DirectionalLight(0xbcd2ff, 1.6);
    rim.position.set(-4, 3, -6);
    scene.add(rim);
    scene.add(new THREE.AmbientLight(0xffffff, 0.35));

    // ── A canvas-generated "perforated" roughness map for a few stickers ──
    function perforatedTexture() {
      const s = 128;
      const c = document.createElement('canvas');
      c.width = c.height = s;
      const g = c.getContext('2d');
      g.fillStyle = '#fff'; g.fillRect(0, 0, s, s);       // rough (matte) base
      g.fillStyle = '#222';                                // smooth dots
      const step = 14;
      for (let y = step / 2; y < s; y += step)
        for (let x = step / 2; x < s; x += step) {
          g.beginPath(); g.arc(x, y, 3.4, 0, Math.PI * 2); g.fill();
        }
      const tex = new THREE.CanvasTexture(c);
      tex.colorSpace = THREE.NoColorSpace;
      return tex;
    }
    const perfMap = perforatedTexture();

    // Pool of black finishes. All share a near-black base color; the look comes
    // entirely from how rough/metallic each one is.
    function makeMaterials() {
      const base = 0x18181a;            // near-black, but not a pure void
      const env = 1.4;                   // how strongly each finish picks up reflections
      const mk = (o) => Object.assign(new THREE.MeshStandardMaterial({ color: base, envMapIntensity: env }), o);
      const mats = [
        mk({ roughness: 0.22, metalness: 0.55 }),                    // glossy
        mk({ roughness: 0.40, metalness: 0.45 }),                    // satin
        mk({ roughness: 0.58, metalness: 0.35 }),                    // soft
        mk({ roughness: 0.78, metalness: 0.20 }),                    // matte
        mk({ roughness: 0.92, metalness: 0.15, roughnessMap: perfMap }), // perforated (rare)
      ];
      return mats;
    }
    const MATS = makeMaterials();

    // Deterministic pseudo-random so the finish layout is stable each load.
    let seed = 1337;
    const rnd = () => (seed = (seed * 1103515245 + 12345) & 0x7fffffff) / 0x7fffffff;

    const cube = new THREE.Group();
    const SIZE = 0.96;          // cubie size
    const GAP  = 1.0;           // center-to-center spacing
    const geo  = new RoundedBoxGeometry(SIZE, SIZE, SIZE, 4, 0.1);

    for (let x = -1; x <= 1; x++)
      for (let y = -1; y <= 1; y++)
        for (let z = -1; z <= 1; z++) {
          // weight toward glossy/satin, a few matte, and only the occasional
          // perforated sticker (≈4%) — matching the real render.
          const r = rnd();
          const mat = r < 0.45 ? MATS[0] : r < 0.72 ? MATS[1] : r < 0.89 ? MATS[2]
                    : r < 0.96 ? MATS[3] : MATS[4];
          const m = new THREE.Mesh(geo, mat);
          m.position.set(x * GAP, y * GAP, z * GAP);
          cube.add(m);
        }
    cube.rotation.x = -0.32;     // fixed tilt so three faces stay visible
    cube.rotation.y = 0.6;       // open on a 3/4 view rather than face-on
    scene.add(cube);

    function resize() {
      const w = window.innerWidth, h = window.innerHeight;
      renderer.setSize(w, h, false);
      camera.aspect = w / h;
      camera.updateProjectionMatrix();
    }
    window.addEventListener('resize', resize);
    resize();

    renderer.setAnimationLoop(() => {
      cube.rotation.y += 0.004;   // slow, steady turn
      renderer.render(scene, camera);
    });
  </script>
</body>
</html>
```

## Source & credit

Effect seen on <https://resend.com/home> — credit to Resend.
Independent recreation, built from scratch for educational use.

## Sitemap

- [All effects](https://fx.statico.io/index.md) — gallery index
- [Site map](https://fx.statico.io/sitemap.md) — every page, grouped
- [sitemap.xml](https://fx.statico.io/sitemap.xml) — machine-readable, with lastmod
- [AGENTS.md](https://fx.statico.io/AGENTS.md) — how to grab and reuse an effect
- [skill.md](https://fx.statico.io/skill.md) — full agent skill file
- [llms.txt](https://fx.statico.io/llms.txt) — short index of every effect
- [Glossary](https://fx.statico.io/glossary.md) — terminology used in the writeups
