WebGL - Hola mundo

Este artículo está compilado a partir del intercambio técnico de Div Xia en Bump en 2022. Presenta brevemente el proceso de dibujar un gráfico básico en WebGL. Espero que después de que lo entiendas, puedas estar menos confundido al usar la biblioteca de renderizado 3D.

Cuatro herramientas de dibujo de páginas de uso común

En cuanto al dibujo de gráficos de páginas h5, hablamos principalmente de estas cuatro herramientas: html+css, svg, canvas2d, webgl.

imagen-20220321180951763

HTML+css es la herramienta de dibujo más común. Usar CSS para dibujar es lo mismo que escribir diseños de página. Al hacer gráficos, podemos usar CSS para definir el estilo del gráfico. Otros son para agregar elementos de acuerdo con los diferentes datos. diferente propiedades Tal desarrollo es muy amigable para escenarios con elementos de gráficos simples y pocos nodos de datos. No solo puede reducir la cantidad de herramientas de desarrollo, sino que tampoco necesita introducir bases de código redundantes. Sin embargo, a medida que se deben dibujar más y más gráficos en cualquier momento, el código css se vuelve cada vez más complicado Además, css no tiene una semántica lógica y el código se vuelve difícil de leer y mantener.

svg es un gráfico vectorial escalable, está estrechamente integrado con html y css, puede usar svg como el src de img, y puede usar css para manipular las propiedades de svg. svg y html son lenguajes de marcado de texto, y svg es más preciso que html Soporte de gráficos lineales, incluidos arcos, curvas bezier, etc. Al mismo tiempo, svg admite la sintaxis de las clases de multiplexación, lo que le permite dibujar muchos gráficos y el código aún conserva cierta legibilidad. Sin embargo, svg también tiene algunas desventajas. Porque un gráfico es un nodo de elemento. Cuando hay una gran cantidad de datos, la sobrecarga de cálculo de diseño y representación causada por la actualización de la página será muy grande. Además, el svg completo reúne la estructura, el estilo y la lógica de reutilización, lo que es un poco menos ordenado que los tres modos separados de html + css + js.

Canvas2D es el contexto de dibujo 2D de canvas. Proporciona una serie de métodos para modificar y dibujar imágenes en el área del lienzo. En comparación con el uso original de los dos primeros, muchos gráficos y colores de canvas2d necesitan ser modificados. implementadas y encapsuladas por sí mismas, lo que hace que sea mucho más difícil comenzar con esta herramienta, pero si haces bien estas cosas básicas, tendrás una herramienta de dibujo que cubre completamente las dos herramientas anteriores y es fácil de expandir.

webGL es también el contexto de dibujo de canvas, la implementación web de opengl es. La característica más importante es que la capa inferior puede usar directamente la capacidad paralela de gpu. Tiene una ventaja de alto rendimiento en la escena de procesamiento de una gran cantidad de gráficos, procesamiento a nivel de píxeles y objetos 3D.

Elección de cuatro herramientas.

imagen-20220321181126634

Cuando obtenemos un requisito de dibujo, primero debemos ver si los gráficos utilizados en este requisito son relativamente pocos y simples. Si es así, puede elegir directamente css para un desarrollo rápido. Si el gráfico es simple pero hay muchos, o el gráfico tiene algunos requisitos de curva, svg puede manejarlo rápidamente en este momento. Si la estructura entre los gráficos es compleja, elija canvas2d cuando el número sea grande. Y cuando el orden de magnitud de los gráficos alcanza una cierta cantidad, o cuando se necesita procesar cada píxel, o cuando se requiere una gran cantidad de pantallas 3D, tenemos que usar webgl.

imagen-20220321181247016

webgl 的 hola mundo

A diferencia de otras herramientas, hello world of webgl se puede hacer con una o dos líneas de código, pero tiene más de 40 líneas de código. Aunque esta cadena de código tiene métodos de encapsulación correspondientes en cada biblioteca de representación 3D, básicamente no necesitamos escribirla nosotros mismos, pero aprender esta cadena de código puede brindarnos una comprensión básica del proceso de dibujo webgl.

Hay cinco pasos en el dibujo webgl:

  1. Crear un contexto de dibujo webgl
  2. Cree programación de sombreadores, enlace al contexto gl (paralelo al paso 3)
  3. Cree los datos, colóquelos en el búfer y asocie el búfer con el contexto gl (paralelo al paso 2)
  4. gpu carga datos en caché
  5. dibujar gráficos

Crear contexto Webgl

const canvas = document.createElement('canvas');
const gl = canvas.getContext('webgl');
复制代码

Crear un programa de sombreado

const program = gl.createProgram();
gl.attachShader(program, /*某个着色器(下文的vertexShader)*/);
gl.linkProgram(program);
gl.useProgram(program);
复制代码

