WebGL y WebGPU

La tarjeta gráfica necesita instalar un controlador de tarjeta gráfica. A través de la API expuesta por el controlador de la tarjeta gráfica, podemos operar la GPU para completar el funcionamiento del procesador gráfico. El problema es que los controladores de las tarjetas gráficas son los mismos que los ensamblados en el mundo de la programación normal: son de bajo nivel y difíciles de escribir, por lo que los principales fabricantes los han empaquetado. Así nació OpenGL, responsable de encapsular la interfaz de la capa superior y manejar el controlador de gráficos de la capa inferior, pero como todos sabemos, su estilo de diseño ya no puede seguir el ritmo de las características de las GPU modernas.

La tecnología OpenGL se propuso en la década de 1990 y WebGL se basa en OpenGL ES. OpenGL jugó su debido valor en esa época en la que las tarjetas gráficas eran débiles.

La última API de gráficos creada por Microsoft es Direct3D, la última API de gráficos creada por Apple es Metal y una organización conocida, Khronos, creó Vulkan. Estas son las tres principales API de gráficos modernos.

Khronos perdió OpenGL en 2006. Hoy en día, casi todos los sistemas operativos no instalan este controlador de gráficos tan antiguo. Entonces, ¿por qué WebGL basado en OpenGL ES puede ejecutarse en navegadores de varios sistemas operativos? Porque WebGL ya no es OpenGL ES. En Windows, ahora se traduce al controlador de la tarjeta gráfica a través de D3D, y en macOS, es Metal. Sin embargo, cuanto más se acerca el momento, más difícil se vuelve esta implementación no parental. . El navegador Safari de Apple recientemente admitió WebGL 2.0 en los últimos años y abandonó las funciones GPGPU de OpenGL ES. Quizás la GPGPU de WebGL 2.0 no se implementará en Safari.

La próxima generación de interfaz gráfica web ya no está en la línea GL, no se llama WebGL 3.0, pero utiliza WebGPU, que está más estrechamente relacionado con el nombre del hardware. WebGPU es fundamentalmente diferente de WebGL en términos de estilo de codificación y rendimiento.

Estilo de codificación WebGL

El estilo de programación de WebGL continúa el de OpenGL. Los estudiantes que hayan estudiado la interfaz WebGL deberían haber utilizado: gl variables, es decir,  WebGLRenderingContext objetos, y WebGL 2.0 es WebGLRenderingContext2。

Aquí hay un código de muestra para crear sombreadores de vértices y fragmentos:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

dieciséis

17

18

19

const vertexShaderCode = `attribute vec4 a_position;

void main() {

    gl_Position = a_position;

}`

 const fragmentShaderCode = `precision mediump float;

 void main() {

     gl_FragColor = vec4(1, 0, 0.5, 1);

}`

 const vertexShader = gl.createShader(gl.VERTEX_SHADER)

 gl.shaderSource(vertexShader, vertexShaderCode)

 gl.compileShader(vertexShader)

 const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER)

 gl.shaderSource(fragmentShader, fragmentShaderCode)

 gl.compileShader(fragmentShader)

 const program = gl.createProgram()

 gl.attachShader(program, vertexShader)

 gl.attachShader(program, fragmentShader)

 gl.linkProgram(program)

 gl.useProgram(program)// ...

El orden de creación de un sombreador, asignación de código de sombreado y compilación es relativamente fijo.

Cada vez que se llama  gl 方法, se completará la transmisión de la señal de la CPU a la GPU y se cambiará el estado de la GPU. Por tanto la eficiencia del proceso es baja.

Las tres principales API de gráficos modernos prefieren preparar las cosas primero, y lo que finalmente se envía a la GPU es un dibujo de diseño completo y datos de búfer, y la GPU solo necesita retenerlo y concentrarse en el trabajo.

Estilo de codificación ensamblador para WebGPU

Aunque WebGPU también tiene un objeto como administrador general: dispositivo, el tipo es  GPUDevice, que representa una abstracción de alto nivel que puede operar dispositivos GPU, es responsable de crear varios objetos que operan operaciones gráficas y finalmente ensamblarlos en un búfer de comando. llamado "CommandBuffer (GPUCommandBuffer)" y envíelo a la cola, luego se completa el trabajo en el lado de la CPU.

Por lo tanto, cuando device.createXXX crea un objeto, no notifica inmediatamente a la GPU sobre el cambio de estado de finalización como WebGL, sino que el código escrito en el lado de la CPU garantiza, desde una perspectiva lógica y de tipo, lo que se pasará a la GPU más adelante. Es preciso y déjelos permanecer en sus propios pozos, esperando ser enviados a la GPU en cualquier momento.

