• Non ci sono risultati.

VERTEX SHADER(GLSL)

N/A
N/A
Protected

Academic year: 2021

Condividi "VERTEX SHADER(GLSL)"

Copied!
6
0
0

Testo completo

(1)

Computer Graphics

Marco Tarini

Università dell’Insubria Corso di Laurea in Informatica Anno Accademico 2014/15

Trasformazioni 3D con three.js

Matrici in GLSL

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 4 / 1 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a

mat4 m , mA , mB ; vec4 v , u;

m = mA * mB ; // prodotto matrice matrice // (riga per colonna)

m *= mB ; // come dire: m = m * mB (non mB * m !) u = m * v ; // prodotto matrice-vettore

u = m[ 0 ] ; // prendi la 1ma colonna di m m[ 3 ] = u ; // setta la 4ta colonna di m

m = mat4( v ) ; // matrice diagonale

m = mat4( 1.0 ) ; // 1 nella diagonale (cioè l’ide)

Matrici in GLSL

mat4 m , mA , mB ; vec4 v , u;

m = transpose( m ); // non oneroso m = inverse( m ); // molto più oneroso!

float k = determinant( m );

m = mA * 5; // moltipilca tutti gli elementi

m = mA + mB; // somma fra matici

mat3 submat = mat3( m ); // sottomatrice 3x3 m = mat4( submat ); // borda con 0, e 1 sulla diago

Vertex shader con transformazione 3D

• Trasformazioni 4x4 = matrici 4x4 (uniforms)

attribute vec3 vertexPos ; attribute vec3 colAttribute ; varying vec3 colVarying;

uniform mat4 mvp ;

void main(void) {

gl_Position = mvp * vec4( vertexPos , 1.0);

colVarying = colAttribute ; }

VE R TE X SH AD ER (G LS L)

X Y Z

(coord W

affine)

Model-View- Projection

(da spazio-oggetto a

spazio-clip in un sol colpo)

(2)

Setting the uniforms: caso matrici

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 4 / 1 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a

G PU

...

uniform mat4 mvp;

...

var mvp_loc = gl.getUniformLocation(

myProg , “mvp"

);

...

gl.uniformMatrix4fv ( mvp_loc , false, xxx );

...

reneder(...); // sends the primitives

C PU

«dammi un vettore (non i valori)»

un Float32Array (16 el)

«column major order»

Serializzare le matrici

Row-major Order

(per riga) : Column-Major Order

(per colonna) :

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 4 / 1 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a

 

 

p o n m

l k j i

h g f e

d c b a

 

 

p l h d

o k g c

n j f b

m i e a

trasposta di

« trascrivere come serie di numeri » (in memoria, su disco, etc)

a b c d e f g h i j k l m n o p standard più

Settare la matrice di MVP

• Come una matrice di scalatura?

// da invocare nella draw, prima di mandare le primitive function setUniforms(){

gl.uniformMatrix4fv( mvp_loc, false, new Float32Array( [

0.5, 0, 0, 0, // first column!!!! (not row) 0, 0.5, 0, 0,

0, 0, 0.5, 0, 0, 0, 0, 1, ] )

);

...

}

Settare la matrice di MVP

• Come una matrice di rot di 45° sull’asse Z?

// da invocare nella draw, prima di mandare le primitive function setUniforms(){

gl.uniformMatrix4fv( mvp_loc, false, new Float32Array( [

+0.707, -0.707, 0, 0, // first column!!!! (not row) +0.707, +0.707, 0, 0,

0, 0, 1, 0, 0, 0, 0, 1, ] )

);

...

}

nota: sin(45°) = cos(45°) = 0.707…

(3)

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 4 / 1 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a

Rotazione attorno all'asse x , y , o z

 

 

 

 

=

1 0 0 0

0 1 0 0

0 0 cos sin

0 0 sin - cos )

( θ θ

θ θ

Z

θ R

 

 

 

 

=

1 0 0 0

0 cos sin 0

0 sin - cos 0

0 0 0 1 )

( θ θ

θ θ

X

θ R

 

 

 

 

=

1 0 0 0

0 cos 0 sin -

0 0 1 0

0 sin 0 cos )

