← All articles

[ Blog ]

July 8, 2026

9 min read

Designing a Shapeshifting Brand Identity Website

How we built a shapeshifting brand identity website for fromanother — light as metaphor, video-layering instead of shaders, and the craft Awwwards featured as a case study.

Case StudyAwwwardsWebGLThree.jsGSAPNext.jsCreative Direction
Designing a Shapeshifting Brand Identity Website

Some brands hand you a logo and a palette. fromanother handed us a harder brief: build a shapeshifting brand identity website for a studio that refuses to be pinned down as an agency, a studio, or a collective. The identity is the fluidity. This is the story of how that got engineered — light as the organizing metaphor, video-layering instead of shaders, and Three.js reserved for the one interaction that truly earned it. Awwwards just published the build as a featured editorial case study, Designing for an Identity That Shapeshifts — one of the very few full case studies its editorial team publishes in a given month — so this is the developer's-eye companion to it.

I built fromanother.love as the creative developer; fromanother owned the creative direction and authored that Awwwards piece. If you want the credentials-and-awards version — the FWA of the Day, the Awwwards Site of the Day and Developer Award — that's the fromanother case study. This post is the craft underneath it: the decisions, the code, and the things that broke.

Light as the design system, not a decoration

The concept fromanother set was singular: light. Not a lighting effect — light as the behavior of the whole interface. Swirls of it, in motion, intangible, forming the environment while the content stays clean and minimal on top. Once you accept that as the design system, a lot of conventional web motion becomes wrong. Light doesn't slide in from the left. It doesn't snap. It doesn't cut. It blooms, bleeds, and diffuses.

So the first rule was subtractive: no sliding, no snapping, no hard cuts anywhere. Every reveal had to read as light arriving or dissolving — which, in practice, means blur and opacity, not x/y translation. That single constraint shaped the motion system, the page transitions, and even how we delivered background media.

Video-layering instead of shaders (the strategic cheat)

The obvious way to make a fluid, light-driven background is a fragment shader — noise fields, flow maps, the usual WebGL toolkit. We deliberately didn't. The background color-states on fromanother.love are layered videos blended with mix-blend-mode and cross-faded on opacity.

The reasoning is pure trade-off math. A hand-authored, cinematic light plate — actually shot and graded footage — reads richer than most procedural noise, ships as a compressed video the CDN already knows how to stream, and costs almost nothing on the main thread. A shader that looked that good would be expensive to write, expensive to run, and harder to art-direct. As fromanother put it in the Awwwards piece: "The goal was never to build something technically impressive for its own sake. It was to make something that feels right and leaves the method hidden."

Here's the shape of the layering — two (or more) light plates, blended and cross-faded on a state change:

// Two light plates stacked; the incoming one fades up while the outgoing fades out.
// mix-blend-mode does the "additive light" look; opacity does the transition.
function LightBackground({ state }: { state: 'warm' | 'cool' }) {
  return (
    <div className="light-stage" aria-hidden>
      <video
        src="/light/warm.mp4"
        autoPlay muted loop playsInline preload="metadata"
        style={{ mixBlendMode: 'screen', opacity: state === 'warm' ? 1 : 0 }}
      />
      <video
        src="/light/cool.mp4"
        autoPlay muted loop playsInline preload="metadata"
        style={{ mixBlendMode: 'screen', opacity: state === 'cool' ? 1 : 0 }}
      />
    </div>
  )
}

The opacity change is driven with GSAP so the cross-fade uses a light-like ease rather than a linear CSS transition:

gsap.to(incoming, { opacity: 1, duration: 1.4, ease: 'power2.inOut' })
gsap.to(outgoing, { opacity: 0, duration: 1.4, ease: 'power2.inOut' })

mix-blend-mode: screen is what sells it as light rather than overlay — screen blending only ever brightens, exactly how real light accumulates. It's a one-line CSS property doing the job a whole shader would otherwise fight for. This is the same "reach for the platform feature before the engine" instinct behind the displacement-vs-CSS decision in the WebGL hover guide.

Text that arrives like light: blur + fade, never slide

With sliding off the table, headline reveals lean entirely on blur and opacity. GSAP animates the CSS filter, so a line resolves out of light instead of flying in:

gsap.from('[data-light-in]', {
  autoAlpha: 0,
  filter: 'blur(14px)',
  duration: 1.2,
  ease: 'power2.out',
  stagger: 0.08,
  scrollTrigger: { trigger: '[data-light-in]', start: 'top 80%', once: true },
})

