WebGL et Hello World

Cet article est compilé à partir du partage technique de Div Xia dans Bump en 2022. Il présente brièvement le processus de dessin d'un graphique de base dans WebGL. J'espère qu'après l'avoir compris, vous pourrez être moins confus lors de l'utilisation de la bibliothèque de rendu 3D.

Quatre outils de dessin de page couramment utilisés

Concernant le dessin graphique des pages h5, on parle surtout de ces quatre outils : html+css, svg, canvas2d, webgl.

image-20220321180951763

HTML+css est l'outil de dessin le plus courant. Utiliser CSS pour dessiner revient à écrire des mises en page. Lors de la création de graphiques, nous pouvons utiliser CSS pour définir le style du graphique. D'autres consistent à ajouter des éléments en fonction des différentes données. Propriétés. Un tel développement est très convivial pour les scénarios avec des éléments graphiques simples et peu de nœuds de données. Non seulement vous pouvez réduire la quantité d'outils de développement, mais vous n'avez pas non plus besoin d'introduire des bases de code redondantes. Cependant, comme de plus en plus de graphiques doivent être dessinés à tout moment, le code css devient de plus en plus compliqué.De plus, css n'a pas de sémantique logique, et le code devient difficile à lire et à maintenir.

svg est un graphique vectoriel évolutif, il est étroitement intégré à html et css, vous pouvez utiliser svg comme src d'img, et vous pouvez utiliser css pour manipuler les propriétés de svg. svg et html sont tous deux des langages de balisage de texte, et svg est plus précis que html. Prise en charge des graphiques linéaires, y compris les arcs, les courbes de Bézier, etc. En même temps, svg supporte la syntaxe des classes de multiplexage, ce qui lui permet de dessiner beaucoup de graphismes, et le code conserve tout de même une certaine lisibilité. Cependant, svg présente également certains inconvénients. Parce qu'un graphe est un nœud d'élément. Lorsqu'il y a beaucoup de données, la surcharge de calcul de mise en page et de rendu causée par l'actualisation de la page sera très importante. De plus, le svg complet rassemble la structure, le style et la logique de réutilisation, ce qui est un peu moins ordonné que les trois modes distincts de html + css + js.

Canvas2D est le contexte de dessin 2D de canvas. Il fournit une série de méthodes pour modifier et dessiner des images dans la zone de canvas. Par rapport à l'utilisation prête à l'emploi des deux premiers, de nombreux graphiques et couleurs de canvas2d doivent être Cela rend beaucoup plus difficile le démarrage avec cet outil, mais si vous faites bien ces choses de base, vous aurez un outil de dessin qui couvre complètement les deux outils précédents et est facile à développer.

webGL est également le contexte de dessin de canvas, l'implémentation web d'opengl es. La plus grande caractéristique est que la couche inférieure peut directement utiliser la capacité parallèle du GPU. Il a un avantage de haute performance dans la scène du traitement d'un grand nombre de graphiques, de traitement au niveau des pixels et d'objets 3D.

Choix de quatre outils

image-20220321181126634

Lorsque nous obtenons une exigence de dessin, nous devons d'abord voir si les graphiques utilisés dans cette exigence sont relativement peu nombreux et simples. Si c'est le cas, vous pouvez directement choisir css pour un développement rapide. Si le graphique est simple mais qu'il y en a beaucoup, ou si le graphique a des exigences de courbe, svg peut rapidement y faire face à ce moment. Si la structure entre les graphiques est complexe, choisissez canvas2d lorsque le nombre est grand. Et lorsque l'ordre de grandeur des graphiques atteint une certaine quantité, ou lorsque chaque pixel doit être traité, ou lorsqu'un grand nombre d'affichages 3D sont nécessaires, nous devons utiliser webgl.

image-20220321181247016

webgl 的 bonjour le monde

Contrairement à d'autres outils, le hello world de webgl peut être fait avec une ou deux lignes de code, mais il a plus de 40 lignes de code. Bien que cette chaîne de code ait des méthodes d'encapsulation correspondantes dans chaque bibliothèque de rendu 3D, nous n'avons fondamentalement pas besoin de l'écrire nous-mêmes, mais apprendre cette chaîne de code peut nous donner une compréhension de base du processus de dessin webgl.

Il y a cinq étapes dans le dessin webgl :

  1. Créer un contexte de dessin WebGL
  2. Créer une programmation de shader, lien vers le contexte gl (parallèle à l'étape 3)
  3. Créez les données, mettez-les dans le tampon et associez le tampon au contexte gl (parallèle à l'étape 2)
  4. gpu charge les données dans le cache
  5. dessiner des graphiques

Créer un contexte Webgl

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

Créer un programme de shader

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

Un shader est un programme qui s'exécute sur le GPU. Nous utilisons glCreateProgram pour créer un objet programme vide, puis utilisons glAttachShader pour remplir cet objet programme avec le code compilé du shader. Ce qu'est un shader et comment le compiler sera discuté plus tard. Ici, il peut être considéré comme le code compilé d'une certaine fonction. Après avoir placé plusieurs de ces fonctions compilées dans l'objet programme, lorsque le gpu exécute l'objet programme, il prend les informations de pixel comme paramètre d'entrée et exécute les fonctions dans l'objet programme à tour de rôle.

Après avoir rempli le code du shader, appelez glLinkProgram pour lier le programme au contexte gl et utilisez glUseProgram pour activer le programme.

Ensuite, voyons comment le code du shader sort.

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);
复制代码

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

image-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);
复制代码

Dans cette étape, nous appelons d'abord glGetAttribLocation pour obtenir la position de la position de la variable dans l'objet programme, appelons glVertexAttribPointer pour définir la longueur de cette variable à 2, définissons le type sur glFLOAT et utilisons glEnableVertexAttribArray pour activer cette variable

dessiner des graphiques

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

À la dernière étape, utilisez simplement glClear pour effacer le tampon de couleur, puis utilisez glDrawArrays pour dessiner. Parmi eux, gl.TRIANGLES détermine la plage de dessin du shader de fragment. Lorsque cette valeur est gl.POINTS, le shader connectera les points par paires, et gl.TRIANGLES fait que le troisième point forme un ensemble de triangles de dessin

image-20220321181511519

De cette façon, un hello world of webgl est terminé, et le triangle ci-dessus est l'image sortie par ces 40 lignes de code.

Résumer

Ce programme a certaines encapsulations dans three.js et d'autres frameworks 3D et bibliothèques d'outils. Il est relativement pratique de dessiner webgl à travers ces bibliothèques, mais si vous ne connaissez pas les opérations les plus fondamentales de ces bibliothèques, il est très facile de se promener quand vous avez un problème. J'espère donc que cet article pourra accroître votre compréhension des aspects sous-jacents du Web 3D et vous fournir une aide lors de l'apprentissage de ces bibliothèques d'outils 3D.

Les références

GPU vs Render Pipeline : Comment dessiner la géométrie la plus simple avec WebGL ?

Je suppose que tu aimes

Origine juejin.im/post/7078615563106254879
conseillé
Classement