← Tutoriais
CONSTRUIR · 3D · 6 MIN

Um hero 3D com React Three Fiber

Um hero 3D girando, em metal escovado, numa página escura, com o seu nome de marca. Levou minutos, não a tarde inteira que eu tinha reservado. A surpresa não é que fica bonito. É que o 3D na web deixou de ser o suplício de um especialista, e quase ninguém reparou.

Para
quem constrói e quer um toque 3D no site, e trabalha com IA
Precisa
Node, Claude Code e um site em React ou Astro (faça um aqui)
Tempo
minutos para a cena, uma hora para deixar a sua cara
Ao vivo, renderizado aqui mesmo pelas ~40 linhas abaixo. Arraste para orbitar.

Sentei para aprender Three.js esperando perder uma tarde nisso. Eu tinha um hero renderizado e girando, com meu nome, antes de o café esfriar. Essa distância, entre o que o 3D custava e o que custa agora, é a história inteira. A matemática do WebGL não ficou mais fácil. O suplício em volta dela foi apagado.

A ideia que destrava tudo: um set de filmagem

Toda cena de Three.js são as mesmas seis coisas. Quando elas encaixam na cabeça, todo tutorial e todo trecho que o Claude te entrega ficam fáceis de ler, e um render quebrado vira um conserto de dez segundos em vez de um mistério.

SCENE mesh + luzes CAMERA seu ponto de vista RENDERER a cada quadro <canvas> o que você vê o loop roda isso ~60×/segundo
Seis substantivos. A cena e a câmera alimentam o renderer, o renderer pinta o canvas, o loop repete tudo a cada quadro.

1. A menor coisa que renderiza

Aqui está o modelo inteiro num arquivo só, sem etapa de build. O Three.js vem direto de uma CDN, então isso roda só abrindo a página. Repare nos seis substantivos passando em ordem:

import * as THREE from 'three';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';

const scene = new THREE.Scene();                       // 1. o cenário

const camera = new THREE.PerspectiveCamera(
  50, innerWidth / innerHeight, 0.1, 100);
camera.position.set(0, 0, 4.5);                        // 2. onde você fica
Mostrar a cena completaMostrar menos
const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
renderer.setSize(innerWidth, innerHeight);            // 3. o filme
document.body.appendChild(renderer.domElement);

const knot = new THREE.Mesh(                           // 4. o ator
  new THREE.TorusKnotGeometry(1, 0.32, 240, 32),      //    forma   (geometria)
  new THREE.MeshStandardMaterial({                    //    superfície (material)
    color: 0x9aa0a6, metalness: 0.9, roughness: 0.22 })
);
scene.add(knot);

scene.add(new THREE.AmbientLight(0xffffff, 0.25));    // 5. luzes
const key = new THREE.DirectionalLight(0xffffff, 2.4);
key.position.set(3, 3, 4);
scene.add(key);

const controls = new OrbitControls(camera, renderer.domElement);
controls.autoRotate = true;

renderer.setAnimationLoop(() => {                      // 6. o loop
  controls.update();
  renderer.render(scene, camera);
});

É isso. Monte o set, posicione o ator e as luzes, coloque a câmera, rode o loop. Uma tela preta quase sempre quer dizer uma de duas coisas: um material que precisa de luz, sem luz nenhuma na cena, ou a câmera parada dentro do objeto. Adicione uma luz, puxe a câmera para trás e olhe de novo.

2. A mesma cena em React Three Fiber

A versão vanilla é ótima para entender o modelo. Para um site de verdade num stack React ou Astro, você quer React Three Fiber (R3F): o mesmo Three.js por baixo, mas a cena escrita como componentes em vez de configuração imperativa. A biblioteca auxiliar drei te entrega câmeras, controles e loaders de graça. Instale tudo:

npx astro add react
npm i three @react-three/fiber @react-three/drei

Aí a cena exata de cima vira isto:

// Hero3D.jsx
import { Canvas } from '@react-three/fiber';
import { OrbitControls } from '@react-three/drei';

function Knot() {
  return (
    <mesh>
      <torusKnotGeometry args={[1, 0.32, 240, 32]} />
      <meshStandardMaterial color="#9aa0a6" metalness={0.9} roughness={0.22} />
    </mesh>
  );
}
Mostrar o componente completoMostrar menos
export default function Hero3D() {
  return (
    <Canvas camera={{ position: [0, 0, 4.5], fov: 50 }}>
      <ambientLight intensity={0.25} />
      <directionalLight position={[3, 3, 4]} intensity={2.4} />
      <Knot />
      <OrbitControls autoRotate enablePan={false} />
    </Canvas>
  );
}

Leia lado a lado com o arquivo vanilla e a troca fica óbvia: o JSX é o grafo da cena. <mesh> envolve uma geometria e um material, as luzes são tags, e não há loop manual para conectar. Esse é o argumento inteiro a favor do R3F quando você já está em React.

3. Coloque no seu site

No Astro, um canvas 3D tem que rodar no navegador, então renderize o componente como uma ilha de cliente. Um import, uma tag:

---
import Hero3D from '../components/Hero3D.jsx';
---
<Hero3D client:only="react" />

client:only="react" diz ao Astro para pular a renderização no servidor e iniciar o componente no cliente, que é o que um canvas WebGL ao vivo precisa. Estilize o <Canvas> para preencher o contêiner, jogue um título por cima e você tem um hero.

O que mudou, e por que isso levou minutos

Reservei uma tarde porque era o que o 3D na web custava: brigar com boilerplate, perda de contexto e erros crípticos antes de qualquer coisa aparecer. Nada disso é mais a parte difícil.

O fosso em volta do 3D nunca foram os conceitos. Era o suplício, e o suplício é justamente a parte que foi automatizada.

Quando algo quebra

Agora tente isto

O hero gira. Algumas formas de deixar a sua cara, cada uma uma frase para o Claude:

O que você acabou de fazer

Um elemento 3D de verdade, numa página de verdade, no tempo que leva para ler isto. O que importa não é Three.js nem R3F. É que a coisa que fazia do 3D uma especialidade, o suplício da configuração, é a coisa que a IA removeu. Os conceitos são pequenos. A barreira era o trabalho braçal, e o trabalho braçal acabou.

ACHOU ÚTIL? RECEBA O PRÓXIMO

Deixe seu email e eu te aviso quando o próximo build sair, com o código e os prompts que usei. Sem spam.

Mais tutoriais ↗