Учебники

WebGL — Цвета

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

Применение цветов

Чтобы применить цвета, вы должны определить цвета для каждой вершины, используя значения RGB в массиве JavaScript. Вы можете назначить одинаковые значения всем вершинам, чтобы иметь уникальный цвет для объекта. После определения цветов вы должны создать цветовой буфер и сохранить в нем эти значения, а также связать его с атрибутами вершинного шейдера.

В вершинном шейдере, вместе с атрибутом координат (который содержит положение вершин), мы определяем атрибут и переменную для обработки цветов.

Атрибут color содержит значение цвета для каждой вершины, а переменная — это переменная, которая передается в качестве входных данных фрагментному шейдеру. Поэтому мы должны присвоить значение цвета переменному .

В фрагментном шейдере переменная , содержащая значение цвета, присваивается gl_FragColor , который содержит окончательный цвет объекта.

Шаги, чтобы применить цвета

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

Шаг 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,
   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]; 

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

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

  • Вершинный шейдер — В вершинном шейдере программы мы определяем векторные атрибуты для хранения трехмерных координат (положения) и цвета каждой вершины. Переменная переменная объявляется для передачи значений цвета из вершинного шейдера во фрагментный шейдер. И, наконец, значение, хранимое в атрибуте цвета, присваивается переменному .

Вершинный шейдер — В вершинном шейдере программы мы определяем векторные атрибуты для хранения трехмерных координат (положения) и цвета каждой вершины. Переменная переменная объявляется для передачи значений цвета из вершинного шейдера во фрагментный шейдер. И, наконец, значение, хранимое в атрибуте цвета, присваивается переменному .

var vertCode = 'attribute vec3 coordinates;'+
   'attribute vec3 color;'+
   'varying vec3 vColor;'+
	
   'void main(void) {' +
      ' gl_Position = vec4(coordinates, 1.0);' +
      'vColor = color;'+
   '}';
  • Фрагментный шейдер — В фрагментном шейдере мы присваиваем изменение переменной gl_FragColor .

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

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

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

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

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

Поскольку мы рисуем два треугольника, которые образуют квад, используя индексы, мы будем использовать метод drawElements () . Для этого метода мы должны передать количество индексов. Значение indices.length указывает количество индексов.

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

Пример — применение цвета

Следующая программа демонстрирует, как нарисовать квад с помощью приложения WebGL и применить к нему цвета.

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

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