Créer des objets 3D avec WebGL

Transformons notre carré en trois dimensions en lui ajoutant cinq faces supplémentaires pour créer un cube. Pour faire cela efficacement, nous allons passer au dessin de sommets directement en appellant la méthode gl.drawArray() et utiliser un tableau de sommets et y référencer les sommets individuels pour définir les positions de chaque face en appelant gl.drawElements().

Considérez : chaque face nécessite quatre sommets pour être définie, mais chaque sommet est partagé entre trois faces. Nous pouvons donc passer beaucoup moins de données en faisant une liste de 24 sommets, et alors se référer à chaque sommet par son index dans cette liste plutôt que une collection de coordonées. Si vous vous demandez pourquoi nous avons besoin de 24 sommets, et non pas 8, c'est parce que chaque coin appartient à trois faces de différentes couleurs, et qu'un sommet doit avoir une couleur spécifique - c'est pourquoi nous allons créer 3 copies de chaque sommet dans trois couleurs différentes, un pour chaque face.

Définir la position des sommets du cube

Premièrement, construisons le buffer des sommets du cube en mettant à jour le code dans initBuffer(). C'est à peu près le même que pour le carré, mais en plus long étant donné qu'il y a 24 sommets (4 par côté) :

  var vertices = [
    // Front face
    -1.0, -1.0,  1.0,
     1.0, -1.0,  1.0,
     1.0,  1.0,  1.0,
    -1.0,  1.0,  1.0,
    
    // Back face
    -1.0, -1.0, -1.0,
    -1.0,  1.0, -1.0,
     1.0,  1.0, -1.0,
     1.0, -1.0, -1.0,
    
    // Top face
    -1.0,  1.0, -1.0,
    -1.0,  1.0,  1.0,
     1.0,  1.0,  1.0,
     1.0,  1.0, -1.0,
    
    // Bottom face
    -1.0, -1.0, -1.0,
     1.0, -1.0, -1.0,
     1.0, -1.0,  1.0,
    -1.0, -1.0,  1.0,
    
    // Right face
     1.0, -1.0, -1.0,
     1.0,  1.0, -1.0,
     1.0,  1.0,  1.0,
     1.0, -1.0,  1.0,
    
    // Left face
    -1.0, -1.0, -1.0,
    -1.0, -1.0,  1.0,
    -1.0,  1.0,  1.0,
    -1.0,  1.0, -1.0
  ];

Définir la couleur des sommets

Nous avons aussi besoin de construire un tableau de couleurs pour chacun des 24 sommets. Ce code commence en définissant une color pour chaque face puis utilise une boucle pour assembler le tableau detoutes les couleurs pour chaque sommet.

  var colors = [
    [1.0,  1.0,  1.0,  1.0],    // Front face: white
    [1.0,  0.0,  0.0,  1.0],    // Back face: red
    [0.0,  1.0,  0.0,  1.0],    // Top face: green
    [0.0,  0.0,  1.0,  1.0],    // Bottom face: blue
    [1.0,  1.0,  0.0,  1.0],    // Right face: yellow
    [1.0,  0.0,  1.0,  1.0]     // Left face: purple
  ];
  
  var generatedColors = [];
  
  for (j=0; j<6; j++) {
    var c = colors[j];
    
    for (var i=0; i<4; i++) {
      generatedColors = generatedColors.concat(c);
    }
  }
  
  cubeVerticesColorBuffer = gl.createBuffer();
  gl.bindBuffer(gl.ARRAY_BUFFER, cubeVerticesColorBuffer);
  gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(generatedColors), gl.STATIC_DRAW);

Définir le tableau d'éléments

Quand le tableau de sommet est généré, nous devons construire le tableau d'éléments.

  cubeVerticesIndexBuffer = gl.createBuffer();
  gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVerticesIndexBuffer);
  
  // This array defines each face as two triangles, using the
  // indices into the vertex array to specify each triangle's
  // position.
  
  var cubeVertexIndices = [
    0,  1,  2,      0,  2,  3,    // front
    4,  5,  6,      4,  6,  7,    // back
    8,  9,  10,     8,  10, 11,   // top
    12, 13, 14,     12, 14, 15,   // bottom
    16, 17, 18,     16, 18, 19,   // right
    20, 21, 22,     20, 22, 23    // left
  ]
  
  // Now send the element array to GL
  
  gl.bufferData(gl.ELEMENT_ARRAY_BUFFER,
      new Uint16Array(cubeVertexIndices), gl.STATIC_DRAW);

Le tableau cubeVertexIndices défini chaque face comme une paire de triangles, en spécifiant chaque sommet du triangle en tant qu'un index dans le tableau de sommets du cube. Ainsi le cube est décrit comme une collection de 12 triangles.

Afficher le cube

Après nous devons ajouter du code à notre fonction drawScene() pour afficher le buffer d'index du cube, en ajoutant de nouveaux appels à bindBuffer() et drawElements() :

  gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVerticesIndexBuffer);
  setMatrixUniforms();
  gl.drawElements(gl.TRIANGLES, 36, gl.UNSIGNED_SHORT, 0);

À partir du moment où chaque face de notre cube est composée de deux triangles, il y a 6 sommets par côté, ou 36 sommets en tout dans le cube, même si beaucoup d'entre eux sont dupliqués. Cependant, dès que votre tableau est composé de simple entiers, ce n'est pas un tas de données désordoné à passer à chaque image d'une animation.

À ce stade, nous avons un cube animé qui rebondit et tourne, ses six faces sont vivement colorés. Si votre navigateur supporte WebGL, regardez la démo en action.

Étiquettes et contributeurs liés au document

Étiquettes : 
 Contributeurs à cette page : teoli, fscholz, Bat
 Dernière mise à jour par : teoli,