Un shader es un programa que se ejecuta en la gpu. Usamos glCreateProgram para crear un objeto de programa vacío y luego usamos glAttachShader para llenar este objeto de programa con código de shader compilado. Más adelante se discutirá qué es un sombreador y cómo compilarlo. Aquí, puede considerarse como el código compilado de una determinada función. Después de poner varias de estas funciones compiladas en el objeto del programa, cuando la gpu ejecuta el objeto del programa, tomará la información del píxel como parámetro de entrada y ejecutará las funciones en el objeto del programa a su vez.

Después de completar el código de sombreado, llame a glLinkProgram para vincular el programa al contexto gl y use glUseProgram para habilitar el programa.

A continuación, veamos cómo sale el código del sombreador.

const vertex = `
      attribute vec2 position;
      void main() {
        gl_Position = vec4(position, 1.0, 1.0);
      }
    `;
const vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, vertex);
gl.compileShader(vertexShader);
复制代码

首先我们定义了一个变量 vertex 并给他赋值一串其他语言格式的代码字符串,这个串代码是 glsl 代码,是一个跟 c 语言很相似的代码。代码接收一个传入的二维向量 position ,然后把他执行环境中的全局变量 gl_Position 设置成一个四维向量,这个四维向量前两个维度的分量是传入的二维向量。

接下来用 glCreateShader 创建一个着色器, VERTEX_SHADER 常量说明这个着色器是一个顶点着色器,跟顶点着色器对应的是片元着色器,顶点着色器处理做为确定点的位置。片元着色器则对顶点构成的图形中的所有位置进行逐个处理,比如两点画一个直线,两点是顶点着色器确定的,直线是片元着色器在确定了两个点的位置之后画的。

在我们创建了一个空的顶点着色器对象 vertexShader 之后,就可以用 glShaderSource 把前面的字符串代码放入顶点着色器对象中,然后用 glCompileShader 把这段代码编译成可执行文件。这个过程跟c语言的编译过程是相似的。

gl.attachShader(program, /*某个着色器(下文的vertexShader)*/);
gl.attachShader(program, vertexShader);
复制代码

完成这一步之后,就要回到上面写注释那里,把着色器对象关联到程序对象里。当然,你还得去写一个片元着色器,用同样的步骤把一个片元着色器也关联到程序对象里。

imagen-20220321181429987

将数据存入缓冲区

const points = new Float32Array([-1, -1, 0, 1, 1, -1]);
const bufferId = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, bufferId);
gl.bufferData(gl.ARRAY_BUFFER, points, gl.STATIC_DRAW);
复制代码

经过上文的操作之后,我们已经有了一个装载着着色器代码的程序对象,这个对象放到 gl 绘图上下文中被启用了。接下来,我们要定义的就是给这个程序用的数据。

在顶点着色器那一块,代码里面接受一个传入的二维向量,就是我们现在要定义的。首先定义一个类型化数组,初始化的时候放入6个数,这个6个数后面会被绘图程序分成三组放到三次顶点着色器调用中。另外,使用类型化数组是为了优化性能,让大量数据的情况下,数据占用的空间更小。

有了数据之后,调用 glCreateBuffer 创建一个缓冲区对象,用 glBindBuffer 把这个对象跟 gl 绘图上下文关联起来,最后调用 glBufferData 把 points 的数据放入缓冲区中。

gpu加载缓存中的数据

const vPosition = gl.getAttribLocation(program, "position");
gl.vertexAttribPointer(vPosition, 2, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(vPosition);
复制代码

En este paso, primero llamamos a glGetAttribLocation para obtener la posición de la variable position en el objeto del programa, llamamos a glVertexAttribPointer para establecer la longitud de esta variable en 2, establecemos el tipo en glFLOAT y usamos glEnableVertexAttribArray para habilitar esta variable

dibujar gráficos

gl.clear(gl.COLOR_BUFFER_BIT);
gl.drawArrays(gl.TRIANGLES, 0, points.length / 2);
复制代码

En el último paso, solo use glClear para borrar el búfer de color y luego use glDrawArrays para dibujar. Entre ellos, gl.TRIANGLES determina el rango de dibujo del fragment shader.Cuando este valor es gl.POINTS, el shader conectará los puntos en pares, y gl.TRIANGLES hace que el tercer punto forme un conjunto de triángulos de dibujo.

imagen-20220321181511519

De esta manera, se completa un hola mundo de webgl, y el triángulo de arriba es la imagen de salida de estas 40 líneas de código.

Resumir

Este programa tiene ciertas encapsulaciones en three.js y otros frameworks 3D y bibliotecas de herramientas.Es relativamente conveniente dibujar webgl a través de esas bibliotecas, pero si no conoce las operaciones más fundamentales de estas bibliotecas, es muy fácil. tienes un problema. Así que espero que este artículo pueda aumentar su comprensión de los aspectos subyacentes de la web 3D y brindarle alguna ayuda cuando aprenda estas bibliotecas de herramientas 3D.

Referencias

GPU vs Render Pipeline: ¿Cómo dibujar la geometría más simple con WebGL?

Supongo que te gusta

Origin juejin.im/post/7078615563106254879
Recomendado
Clasificación