[ Web Proxy ]
URL:
Viewing: https://developer.mozilla.org/fr/docs/Web/API/WebGL_API/Tutorial/Creating_3D_objects_using_WebGL [Back]  [Original]

Crer des objets 3D avec WebGL - Les API Web | MDN

Cette page a t traduite partir de l'anglais par la communaut. Vous pouvez contribuer en rejoignant la communaut francophone sur MDN Web Docs.

View in English Always switch to English

Crer des objets 3D avec WebGL

Transformons notre carr en trois dimensions en lui ajoutant cinq faces supplmentaires pour crer un cube. Pour faire cela efficacement, nous allons passer du dessin de sommets par l'appel direct de la mthode gl.drawArrays(), l'utilisation du tableau des sommets comme une table, et rfrencer les sommets individuels dans cette table pour dfinir les positions des sommets de chaque face, en appelant directement gl.drawElements().

Notez que chaque face ncessite quatre sommets pour la dfinir, mais que chaque sommet est partag entre trois faces. Nous pouvons donc passer beaucoup moins de donnes en faisant un tableau des 24 sommets, puis en rfrenant chaque sommet par son indice dans ce tableau, au lieu de passer des ensembles complets de coordonnes. Si vous vous demandez pourquoi nous avons besoin de 24 sommets, et non pas seulement de 8, c'est parce que chaque coin appartient trois faces de couleurs diffrentes, et qu'un sommet donn doit avoir une couleur spcifique - c'est pourquoi nous allons crer 3 copies de chaque sommet dans les trois couleurs diffrentes, une pour chaque face.

Dans cet article

Dfinir la position des sommets du cube

Tout d'abord, construisons le tampon des sommets du cube en mettant jour le code de initBuffer(). C'est sensiblement le mme que pour le carr, mais en plus long, du fait qu'il y a 24 sommets (4 par ct) :

js
const positions = [
  // Face avant
  -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0,

  // Face arrire
  -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0,

  // Face suprieure
  -1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0,

  // Face infrieure
  -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, -1.0, 1.0, -1.0, -1.0, 1.0,

  // Face droite
  1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0,

  // Face gauche
  -1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0, -1.0,
];

Du fait que nous avons ajout une composante z nos sommets, nous avons besoin de changer en 3 le numComponents de notre attribut vertexPosition.

js
// Indiquer  WebGL comment extraire les positions du tampon des
// positions dans l'attribut vertexPosition
{
  const numComponents = 3;
  ...
  gl.vertexAttribPointer(
    programInfo.attribLocations.vertexPosition,
    numComponents,
    type,
    normalize,
    stride,
    offset);
  gl.enableVertexAttribArray(
    programInfo.attribLocations.vertexPosition);
}

Dfinir les couleurs des sommets

Nous avons aussi besoin de construire un tableau des couleurs pour chacun des 24 sommets. Ce code commence par dfinir une couleur pour chaque face, puis il utilise une boucle pour assembler le tableau de toutes les couleurs pour chacun des sommets.

js
const faceColors = [
  [1.0, 1.0, 1.0, 1.0], // Face avant : blanc
  [1.0, 0.0, 0.0, 1.0], // Face arrire : rouge
  [0.0, 1.0, 0.0, 1.0], // Face suprieure : vert
  [0.0, 0.0, 1.0, 1.0], // Face infirieure : bleu
  [1.0, 1.0, 0.0, 1.0], // Face droite : jaune
  [1.0, 0.0, 1.0, 1.0], // Face gauche : violet
];

// Conversion du tableau des couleurs en une table pour tous les sommets

var colors = [];

for (j = 0; j < faceColors.length; j++) {
  const c = faceColors[j];

  // Rpter chaque couleur quatre fois pour les quatre sommets d'une face
  colors = colors.concat(c, c, c, c);
}

const colorBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW);

Dfinir le tableau des lments

Une fois que les tableaux des sommets sont gnrs, nous devons construire le tableau des lments.

js
  const indexBuffer = gl.createBuffer();
  gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);

  // Ce tableau dfinit chaque face comme deux triangles, en utilisant les
  // indices dans le tableau des sommets pour spcifier la position de chaque
  // triangle.

  const indices = [
    0,  1,  2,      0,  2,  3,    // avant
    4,  5,  6,      4,  6,  7,    // arrire
    8,  9,  10,     8,  10, 11,   // haut
    12, 13, 14,     12, 14, 15,   // bas
    16, 17, 18,     16, 18, 19,   // droite
    20, 21, 22,     20, 22, 23,   // gauche
  ];

  // Envoyer maintenant le tableau des lments  GL

  gl.bufferData(gl.ELEMENT_ARRAY_BUFFER,
      new Uint16Array(indices), gl.STATIC_DRAW);

  return {
    position: positionBuffer,
    color: colorBuffer,
    indices: indexBuffer,
  };
}

Le tableau indices dfinit chaque face comme tant une paire de triangles, en spcifiant chaque sommet du triangle comme un indice dans les tableaux des sommets du cube. Ainsi le cube est dcrit comme une collection de 12 triangles.

Dessiner le cube

Ensuite, nous devons ajouter du code notre fonction drawScene() pour dessiner le tampon des indices du cube, en ajoutant de nouveaux appels gl.bindBuffer() et gl.drawElements() :

js
// Indiquer  WebGL quels indices utiliser pour indexer les sommets
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, tampons.indices);

...

{
  const vertexCount = 36;
  const type = gl.UNSIGNED_SHORT;
  const offset = 0;
  gl.drawElements(gl.TRIANGLES, vertexCount, type, offset);
}

Du fait que chaque face de notre cube est compose de deux triangles, il y a 6 sommets par ct, soit 36 sommets au total dans le cube, mme si beaucoup d'entre eux sont des doublons.

Finalement, remplaons notre variable squareRotation par cubeRotation et ajoutons une seconde rotation autour de l'axe des x :

js
mat4.rotate(modelViewMatrix, modelViewMatrix, cubeRotation * 0.7, [0, 1, 0]);

ce stade, nous avons un cube anim en rotation, ses six faces ayant des couleurs assez vives.

Voir le code complet | Ouvrir cette dmo dans une nouvelle page


Web Proxy Viewer  |  New URL  |  Original Page