Aquí, el objeto del búfer de instrucciones tiene datos completos (geometría, textura, sombreador, lógica de programación de tuberías, etc.) y la GPU sabe qué hacer tan pronto como los obtiene.

La variable gl de WebGL se basa en el elemento HTML Canvas y solo puede programar la GPU en el hilo principal. WebWorker en WebGL solo puede procesar datos y no puede operar la GPU.

También se puede acceder a los objetos en los que se basa el adaptador en WebGPU  navigator.gpu en WebWorker, por lo que también puede crear dispositivos y ensamblar búferes de instrucciones en Worker, logrando así el envío multiproceso de búferes de instrucciones y la capacidad de la CPU para programar la GPU con múltiples -hilos.

adaptador constante = esperar navigator.gpu.requestAdapter();
si (!adaptador) {
  devolver
}
dispositivo constante = espera adaptador.requestDevice()
// Obtiene un búfer de GPU en un estado mapeado y un arrayBuffer para escribir
búfer constante = dispositivo.createBuffer({
  mappedAtCreation: verdadero,
  tamaño: 4,
  uso: GPUBufferUsage.MAP_WRITE
})
const arrayBuffer = gpuBuffer.getMappedRange();
// Escribe bytes en el búfer.
nuevo Uint8Array(arrayBuffer).set([0, 1, 2, 3]);
 
textura constante = dispositivo.createTexture({
  /* Textura del ensamblaje e información de muestreo */
})
 
const pipelineLayout = dispositivo.createPipelineLayout({
  /* Crear diseño de canalización y pasar objeto de diseño de grupo vinculante */
})
 
/* Crear módulo de sombreado */
const vertexShaderModule = dispositivo.createShaderModule({ /* ... */ })
const fragmentShaderModule = dispositivo.createShaderModule({ /* ... */ })
 
/*
Calcular los módulos de sombreado que puede utilizar el sombreador.
const ComputeShaderModule = dispositivo.createShaderModule({ /* ... * / })
*/
 
const bindGroupLayout = dispositivo.createBindGroupLayout({
  /* Crear el objeto de diseño del grupo de enlace */
})
 
const pipelineLayout = dispositivo.createPipelineLayout({
  /* Pasar el objeto de diseño del grupo de enlace */
})
 
/*
De hecho, los dos objetos de diseño anteriores pueden ser diferidos y no crearse. Aunque el grupo vinculante debe estar vinculado al diseño del grupo,
Notifica cómo se ven los recursos del grupo de enlace de la etapa de canalización correspondiente, pero el diseño del grupo de enlace puede ser
El objeto de canalización infiere el propio objeto de diseño del grupo de enlace a través del código en la etapa programable.
Este código de muestra guarda el proceso completo.
*/
 
canalización constante = dispositivo.createRenderPipeline({
  /*
  Crear canalización
  Especificar los materiales necesarios para cada etapa del ducto.
  Hay tres etapas en las que se pueden pasar los sombreadores para lograr la programabilidad: vértice, fragmento y cálculo.
  Cada etapa también puede especificar los datos y la información que necesita, como el búfer, etc.
   
  Además, la tubería también necesita un objeto de diseño de tubería, y su objeto de diseño de grupo de enlace incorporado puede
  Informe al sombreador cómo se verán los recursos del grupo de enlace utilizados en el pase.
  */
})
 
const bindGroup_0 = deivce.createBindGroup({
  /*
  Agrupe recursos y búferes y texturas en grupos lógicos.
  Es conveniente llamar a cada proceso, el proceso es la canalización.
  El objeto de diseño del grupo de enlace debe pasarse aquí, que se puede inferir de la canalización, o el objeto de diseño del grupo de enlace en sí se puede pasar directamente
  */
})
 
const commandEncoder = device.createCommandEncoder() // Crear objeto codificador de búfer de comando
const renderPassEncoder = commandEncoder.beginRenderPass() // Iniciar un codificador de paso de renderizado
// También puedes iniciar un canal de cálculo
// const computePassEncoder = commandEncoder.beginComputePass({ /* ... */ })
 
/*
Tomando el paso de renderizado como ejemplo, use renderPassEncoder para completar la configuración de secuencia de lo que se debe hacer en este paso, por ejemplo
*/
 
