Tuesday, December 22, 2009

Lezione 2: aggiungiamo un po' di colore...

Nella seconda lezione vedremo come aggiungere un po' di colore alla nostra scena 3d; le uniche cose che cambieranno saranno gli shaders, l' initBuffers e la funzione drawScene. Il funzionamento della pipeline di rendering di webgl lo si puo' vedere nella seconda lezione sul sito originale. Qui mi addentrero' subito nel codice, spiegando qua' e la' come funziona la logica di visualizzazione.

the vertex shader.
ecco come cambia:
attribute vec3 aVertexPosition;
attribute vec4 aVertexColor;
uniform mat4 uMVMatrix;
uniform mat4 uPMatrix;
varying vec4 vColor;
void main(void) {
gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
vColor = aVertexColor;
}

Abbiamo due attribute, VertexPosition and aVertexColor, due uniforms non variabili called uMVMatrix anduPMatrix, e un output rappresentato dalla variabile vColor.
Nella parte centrale dello shader calcoleremo la gl_Position (che e' implicitamente definita come una variabile per ogni vertex shader) esattamente come abbiamo fatto nella lezione precedente.


Una volta eseguito questo per ogni vertice, viene eseguita un'interpolazione per generare il fragments, i quali vengono passati allo fragmaents shader:

varying vec4 vColor;
void main(void) {
gl_FragColor = vColor;
}

Qui prendiamo la variabile in input vColor , che contieneil colotr elaborato dall'interpolazione lineare e lo ritorna subito come colore per questo fragment.

Ci sono altre due modifiche. La prima nell' initShaders , dove ora otteniamo i riferimenti di due attributi invece di uno:

var shaderProgram;
var vertexPositionAttribute;
var vertexColorAttribute;
function initShaders() {
var fragmentShader = getShader(gl, "shader-fs");
var vertexShader = getShader(gl, "shader-vs");
shaderProgram = gl.createProgram();
gl.attachShader(shaderProgram, vertexShader);
gl.attachShader(shaderProgram, fragmentShader);
gl.linkProgram(shaderProgram);
if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
alert("Could not initialise shaders");
}
gl.useProgram(shaderProgram);
vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition");
gl.enableVertexAttribArray(vertexPositionAttribute);
vertexColorAttribute = gl.getAttribLocation(shaderProgram, "aVertexColor");
gl.enableVertexAttribArray(vertexColorAttribute);
}

Nella lezione precedente avevamo solo l'attributo per la posizione...

I cambiamenti nell' initBuffers consistono nel definire due variabili che conterranno il color buffer per il triangolo e per il quadrato:

var triangleVertexPositionBuffer;
var triangleVertexColorBuffer;
var squareVertexPositionBuffer;
var squareVertexColorBuffer;

Dopo avere creato il buffer che contiene la posizione del triangolo, specifichiamo anche il colore dei vertici:

function initBuffers() {
triangleVertexPositionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, triangleVertexPositionBuffer);
var vertices = [ 0.0, 1.0, 0.0, -1.0, -1.0, 0.0, 1.0, -1.0, 0.0 ];
gl.bufferData(gl.ARRAY_BUFFER, new WebGLFloatArray(vertices), gl.STATIC_DRAW);
triangleVertexPositionBuffer.itemSize = 3;
triangleVertexPositionBuffer.numItems = 3;
triangleVertexColorBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, triangleVertexColorBuffer);
var colors = [ 1.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0, ];
gl.bufferData(gl.ARRAY_BUFFER, new WebGLFloatArray(colors), gl.STATIC_DRAW);
triangleVertexColorBuffer.itemSize = 4; triangleVertexColorBuffer.numItems = 3;

E' evidente la principale differenza fra i buffer posizione e colore: mentre la posizione dei vertici e' definita da tre numeri(le coordinate x,y,z), il loro colore e' definito da quattro elementi(il colore rosso, il verde, il blue ed il canale alpha per la trasparenza).
E' ovvio che questa variazione influenza anche l' itemSize ...

Successivamente facciamo lo stesso per il quadrato ma questa volta useremo lo stesso colore per ogni vertice e per far questo useremo un ciclo:

squareVertexPositionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, squareVertexPositionBuffer);
vertices = [ 1.0, 1.0, 0.0, -1.0, 1.0, 0.0, 1.0, -1.0, 0.0, -1.0, -1.0, 0.0 ];
gl.bufferData(gl.ARRAY_BUFFER, new WebGLFloatArray(vertices), gl.STATIC_DRAW);
squareVertexPositionBuffer.itemSize = 3;
squareVertexPositionBuffer.numItems = 4;
squareVertexColorBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, squareVertexColorBuffer);
colors = [];
for (var i=0; i < 4; i++) {
colors = colors.concat([0.5, 0.5, 1.0, 1.0]);
}
gl.bufferData(gl.ARRAY_BUFFER, new WebGLFloatArray(colors), gl.STATIC_DRAW);
squareVertexColorBuffer.itemSize = 4;
squareVertexColorBuffer.numItems = 4;

Ora modifichiamo drawScene per usare le nuove informazioni sui colori:

function drawScene() {
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
perspective(45, 1.0, 0.1, 100.0);
loadIdentity();
mvTranslate([-1.5, 0.0, -7.0]);
gl.bindBuffer(gl.ARRAY_BUFFER,triangleVertexPositionBuffer);
gl.vertexAttribPointer(vertexPositionAttribute,triangleVertexPositionBuffer.itemSize,gl.FLOAT,false,0,0);
gl.bindBuffer(gl.ARRAY_BUFFER,triangleVertexColorBuffer);
gl.vertexAttribPointer(vertexColorAttribute,triangleVertexColorBuffer.itemSize,gl.FLOAT,false,0,0); setMatrixUniforms();
gl.drawArrays(gl.TRIANGLES,0,triangleVertexPositionBuffer.numItems);
mvTranslate([3.0, 0.0, 0.0]);
gl.bindBuffer(gl.ARRAY_BUFFER,squareVertexPositionBuffer);
gl.vertexAttribPointer(vertexPositionAttribute,squareVertexPositionBuffer.itemSize,gl.FLOAT,false, 0, 0);
gl.bindBuffer(gl.ARRAY_BUFFER,squareVertexColorBuffer);
gl.vertexAttribPointer(vertexColorAttribute,squareVertexColorBuffer.itemSize,gl.FLOAT,false,0,0);
setMatrixUniforms();
gl.drawArrays(gl.TRIANGLE_STRIP, 0, squareVertexPositionBuffer.numItems);
}

...thats all folks!
Ora abbiamo il colore nella nostra scena!

No comments:

Post a Comment