Prossimo passo:
• Aggiungiamo attributi (per vertice!)
• Roadmap:
1. includiamoli nel buffer
2. facciamoli prendere dal vetex puller 3. usiamoli nel vertex shader
4. (verranno inteprolati autmaticamente nel rast.) 5. usiamo la loro interpolaz nel fragment shader
M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 6 / 1 7 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
ES: attributo COLORE
• Se abbiamo, per ogni vertice:
– X,Y,Z (geometria = attributo di indice 0)
– R,G,B (attributo colore = attributo di indice 1)
• Vari modi per formattare dati:
– in un buffer interleaved:
X 0 ,Y 0 ,Z 0 ,R 0 ,G 0 ,B 0 , X 1 ,Y 1 ,Z 1 ,R 1 ,G 1 ,B 1 ,…
– in buffer separati:
X 0 ,Y 0 ,Z 0 , X 1 ,Y 1 ,Z 1 , … R 0 ,G 0 ,B 0 , R 1 ,G 1 ,B 1 , – oppure anche:
X 0 ,X 1 , … Y 0 ,Y 1 ,… Z 0 ,Z 1 ,… R 0 ,R 1 ,… G 0 ,G 1 …
segliamo
questo
Attributo colore
• Un secondo indice, per un altro attributo
• Aggiungiamo i dati
– es: un vertice blu, uno verde, uno rosso:
M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 6 / 1 7 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
const positionAttribIndex = 0;
const rgbAttributeIndex = 1;
var positions = [
0.0, 0.0, 0.0,0.0,1.0, // 1st vertex 1.0, 0.0, 0.0,1.0,0.0, // 2nd vertex 0.0, 1.0, 1.0,0.0,0.0, // 3rd vertex ];
X 0 Y 0 R 0 G 0 B 0 X 1 Y 1 R 1 G 1 B 1 X 2 …
(globali, costanti)
Spieghiamo il formato dei buffer al Vertex Puller
• Attributo Posizione:
gl.vertexAttribPointer( positionAttributeIndex , 2, gl.FLOAT ,
false , 5*4, 0);
X 0 Y 0 R 0 G 0 B 0 X 1 Y 1 R 1 G 1 B 1 X 2 …
stride 5 x 4 bytes = n. elem = 2 (float)
Buffer:
stride
Spieghiamo il formato dei buffer al Vertex Puller
• Attributo Colore:
M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 6 / 1 7 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
X 0 Y 0 R 0 G 0 B 0 X 1 Y 1 R 1 G 1 B 1 X 2 …
Buffer:
gl.vertexAttribPointer( colorAttributeIndex , 3, gl.FLOAT ,
false , 5*4, 2*4);
stride 5 x 4 bytes = n. elem = 3 (floats)
offset 2 x 4 bytes =
stride
Negli shaders: prima
attribute vec2 aPosition;
void main(void) {
gl_Position = vec4( aPosition, 0.0, 1.0 );
}
void main(void) {
gl_FragColor = vec4(0.0, 0.0, 1.0, 1.0);
}
V E R TE X S ha de r FR A G S ha d.
Negli shaders: dopo
M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 6 / 1 7 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
attribute vec2 position;
attribute vec3 baseColor;
varying vec3 color;
void main(void) {
gl_Position = vec4( position, 0.0, 1.0 );
color = baseColor ;
}
V E R TE X S ha de r
precision highp float;
varying vec3 color;
void main(void) {
gl_FragColor = vec4( color , 1.0);
}
FR A G M E N T S ha de r
L I N K
Linguaggio GLSL:
classi di allocazione
• attribute
– valore definito su ogni vertice
– nel vertex shader: INPUT (sola lettura) – nel fragment shader: non usato
• varying
– valore che varia dentro la primitiva
– nel vertex shader: OUTPUT (sola scrittura) – interpolato dal rasterizzatore
– nel fragment shader: INPUT (sola lettura) varying vec3 color;
attribute vec3 baseColor;
Linking di vertex e fragment shader
• Vertex Shader:
– input:
• gli attributes – output:
• i varyings
• gl_Position (vec4)
• Fragment Shader:
– input:
• i varyings – output:
• gl_FragColor (vec4)
• gl_Depth (float) (opzionale)
M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 6 / 1 7 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
LINK
Linguaggio GLSL: (per completezza)
altre classi di allocazione
• const
– valore costante, noto a compilazione
– definito quando dichiarato (obbligatoriamente) – risolto direttamente dal compilatore
• temporanea
– valore “usa e getta” , di lavoro – var locale o globale
– lettura / scrittura
const vec3 PINK_COLOR = vec3( 1.0, 0.5, 0.5 );
vec3 tmp ;
niente
Prossimo passo:
• Usiamo struttura mesh indexed
• Due tipi di buffer, detti:
M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 6 / 1 7 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
ARRAY_BUFFER ELEMENT_ARRAY_BUFFER
array di indici
• indici di vertice, per primitiva (element)
• connettività della mesh
array di vertici
• geometria + attributi, per vertice
(l’unico che usavamo prima)
Prima mesh indicizzata:
• Un quad con diagonal split – (4 vertici, 2 tris)
V0 V1
V2 V3
var indices = [
0,1,2, // 1st triangle
1,3,2, // 2nd triangle
];
Prepariamo il buffer di indici
• Un buffer ulteriore per la connettività della mesh
• Similmente agli altri buffer:
M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 6 / 1 7 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
var elBufferId = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, elBufferId );
var indices = [
0,1,2, // 1st triangle 1,3,2, // 2nd triangle ];
var indexData = new Uint16Array( indices );
gl.bufferData(
gl.ELEMENT_ARRAY_BUFFER, indexData,
gl.STATIC_DRAW );
Dopo la bind, tutte le op su
Element Array Buffer
(rendering compreso) si riferiranno a questo buffer
Disegnamo la mesh indicizzata
gl.drawArrays( gl.TRIANGLES , 0, 3
);
gl.drawElements( gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 );
quanti indici di vertice
(ogni 3 = un tri) da quale
indice partire quanti vertici
(ogni 3 = un tri)
mesh
non indicizzata,
mesh indicizzata tipo di ogni indice
(short = 16 bit =
Piccole domande
• Come fai ad eseguire l’altro diagonal split?
(a dividere il quadrilatero diversamente nei due triangoli)?
• Vengono prodotti più o meno frammenti?
• Il risultato a schermo è indentico o differente?
– (pensa agli attributi nel punto in mezzo alla diagonale)
M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 6 / 1 7 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
Per una visione d’insieme del codice, vedere l’implementazione sul sito:
Esercitaz 01
Consiglio:
invece che utilizzare l’implementazione fornita, scrivere la propria implementando uno ad uno
tutti i passi come descritto qui,
a partire dall’esercitaz 00
WebGL pipeline con attributi e indexed
M a r c o T a r i n i ‧ C o m p u t e r G r a p h i c s ‧ 2 0 1 6 / 1 7 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a
Primitive:
primitive assembler (& setup) Transformed
Vertex:
XYZW (clip space) computed + varying vertex
shader Input
Vertex:
(object space) XYZ input + attributes
GPU-RAM
Mesh:
vertex puller vertex buffer index
buffer rasterizer
rasterizer point
(1xV) (2xV) line triangle
(3xV)
WebGL pipeline
GPU-RAM screento