WebGL - Couleurs

Dans tous nos exemples précédents, nous avons appliqué une couleur à l'objet en attribuant une valeur de couleur souhaitée au gl_FragColorvariable. En plus de cela, nous pouvons définir des couleurs pour chaque sommet - tout comme les coordonnées et les indices de sommet. Ce chapitre prend un exemple pour montrer comment appliquer des couleurs à un quadrilatère à l'aide de WebGL.

Application de couleurs

Pour appliquer des couleurs, vous devez définir les couleurs de chaque sommet à l'aide des valeurs RVB, dans un tableau JavaScript. Vous pouvez attribuer les mêmes valeurs à tous les sommets pour avoir une couleur unique à l'objet. Après avoir défini les couleurs, vous devez créer un tampon de couleur, y stocker ces valeurs et l'associer aux attributs de vertex shader.

Dans le vertex shader, avec l'attribut de coordonnées (qui contient la position des sommets), nous définissons un attribute et un varying pour gérer les couleurs.

le color l'attribut contient la valeur de couleur par sommet, et varyingest la variable qui est transmise en entrée au shader de fragment. Par conséquent, nous devons attribuer lecolor valeur à varying.

Dans le shader de fragment, le varying qui contient la valeur de couleur est assignée à gl_FragColor, qui contient la couleur finale de l'objet.

Étapes pour appliquer les couleurs

Les étapes suivantes sont nécessaires pour créer une application WebGL pour dessiner un Quad et lui appliquer des couleurs.

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

Un carré peut être dessiné à l'aide de deux triangles. Par conséquent, dans cet exemple, nous fournissons les sommets de deux triangles (avec une arête commune) et des indices. Puisque nous voulons lui appliquer des couleurs, une variable contenant les valeurs de couleur est également définie et les valeurs de couleur pour chacune (rouge, bleu, vert et rose) lui sont affectées.

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

var colors = [ 0,0,1, 1,0,0, 0,1,0, 1,0,1,];
indices = [3,2,1,3,1,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 des attributs vectoriels pour stocker les coordonnées 3D (position), et la couleur de chaque sommet. UNEvaringest déclarée pour transmettre les valeurs de couleur du vertex shader au fragment shader. Et enfin, la valeur stockée dans l'attribut de couleur est affectée àvarying.

var vertCode = 'attribute vec3 coordinates;'+
   'attribute vec3 color;'+
   'varying vec3 vColor;'+
	
   'void main(void) {' +
      ' gl_Position = vec4(coordinates, 1.0);' +
      'vColor = color;'+
   '}';
  • Fragment Shader - Dans le fragment shader, nous attribuons le varying à la gl_FragColor variable.

var fragCode = 'precision mediump float;'+
   'varying vec3 vColor;'+
   'void main(void) {'+
      'gl_FragColor = vec4(vColor, 1.);'+
   '}';

Step 4 − Associate the Shader Programs with the Buffer Objects

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

Step 5 − Drawing the Required Object

Puisque nous dessinons deux triangles qui formeront un quad, à l'aide d'indices, nous utiliserons la méthode drawElements(). A cette méthode, il faut passer le nombre d'indices. La valeur deindices.length indique le nombre d'indices.

gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_SHORT,0);

Exemple - Application de la couleur

Le programme suivant montre comment dessiner un quad à l'aide de l'application WebGL et lui appliquer des couleurs.

<!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,
            0.5,0.5,0.0
         ];

         var colors = [0,0,1, 1,0,0, 0,1,0, 1,0,1,];
         
         indices = [3,2,1,3,1,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);

         // Create an empty buffer object and store Index data
         var Index_Buffer = gl.createBuffer();
         gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, Index_Buffer);
         gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW);
         gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);

         // Create an empty buffer object and store color data
         var color_buffer = gl.createBuffer ();
         gl.bindBuffer(gl.ARRAY_BUFFER, color_buffer);
         gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW);

         /*======================= Shaders =======================*/
         
         // vertex shader source code
         var vertCode = 'attribute vec3 coordinates;'+
            'attribute vec3 color;'+
            'varying vec3 vColor;'+
            'void main(void) {' +
               ' gl_Position = vec4(coordinates, 1.0);' +
               'vColor = color;'+
            '}';
            
         // Create a vertex shader object
         var vertShader = gl.createShader(gl.VERTEX_SHADER);

         // Attach vertex shader source code
         gl.shaderSource(vertShader, vertCode);

         // Compile the vertex shader
         gl.compileShader(vertShader);


         // fragment shader source code
         var fragCode = 'precision mediump float;'+
            'varying vec3 vColor;'+
            'void main(void) {'+
               'gl_FragColor = vec4(vColor, 1.);'+
            '}';
            
         // Create fragment shader object
         var fragShader = gl.createShader(gl.FRAGMENT_SHADER);

         // Attach fragment shader source code
         gl.shaderSource(fragShader, fragCode);

         // Compile the fragmentt shader
         gl.compileShader(fragShader);

         // Create a shader program object to
         // store the combined shader program
         var shaderProgram = gl.createProgram();

         // Attach a vertex shader
         gl.attachShader(shaderProgram, vertShader);

         // Attach a fragment shader
         gl.attachShader(shaderProgram, fragShader);

         // Link both the programs
         gl.linkProgram(shaderProgram);

         // Use the combined shader program object
         gl.useProgram(shaderProgram);

         /* ======== Associating shaders to buffer objects =======*/

         // Bind vertex buffer object
         gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);

         // Bind index buffer object
         gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, Index_Buffer);

         // Get the attribute location
         var coord = gl.getAttribLocation(shaderProgram, "coordinates");

         // point an attribute to the currently bound VBO
         gl.vertexAttribPointer(coord, 3, gl.FLOAT, false, 0, 0);

         // Enable the attribute
         gl.enableVertexAttribArray(coord);

         // bind the color buffer
         gl.bindBuffer(gl.ARRAY_BUFFER, color_buffer);
         
         // get the attribute location
         var color = gl.getAttribLocation(shaderProgram, "color");
 
         // point attribute to the volor buffer object
         gl.vertexAttribPointer(color, 3, gl.FLOAT, false,0,0) ;
 
         // enable the color attribute
         gl.enableVertexAttribArray(color);

         /*============Drawing the Quad====================*/

         // Clear the canvas
         gl.clearColor(0.5, 0.5, 0.5, 0.9);

         // Enable the depth test
         gl.enable(gl.DEPTH_TEST);

         // Clear the color buffer bit
         gl.clear(gl.COLOR_BUFFER_BIT);

         // Set the view port
         gl.viewport(0,0,canvas.width,canvas.height);

         //Draw the triangle
         gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_SHORT,0);
      </script>
   </body>
</html>

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