WebGL - Màu sắc

Trong tất cả các ví dụ trước đây, chúng tôi đã áp dụng màu cho đối tượng bằng cách gán giá trị màu mong muốn cho gl_FragColorBiến đổi. Ngoài ra, chúng ta có thể xác định màu sắc cho từng đỉnh - giống như tọa độ và chỉ số của đỉnh. Chương này lấy một ví dụ minh họa cách áp dụng màu sắc cho một hình tứ giác bằng cách sử dụng WebGL.

Áp dụng màu sắc

Để áp dụng màu, bạn phải xác định màu cho từng đỉnh bằng cách sử dụng các giá trị RGB, trong mảng JavaScript. Bạn có thể gán các giá trị giống nhau cho tất cả các đỉnh để có một màu duy nhất cho đối tượng. Sau khi xác định màu sắc, bạn phải tạo một bộ đệm màu và lưu trữ các giá trị này trong đó, đồng thời liên kết nó với các thuộc tính đổ bóng đỉnh.

Trong bộ đổ bóng đỉnh, cùng với thuộc tính tọa độ (giữ vị trí của các đỉnh), chúng tôi xác định một attribute và một varying để xử lý màu sắc.

Các color thuộc tính giữ giá trị màu trên mỗi đỉnh và varyinglà biến được chuyển làm đầu vào cho trình đổ bóng phân mảnh. Do đó, chúng ta phải chỉ địnhcolor có giá trị đối với varying.

Trong trình đổ bóng mảnh, varying giữ giá trị màu được gán cho gl_FragColor, giữ màu cuối cùng của đối tượng.

Các bước áp dụng màu

Các bước sau là cần thiết để tạo một ứng dụng WebGL để vẽ một Quad và áp dụng màu sắc cho nó.

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

Trong bước này, chúng tôi lấy đối tượng ngữ cảnh Kết xuất WebGL bằng cách sử dụng getContext().

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

Một hình vuông có thể được vẽ bằng cách sử dụng hai hình tam giác. Do đó, trong ví dụ này, chúng tôi cung cấp các đỉnh của hai tam giác (với một cạnh chung) và các chỉ số. Vì chúng ta muốn áp dụng màu sắc cho nó, một biến chứa các giá trị màu cũng được xác định và các giá trị màu cho mỗi (Đỏ, Xanh lam, Xanh lục và Hồng) được chỉ định cho nó.

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

Trong bước này, bạn cần viết chương trình tô bóng đỉnh và tô bóng phân mảnh, biên dịch chúng và tạo một chương trình kết hợp bằng cách liên kết hai chương trình này.

  • Vertex Shader- Trong phần đổ bóng đỉnh của chương trình, chúng ta xác định các thuộc tính vector để lưu trữ tọa độ 3D (vị trí), và màu sắc của mỗi đỉnh. Avaringbiến được khai báo để chuyển các giá trị màu từ bộ đổ bóng đỉnh đến bộ đổ bóng phân đoạn. Và cuối cùng, giá trị được lưu trữ trong thuộc tính color được gán chovarying.

var vertCode = 'attribute vec3 coordinates;'+
   'attribute vec3 color;'+
   'varying vec3 vColor;'+
	
   'void main(void) {' +
      ' gl_Position = vec4(coordinates, 1.0);' +
      'vColor = color;'+
   '}';
  • Fragment Shader - Trong trình đổ bóng phân mảnh, chúng tôi chỉ định varying đến gl_FragColor Biến đổi.

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

Trong bước này, chúng tôi liên kết các đối tượng đệm và chương trình đổ bóng.

Step 5 − Drawing the Required Object

Vì chúng ta đang vẽ hai tam giác sẽ tạo thành một tứ giác, bằng cách sử dụng các chỉ số, chúng ta sẽ sử dụng phương pháp drawElements(). Đối với phương pháp này, chúng ta phải chuyển số chỉ số. Giá trị củaindices.length cho biết số lượng chỉ số.

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

Ví dụ - Áp dụng màu

Chương trình sau đây trình bày cách vẽ một quad bằng ứng dụng WebGL và áp dụng màu sắc cho nó.

<!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>

Nếu bạn chạy ví dụ này, nó sẽ tạo ra kết quả sau: