Preparando seu ambiente

Estúdio de desenvolvimentoBrasil → Mundo

🎃 EVENTO DE HALLOWEEN · ATÉ 31/10

Códigos movem o mundo.Sites deoutro mundo.

MILWEB® · Desenvolvimento criativo · Brasil → Mundo

Projetos / Lumen

COLEÇÃO DE RECOMPENSAS · 25 missões

07 de 25

MISSÃO ESPECIALLumenLumenMW/OS · CASO 07 / 25Site cinematográfico 3D para arquitetura · React Three Fiber

07 de 25 · EXPERIÊNCIA WEBGL

Lumen

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

DEMONSTRAÇÃONO AR

Lumen — tela inicial
ESTÚDIO
MILWEB
Tipo
Site Institucional Premium
Stack
React · Vite · TypeScript · Three.js · R3F · SCSS

CONTEXTO

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.

O QUE FOI FEITO

Vitrine imersiva em 3D (React Three Fiber) com cenas cinematográficas e navegação fluida que apresentam o escritório como uma experiência, não como uma lista de fotos.

EXPERIÊNCIA 3D CINEMATOGRÁFICA

SOLUÇÕES

  • Casa 100% procedural

    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.

  • Câmera por keyframes + scroll

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

  • DPR adaptativo por fps real

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

  • Degradação graciosa mobile/a11y

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

DETALHE TÉCNICO

  • 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.

TELAS

RESULTADO

Vitrine imersiva em 3D (React Three Fiber) com cenas cinematográficas e navegação fluida que apresentam o escritório como uma experiência, não como uma lista de fotos.

QUERO ALGO PARECIDO ↗ABRIR SITE ↗

Enter abre o primeiro resultado · Esc fecha · tecla / abre a busca

Lumen — Site cinematográfico 3D para arquitetura · React Three Fiber | MilWeb