Black Rubik's Cube
How it works
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.
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.
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.
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.
Code — copy & paste this whole file
<!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.
This is an independent recreation of the effect built from scratch for educational use. No proprietary source code was copied.
<!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>