3dpolyx
Tutoriales

3D en la web con Three.js: un rincón acogedor en un solo archivo HTML

Pon modelos 3D reales en una página web con unas pocas líneas de JavaScript. Tutorial de Three.js para principiantes con el código completo.

4 min de lectura
3D en la web con Three.js: un rincón acogedor en un solo archivo HTML
En esta página

Un modelo 3D girando en una landing page llama la atención como no puede hacerlo una imagen plana. La buena noticia: GLB es el formato nativo del 3D en la web, así que mostrar nuestros modelos en un navegador requiere sorprendentemente poco código.

En este tutorial crearemos una pequeña escena interactiva con Three.js: un rincón de lectura con el Sillón de madera, la Lámpara de mesa de cerámica, la Mesita de noche de roble y el Ficus lyrata en cesta.

Qué necesitas

  • Los archivos GLB de los modelos, colocados en una carpeta models junto a tu archivo HTML.

  • Un servidor web local. Los navegadores bloquean la carga de archivos directamente desde el disco, así que usa algo como npx serve o la extensión Live Server de VS Code.

  • Nada de herramientas de compilación: cargaremos Three.js desde una CDN mediante un import map.

El código completo

Crea index.html con este contenido:

<!doctype html>
<html>
  <head>
    <style>body { margin: 0; background: #f3efe8; }</style>
    <script type="importmap">
      { "imports": {
        "three": "https://cdn.jsdelivr.net/npm/[email protected]/build/three.module.js",
        "three/addons/": "https://cdn.jsdelivr.net/npm/[email protected]/examples/jsm/"
      } }
    </script>
  </head>
  <body>
    <script type="module">
      import * as THREE from 'three';
      import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
      import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
      import { RoomEnvironment } from 'three/addons/environments/RoomEnvironment.js';

      const renderer = new THREE.WebGLRenderer({ antialias: true });
      renderer.setSize(innerWidth, innerHeight);
      renderer.setPixelRatio(devicePixelRatio);
      document.body.appendChild(renderer.domElement);

      const scene = new THREE.Scene();
      scene.background = new THREE.Color('#f3efe8');
      const pmrem = new THREE.PMREMGenerator(renderer);
      scene.environment = pmrem.fromScene(new RoomEnvironment()).texture;

      const camera = new THREE.PerspectiveCamera(40, innerWidth / innerHeight, 0.1, 100);
      camera.position.set(2.5, 1.6, 3);
      const controls = new OrbitControls(camera, renderer.domElement);
      controls.target.set(0, 0.6, 0);
      controls.enableDamping = true;

      const loader = new GLTFLoader();
      const place = (file, x, z, rotY = 0) =>
        loader.load('models/' + file, (gltf) => {
          gltf.scene.position.set(x, 0, z);
          gltf.scene.rotation.y = rotY;
          scene.add(gltf.scene);
        });

      place('wooden-armchair.glb', 0, 0, 0.4);
      place('oak-bedside-table.glb', 0.9, -0.2);
      place('ceramic-table-lamp.glb', 0.9, -0.2);
      place('fiddle-leaf-fig.glb', -0.9, -0.4);

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

      addEventListener('resize', () => {
        camera.aspect = innerWidth / innerHeight;
        camera.updateProjectionMatrix();
        renderer.setSize(innerWidth, innerHeight);
      });
    </script>
  </body>
</html>

Cambia el nombre de los archivos descargados para que coincidan con los del código, o cambia los nombres en el código. Inicia tu servidor local y abre la página. Puedes girar la escena con el ratón y hacer zoom con la rueda.

Qué hace el código

Renderer y escena. Creamos un renderer WebGL que ocupa toda la ventana y una escena con un color de fondo cálido.

Iluminación de entorno. RoomEnvironment genera un entorno de luz suave, como de estudio. Los materiales PBR necesitan un entorno que reflejar, y esta única línea da a nuestros modelos reflejos creíbles sin cargar un HDRI.

Cámara y controles. Una cámara en perspectiva enfoca el rincón, y OrbitControls permite a los visitantes girar y hacer zoom. La amortiguación (damping) hace que el movimiento resulte suave.

Carga de modelos. GLTFLoader lee cada GLB, con sus materiales y texturas, y nos devuelve un objeto de escena que podemos colocar y girar. Nuestros modelos usan escala real en metros y tienen el origen en la base, así que para colocarlos en el suelo basta con y = 0.

Consejos de colocación

  • Apilar objetos. La lámpara tiene que ir encima de la mesita. Elévala según la altura de la mesita: sustituye 0 por la altura de la mesita en la línea de posición, o calcúlala con new THREE.Box3().setFromObject(table).

  • Rotación. rotation.y va en radianes: Math.PI / 2 gira un modelo 90 grados.

  • Escala. Todos nuestros modelos comparten la misma escala, así que no deberías tener que escalar nada.

Listo para producción

  • Sombras. Añade una DirectionalLight con castShadow = true y activa castShadow en las mallas de los modelos para que los objetos queden bien asentados.

  • Pantalla de carga. Usa THREE.LoadingManager para mostrar el progreso mientras se descargan los modelos.

  • Compresión. Para escenas grandes, herramientas como gltf-transform pueden comprimir aún más la geometría y las texturas. Nuestra licencia permite convertir archivos para tu propio proyecto.

  • Opción más sencilla. Si solo necesitas un modelo con giro y zoom, el componente web model-viewer de Google muestra un GLB con una sola etiqueta HTML.

Te toca

Cambia el rincón de lectura por una cocina, un cuarto de juegos o un pueblecito. Todos los modelos de la tienda son archivos GLB que funcionan con este mismo código.

Modelos de este artículo

Todos los modelos →
Compartir

Artículos seleccionados del mismo tema.