WebGL - Cores
Em todos os nossos exemplos anteriores, aplicamos cor ao objeto atribuindo um valor de cor desejado ao gl_FragColorvariável. Além disso, podemos definir cores para cada vértice - assim como as coordenadas e índices dos vértices. Este capítulo dá um exemplo para demonstrar como aplicar cores a um quadrilátero usando WebGL.
Aplicando Cores
Para aplicar cores, você deve definir as cores para cada vértice usando os valores RGB, em array JavaScript. Você pode atribuir os mesmos valores a todos os vértices para ter uma cor única para o objeto. Depois de definir as cores, você deve criar um buffer de cores e armazenar esses valores nele, e associá-lo aos atributos do sombreador de vértice.
No sombreador de vértice, junto com o atributo de coordenadas (que mantém a posição dos vértices), definimos um attribute e um varying para lidar com cores.
o color atributo contém o valor da cor por vértice, e varyingé a variável que é passada como entrada para o sombreador de fragmento. Portanto, temos que atribuir ocolor valor para varying.
No shader de fragmento, o varying que contém o valor da cor é atribuído a gl_FragColor, que contém a cor final do objeto.
Etapas para aplicar cores
As etapas a seguir são necessárias para criar um aplicativo WebGL para desenhar um Quad e aplicar cores a ele.
Step 1 − Prepare the Canvas and Get the WebGL Rendering Context
Nesta etapa, obtemos o objeto de contexto de renderização WebGL usando getContext().
Step 2 − Define the Geometry and Store it in the Buffer Objects
Um quadrado pode ser desenhado usando dois triângulos. Portanto, neste exemplo, fornecemos os vértices para dois triângulos (com uma aresta comum) e índices. Como queremos aplicar cores a ela, uma variável contendo os valores das cores também é definida e os valores das cores para cada uma (vermelho, azul, verde e rosa) são atribuídos a ela.
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
Nesta etapa, você precisa escrever os programas do sombreador de vértice e do sombreador de fragmento, compilá-los e criar um programa combinado vinculando esses dois programas.
Vertex Shader- No sombreador de vértice do programa, definimos atributos de vetor para armazenar coordenadas 3D (posição) e a cor de cada vértice. UMAvaringvariável é declarada para passar os valores de cor do sombreador de vértice para o sombreador de fragmento. E, finalmente, o valor armazenado no atributo de cor é atribuído avarying.
var vertCode = 'attribute vec3 coordinates;'+
'attribute vec3 color;'+
'varying vec3 vColor;'+
'void main(void) {' +
' gl_Position = vec4(coordinates, 1.0);' +
'vColor = color;'+
'}';
Fragment Shader - No shader de fragmento, atribuímos o varying ao gl_FragColor variável.
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
Nesta etapa, associamos os objetos buffer e o programa shader.
Step 5 − Drawing the Required Object
Como estamos desenhando dois triângulos que formarão um quadrante, usando índices, usaremos o método drawElements(). Para este método, temos que passar o número de índices. O valor deindices.length indica o número de índices.
gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_SHORT,0);
Exemplo - Aplicando Cor
O programa a seguir demonstra como desenhar um quadrante usando o aplicativo WebGL e aplicar cores a ele.
<!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>
Se você executar este exemplo, ele produzirá a seguinte saída -