Во всех наших предыдущих примерах мы применяли цвет к объекту, назначая желаемое значение цвета переменной 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 и применить к нему цвета.
<!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>
Если вы запустите этот пример, он выдаст следующий вывод: