← Tutoriales
CONSTRUIR · 3D · 6 MIN

Un hero 3D con React Three Fiber

Un hero 3D girando, en metal cepillado, sobre una página oscura y con tu nombre. Tardé minutos, no la tarde que había reservado. Lo sorprendente no es que se vea bien. Es que el 3D en la web dejó de ser cosa de especialistas y casi nadie se enteró.

Para
quien quiere un toque 3D en su web y construye con IA
Necesitas
Node, Claude Code, y una web en React o Astro (haz una aquí)
Tiempo
minutos para la escena, una hora para hacerla tuya
En vivo, renderizado aquí mismo por las ~40 líneas de abajo. Arrastra para girar.

Me senté a aprender Three.js contando con perder la tarde. Tenía un hero girando con mi nombre antes de que se enfriara el café. Esa distancia, entre lo que costaba el 3D y lo que cuesta ahora, es toda la historia. Las matemáticas de WebGL no se volvieron más fáciles. El andamiaje de alrededor desapareció.

La idea que lo desbloquea: un set de cine

Toda escena de Three.js son las mismas seis cosas. Cuando encajan, cualquier tutorial y cualquier fragmento que te dé Claude se leen claros, y un render roto pasa a ser un arreglo de diez segundos en vez de un misterio.

SCENE mesh + luces CAMERA tu punto de vista RENDERER cada cuadro <canvas> lo que ves el loop ejecuta esto ~60×/segundo
Seis sustantivos. La escena y la cámara alimentan al renderer, el renderer pinta el canvas, el loop lo repite cada cuadro.

1. Lo mínimo que renderiza

Aquí está todo el modelo en un archivo, sin paso de build. Three.js viene directo de un CDN, así que esto corre con solo abrir la página. Fíjate en los seis sustantivos pasando en orden:

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

const scene = new THREE.Scene();                       // 1. el set

const camera = new THREE.PerspectiveCamera(
  50, innerWidth / innerHeight, 0.1, 100);
camera.position.set(0, 0, 4.5);                        // 2. dónde te paras
Ver la escena completaVer menos
const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
renderer.setSize(innerWidth, innerHeight);            // 3. la película
document.body.appendChild(renderer.domElement);

const knot = new THREE.Mesh(                           // 4. el actor
  new THREE.TorusKnotGeometry(1, 0.32, 240, 32),      //    forma     (geometry)
  new THREE.MeshStandardMaterial({                    //    superficie (material)
    color: 0x9aa0a6, metalness: 0.9, roughness: 0.22 })
);
scene.add(knot);

scene.add(new THREE.AmbientLight(0xffffff, 0.25));    // 5. las luces
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. el loop
  controls.update();
  renderer.render(scene, camera);
});

Eso es. Monta el set, coloca al actor y las luces, para la cámara, corre el loop. Una pantalla en negro casi siempre es una de dos cosas: un material que necesita luz sin ninguna luz en la escena, o la cámara metida dentro del objeto. Agrega una luz, aleja la cámara y vuelve a mirar.

2. La misma escena en React Three Fiber

La versión vanilla es ideal para entender el modelo. Para una web real sobre React o Astro, quieres React Three Fiber (R3F): el mismo Three.js por debajo, pero la escena se escribe como componentes en vez de configuración imperativa. La librería de ayudas drei te da cámaras, controles y loaders gratis. Instálalos:

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

Y la escena de arriba se vuelve esto:

// 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>
  );
}
Ver el componente completoVer 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>
  );
}

Léelo al lado del archivo vanilla y el cambio es obvio: el JSX es el grafo de la escena. <mesh> envuelve una geometría y un material, las luces son etiquetas, y no hay loop que cablear a mano. Ese es todo el argumento para R3F una vez que estás en React.

3. Llévalo a tu web

En Astro, un canvas 3D tiene que correr en el navegador, así que renderiza el componente como una isla de cliente. Un import, una etiqueta:

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

client:only="react" le dice a Astro que se salte el render en el servidor y lo arranque en el cliente, que es lo que necesita un canvas WebGL en vivo. Estira el <Canvas> para que llene su contenedor, pon un titular encima, y tienes un hero.

Qué cambió, y por qué esto tardó minutos

Reservé una tarde porque eso costaba antes el 3D en la web: pelear con el andamiaje, la pérdida de contexto y errores crípticos antes de ver nada. Nada de eso es ya la parte difícil.

La barrera del 3D nunca fueron los conceptos. Fue el andamiaje, y el andamiaje es justo lo que se automatizó.

Cuando algo se rompe

Ahora prueba esto

El hero gira. Unas formas de hacerlo tuyo, cada una una frase a Claude:

Lo que acabas de hacer

Un elemento 3D real, en una página real, en lo que tardas en leer esto. Lo que importa no es Three.js ni R3F. Es que lo que hacía del 3D una especialidad, el andamiaje, es justo lo que la IA quitó. Los conceptos son pocos. La barrera era el trabajo, y el trabajo ya no está.

¿TE SIRVIÓ? RECIBE EL PRÓXIMO

Déjame tu email y te aviso cuando salga el próximo build, con el código y los prompts que usé. Sin spam.

Más tutoriales ↗