WebGL - Dịch

Cho đến nay, chúng ta đã thảo luận về cách vẽ các hình dạng khác nhau và áp dụng màu sắc cho chúng bằng cách sử dụng WebGL. Ở đây, trong chương này, chúng tôi sẽ lấy một ví dụ để chỉ ra cách dịch một tam giác.

Dịch

Bản dịch là một trong những affine transformationsdo WebGL cung cấp. Sử dụng phép tịnh tiến, chúng ta có thể di chuyển một tam giác (bất kỳ đối tượng nào) trên mặt phẳng xyz. Giả sử chúng ta có một tam giác [a, b, c] và chúng ta muốn di chuyển tam giác đến một vị trí cách trục X dương 5 đơn vị và 3 đơn vị đối với trục Y dương. Khi đó các đỉnh mới sẽ là [a + 5, b + 3, c + 0]. Điều đó có nghĩa là, để tịnh tiến tam giác, chúng ta cần thêm các khoảng cách tịnh tiến, giả sử, tx, ty, tz vào mỗi đỉnh.

Vì nó là một per-vertex operation, chúng ta có thể mang nó trong chương trình đổ bóng đỉnh.

Trong bộ đổ bóng đỉnh, cùng với thuộc tính, coordinates(giữ các vị trí đỉnh), chúng tôi xác định một biến đồng nhất chứa các khoảng cách tịnh tiến (x, y, z). Sau đó, chúng tôi thêm biến thống nhất này vào biến tọa độ và gán kết quả chogl_Position Biến đổi.

Note - Vì vertex shader sẽ được chạy trên mỗi đỉnh, nên tất cả các đỉnh của tam giác sẽ được dịch.

Các bước để dịch một tam giác

Các bước sau là bắt buộc để tạo một ứng dụng WebGL để vẽ một hình tam giác và sau đó dịch nó sang một vị trí mới.

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

Vì chúng ta đang vẽ một tam giác, chúng ta phải đi qua ba đỉnh của tam giác và lưu chúng trong bộ đệm.

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

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 một thuộc tính vector để lưu trữ tọa độ 3D. Cùng với nó, chúng tôi xác định một biến thống nhất để lưu trữ khoảng cách dịch và cuối cùng, chúng tôi thêm hai giá trị này và gán nó chogl_position mà giữ vị trí cuối cùng của các đỉnh.

var vertCode =
   'attribute vec4 coordinates;' +
   'uniform vec4 translation;'+
   'void main(void) {' +
      ' gl_Position = coordinates + translation;' +
   '}';
  • Fragment Shader - Trong bộ đổ bóng phân mảnh, chúng ta chỉ cần gán màu phân mảnh cho biến 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

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

Step 5 − Drawing the Required Object

Vì chúng tôi đang vẽ tam giác bằng cách sử dụng các chỉ số, chúng tôi sẽ sử dụng phương pháp drawArrays(). Đối với phương pháp này, chúng ta phải truyền số lượng đỉnh / phần tử được xem xét. Vì chúng ta đang vẽ một tam giác, chúng ta sẽ chuyển 3 làm tham số.

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

Ví dụ - Dịch một Tam giác

Ví dụ sau đây cho thấy cách tịnh tiến một tam giác trên mặt phẳng 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>

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