WebGL - Traduction

Jusqu'à présent, nous avons expliqué comment dessiner différentes formes et leur appliquer des couleurs à l'aide de WebGL. Ici, dans ce chapitre, nous prendrons un exemple pour montrer comment traduire un triangle.

Traduction

La traduction est l'une des affine transformationsfourni par WebGL. En utilisant la translation, nous pouvons déplacer un triangle (n'importe quel objet) sur le plan xyz. Supposons que nous ayons un triangle [a, b, c] et que nous voulions déplacer le triangle vers une position qui est de 5 unités vers l'axe X positif et de 3 unités vers l'axe Y positif. Alors les nouveaux sommets seraient [a + 5, b + 3, c + 0]. Cela signifie que pour traduire le triangle, nous devons ajouter les distances de translation, disons, tx, ty, tz à chaque sommet.

Puisqu'il s'agit d'un per-vertex operation, nous pouvons le transporter dans le programme vertex shader.

Dans le vertex shader, avec l'attribut, coordinates(qui contiennent les positions des sommets), nous définissons une variable uniforme qui contient les distances de translation (x, y, z). Plus tard, nous ajoutons cette variable uniforme à la variable de coordonnées et affectons le résultat augl_Position variable.

Note - Puisque le vertex shader sera exécuté sur chaque sommet, tous les sommets du triangle seront traduits.

Étapes pour traduire un triangle

Les étapes suivantes sont nécessaires pour créer une application WebGL afin de dessiner un triangle, puis de le traduire vers une nouvelle position.

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 variable uniforme pour stocker les distances de translation, et enfin, nous ajoutons ces deux valeurs et les affectons àgl_position qui contient la position finale des sommets.

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

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

Step 4 − Associate the Shader Programs to 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 utiliserons la méthode drawArrays(). 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 - Traduire un triangle

L'exemple suivant montre comment traduire un triangle sur le plan xyz.

<!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(); 
			
         //Create a new buffer
         gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);   
			
         //bind it to the current buffer			
         gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW); 
			
         // Pass the buffer data
         gl.bindBuffer(gl.ARRAY_BUFFER, null);  
            
         /*========================Shaders============================*/
            
         //vertex shader source code 
         var vertCode =
            'attribute vec4 coordinates;' + 
            'uniform vec4 translation;'+
            'void main(void) {' +
               '  gl_Position = coordinates + translation;' +
            '}';
            
         //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);
   
         /* ===========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); 
   
         /* ==========translation======================================*/
         var Tx = 0.5, Ty = 0.5, Tz = 0.0;
         var translation = gl.getUniformLocation(shaderProgram, 'translation');
         gl.uniform4f(translation, Tx, Ty, Tz, 0.0);
 
         /*=================Drawing the riangle and transforming it========================*/ 

         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 -