// El primer dibujo, establece la tubería 0, el grupo de enlace 0, el grupo de enlace 1, vbo y activa el dibujo
renderPassEncoder.setPipeline(renderPipeline_0)
renderPassEncoder.setBindGroup(0, bindGroup_0)
renderPassEncoder.setBindGroup(1, bindGroup_1)
renderPassEncoder.setVertexBuffer(0, vbo, 0, tamaño)
renderPassEncoder.draw(vérticeCount)
 
// El segundo dibujo, establece la canalización 1, otro grupo de enlace y activa el dibujo
renderPassEncoder.setPipeline(renderPipeline_1)
renderPassEncoder.setBindGroup(1, otro_bindGroup)
renderPassEncoder.draw(vérticeCount)
 
//Codificación del canal final
renderPassEncoder.endPass()
 
//Finalmente enviado a la cola, es decir, las llamadas a commandEncoder finalizan para completar la codificación y devuelven un búfer de comando navigator.gpu.requestAdapter device.queue.submit([
  comandoEncoder.finish()
])
y

Resumen de ventajas de WebGPU

WebGPU es un nuevo estándar web diseñado para proporcionar a los desarrolladores web una interfaz de programación de gráficos más eficiente, flexible y moderna. WebGPU tiene las siguientes ventajas:

  1. Más eficiente: WebGPU utiliza la GPU para acelerar el procesamiento de gráficos, proporcionando un mayor rendimiento que las API de gráficos web tradicionales.

  2. Más flexible: WebGPU proporciona un modelo de programación más flexible, lo que permite a los desarrolladores controlar más fácilmente las operaciones de la GPU y explotar mejor el paralelismo de la GPU.

  3. Más moderno: WebGPU aprovecha las capacidades de las GPU modernas, incluidas características como cálculo asíncrono, compresión de texturas y modularidad de sombreado, lo que lo hace ideal para desarrollar aplicaciones web más modernas.

  4. Multiplataforma: WebGPU es un estándar multiplataforma que puede ejecutarse en cualquier dispositivo que admita WebGPU, incluidos navegadores de escritorio, dispositivos móviles y pantallas VR/AR montadas en cascos.

  5. Integre con la Web: WebGPU está diseñado para el desarrollo web, por lo que se integra perfectamente con otras tecnologías web, incluidas WebGL, WebVR y WebXR.

¿Cuáles son las ventajas de WebGPU sobre WebGL?

WebGPU y WebGL son dos API de gráficos web diferentes y tienen las siguientes ventajas:

  • Rendimiento: WebGPU puede aprovechar mejor la aceleración del hardware y, por lo tanto, proporcionar un mayor rendimiento gráfico, especialmente al procesar grandes cantidades de datos. En comparación, WebGL tiene un rendimiento menor.

  • Características: WebGPU proporciona más funciones y flexibilidad, como compatibilidad con sombreadores de cálculo, suavizado y otras tecnologías de renderizado avanzadas. WebGL tiene relativamente pocas funciones y está limitado por el antiguo estándar OpenGL ES.

  • Diseño: WebGPU está diseñado en base a una API de gráficos moderna, que es más escalable y fácil de mantener, mientras que WebGL está diseñado en base al antiguo estándar OpenGL ES.

En términos generales, WebGPU es más adecuado para escenas que requieren alto rendimiento y tecnología de renderizado avanzada, mientras que WebGL es más adecuado para algunas necesidades simples de renderizado 2D o 3D.

¿Cuáles son las diferencias entre WebGPU y WebAssembly?

WebGPU y WebAssembly son dos tecnologías diferentes y sus principales diferencias son las siguientes:

  1. WebGPU es una nueva API para la representación de gráficos de alto rendimiento en navegadores web, mientras que WebAssembly es un formato de código de bytes para ejecutar aplicaciones informáticas de alto rendimiento en navegadores web.

  2. WebGPU tiene como objetivo proporcionar un mejor rendimiento y eficiencia que las API de gráficos web existentes, mientras que WebAssembly tiene como objetivo proporcionar una ejecución más rápida que JavaScript y una mejor portabilidad y seguridad.

  3. WebGPU requiere soporte de hardware y solo se puede usar en navegadores que admitan WebGPU, mientras que WebAssembly se puede usar en cualquier navegador web que lo admita.

  4. Aunque tanto WebGPU como WebAssembly ofrecen algunas características y beneficios nuevos, no son mutuamente excluyentes y, de hecho, pueden usarse juntos para lograr aplicaciones web más eficientes y flexibles.

Guess you like

Origin blog.csdn.net/o67f2wpkvdf3bpe8/article/details/131137934