Учебники

WebGL — масштабирование

В этой главе мы рассмотрим пример, показывающий, как изменить масштаб треугольника с помощью WebGL.

пересчет

Масштабирование — это не что иное, как увеличение или уменьшение размера объекта. Например, если треугольник имеет вершины размера [a, b, c], то треугольник с вершинами [2a, 2b, 2c] будет в два раза больше своего размера. Поэтому, чтобы масштабировать треугольник, вы должны умножить каждую вершину на коэффициент масштабирования. Вы также можете масштабировать конкретную вершину.

Чтобы масштабировать треугольник, в вершинном шейдере программы мы создаем равномерную матрицу и умножаем значения координат на эту матрицу. Позже мы передаем диагональную матрицу 4 × 4 с масштабными коэффициентами координат x, y, z в диагональных позициях (последняя диагональная позиция 1).

Требуемые шаги

Следующие шаги необходимы для создания приложения WebGL для масштабирования треугольника.

Шаг 1. Подготовьте холст и получите контекст рендеринга WebGL

На этом шаге мы получаем объект контекста рендеринга WebGL, используя getContext () .

Шаг 2 — Определите геометрию и сохраните ее в буферных объектах

Поскольку мы рисуем треугольник, мы должны пропустить три вершины треугольника и сохранить их в буферах.

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

Шаг 3 — Создание и компиляция шейдерных программ

На этом этапе вам нужно написать программы вершинного шейдера и фрагментного шейдера, скомпилировать их и создать объединенную программу, соединив эти две программы.

  • Вершинный шейдер — В вершинном шейдере программы мы определяем векторный атрибут для хранения трехмерных координат. Наряду с этим, мы определяем равномерную матрицу для хранения коэффициентов масштабирования, и, наконец, мы умножаем эти два значения и присваиваем ей gl_position, которая содержит конечную позицию вершин.

Вершинный шейдер — В вершинном шейдере программы мы определяем векторный атрибут для хранения трехмерных координат. Наряду с этим, мы определяем равномерную матрицу для хранения коэффициентов масштабирования, и, наконец, мы умножаем эти два значения и присваиваем ей gl_position, которая содержит конечную позицию вершин.

var vertCode =
   'attribute vec4 coordinates;' +
   'uniform mat4 u_xformMatrix;' +
   'void main(void) {' +
      ' gl_Position = u_xformMatrix * coordinates;' +
   '}';
  • Фрагментный шейдер. В фрагментном шейдере мы просто назначаем цвет фрагмента переменной gl_FragColor .

Фрагментный шейдер. В фрагментном шейдере мы просто назначаем цвет фрагмента переменной gl_FragColor .

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

Шаг 4 — Связать шейдерные программы с объектами буфера

На этом этапе мы связываем объекты буфера с программой шейдера.

Шаг 5 — Рисование необходимого объекта

Поскольку мы рисуем треугольник с помощью индексов, мы используем метод drawArrays () . Для этого метода мы должны передать количество вершин / элементов, которые необходимо рассмотреть. Поскольку мы рисуем треугольник, мы передадим 3 в качестве параметра.

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

Пример — масштабирование треугольника

В следующем примере показано, как масштабировать треугольник —

Live Demo

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

Если вы запустите этот пример, он выдаст следующий вывод: