Video Summary and Transcription
Esta charla explora las diferencias entre WebGL y WebGPU, con un enfoque en la transición de WebGL a WebGPU. Se discute el proceso de inicialización y los programas de sombreado en ambas APIs, así como la creación de tuberías en WebGPU. La comparación de los uniformes destaca el uso de buffers uniformes para mejorar el rendimiento. La charla también cubre las diferencias en las convenciones entre WebGL y WebGPU, incluyendo texturas, espacios de vista y recorte. Por último, se mencionan las diferencias en el rango de profundidad y la matriz de proyección entre las dos APIs.
1. Introducción a WebGL y WebGPU
En esta charla, exploraremos las diferencias entre WebGL y la próxima versión de WebGPU y aprenderemos cómo preparar el proyecto para la transición. WebGL tiene una historia que se remonta a 1993, y la primera versión estable, WebGL 1.0, se lanzó en 2011. WebGL 2.0, lanzado en 2017, trajo varias mejoras y nuevas características. WebGPU, construido sobre Vulkan, Direct3D 12 y Metal, ha estado progresando significativamente y es compatible con varios motores.
Hola a todos. Soy Dmitry Vaschenko, un ingeniero de software líder en My.Games. En esta charla, exploraremos las diferencias entre WebGL y la próxima versión de WebGPU y aprenderemos cómo preparar el proyecto para la transición.
Comencemos explorando la línea de tiempo de WebGL y WebGPU, así como el estado actual de WebGL y WebGPU. WebGL, al igual que otras tecnologías, tiene una historia que se remonta al pasado. La versión de escritorio de WebGL debutó en 1993. En 2011, se lanzó WebGL 1.0 como la primera versión estable de WebGL. Se basaba en OpenGL ES 2.0, que se introdujo en 2007. Y este lanzamiento permitió a los desarrolladores web incorporar objetos 3D en los navegadores sin necesidad de complementos adicionales. En 2017, se introdujo una nueva versión de WebGL, llamada WebGL 2.0. Esta versión se lanzó seis años después de la versión inicial y se basaba en WebGL ES 3.0, que se lanzó en 2012. WebGL 2.0 vino con varias mejoras y nuevas características, lo que lo hace aún más capaz de producir gráficos 3D potentes en la web.
Últimamente, ha habido un creciente interés en nuevas API de gráficos que ofrecen a los desarrolladores más control y flexibilidad. Tres API notables aquí son Vulkan, Direct3D 12 y Metal. Juntas, estas tres API crean la base para WebGPU. Vulkan, desarrollado por el Grupo Kronos, es una API multiplataforma que proporciona a los desarrolladores un acceso de nivel inferior a los recursos de hardware gráfico. Esto permite aplicaciones de alto rendimiento con un mejor control del hardware gráfico. Direct3D 12, creado por Microsoft, es exclusivo para Windows y Xbox, obviamente, y ofrece a los desarrolladores un control más profundo sobre los recursos gráficos. Y Metal, una API exclusiva para dispositivos Apple, diseñada por Apple, por supuesto, con un rendimiento máximo en mente de su hardware. WebGPU ha estado progresando significativamente últimamente. Se ha expandido a plataformas como Mac, Windows y Chrome OS, ahora disponible en Chrome y en las versiones 113. Se espera que se agregue soporte para Linux y Android pronto. Hay varios motores que admiten o están experimentando con WebGPU. Por ejemplo, Babylon.js admite completamente WebGPU, mientras que Tree.js actualmente tiene soporte experimental. Play Canvas todavía está en desarrollo, pero su futuro parece prometedor. Y Unity anunció el soporte temprano y experimental de WebGPU en la versión alfa 2023.2. Cocoa's Creator 3.6.2 admite oficialmente WebGPU. Y finalmente, Construct actualmente solo admite la versión 113 o posterior de Chrome en máquinas con Windows, MacOS y Chrome OS. Teniendo esto en cuenta, parece una decisión inteligente comenzar la transición hacia WebGPU o al menos preparar los proyectos para una transición futura. Ahora exploremos las principales diferencias de alto nivel.
2. Inicialización de la API de gráficos y programas de sombreado
Cuando se trabaja con API de gráficos como WebGL y WebGPU, el primer paso es inicializar el objeto principal para la interacción. WebGL utiliza contextos para representar una interfaz para dibujar en un elemento de lienzo HTML5 específico, mientras que WebGPU introduce el concepto de un dispositivo que proporciona más flexibilidad. En WebGL, el programa de sombreado es el enfoque principal y crear un programa implica varios pasos. Sin embargo, este proceso puede ser complicado y propenso a errores.
Y al comenzar a trabajar con API de gráficos, el primer paso es inicializar el objeto principal para la interacción. Este proceso del proyecto tiene algunas diferencias entre WebGL y WebGPU, lo que puede causar algunos problemas en ambos sistemas. En WebGL, este objeto se llama contextos. Y este contexto representa una interfaz para dibujar en un elemento de lienzo HTML5. Obtener estos contextos es fácil, pero es importante tener en cuenta que está vinculado a un lienzo específico. Esto significa que si necesita renderizar en varios lienzos, necesitará múltiples contextos.
Y WebGPU introduce un nuevo concepto llamado dispositivo. El dispositivo representa una abstracción de GPU con la que interactuará. El proceso de inicialización es un poco más complejo que en WebGL, pero proporciona más flexibilidad. Una ventaja de este modelo es que un dispositivo puede renderizar en varios lienzos o incluso en ninguno. Esto proporciona flexibilidad adicional, permitiendo que un dispositivo controle el renderizado en múltiples ventanas o contextos.
WebGL y WebGPU son dos métodos distintos para administrar y organizar el pipeline de gráficos. En WebGL, el énfasis principal está en el programa de sombreado, que combina sombreadores de vértices y fragmentos para determinar cómo se transforma el vértice y cómo se colorea cada píxel. Para crear un programa en WebGL, es necesario seguir varios pasos. En primer lugar, es necesario escribir y compilar el código fuente de los sombreadores. A continuación, es necesario adjuntar los sombreadores compilados al programa y luego vincularlos. Después, es necesario activar el programa antes de renderizar. Y por último, es necesario transmitir datos al programa activado. Este proceso proporciona un control flexible sobre los gráficos, pero puede ser complicado y propenso a errores, especialmente para proyectos grandes y complejos.
3. Creación de la tubería de WebGPU
En WebGPU, una tubería reemplaza los programas separados e incluye sombreadores y otros parámetros de renderizado. La creación de una tubería implica definir el sombreador, crear la tubería y activarla antes de renderizar. Este enfoque simplifica el proceso y permite gráficos optimizados y eficientes en la web.
Cuando se desarrollan gráficos para la web, es esencial tener un proceso fluido y eficiente. Y en WebGPU, esto se logra a través del uso de una tubería. La tubería reemplaza la necesidad de programas separados e incluye no solo sombreadores, sino también otra información crítica que se establece como estados en WebGL. La creación de una tubería en WebGPU puede parecer más complicada al principio, pero ofrece una mayor flexibilidad y modularidad. El proceso implica tres pasos clave. En primer lugar, debe definir el sombreador escribiendo y compilando el código fuente del sombreador, al igual que en WebGL. En segundo lugar, crea la tubería combinando los sombreadores y otros parámetros de renderizado en una unidad cohesiva. Y finalmente, debe activar la tubería antes de renderizar. En comparación con WebGL, WebGPU encapsula más aspectos del renderizado en un solo objeto. Este enfoque crea un proceso más predecible y resistente a errores, y en lugar de administrar sombreadores y estados de renderizado por separado, todo se combina en un solo objeto de tubería. Siguiendo estos pasos, los desarrolladores pueden crear gráficos optimizados y eficientes para la web con facilidad.
4. Comparación de Uniformes en WebGL y WebGPU
Las variables uniformes en WebGL y WebGPU se pueden consolidar en estructuras más grandes utilizando buffers uniformes, lo que reduce las llamadas a la API y mejora el rendimiento. WebGL2 permite enlazar subconjuntos de un buffer uniforme grande a través de la llamada a la API bind-buffer-range, mientras que WebGPU utiliza desplazamientos de buffer uniforme dinámicos. Estas optimizaciones brindan flexibilidad y eficiencia a los desarrolladores que trabajan en proyectos de WebGL y WebGPU.
Ahora, comparemos los uniformes en WebGL y WebGPU. Las variables uniformes ofrecen datos constantes que pueden ser accedidos por todas las instancias de sombreadores, y con WebGL básico, podemos establecer variables uniformes directamente a través de llamadas a la API. Sin embargo, este enfoque es sencillo pero requiere múltiples llamadas a la API para cada variable uniforme. Con la llegada de WebGL2, los desarrolladores ahora pueden agrupar variables uniformes en buffers, una alternativa altamente eficiente para usar sombreadores uniformes separados. Al consolidar diferentes uniformes en una estructura más grande utilizando buffers uniformes, todos los datos uniformes pueden ser transmitidos a la GPU de una vez, lo que reduce las llamadas a la API y mejora el rendimiento. En el caso de WebGL2, se pueden enlazar subconjuntos de un buffer uniforme grande a través de una llamada especial a la API, conocida como bind-buffer-range. De manera similar, en WebGPU, se utilizan desplazamientos de buffer uniforme dinámicos para el mismo propósito, lo que permite pasar una lista de desplazamientos al invocar la API set-bind group. Este nivel de flexibilidad y optimización ha convertido a los buffers uniformes en una herramienta valiosa para los desarrolladores que buscan optimizar sus proyectos de WebGL y WebGPU.
5. Transición de WebGL a WebGPU
En lugar de admitir variables uniformes individuales, el trabajo se realiza exclusivamente a través de buffers uniformes. Cargar datos en un solo bloque grande es preferido por las GPU modernas en lugar de muchos pequeños. La transición de WebGL a WebGPU implica modificar tanto la API como los sombreadores. La especificación WGSL facilita una transición fluida e intuitiva al tiempo que garantiza una eficiencia y rendimiento óptimos para las GPU contemporáneas. Si estás trabajando con WGSL, notarás que algunas de las funciones integradas de GLSL tienen nombres diferentes o han sido reemplazadas. Hay herramientas disponibles que pueden automatizar el proceso de conversión de GLSL a WGSL. Hablemos sobre algunas de las diferencias en las convenciones entre WebGL y WebGPU. Específicamente, repasaremos las disparidades en texturas, espacios de vista y recorte. Cuando hagas la migración, es posible que te encuentres con un problema inesperado donde tus imágenes estén invertidas.
Un mejor método está disponible a través de WebGPU. En lugar de admitir variables uniformes individuales, el trabajo se realiza exclusivamente a través de buffers uniformes. Cargar datos en un solo bloque grande es preferido por las GPU modernas en lugar de muchos pequeños. En lugar de recrear y volver a enlazar pequeños buffers cada vez, crear un solo buffer grande y usar diferentes partes de él para diferentes llamadas de dibujo puede aumentar significativamente el rendimiento. Y aunque WebGL es más imperativo, restableciendo el estado global con cada llamada y esforzándose por ser lo más simple posible, WebGPU tiene como objetivo ser más orientado a objetos y centrado en la reutilización de recursos, lo que conduce a la eficiencia, por supuesto.
Aunque la transición de WebGL a WebGPU puede parecer difícil debido a las diferencias en los métodos, comenzar con una transición a WebGL2 como paso intermedio puede simplificar el trabajo. La transición de WebGL a WebGPU implica modificar tanto la API como los sombreadores. La especificación WGSL facilita una transición fluida e intuitiva al tiempo que garantiza una eficiencia y rendimiento óptimos para las GPU contemporáneas. Tengo un ejemplo de sombreador para una textura que utiliza GLSL y WGSL. WGSL sirve como una conexión entre WebGPU y las API gráficas nativas. Aunque WGSL parece ser más mundano que GLSL, el formato sigue siendo reconocible. Las siguientes tablas muestran una comparación entre los tipos de datos básicos y de matriz que se encuentran en GLSL y WGSL. Pasar de GLSL a WGSL indica una preferencia por una tipificación más estricta y una especificación clara del tamaño de los datos, lo que resulta en una mejor legibilidad y una menor probabilidad de error. La estructura de metadeclaración se ha alterado con la adición de una sintaxis explícita para declarar campos en las estructuras de WGSL, y esto destaca la necesidad de una mayor claridad y simplificación para las estructuras de datos en los sombreadores. Al alterar la sintaxis de las funciones en WGSL, se promueve un enfoque unificado para las declaraciones y los valores de retorno, lo que resulta en un código más consistente y predecible.
Si estás trabajando con WGSL, notarás que algunas de las funciones integradas de GLSL tienen nombres diferentes o han sido reemplazadas. Esto en realidad es útil porque simplifica los nombres de las funciones y los hace más intuitivos. Esto facilitará la transición a WGSL para los desarrolladores que están familiarizados con otras API gráficas. Si planeas convertir tus proyectos de WebGL a WebGPU, hay herramientas disponibles que pueden automatizar el proceso de conversión de GLSL a WGSL. Una de esas herramientas es Naga, una biblioteca de Rust que se puede utilizar para convertir GLSL a WGSL, y lo mejor de todo es que incluso se puede utilizar directamente en tu navegador con la ayuda de WebAssembly.
Hablemos sobre algunas de las diferencias en las convenciones entre WebGL y WebGPU. Específicamente, repasaremos las disparidades en texturas, espacios de vista y recorte. Y cuando hagas la migración, es posible que te encuentres con un problema inesperado donde tus imágenes estén invertidas. Este es un problema común para aquellos que han trasladado aplicaciones de OpenGL a Direct3D. En OpenGL y WebGL, las imágenes generalmente se cargan de modo que el primer píxel esté en la esquina inferior izquierda. Sin embargo, muchos desarrolladores cargan imágenes comenzando desde la esquina superior izquierda, lo que resulta en una imagen invertida. Los sistemas Direct3D y Metal utilizan la esquina superior izquierda como punto de partida para las texturas, y los desarrolladores de WebGPU han decidido seguir esta práctica, ya que parece ser el enfoque más sencillo para la mayoría de los desarrolladores. Si tu código de WebGL selecciona píxeles del búfer de fotogramas, es importante tener en cuenta que WebGPU utiliza un sistema de coordenadas diferente. Para ajustar esto, es posible que debas aplicar una operación y="1-y'' sencilla para corregir las coordenadas.
6. Diferencias en el Rango de Profundidad y la Matriz de Proyección
WebGL y WebGPU tienen diferentes definiciones para el rango de profundidad del espacio de recorte. WebGL utiliza un rango de menos uno a uno, mientras que WebGPU utiliza un rango de cero a uno. La matriz de proyección se encarga de transformar las posiciones de tu modelo en espacio de recorte. Se pueden realizar ajustes asegurando que la matriz de proyección genere salidas que van de cero a uno. La transición a WebGPU es un paso hacia el futuro de los gráficos web, combinando características y prácticas exitosas de varias API gráficas.
Si un desarrollador se encuentra con un problema donde los objetos desaparecen o se recortan demasiado pronto, puede deberse a diferencias en el dominio de profundidad. WebGL y WebGPU tienen diferentes definiciones para el rango de profundidad del espacio de recorte. Mientras que WebGL utiliza un rango de menos uno a uno, WebGPU utiliza un rango de cero a uno, similar a otras API gráficas como Diag2D, Metal y Vulkan. Esta decisión se tomó en base a las ventajas de utilizar un rango de cero a uno que se descubrieron al trabajar con otras API gráficas.
Entonces, la matriz de proyección es principalmente responsable de transformar las posiciones de tu modelo en espacio de recorte, y una forma útil de realizar ajustes en tu código es asegurarse de que la matriz de proyección genere salidas que van de cero a uno. Esto se puede lograr implementando ciertas funciones disponibles en bibliotecas como GLMatrix, como la función PerspectiveCO. También existen otras operaciones métricas que ofrecen funciones comparables que puedes utilizar. Y en caso de que estés trabajando con una matriz de proyección existente que no se puede modificar, aún hay una solución. Puedes transformar la matriz de proyección para que se ajuste al rango de 0 a 1 aplicando otra métrica que modifique el rango de profundidad antes de la matriz de proyección. Esta técnica de pre-multiplicación puede ser una forma efectiva de ajustar el rango de tu matriz de proyección según tus necesidades.
Entonces, como puedes ver, la transición a WebGPU es más que simplemente cambiar de API gráfica. Es un paso hacia el futuro de los gráficos web, combinando características y prácticas exitosas de varias API gráficas. Y esta migración requiere una comprensión profunda de los cambios técnicos y filosóficos, pero los beneficios son significativos, ¿verdad? Así que, gracias por tu atención y que tengas un excelente día.
Comments