Skip to content

2. Estructura Básica de una Escena en Three.js

2.1 Componentes Principales de una Escena

Para crear una escena 3D en Three.js, necesitas comprender y configurar tres componentes fundamentales:

  1. Escena (THREE.Scene)
  2. Cámara (THREE.Camera)
  3. Renderizador (THREE.Renderer)

Estos componentes trabajan en conjunto para definir qué se muestra en la pantalla, desde qué perspectiva y cómo se renderiza visualmente.

2.2 Descripción de los Componentes

2.2.1 Escena (THREE.Scene)

La escena es el contenedor principal donde se agregan todos los objetos, luces y otros elementos 3D. Actúa como un espacio tridimensional donde se organiza todo lo que se desea visualizar.

Características clave:

  • Contenedor de objetos: Puedes agregar mallas (Mesh), luces (Light), cámaras adicionales, y más.
  • Jerarquía: Utiliza una estructura de árbol donde los objetos pueden contener otros objetos, permitiendo agrupaciones y transformaciones jerárquicas.
  • Propiedades: Permite establecer propiedades globales como el fondo de la escena.

Ejemplo de creación de una escena:

const scene = new THREE.Scene();

2.2.2 Cámara (THREE.Camera)

La cámara determina desde qué perspectiva se visualiza la escena. Existen diferentes tipos de cámaras en Three.js, pero las más comunes son:

  • Cámara en Perspectiva (THREE.PerspectiveCamera): Simula la percepción humana con perspectiva, donde los objetos más lejanos parecen más pequeños.
  • Cámara Ortográfica (THREE.OrthographicCamera): Muestra los objetos sin perspectiva, manteniendo las mismas dimensiones independientemente de la distancia.

Para este tema, nos enfocaremos en la Cámara en Perspectiva.

Parámetros clave de PerspectiveCamera:

  • Campo de Visión (fov): Ángulo de visión en grados.
  • Aspect Ratio (aspect): Proporción entre el ancho y alto de la pantalla.
  • Plano cercano (near): Distancia mínima desde la cámara donde los objetos comienzan a ser visibles.
  • Plano lejano (far): Distancia máxima desde la cámara donde los objetos dejan de ser visibles.

Ejemplo de creación de una cámara en perspectiva:

const camera = new THREE.PerspectiveCamera(
    75, // Campo de visión en grados
    window.innerWidth / window.innerHeight, // Aspect ratio
    0.1, // Plano cercano
    1000 // Plano lejano
);

2.2.3 Renderizador (THREE.Renderer)

El renderizador es responsable de dibujar la escena desde la perspectiva de la cámara en el lienzo (canvas) HTML. El tipo más común es el Renderizador WebGL (THREE.WebGLRenderer), que utiliza la API WebGL para renderizar gráficos 3D.

Características clave:

  • Renderización en tiempo real: Actualiza la visualización continuamente para animaciones e interacciones.
  • Configuración de tamaño: Determina el tamaño del lienzo donde se renderiza la escena.
  • Adjuntar al DOM: Añade el lienzo al documento HTML para que sea visible en la página.

Ejemplo de creación y configuración del renderizador:

const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight); // Configura el tamaño del lienzo
document.body.appendChild(renderer.domElement); // Añade el lienzo al DOM

2.3 Ciclo de Renderizado

El ciclo de renderizado es una función que actualiza y dibuja la escena en cada frame, permitiendo animaciones y actualizaciones dinámicas. Utiliza requestAnimationFrame para sincronizar la renderización con la tasa de refresco del navegador, optimizando el rendimiento.

Pasos básicos del ciclo de renderizado:

  1. Actualizar objetos: Modificar las propiedades de los objetos (por ejemplo, rotaciones, posiciones).
  2. Renderizar la escena: Dibujar la escena desde la perspectiva de la cámara.
  3. Solicitar el siguiente frame: Llamar nuevamente a la función de animación para el próximo frame.

Ejemplo de ciclo de renderizado:

function animate() {
    requestAnimationFrame(animate); // Solicita el siguiente frame

    // Actualiza objetos aquí (por ejemplo, rotaciones)
    cube.rotation.x += 0.01;
    cube.rotation.y += 0.01;

    // Renderiza la escena
    renderer.render(scene, camera);
}

animate(); // Inicia el ciclo de animación

2.4 Manejo del Redimensionamiento de la Ventana

Es importante que la escena se adapte dinámicamente al tamaño de la ventana del navegador para mantener la proporción y la calidad visual. Esto implica actualizar tanto el renderizador como la cámara cuando la ventana cambia de tamaño.

Implementación del manejo de redimensionamiento:

window.addEventListener('resize', () => {
    const width = window.innerWidth;
    const height = window.innerHeight;

    // Actualiza el tamaño del renderizador
    renderer.setSize(width, height);

    // Actualiza la proporción de la cámara
    camera.aspect = width / height;
    camera.updateProjectionMatrix();
});

2.5 Ejemplo Completo: Creación de una Escena Básica

A continuación, se presenta un ejemplo completo que integra todos los conceptos mencionados anteriormente para crear una escena básica con un cubo giratorio.

2.5.1 Estructura de Carpetas

mi-escena-basica-threejs/
├── index.html
└── js/
    └── three.min.js

2.5.2 Contenido de index.html

<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Escena Básica con Three.js</title>
    <style>
        body { margin: 0; }
        canvas { display: block; }
    </style>
</head>
<body>
    <!-- Enlace a Three.js -->
    <script src="js/three.min.js"></script>
    <script>
        // 1. Crear la escena
        const scene = new THREE.Scene();

        // 2. Crear la cámara
        const camera = new THREE.PerspectiveCamera(
            75, // Campo de visión
            window.innerWidth / window.innerHeight, // Aspect ratio
            0.1, // Plano cercano
            1000 // Plano lejano
        );

        // 3. Crear el renderizador
        const renderer = new THREE.WebGLRenderer({ antialias: true });
        renderer.setSize(window.innerWidth, window.innerHeight);
        document.body.appendChild(renderer.domElement);

        // 4. Crear una geometría y material (un cubo)
        const geometry = new THREE.BoxGeometry();
        const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
        const cube = new THREE.Mesh(geometry, material);
        scene.add(cube); // Añadir el cubo a la escena

        // 5. Posicionar la cámara
        camera.position.z = 5;

        // 6. Función de animación
        function animate() {
            requestAnimationFrame(animate); // Solicita el siguiente frame

            // Rotar el cubo
            cube.rotation.x += 0.01;
            cube.rotation.y += 0.01;

            // Renderizar la escena
            renderer.render(scene, camera);
        }

        animate(); // Inicia la animación

        // 7. Manejar el redimensionamiento de la ventana
        window.addEventListener('resize', () => {
            const width = window.innerWidth;
            const height = window.innerHeight;

            renderer.setSize(width, height);
            camera.aspect = width / height;
            camera.updateProjectionMatrix();
        });
    </script>
</body>
</html>

2.5.3 Ejecutar el Proyecto

  1. Estructura de carpetas:
  2. Crea una carpeta llamada mi-escena-basica-threejs.
  3. Dentro de ella, crea una subcarpeta js y descarga el archivo three.min.js desde el sitio oficial de Three.js.
  4. Crea el archivo index.html con el contenido proporcionado anteriormente.

  5. Abrir el archivo en el navegador:

  6. Abre el archivo index.html en tu navegador favorito (Chrome, Firefox, Edge, Safari).
  7. Deberías ver un cubo verde girando en el centro de la pantalla.