MILWEB®
MILWEB®
MW/016LUMENESTÚDIO

Lumen

Lumen — tela inicial
ESTÚDIO
MILWEB
TIPO
EXPERIÊNCIA WEBGL
STATUS
NO AR

02 / A IDEIA

Site cinematográfico 3D para arquitetura · React Three Fiber

Escritórios de arquitetura precisam transmitir sofisticação e domínio do espaço, e um site comum não passa a sensação do trabalho deles.

03 / EXPERIÊNCIA
  1. 01 / 01

    Nenhum GLB: volumes, vidro, mobília e piscina são geometria Three.js gerada em código, com fallback documentado para trocar por modelo real.

    Lumen — 01
  2. 02 / 02

    6 posições interpoladas com smoothstep, dirigidas por GSAP ScrollTrigger + Lenis fora do ciclo de render do React.

    Lumen — 02
  3. 03 / 03

    PerformanceMonitor mede a GPU em ~1,2s e ajusta a resolução do canvas entre 0.6 e 1.6 automaticamente.

    Lumen — 03
  4. 04 / 04

    Vidro, sombras e Bloom mais baratos no mobile; parallax e micro-loops desligam com prefers-reduced-motion.

    Lumen — 04
Hero 3D da Lumen com a residência procedural e headline animada

04 / POR BAIXO DO CAPÔ

  • 01A casa que ancora o hero não é um modelo importado. É geometria procedural, montada em código com primitivas do Three.js (boxGeometry, plane…+

    A casa que ancora o hero não é um modelo importado. É geometria procedural, montada em código com primitivas do Three.js (boxGeometry, planeGeometry, icosahedronGeometry): laje em balanço, fachada de vidro, mobília, piscina e vegetação, tudo posicionado por coordenadas explícitas dentro de um único componente House. O motivo é prático: sem GLB para baixar, decodificar (Draco/Meshopt) ou hospedar, o hero começa a renderizar no primeiro frame do Canvas. O componente Residence já deixa a porta aberta para trocar por um modelo real. Uma constante RESIDENCE_GLB e um SceneBoundary (error boundary de classe que captura falhas do WebGL e do R3F) garantem que, se o GLB não existir ou falhar ao carregar, a cena cai de volta para a casa procedural sem quebrar a página.

  • 02A câmera não segue uma timeline de biblioteca externa. É um sistema de keyframes escrito à mão em CameraRig, com seis pares de posição e loo…+

    A câmera não segue uma timeline de biblioteca externa. É um sistema de keyframes escrito à mão em CameraRig, com seis pares de posição e lookAt (fachada, entrada, sala, escada, varanda, piscina) interpolados com smoothstep conforme um valor journey.progress entre 0 e 1. Esse progresso é escrito por um ScrollTrigger do GSAP pinado na seção do hero, com o Lenis dirigindo o rAF do scroll suave e emitindo eventos que o ScrollTrigger consome (lenis.on('scroll', ScrollTrigger.update)). A ponte entre DOM e loop de render do R3F é um objeto mutável (journey.progress) fora do React, lido dentro de useFrame. Isso evita re-render do componente a cada tick de scroll, que a 60fps seria centenas de renders por segundo.

  • 03Performance em WebGL no navegador foi tratada como orçamento, não como sorte. O DPR do canvas é adaptativo: um PerformanceMonitor do drei me…+

    Performance em WebGL no navegador foi tratada como orçamento, não como sorte. O DPR do canvas é adaptativo: um PerformanceMonitor do drei mede o fps real por ~1,2s e um hook (useAdaptiveDpr) recalcula a resolução interna dentro de uma faixa mínima e máxima. GPU fraca cai até 0.6, GPU com folga sobe até 1.6, em vez de travar a 17fps com DPR fixo. Mobile recebe uma cena mais barata por decisão explícita: material de vidro simples (reflexo transparente) em vez de MeshTransmissionMaterial com transmissão real, sombras suaves (SoftShadows/PCSS) e Bloom desligados, resolução do ContactShadows reduzida pela metade. O canvas 3D também só monta depois do primeiro paint, via requestIdleCallback com timeout de 1200ms como rede de segurança, para não pesar no LCP e no TBT. E o frameloop do R3F alterna entre always e never conforme um IntersectionObserver (useInView), então a cena para de renderizar assim que sai da viewport.

  • 04Acessibilidade de movimento entrou na própria cena 3D, não só nas animações de DOM. O usePrefersReducedMotion desliga o parallax da câmera q…+

    Acessibilidade de movimento entrou na própria cena 3D, não só nas animações de DOM. O usePrefersReducedMotion desliga o parallax da câmera que segue o ponteiro e os micro-loops de vida (respiração da água na piscina, pulso da luz interna quente) tanto em CameraRig quanto em House, mantendo os valores de repouso já definidos no JSX. O scroll suave do Lenis também sai de cena inteiramente quando prefers-reduced-motion: reduce está ativo, e a página volta ao scroll nativo do navegador. Esse cuidado, somado ao poster estático (mesmo enquadramento do fallback) exibido atrás do Canvas antes da montagem, foi o que manteve o hero rápido e acessível sem abrir mão do efeito cinematográfico como diferencial do produto.

CONSTRUÍDO COMReact · Vite · TypeScript · Three.js · R3F · SCSSCÓDIGO

06 / RESULTADO

Experiência 3D cinematográfica

PROJETO AUTORAL · DEMO

[ QUERO ALGO PARECIDO ]

07 / TELAS SELECIONADAS
Hero 3D da Lumen com a residência procedural e headline animada
TELA 01Hero 3D da Lumen com a residência procedural e headline animada
Seção de serviços do estúdio de arquitetura
TELA 02Seção de serviços do estúdio de arquitetura
Seção de modelo 3D interativo (arraste para girar, scroll para zoom)
TELA 03Seção de modelo 3D interativo (arraste para girar, scroll para zoom)
PRÓXIMA EXPERIÊNCIA08 / ALVA ODONTOLOGIA

ALVA Odontologia

ALVA Odontologia

TODOS OS PROJETOS

TODOS OS PROJETOS