WebGL - Mise à l'échelle

Dans ce chapitre, nous prendrons un exemple pour montrer comment modifier l'échelle d'un triangle à l'aide de WebGL.

Mise à l'échelle

La mise à l'échelle n'est rien d'autre que l'augmentation ou la diminution de la taille d'un objet. Par exemple, si un triangle a des sommets de la taille [a, b, c], alors le triangle avec les sommets [2a, 2b, 2c] sera le double de sa taille. Par conséquent, pour mettre à l'échelle un triangle, vous devez multiplier chaque sommet avec le facteur de mise à l'échelle. Vous pouvez également mettre à l'échelle un sommet particulier.

Pour mettre à l'échelle un triangle, dans le vertex shader du programme, nous créons une matrice uniforme et multiplions les valeurs de coordonnées avec cette matrice. Plus tard, nous passons une matrice diagonale 4 × 4 ayant les facteurs d'échelle des coordonnées x, y, z dans les positions diagonales (dernière position diagonale 1).

Étapes requises

Les étapes suivantes sont nécessaires pour créer une application WebGL pour mettre à l'échelle un triangle.

Step 1 − Prepare the Canvas and Get the WebGL Rendering Context

Dans cette étape, nous obtenons l'objet de contexte de rendu WebGL en utilisant getContext().

Step 2 − Define the Geometry and Store it in the Buffer Objects

Puisque nous dessinons un triangle, nous devons passer trois sommets du triangle et les stocker dans des tampons.

var vertices = [ -0.5,0.5,0.0, -0.5,-0.5,0.0, 0.5,-0.5,0.0, ];

Step 3 − Create and Compile the Shader Programs

Dans cette étape, vous devez écrire les programmes vertex shader et fragment shader, les compiler et créer un programme combiné en liant ces deux programmes.

  • Vertex Shader- Dans le vertex shader du programme, nous définissons un attribut vectoriel pour stocker les coordonnées 3D. Parallèlement, nous définissons une matrice uniforme pour stocker les facteurs de mise à l'échelle, et enfin, nous multiplions ces deux valeurs et les affectonsgl_position qui contient la position finale des sommets.

var vertCode =
   'attribute vec4 coordinates;' +
   'uniform mat4 u_xformMatrix;' +
   'void main(void) {' +
      ' gl_Position = u_xformMatrix * coordinates;' +
   '}';
  • Fragment Shader - Dans le shader de fragment, nous attribuons simplement la couleur du fragment au gl_FragColor variable.

var fragCode = 'void main(void) {' +' gl_FragColor = vec4(1, 0.5, 0.0, 1);' +'}';

Step 4 − Associate the Shader Programs with the Buffer Objects

Dans cette étape, nous associons les objets tampons au programme shader.

Step 5 − Drawing the Required Object

Puisque nous dessinons le triangle à l'aide d'indices, nous utilisons le drawArrays()méthode. A cette méthode, il faut passer le nombre de sommets / éléments à considérer. Puisque nous dessinons un triangle, nous passerons 3 comme paramètre.

gl.drawArrays(gl.TRIANGLES, 0, 3);

Exemple - Mettre à l'échelle un triangle

L'exemple suivant montre comment mettre à l'échelle un triangle -

<!doctype html>
<html>
   <body>
      <canvas width = "300" height = "300" id = "my_Canvas"></canvas>

      <script>
         /*=================Creating a canvas=========================*/
         var canvas = document.getElementById('my_Canvas');
         gl = canvas.getContext('experimental-webgl'); 

         /*===========Defining and storing the geometry==============*/
         var vertices =  [
            -0.5,0.5,0.0, 	
            -0.5,-0.5,0.0, 	
            0.5,-0.5,0.0,   
         ];

         //Create an empty buffer object and store vertex data

         var vertex_buffer = gl.createBuffer();                                                     
         gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);                                                
         gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);           
         gl.bindBuffer(gl.ARRAY_BUFFER, null);  

         /*========================Shaders============================*/

         //Vertex shader source code
         var vertCode =
            'attribute vec4 coordinates;' + 
            'uniform mat4 u_xformMatrix;' +
            'void main(void) {' +
               '  gl_Position = u_xformMatrix * coordinates;' +
            '}';

         //Create a vertex shader program object and compile it                
         var vertShader = gl.createShader(gl.VERTEX_SHADER);
         gl.shaderSource(vertShader, vertCode);
         gl.compileShader(vertShader);

         //fragment shader source code
         var fragCode =
            'void main(void) {' +
               '   gl_FragColor = vec4(0.0, 0.0, 0.0, 0.1);' +
            '}';

         //Create a fragment shader program object and compile it 
         var fragShader = gl.createShader(gl.FRAGMENT_SHADER);
         gl.shaderSource(fragShader, fragCode);
         gl.compileShader(fragShader);

         //Create and use combiened shader program
         var shaderProgram = gl.createProgram();
         gl.attachShader(shaderProgram, vertShader);
         gl.attachShader(shaderProgram, fragShader);
         gl.linkProgram(shaderProgram);

         gl.useProgram(shaderProgram); 

         /*===================scaling==========================*/

         var Sx = 1.0, Sy = 1.5, Sz = 1.0;
         var xformMatrix = new Float32Array([
            Sx,   0.0,  0.0,  0.0,
            0.0,  Sy,   0.0,  0.0,
            0.0,  0.0,  Sz,   0.0,
            0.0,  0.0,  0.0,  1.0  
         ]);

         var u_xformMatrix = gl.getUniformLocation(shaderProgram, 'u_xformMatrix');
         gl.uniformMatrix4fv(u_xformMatrix, false, xformMatrix);

         /* ===========Associating shaders to buffer objects============*/
         gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);   

         var coordinatesVar = gl.getAttribLocation(shaderProgram, "coordinates"); 
         gl.vertexAttribPointer(coordinatesVar, 3, gl.FLOAT, false, 0, 0);  
         gl.enableVertexAttribArray(coordinatesVar);

         /*=================Drawing the Quad========================*/ 
         gl.clearColor(0.5, 0.5, 0.5, 0.9);
         gl.enable(gl.DEPTH_TEST);

         gl.clear(gl.COLOR_BUFFER_BIT);
         gl.viewport(0,0,canvas.width,canvas.height);
         gl.drawArrays(gl.TRIANGLES, 0, 3);
      </script>
   </body>
</html>

Si vous exécutez cet exemple, il produira la sortie suivante -