( θ θ

θ θ

Y

θ R

Ci serve una libreria JavaScript per matrici, vettori, etc

• three.js

– http://threejs.org

• GLGE

– http://www.glge.org

• SpiderGL

– http://spidergl.org

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 4 / 1 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a

adottiamo questa

three.js quick start

• download it ( http://threejs.org )

• dal package prendere i builds – three.js

– three.min.js (versione minimale, ci basta per ora)

• metterli a dispozisione della pagina html – (es dentro una cartella “ js/ ”)

• inlcuderli:

<html>

<head>

<script src="js/three.min.js"></script>

<script type="text/javascript">

</script>

</head>

he ad

(come tutte le librerie JavaScript)

Matrici in three.js

var

m = new

THREE.Matrix4(); // m = identità

/* costruzioni di matrici utili, comprese quelle che abbiamo visto: */

m.makeTranslation( dx, dy, dz );

m.makeScale( sx, sx, sz );

m.makeRotationX( radiants );

m.makeRotationY( radiants );

m.makeRotationZ( radiants );

m.makeAxis( axisX, axisY, axisZ ); // dai tre vettori asse m.makePerspective( fov, aspect, nearZ, farZ );

/* accesso agli elementi */

m.elements(); // un Float32Array con i 16 elementi

(4)

Matrici in three.js

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 4 / 1 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a var

m = new

THREE.Matrix4();

var

b = new

THREE.Matrix4();

/* moltipilcazione riga colonna: */

m.multiply( b ); // a destra! m *= b;

// cioè m = m*b;

// (equivale a fare prima b, poi m)

/* inversioni etc */

var

det

= m.determinant(); // un float

m.transpose(); // “in place”, cioe’ m = transposta di m ; m.getInverse( b ); // m = inversa di b

/* e molto altro, per es: */

// costruisce una matr. vista (vedi esercizio di trasformazione) m.lookAt ( eyePos, targetPos, upVec );

Un modo per definire la matrice di vista una semplice “Trackball”:

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 4 / 1 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a

phi theta

z -x

y

var

trackball = {

phi: 0.0, // degrees theta: 0.0, dist: 5.0

};

Soluz (traccia):

• Se la camera fosse un oggetto qualsiasi, per portarla nella pos giusta:

– ricetta:

• partenza: camera nello 0, puntata verso –Z, etc.

• prima la sposto sulla Z di dist

• poi lo ruoto attorno alla X di theta

• poi lo ruoto attorno alla Y di phi

Soluz (traccia):

• Allora la matrice di vista V si ottiene invertendo (sia ciascuna op che il loro ordine) :

– ricetta:

• partenza: spazio mondo

• prima lo ruoto attorno alla Y di −phi

• poi lo ruoto attorno alla X di −theta

• poi la sposto sulla Z di −dist

• arrivo: spazio vista

M1 M0 M2

V = M2*M1*M0

(5)

Setting della view matrix

• In Javascript (con three.js ) :

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 4 / 1 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a var

view = new

THREE.Matrix4();

var

m0 = new

THREE.Matrix4();

var

m1 = new

THREE.Matrix4();

var

m2 = new

THREE.Matrix4();

m2.makeTranslation( 0,0, -trackball.dist );

view.multiply( m2 );

m1.makeRotationX( -trackball.theta / 180.0 * 3.1415 );

view.multiply( m1 );

m0.makeRotationY( -trackball.phi / 180.0 * 3.1415 );

view.multiply( m0 );

conversione da degree a rad (ma meglio usare Math.PI)

Setting della projection matrix

• In Javascript (con three.js ) :

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 4 / 1 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a var

view = ...;

var projection = new

THREE.Matrix4();

projection.makePerspective( 60, 1.0, 0.5, 100.0 );

var

mvp = new

THREE.Matrix4();

mvp.multiply( projection );

mvp.multiply( view );

gl.uniformMatrix4fv( mvp_loc, false, mvp.elements

);

convenientemente, un Float32Array mandiamo la matrice di MVP

allo shader come uniform precedentemente trovato (dopo la costruz. dello shader)

Field of View

(degrees) Aspect Ratio del viewPort

Distanze del Near e Far Clipping Plane

(in spazio vista!)

Proiezione prospettica

 

 

 

 

=

0 / 1 0 0

0 1 0 0

0 0 1 0

0 0 0 1

d P

 

 

=

 

 

d z

z y x z

y x

/ 1

P

 

 

 

 

 

 

1 / /

d d z

y d z

x

divisione per 4ta comp

matrice di trasformazione per la proiezione prospettica

Paradigmi di interazione 3D

• World in Hand (or Object in Hand)

– mi immagino la camera fissa,

manipolo l’oggetto davanti alla camera – es: un visualizzatore di oggetti 3D

• Camera in Hand

– mi immagino un oggetto / il mondo fermo, muovo la camera intorno

– es: un game 1st person shooter

(6)

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 4 / 1 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a

Depth test, in OpenGL

• Abilitarlo:

gl.enable(gl.DEPTH_TEST);

primitivequi

pixels tutto il pipeline

(proiezione, setup, rasterizzazione...) stato di OpenGL manipolazioni di stato (es. settare la matrice)

Determinare la condizione per passare il test:

gl.DepthFunc( GL_LESS ) gl.NEVER

gl.EQUAL gl.LEQUAL gl.GREATER gl.NOTEQUAL gl.LESS gl.GEQUAL gl.ALWAYS

(dafault)

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 4 / 1 5 ‧ U n i v e r s i t à d e l l ’ I n s u b r i a

Depth test, in WebGL (o OpenGL)

• Quando si cancella lo schermo, cancellare anche il depth buffer

...

gl.clear(

gl.COLOR_BUFFER_BIT );

...

| gl.DEPTH_BUFFER_BIT

OR bit a bit (la clear prende una maschera di bits che specifica

quali buffer cancellare)

Depth test, in WebGL (o OpenGL)

• Il rasterizzatore produce un valore di depth di default

– per ogni frammento prodotto

– interpolando la Z dei vertici proiettati in input

• Possiamo sovrascrivere questo valore (se vogliamo) nel fragment shader

// fragment shader

void main() { ...

gl_FragColor = ... // un vec4 gl_FragDepth = ... // un float

assegnamento opzionale.

(ha un costo grande farlo! depth test va rimandato e alcune ottimizzazioni HW

Per i dettagli,

vedere l’implementazione sul sito (come al solito):

lez 19B

Riferimenti

Documenti correlati

• Depth test: viene eseguito automaticamente alla fine del nostro fragment shader. –

• Depth test: viene eseguito automaticamente alla fine del nostro fragment shader. –

facciamoli prendere dal vetex puller 3.. usiamoli nel

[r]

– es: normale, colore, altri parametri materiale, … come lo memorizzo. • Soluzione 1: come

Capire se la texture sta venendo rimpicciolita o ingrandita – nel passare da texel nel texture sheet a pixel sulle schermo – texture “minification” o “magnification”.. –

• Depth test: viene eseguito automaticamente alla fine del nostro fragment shader. –

Document Title: LHC-B Level-1 Vertex Topology Trigger User Requirements Document 2.. Document Reference Number: LHC-B