¿Qué es Three.js?

0 acciones
0
0
0
0

Introducción

Three.js ofrece una gran cantidad de funciones y su relación con otros campos 3D puede resultar algo confusa. Su alcance también está en constante evolución, por lo que no es fácil resumirlo, y estas observaciones son subjetivas.

Biblioteca 3D de JavaScript

El objetivo de este proyecto es crear una biblioteca 3D ligera y fácil de usar. Esta biblioteca proporciona renderizados. , , CSS3D y WebGL.

Esta es la descripción oficial del repositorio de GitHub. De hecho, lo resume bastante bien, pero cada tema en esta oración es un tema amplio en sí mismo, y eso no es todo lo que three.js hace.

La biblioteca está escrita en JavaScript y está diseñada para usarse en un entorno JavaScript. En la mayoría de los casos, esto significa que se ejecuta en el lado del cliente, en un navegador web o en algún dispositivo. Pero con Node.js y navegadores headless, también se puede usar en el lado del servidor. Lo primero que viene a la mente es renderizar: quizás algunas imágenes de vista previa en el servidor, pero también podrían ser cálculos 3D, ya que three.js cuenta con una rica biblioteca matemática. Este es un término increíblemente amplio. 3D puede significar mucho. En la mayoría de los casos, pensamos en "gráficos".

La mayoría de los proyectos three.js que vemos utilizan gráficos 3D en tiempo real, donde la interacción del usuario genera una respuesta visual inmediata. Otros tipos de gráficos 3D son diversos efectos o personajes artificiales en películas, o diversas "representaciones" que se pueden ver impresas o en un catálogo web (por ejemplo, el sitio web de IKEA está repleto de gráficos 3D, ya que todas las fotos de sus productos son generadas por computadora).

Un subconjunto de todo esto son las matemáticas 3D. Los gráficos 3D son indispensables sin matemáticas, y los lenguajes de programación no comprenden los conceptos 3D por defecto. Aquí es donde entra en juego una biblioteca, que abstrae esas operaciones matemáticas, quizás optimizándolas, y expone una interfaz de alto nivel como Matrix4 o .dot().

Three.js incluye su propia biblioteca matemática con clases específicas para matemáticas 3D. Existen bibliotecas independientes que gestionan estas matemáticas por sí solas, pero con Three, es solo un subconjunto de un sistema mucho más amplio.

El renderizado es otra gran responsabilidad de la biblioteca, pero aquí también se complica un poco. WebGL es muy específico y destaca entre la multitud.

Con canvas, SVG y CSS, la responsabilidad del renderizado recae completamente en 3D. Estas API cuentan con numerosas bibliotecas para dibujar elementos no 3D, o incluso lo hacen por defecto (CSS dibuja rectángulos 2D, Canvas dibuja diversas formas 2D), pero requieren un toque mágico y matemáticas 3D para realizar el renderizado 3D.

El toque mágico se presenta principalmente en forma de abstracción de la interfaz. Por ejemplo, al gestionar el estado 3D de un elemento. <div> Convertir a 3D mediante CSS es muy difícil. Se requiere mucha lógica para que la API de Canvas dibuje algo que parezca 3D. WebGL es mucho más complejo.

Three abstrae todas estas API en algo tan simple como render(), pero para hacerlo necesita una representación genérica de lo que es el "mundo 3D".

Diagrama de escena

Se puede identificar un área de three.js que actúa como esta abstracción general del "mundo 3D". Un gráfico de escena es una estructura de datos que describe cómo se relacionan los objetos de una escena (mundo) 3D. No tiene por qué ser 3D, ya que es una forma práctica de describir cualquier jerarquía de gráficos vectoriales. Es más específicamente un "árbol" que se ramifica a partir de "nodos" con un "nodo raíz". En three.js, la clase base para esta estructura de datos es Object3D.

Esto es casi exactamente igual que el árbol DOM. THREE.Scene es similar. <body> Será y todo lo demás es una rama. En el DOM podemos colocar elementos en su lugar, pero su alcance es relativamente limitado. La rotación suele ocurrir alrededor de un eje y movemos los elementos a la izquierda/derecha o arriba/abajo. En un gráfico de escena 3D tenemos más grados de libertad.

La escena tres se asemeja más a un DOM virtual. Realizamos nuestras operaciones y establecemos el estado en ese árbol, y cuando queremos tener una instantánea visual de ese estado (por ejemplo, en un bucle continuo o en algún cambio de estado o interacción del usuario), llamamos a render (escena). Cuando algo cambia, no es necesario actualizar todo el árbol DOM, mientras que con el elemento , tenemos que borrar toda la vista y luego volver a dibujar todo, incluso si solo un elemento cambia su posición.

Uno <div> En uno <div> Similar a la relación padre-hijo THREE.Mesh(&#039;sol&#039;)-&gt;THREE.Mesh(&#039;tierra&#039;). Una regla CSS podría ser similar a un THREE.Material donde una descripción como color:&#039;rojo&#039; hace que algo se vuelva rojo. Finalmente, la llamada a threeRenderer.render(scene) podría ser similar a que el navegador cargue una página HTML con reglas CSS.

Malla, Escena, Cámara y Luz son subclases de esta clase genérica. Esto permite agregar () una "caja" a la "escena" o una "luz" a la "cámara".

Una estructura simple puede ser muy plana. El nodo raíz puede considerarse como "mundo" y puede tener como hijos "tierra", "casa", "sol" y "cámara".

THREE.Scene('world')
|-THREE.Mesh('ground')
|-THREE.Mesh('house')
|-THREE.Light('sun')
|-THREE.Camera('main')

Esta información es suficiente para alimentar un renderizador y obtener un resultado visual. En algunas escenas, hay dos cuadrículas que representan elementos diferentes: el suelo y la casa en la colina. Una luz define cómo se iluminan (mañana, mediodía o flash) y un objeto (la cámara) define nuestro punto de vista, nuestra visión del mundo.

Los resultados pueden variar, por ejemplo, CSS está limitado a una representación muy ligera, mientras que WebGL puede proporcionar sombras y, en general, alta fidelidad.

Mediante esta estructura, se gestiona el mundo 3D. Si queremos simular cómo la luz natural afecta a una casa en diferentes estaciones, cambiamos programáticamente la posición y la dirección de la luz en el mundo. La función del gráfico de escena es exponer este gancho de "posición", pero para animarlo, es necesario implementar una lógica propia. Una forma sencilla de animar una escena 3D es three.js con una biblioteca de interpolación.

Todo esto probablemente solo sea cierto en teoría, y es posible que no puedas cambiar los renderizados de la escena a voluntad. Pero esto se debe principalmente a la superposición de los &quot;materiales&quot; con el gráfico de la escena y su acoplamiento con los renderizados. Por ejemplo, no hay forma de sombrear un... <div> O bien no aparece como metal, que es algo que un material WebGL puede describir, pero puede volverse rojo, algo que todos los materiales pueden hacer.

En el fondo, Object3D sigue siendo genérico y la relación espacial y jerárquica de los nodos entre sí se describe a través de un “gráfico de escena”.

En términos simples, esta es la variable de escena que obtendrás después de llamar a scene.add(my_foo) varias veces.

WebGL

Webgl es increíblemente específico y probablemente se usa en aproximadamente el 99 % de las aplicaciones three.js existentes. Es un tema amplio, por lo que quizás valga la pena revisar primero las alternativas.

lienzo, css, svg

Todas estas son API. Se trata de una interfaz que, como programador, puedes usar para indicarle al navegador que dibuje ciertas cosas. CSS es la interfaz más común en la web porque, sin ella, todo parece texto plano. Históricamente, no tenía nada que ver con el 3D.

Canvas usa el mismo elemento WebGL para dibujar, pero tiene un contexto diferente. Este contexto se llama "2D", pero como el 3D es falso y siempre dibujamos algún tipo de superficie 2D, ya sea real o virtual, también podemos usar este contexto para dibujar gráficos 3D.

SVG es otra API no 3D que se suele usar para describir elementos como logotipos o iconos. Sin embargo, dado que puede describir elementos básicos como líneas, también puede representarse en un contexto 3D (como una superposición en un mapa o elementos de interfaz de usuario o HUD con reconocimiento espacial).

Un tema común aquí es que ninguno de estos está diseñado para uso 3D. Otra característica importante es que todos son de alto nivel; anteriormente estaban diseñados para hacer otra cosa. Por ejemplo, los tres saben cómo dibujar un "círculo". Con Canvas, esta es una forma explícita; con CSS, puede que tengas que usar radios de borde, pero el resultado final es un acceso muy directo a un círculo.

WebGL es de muy bajo nivel; desconoce el concepto de gráficos 3D. Los gráficos 3D requieren cálculos matemáticos específicos, y muchos. Piense por un momento en una pantalla de alta resolución y la cantidad de píxeles que tiene. Si tiene que realizar cálculos para cada píxel para determinar cómo cierta cantidad de luz afecta la superficie, y tiene que hacerlo 60 veces por segundo, la suma es considerable.

Procesador gráfico

La mayoría de las computadoras, como portátiles, ordenadores de sobremesa, teléfonos móviles e incluso relojes, cuentan con algún tipo de dispositivo de hardware que puede calcular eficientemente estas operaciones 3D y permitir la visualización de gráficos interactivos. Esto se denomina unidad de procesamiento gráfico.

Se diferencia del procesador principal porque está diseñado para propósitos diferentes: operaciones matemáticas específicas que se ejecutan en paralelo.

Así como utilizamos JavaScript para la programación de navegadores, utilizamos WebGL para la programación de tarjetas gráficas.

Bueno, eso es cierto en teoría, pero en la práctica son dos cosas muy distintas. WebGL se compone tanto de código JavaScript (las instrucciones) como de un lenguaje completamente distinto que realiza los cálculos (GLSL). Se pueden establecer algunos paralelismos entre HTML y JavaScript y cómo funcionan juntos en una página.

Bidimensional y tridimensional

No solo el 3D se beneficia de esta aceleración de hardware. El procesamiento de vídeo también es un buen candidato. Puedes programar la tarjeta gráfica para cambiar los colores o la imagen en una transmisión de vídeo en directo.

WebGL, que es de muy bajo nivel, es genérico. No comprende el 2D ni el 3D, pero sí la memoria, los búferes, las colas de comandos, los sombreadores, etc.

La programación paralela es diferente a la programación en JavaScript. Un problema común es cómo los distintos subprocesos acceden a una variable compartida.

Este paradigma diferente implica la existencia de un lenguaje completamente nuevo llamado GLSL. Es un lenguaje de sombreado presente en casi todas las API de gráficos de bajo nivel. Es donde se escribe la lógica para estos grandes números, y la única ventaja es que no es necesario escribir código máquina.

La otra parte de la API de WebGL son los enlaces de JavaScript que le indican a la GPU qué hacer. Un sombreador "realiza los cálculos A" y un enlace "los ejecuta un millón de veces".

Depende del programador calcular qué es A. Podría ser algo relacionado con 3D o podría ser un kernel que desenfoca el video.

Cuando comienzas a abstraer estos cálculos y estos comandos, terminas con three.js.

Renders que trabajan juntos

Un caso de uso muy lógico es usar una combinación de renderizadores para dibujar elementos que se ven bien en 3D. WebGL puede procesar muchos números y crear imágenes muy realistas, pero es deficiente al manejar texto e incluso algunas líneas. Una capa adicional de texto renderizado se puede gestionar mediante CSS y renderizadores de lienzo, mientras que las rutas y diversas líneas se pueden gestionar mediante SVG.

TRES.WebGLRenderer

Todo este contenido de bajo nivel se abstrae mediante una clase WebGLRenderer de three.js. Esto es lo que convierte el cubo en un conjunto de números en la memoria de la GPU.

Irónicamente, es el único renderizador de three.js que no necesita gráficos 3D, pero es la mejor opción. El resto simula 3D mediante API 2D, mientras que WebGL lo hace intencionalmente mediante una API genérica de computación paralela. Sin embargo, esto no descarta un escenario en el que se pueda usar exclusivamente para procesar esa transmisión de video en vivo. Se abstrae lo suficiente de WebGL como para ser útil para esto, pero probablemente se esté usando un tercio de la biblioteca. Se podría crear una capa de interfaz de usuario súper responsiva con WebGL, o un juego de plataformas tipo Super Mario donde three.js seguiría siendo una gran herramienta.

El hecho de que solo uses un tercio de la biblioteca significa que otra herramienta podría ser más adecuada para ese uso, o que podrías simplemente crear un subconjunto de three.js. Tanto los ejemplos de Super Mario como los de procesamiento de vídeo podrían necesitar solo PlaneGeometry y quizás un tipo de material.

tres matemáticas

Código JavaScript que realiza ciertas operaciones matemáticas en 3D. JS tiene Math.pow() por defecto, pero no Quaternion.inverse(). Con estas clases, podemos escribir algoritmos que no requieren renderizado; por ejemplo, un servidor de juegos que verifica quién dispara y quién genera muchos rayos, pero no dibuja nada.

gráfico de tres escenas

Una familia de subclases de Object3D que forman una estructura de datos de árbol que describe un "mundo 3D" y las relaciones entre los objetos que lo componen. Es conceptualmente abstracta, pero puede renderizarse con renderizado específico una vez que se profundiza en el código.

tres representaciones

La capa que traduce ese gráfico genérico a una representación visual en la pantalla o en algún búfer (por ejemplo, se crea en el servidor). Utiliza diversas tecnologías para lograr este objetivo.

TRES-WebGLRenderer

Un renderizador especial que permite la aceleración por hardware y domina muchos conceptos 3D, pero que también puede usarse para 2D (e incluso computación general). Estos son los componentes principales de three.js, en mi opinión. Suelo reemplazar “3D” por “Gráficos”, pero esto solo aplica al WebGLRenderer.

Three.js no es un motor de juego.

No todos los que necesitan 3D (o gráficos) en la web desarrollan juegos. Los motores de juego suelen realizar muchas optimizaciones más allá de describir y mostrar mundos 3D. Cada juego tiene necesidades diferentes, y la física y los sistemas de renderizado para juegos de estrategia en tiempo real y de disparos en primera persona probablemente tengan necesidades muy diferentes. Todo esto implica más código, y para alguien que solo quiere crear un modelo 3D como parte de un catálogo de productos, esto no solo es innecesario, sino indeseable. Por supuesto, se podría crear un motor de juego y usar tres para renderizar y construir los bloques del motor.

Three.js no carga mucho

Claro, el núcleo cuenta con múltiples cargadores para algunos recursos, pero todos los formatos comunes como gltf o fbx son independientes. A Three.js no le importa cómo se obtienen los recursos, siempre y cuando se analicen correctamente y se cree un objeto 3D. En Three.js, no hay diferencia entre una malla de un archivo gltf y una esfera procedural. Muchos ejemplos creativos usan cubos y esferas y no cargan nada más que el propio Three.js. Los cargadores del núcleo son muy genéricos: cargan imágenes y archivos y tienen una representación directa de un objeto de Three.js, como un material o una textura. Los cargadores específicos para cada formato se construyen con estos bloques de construcción.

 

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

También te puede gustar