The logo is reconstructed from a grid of small glass blocks. Each tile floats apart, refracts the background through real MeshPhysicalMaterial transmission, then assembles into the silhouette on load. Hover separates the tiles slightly. Built with Three.js InstancedMesh + HDRI reflections + soft contact shadows.
import GlassTileLogo from '@crazygl/hero-glass-tile-logo';
export default function Page() {
return (
<GlassTileLogo
logo="https://crazygl.com/samples/crazygl.png"
tileGrid={20}
glassIOR={1.5}
glassDispersion={0.04}
heading="Built block by block."
/>
);
}logo (transparent PNG), tileGrid (tiles per long edge, 10–40), tileGapPct, tileDepth, logoZoom, logoCenterX/Y.glassTransmission, glassRoughness, glassIOR (1.5 = BK7, up to 2.4 for diamond), glassThickness, glassDispersion (rainbow seam), glassTintHex, envIntensity.assembleDuration, scatterDistance, staggerAmount (ripple-in order).hoverSeparation, hoverRadiusPct.ambientFloat, ambientSwaySpeed.environmentImage (equirectangular HDRI; biggest mood lever), bgTopHex, bgBotHex, shadowAlpha.npm install @crazygl/hero-glass-tile-logoThe component takes the same props you see in the live customizer on the right — every default ships poster-quality.
import GlassTileLogo from '@crazygl/hero-glass-tile-logo';
export default function Landing() {
return (
<GlassTileLogo />
);
}The wrapper renders static HTML on the server and only initialises the canvas after hydration, so search engines see your copy.
// app/page.tsx — works in SSR-first frameworks (Next, Remix, Astro, etc.)
'use client';
import GlassTileLogo from '@crazygl/hero-glass-tile-logo';
export default function Page() {
return (
<section>
<GlassTileLogo
heading="Say hi."
subheading="Your new hero."
/>
<article>
<h2>Welcome</h2>
<p>Your content keeps its own voice below the hero.</p>
</article>
</section>
);
}