Two production notes that matter. First, animating filter: blur() is a paint operation, not a compositor one — it's cheaper than a shader but not free, so it's fine for a handful of headline lines on enter and wrong for anything continuous or large-area. Second, always pair it with autoAlpha (GSAP's visibility + opacity) so a blurred-but-not-yet-visible line can't be read by assistive tech or grabbed by the pointer mid-transition. The reveal grammar itself — one ease, one duration scale, ScrollTrigger gating — is the same motion-system discipline I break down in the GSAP ScrollTrigger tutorial.

Page transitions that bleed and diffuse

Route changes were the biggest test of the light metaphor. A standard crossfade would have been a cut in disguise. Instead, transitions bleed and diffuse: the outgoing page dissolves up into a light wash, the incoming page resolves down out of it — the same blur-and-opacity language as the text, scaled to the whole viewport.

In the Next.js App Router that lives in a transition layer over the route, with the incoming route held until its first light plate is ready so you never diffuse into a blank frame. The key is that the overlay is a timeline, not two independent fades — the out and in share one clock so the handoff reads as a single continuous bloom rather than two events. (For the mechanics of App Router route transitions generally, this pairs with the pillar work on immersive website development.)

Where Three.js actually earned its place: the ripple

Here's the discipline that Awwwards singled out — knowing which effects to cheat and which to build for real. Almost everything fluid on the site is video and blend modes. Exactly one interaction gets a full WebGL treatment: the ripple on project thumbnails, where the image distorts like a stone dropped in still water under the cursor.

That one earns Three.js because it's genuinely interactive and geometric — it responds to pointer position and time in a way you can't fake with pre-rendered video. It's a plane, a texture, and a displacement shader driven by a pointer uniform:

const uniforms = {
  uTexture: { value: thumbnailTexture },
  uPointer: { value: new THREE.Vector2(0.5, 0.5) },
  uTime:    { value: 0 },
  uStrength:{ value: 0 }, // eased 0→1 on hover, 1→0 on leave
}

useFrame((_, dt) => {
  uniforms.uTime.value += dt
  // ease strength toward the hover target so the ripple settles, never snaps
  uniforms.uStrength.value = THREE.MathUtils.damp(
    uniforms.uStrength.value, hovering.value ? 1 : 0, 6, dt,
  )
})

Wrapped in React Three Fiber, the whole thing is a few dozen lines and only ever runs for the thumbnail under the cursor. The hard part wasn't the shader — it was containment: keeping the ripple inside the image bounds instead of bleeding across the screen. That took real tuning (clip the displaced UVs, clamp strength at the edges) and is exactly the kind of surgical WebGL that the Three.js performance guide is about.

The performance war: light is heavy

Light-as-video is beautiful and heavy. The dense, media-rich project pages were a constant fight between load time and quality, and the single biggest lesson was about video delivery.

We started on Vimeo and hit its ceiling for this kind of programmatic, autoplaying, blend-mode-layered use. We evaluated Gumlet and Mux — each with different delivery logic — and had to rework how the site requested and streamed footage around whichever we landed on. The takeaway for anyone building a video-driven site: the player is not the hard part; the delivery pipeline (adaptive HLS, poster frames, preload="metadata", per-device renditions) is where the performance actually lives.

ConcernNaive approachWhat shipped
Fluid backgroundFragment shaderLayered video + mix-blend-mode: screen
Text revealSlide + fadeBlur + autoAlpha, blur only on enter
Page transitionCrossfade (a cut)Shared-timeline bleed & diffuse
Thumbnail effectVideo overlayThree.js ripple, contained to the image
Video deliverySingle MP4 / VimeoAdaptive HLS (Mux-class), per-device renditions

Cross-device was its own project: phone, tablet, and desktop each needed separate work, because a blend-mode light stack that sings on a desktop GPU can melt a mid-range phone. The guardrails — capping how many video layers composite at once, dropping to a static light plate on constrained devices, respecting prefers-reduced-motion — are the same budget discipline behind Core Web Vitals for animation-heavy sites.

Why this is the real case study

The Awwwards editorial feature matters more than a badge because it's editorial — a written, edited breakdown of the thinking, not a one-day showcase vote. What it documents is a philosophy I try to bring to every build: make it feel right, and leave the method hidden. The best technical decision on this project was choosing not to write a shader. Restraint is the craft.

If your brand's identity is fluid, layered, or hard to pin to one label, that's not a problem to design around — it can be the whole concept, if the engineering is disciplined enough to carry it.

FAQ

What is a shapeshifting brand identity website?

One whose visual language is deliberately fluid rather than fixed — the brand's identity is expressed through motion, transition, and transformation instead of a single static logo-and-color system. fromanother.love uses light in motion as that fluid identity.

Why use layered video instead of a shader for the background?

For a cinematic, hand-graded light look, shot footage reads richer than procedural noise, streams efficiently from a CDN, and costs almost nothing on the main thread. A shader that looked as good would be more expensive to write, run, and art-direct. Shaders earn their place in genuinely interactive, geometric effects — like the site's ripple.

What is the fromanother website built with?

Next.js and React, Prismic as the headless CMS, GSAP and the Web Animations API for motion, and Three.js with React Three Fiber for the ripple interaction — with video-layering and blend modes carrying the fluid, light-driven backgrounds.

Who built fromanother.love?

fromanother led the creative direction and identity and authored the Awwwards case study; Hon Tran built it as the creative developer responsible for the front-end, motion, WebGL and CMS integration.

Work with me

If you're a brand, studio, or agency with an identity that resists a single fixed look — and you want a site engineered to carry that fluidity at 60fps — that's exactly what I do as a creative developer.


Written by Hon Tran — creative developer, founder of hontran.dev, and Awwwards jury member. 11+ years building award-winning, performance-first web experiences (GSAP, WebGL, Next.js) for clients worldwide. hontran.dev · Behance.