texture
texture
argomenti trattati (cenni...)
* texture
* bump mapping
* procedure OpenGL per le texture
texture
un sistema per aumentare il realismo della scena e'
nell'uso delle "tessiture" - immagini qualunque in una
o due dimensioni che vengono "incollate" sulla
superfice dell'oggetto che si vuole rappresentare;
qui sopra la texture (ad es. in
formato xxx.bmp), a destra l'
immagine di due cubi ottenuta
con proiezione, su cubi e' stata
applicata questa texure
texture
le "tessiture" sono immagini qualunque in due
dimensioni - che vengono "incollate" sulla superfice
dell'oggetto che si vuole rappresentare:
procedimento diretto:
data un'immagine (texture), per applicare una
tessitura ad una primitiva (un triangolo)
devo passare
dalla texture [ data come una superfice
(un'immagine) in coordinate (u,v) ]
alla primitiva (faccia) dell'ogetto:
i singoli punti della tessitura ("texel") sono riportati,
mappati sulla primitiva nello spazio data in coordinate
oggetto (colore dei singoli punti)
e quindi trasformati (proiettati, normalizzati,..) in
coordinate display;
texture
il procedimento inverso e' piu' usato:
data la texture come immagine
dato l'oggetto 3D da rappresentare in 2D,
per ogni pixel [xsch,ysch] dello schermo
(su cui sono proiettati i punti dell'oggetto a cui
voglio applicare la texture)
ritorno alle coordinate [x,y,z] dell' oggetto,
e quindi alle coordinate [xlato,ylato] di un lato dell'
oggetto, e
infine
passo alle coordinate u,v del punto della tessitura
corrispondente;
texture
si osservi che l'applicazione della tessitura puo'
essere fatta in semi-trasparenza, conservando un
colore e un'ombreggiatura:
in tal caso si usa anche per la tessitura il fattore Alfa
ogni "texel" ha i componenti (R,G,B,A),
e l'intensita' di luce ovvero il colore del pixel
dell'oggetto e' dato da
Ip = a*Itext + b*Ig
texture 1D
Tessitura lineare 1D specifico un array monodimensionale di colori (R,G,B,A)
e lo associo ad una "scena" lineare (un segmento di
retta, una curva generica) con il procedimento seguente:
ColorTex [n] = {(r,g,b,a), (r,g,b,a), (r,g,b,a),...(r,g,b,a)}
indici
0
1
2
n
coordinate
s0=0.0
s1
s2
sn=1.0
corrispondenza x0 =xmin x1
x2
xn =xmax
la coordinata s nello spazio tessitura va da 0.0 a 1.0,
se s=0.0 uso il colore tex[0],
se s=1.0 uso colore tex[n-1]
se vi sono pochi colori allora si associa un colore tex[i] a
piu' pixel xi,xi+1,..xi+k oppure si usa un'interpolazione
lineare tra i due texel piu'vicini.
texture 2D
(1,1)
La tessitura 2D e' data
con un array a 3 indici,
cioe' terne di valori (r,g,b)
individuate da due indici
(u,v) o (xtess,ytess);
associo la posizione (0,0)
agli indici (0,0) e la
posizione (1,1) agli indici
(nxt,nyt);
(0,0)
file MonaLisa.BMP
50x50 pixel,
qui sopra ingrandita
texture 2D
Tessitura 2D - la tessitura e' data con un array a 3 indici,
cioe' terne di valori (r,g,b)
(1,1)
individuate da due indici xt,yt o u,v;
generalmente si associa
la posizione (0,0) agli indici (0,0) e
la posizione (1,1) agli indici (nxt,nyt);
con il procedimento diretto da
texture->oggetto->display si
presenta il problema che un
quadratino della tessitura
( trasformato dalla pipeline
grafica oggetto->display )
non si sovrappone ad un
quadratino-pixel su schermo, ma
ne viene a coprire una parte;
(0,0)
texture 2D
piu' usato il procedimento
inverso,
dove si esegue per ogni
pixel dello schermo la
trasformazione inversa,
da pixel a oggetto a texel:
texture 2D
piu' usato il procedimento inverso,
dove si esegue per ogni pixel dello
schermo la trasformazione inversa,
da pixel a oggetto a texel:
in genere viene presa un' area piu'
ampia di un pixel si estende il pixel di mezzo pixel ad
ogni lato e si ritorna alla texture,
dove i punti della texture corrispondenti alle 9 regioni del pixel "grande"
sono pesati con una funzione /\
tessiture + colori
Una tessitura si puo' applicare all'oggetto
come un foglio elastico non trasparente
che ricopre l'oggetto completamente,
oppure come foglio semitrasparente, in modo
che i colori della tessitura si mescolano con
i colori dell'oggetto (e con le ombre dell'oggetto)
(esempio da fare...) vedremo i parametri nelle
procedure dell'OpenGL
in una sequenza di immagini un oggetto puo'
cambiare dimensione apparente sullo schermo;
in tal caso cambia la corrispondenza tra texture e i
pixel, si deve applicare la tessitura originale
ad una superficie diversa (piu' piccola o piu' grande)
si ricorre a texture precalcolate di dimensioni diverse
texture :
MIP maps
texture 2D e mip-maps
un oggetto cambia dimensione in esecuzione - in tal caso si
deve applicare la tessitura originale ad una superficie di pixel
diversa (piu' piccola/ piu' grande);
per evitare distorsioni si possono predisporre piu' tessiture
"pre-ridotte" e/o pre-aumentate; di solito a multipli di due,
ovvero 1/2, 1/4, 1/8, ecc della dimensione originale;
ad es. se la tessitura originale era 256x256, allora le tessiture
ridotte saranno 128x128, 64x64, 32x32 ecc;
queste repliche ridotte (e aumentate) della tessitura sono
spesso dette
mip-maps,
MIP dal termine "multum-in-parvo" (dove
multum sta per le repliche della tessitura, e
parvo sta per l'oggetto...)
L' openGL ha procedure apposite
per il calcolo delle mip-maps
...
vedremo tra breve
tessiture, mip-maps e OpenGL
segue ora una breve presentazione
delle procedure di base
per l'uso delle texture disponibili
nella libreria OpenGL
libreria OpenGL per le tessiture
procedure OpenGL per le tessiture, caso piu' semplice:
glTexImage1D ( GL_TEXTURE_1D, 0, GL_RGBA, width,
0, dataFormat, dataType, lineTexArray );
glEnable( GL_TEXTURE_1D);
parametri della glTexImage1D :
1) GL_TEXTURE_1D specifica texture monodimensionale
2) zero se non sono previste text-maps multiple (mipmaps)
3) GL_RGBA =4 specifica quali componenti sono usati per il
blending, qui 4 valori per colore, RGBA
(altri: tre valori=GL_RGB, un solo valore=intensita', ecc.)
4) width = dimensione della texture array =
nTexColors = numero colori nel texture pattern, e' una potenza
di due=2^n; nota che la dimensione dell'array e' 4*nTexColors;
libreria OpenGL per le tessiture
procedure OpenGL per le tessiture:
glTexImage1D( GL_TEXTURE_1D, 0, GL_RGBA, width,
0 /*5bordo*/, dataFormat, dataType, lineTexArray );
continua parametri:
5) bordo zero indica niente bordo attorno la tessitura (uno per
avere un bordo di un pixel, per fusione con la prossima texture, in
tale caso il 4.o param. deve essere 2+2^n
6) dataFormat specifica come sono memorizzati i colori (valori
possibili: GL_RGBA, GL_BGRA, GL_RGB, GL_BGR, GL_BLUE, ecc )
7) dataType tipo colore(GL_INT, GL_UNSIGNED_BYTE, GL_FLOAT,...)
8) lineTexArray
---------------------------------------------------------
(*) pag seg
NOTA:
in glTexImage1D( GL_TEXTURE_1D, 0, GL_RGBA, width,
0/*5bordo*/, dataFormat, dataType, lineTexArray );
i due parametri della procedura glTexImage1D: dataFormat, e
dataType, sono gli stessi usati nella procedura prevista dall'
OpenGL per disegnare un blocco di colori direttamente nel
frame - buffer, la:
glDrawPixels(width, height, dataFormat, dataType, pixMap);
con
dataFormat = formato colori(GL_RGBA, GL_BGR, GL_BLUE,
dataType tipo valore di un colore (GL_INT, GL_FLOAT,...)
es:
glDrawPixels(128,128, GL_RGB, GL_UNSIGNED_BYTE, colorShape),
disegna un pixmap raster direttamente copiando dall'array
colorShape nel frame buffer, l'elemento di posizione in basso a
sinistra e' copiato nella posizione specificata prima con la
funzione glRasterPosXX (dove XX e' ad es. 2i ...)
libreria OpenGL per le tessiture
per semplificare il calcolo della mappatura della tessitura
nel caso (frequente) di mappatura da rettangolo texture a
rettangolo lato di oggetto 3D, si usano le procedure mip-maps:
se devo ingrandire la tessitura per coprire un'area grande:
glTexParameteri(
GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
oppure se devo ridurre l'area della tessitura per mapparla su
un'area piu' piccola:
glTexParameteri(
GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
per avere il colore dato dall'interpolazione dei pixel piu'vicini
invece di GL_NEAREST useremo GL_LINEAR .
libreria OpenGL per le tessiture
per il caso 2D useremo
glTexImage2D ( GL_TEXTURE_2D, 0, GL_RGBA,
texWidth, texHeight, 0, dataFormat, dataType, surfTexArray );
glEnable( GL_TEXTURE_2D);
parametri:
1) GL_TEXTURE_2Dspecifica texture BIdimensionale
2) zero == un solo livello, non usati mipmaps
3) GL_RGBA (=4) tipo colore, (GL_RGB, GL_RED,GLBGR,..)
4) texWidth, texHeight della texture pattern, sempre potenza di
due=2^n; dimensione del texture array e' 4 * texWidth * texHeight;
5) zero == niente bordo attorno la tessitura
6) dataFormat (GL_RGBA, GL_BGRA, GL_RGB, GL_BGR, GL_BLUE,
7) dataType tipo colore(GL_INT, GL_UNSIGNED_BYTE, GL_FLOAT,...)
8) surfTexArray dove e' memorizzata la texture, prima
riga=posizione in basso, ...
libreria OpenGL per le tessiture
... esempio da Hearn & Baker :
GLubyte texArray[32][32] [4]; // la tessitura, da specificare ...
glTexParameteri( // nota [4] per RGBA, 4 si allinea bene..
GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
glTexParameteri(
GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, 32,32,
0, GL_RGBA, GL_UNSIGNED_BYTE, texArray);
glEnable( GL_TEXTURE_2D );
// assign full range of texture colors to a quadrilateral:
glBegin( GL_QUADS );
glTexCoord2f( 0.0, 0.0 ); glVertex3fv( vertex1 ); // vertici:
glTexCoord2f( 1.0, 0.0 ); glVertex3fv( vertex2 ); // 4 3
glTexCoord2f( 1.0, 1.0 ); glVertex3fv( vertex3 ); // 1 2
glTexCoord2f( 0.0, 1.0 ); glVertex3fv( vertex4 ); //
glEnd();
glDisable( GL_TEXTURE_2D );
un es. OpenGL per uso tessiture
inizializzo una (o piu') tessiture, es. nella init(); chiamo
LoadTexture, che fornira' il "nome" (numero) della textr:
GLuint tess1 = LoadTexture( ...da file...), dove nella
GLuint LoadTexture{ .. GLuint txtr; ...
glGenTextures( 1, &txtr); // chiedi a OpenGL un num
glBindTexture( GL_TEXTURE_2D, txtr);
// poi genera(calcola) oppure leggi da file la tessitura
// in una zona di memoria (con l'immagine bitmap),
// *data e infine costruisce la texture txtr
// qui gluBuild2DMipmaps al posto di glTexImage2D
gluBuild2DMipmaps(GL_TEXTURE_2D,3, width,height,
GL_RGB, GL_UNSIGNED_BYTE, data );
free( data ); return txtr;
} // LoadTexture (vedi piu'dettagli tra 3 slide)
un es. OpenGL per uso tessiture
poi, uso tessitura:
.. drawFace(tess1,..);..dove:
void drawFace( int mytexture, float siz ){
glEnable( GL_TEXTURE_2D );
glBindTexture( GL_TEXTURE_2D, mytexture );
glBegin(GL_QUADS);
...
glEnd();
glDisable (GL_TEXTURE_2D);
}
mappatura da area tessitura a area oggetto
void draw2(int mytxtr, float siz){ float sx=1.0;
glEnable( GL_TEXTURE_2D );
glBindTexture( GL_TEXTURE_2D, mytxtr );
/*per ogni lato fisso corrisp.lato-tessitura*/
glBegin(GL_QUADS);
glTexCoord2f( 0.0, 0.0);/*tessit.basso sin */
glVertex3f( -siz, -siz, siz); /*basso sin */
glTexCoord2f( sx, 0.0);/*tessit.basso des */
glVertex3f( siz, -siz, siz); /*basso dest*/
glTexCoord2f( sx, sx); /* tessit.alto dest*/
glVertex3f( siz, siz, siz); /*alto dest*/
glTexCoord2f( 0.0, sx); /*tessit.alto sin*/
glVertex3f( -siz, siz, siz); /*alto sin*/
glEnd(); // da'la corrispondenza tra area tess.
glDisable (GL_TEXTURE_2D); // e un'area oggetto
}
GLuint LoadTexture( char * filename, int wrap ) {
GLuint txtr;
int width=256, height=256; char * data;
data = ReadBMP( width, height, filename );
glGenTextures( 1, & txtr); // nota & stile C (param in uscita)
glBindTexture( GL_TXTR_2D, txtr);
/* segue specifica di come si aggiunge la txtr a superf.precedente */
glTexEnvf(GL_TXTR_ENV, GL_TXTR_ENV_MODE, GL_MODULATE );
/* GL_MODULATE oppure GL_DECAL, 2 slide dopo */
/* segue come si rimpiccolisce/ingrandisce la txtr (MIPMAP !): */
glTexParameterf( GL_TXTR_2D, GL_TXTR_MIN_FILTER,
GL_LINEAR_MIPMAP_NEAREST );
glTexParameterf(GL_TXTR_2D, GL_TXTR_MAG_FILTER, GL_LINEAR );
/* now, if wrap - the txtr wraps over at the edges (repeat!),
if not wrap - the txtr ends at the edges (clamp) */
glTexParameterf( GL_TXTR_2D, GL_TXTR_WRAP_S,
wrap ? GL_REPEAT : GL_CLAMP );
continua la
GLuint LoadTexture( char * filename, int wrap ) {
GLuint txtr; int width=256, height=256; char * data;
data = ReadBMP( width, height, filename );
glGenTextures( 1, &txtr);
glBindTexture( GL_TXTR_2D, txtr);
...
/*now build texture MIP maps, 3 levels, copy image data*/
gluBuild2DMipmaps( GL_TXTR_2D, 3, width, height,
GL_RGB, GL_UNSIGNED_BYTE, data );
// questo genera 3 livelli di riduzione della tessitura
// fornita con il puntatore data, associati a txtr...
// nota: gluBuild2DMipmaps e' al posto di glTexImage2D
// ora la txtr e' fatta, posso eliminare il buffer "data" :
free( data );
return txtr; // questo e' il risultato: il numero della txtr
} /* fine della procedura LoadTexture */
un es. OpenGL per uso tessiture
continua la LoadTexture, vediamo meglio il glTexEnv :
GLuint LoadTexture{
GLuint txtr; int width=256, height=256; char * data;
data = ReadBMP( width, height, filename );
glGenTextures( 1, & txtr); // nota & stile C (param in uscita)
glBindTexture( GL_TXTR_2D, txtr);
glTexEnv (
GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE,
GL_MODULATE);
/* come si combina tessitura con l'ambiente:
GL_MODULATE per il prodotto dei due colori,
GL_REPLACE se tessitura copre l'oggetto;
GL_DECAL combina colore dell'oggetto(trasparente)
con tessitura(sfondo);
GL_BLEND se uso blend devo specificare un
colore bC per il blending, con un altra call:
glTexEnv3f( GL_TEXTURE_ENV,GL_TEXTURE_ENV_COLOR, bC )
...
altre proc per tessiture
l'OpenGL prevede altre procedure per la creazione e gestione
delle tessiture, ad es:
glTexParameter*( texSpace, texWrapCoord, GL_REPEAT);
dove texSpace e' ad es. GL_TEXTURE_2D, e dove
texWrapCoord e' GL_TEXTURE_WRAP_S, oppure
GL_TEXTURE_WRAP_T (indicazione di come si ripete la
tessitura se si hanno coordinate tessitura maggiori di 1)
invece di GL_REPEAT posso avere GL_CLAMP, che indica che
coordinate s,t della tessitura maggiori di 1 sono troncate.
ecc:
vedere manuale ...
e gli esempi
vedere il primo esempio di uso delle texture
EGD3D_21_TXTR
in questo esem. e' riportata anche la procedura di
lettura di file immagini (nel formato piu' semplice, il
bit-map, "bmp", dove c'e' una parte iniziale con
informazioni sul formato del file;
(non riportato il formato "raw", con solo pixel grafici,
niente informazione, tutto a formato fisso) letto un
file, con l'uso di
char * ReadBMP ( int & width, int & height,
char * filename ); proc. della
"BITMAP_AU.h", il resto e' come detto prima...
tessiture su oggetti "complicati"
una tessitura si puo' applicare su superfici
complesse,
sia regolari (sfera,cilindro ecc)
sia irregolari (teiera, una faccia - date con
una superficie fatte di triangoli)
di seguito quattro esempi,
tre con foto (corso EGD07) applicate a
superfici + o - regolari,
tessitura su cilindro e su cono,
es. dal programma di Tamiazzo (giu.07)
(Dotta e Hmeljak)
tessitura applicata a teiera,
programma di Tamiazzo giugno 2007
(Mauri)
l' immagine seguente e' ottenuta
applicando una texture (foto di una
faccia) ad un' immagine costruita con
triangoli nello spazio, che
definiscono una "faccia"
(la faccia e' da rete)
"Oscar"
immagini da tesi di laurea triennale di Righetti su
riconoscimento del parlato di una persona in real time,
9 apr. 2008, corso ing.inf. teledidattico, relatore prof.Mumolo
tessiture
seguono quattro slide
con esempi di immagini prodotte
dai programmi:
EGD3D_21_TXTR.cpp
EGD3D_22_TXTR_CUBO.cpp
EGD3D_24_ANICUBO.cpp
EGD3D_25texgen1D.c
tessiture
es da programma EGD3D_21_TXTR.cpp, tessitura
(quadrata) su un triangolo (nello spazio)
tessiture
esempio da programma EGD3D_22_TXTR_CUBO, stessa
tessitura di prima applicata alle facce di un cubo
tessiture
da programma EGD3D_24_ANICUBO,
tre cubi con tre tessiture diverse
tessiture
programma EGD3D_25texgen1D.c
(dal manuale, tessitura calcolata)
due immagini con texture applicata a un oggetto sfera,
con costruzione esplicita (vedi slide seguente)
nel testo seguente sono stati ommesse alcune istruzioni, come:
glEnable(GL_CULL_FACE); glCullFace(GL_BACK);
glColor4f(1,1,1,1);
void drawSphere(int txtr, int nMaj, int nMin, float radius) {
double majorStep= M_PI / nMaj, minorStep= 2*M_PI / nMin;
glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, txtr);
for (int i = 0; i < nMaj; ++i) { double a,b,r0,r1;
GLfloat z0,z1;
a = i * majorStep;
b = a + majorStep;
r0 = radius * sin(a);
z0 = radius * cos(a);
z1 = radius * cos(b);
r1 = radius * sin(b);
glBegin(GL_TRIANGLE_STRIP);
for (int j = 0; j <= nMin; ++j) { GLfloat x,y;
double c = j * minorStep; x = cos(c); y = sin(c);
glNormal3f( (x*r0)/radius, (y*r0)/radius, z0/radius);
glTexCoord2f( j/(GLfloat) nMin, i/(GLfloat)nMaj);
glVertex3f( x * r0, y * r0, z0);
glNormal3f( (x*r1)/radius, (y*r1)/radius, z1/radius);
glTexCoord2f( j/(GLfloat)nMin, (i+1)/(GLfloat)nMaj);
glVertex3f( x * r1, y * r1, z1);
} /* for j */
glEnd(); /* triangle strip */
} /* for i */
glDisable (GL_TEXTURE_2D); glDisable(GL_CULL_FACE);
} /* drawSphere */
a sinistra "schiera oggetti Mona Lisa" - nota tessitura sui tetraedri, che
si ricompone sulla schiera dei tetraedri piu' vicini all'osservatore;
a destra (teiere) e' stato aggiunto il blending (alfa=0.5)
di seguito parte del testo di disegno schiera oggetti
void displaySolid(){
glPushMatrix();
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE,
GL_SPHERE_MAP);
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE,
GL_SPHERE_MAP);
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
glEnable(GL_TEXTURE_2D);
glBindTexture( GL_TEXTURE_2D, texture1 );
glutSolidTetrahedron(); // o altro glutSolid...
glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);
glDisable (GL_TEXTURE_2D);
glPopMatrix();
} // displaySolid
seguono delle presentazioni
di tecniche di uso di texture
per ottenere effetti di realismo piu' spinti:
environmental mapping
bump mapping
parallax mapping ...
le slide seguenti
sono dal materiale preparato dagli studenti
Tamiazzo (07), Tubini (06) e Signoretti (07)
per il seminario finale del corso
Environment Mapping
Tamiazzo Claudio
EGD07
Environment Mapping - Cos’è
Tecnica utilizzata in grafica digitale allo
scopo di realizzare oggetti riflettenti senza
ricorrere agli onerosi calcoli computazionali
del RayTracing:
la scena riflessa non e' calcolata (ray
tracing) ma e' precalcolata (predisposta,
spesso come immagine fotografica)
e poi incollata sull'ogetto come fosse un
adesivo !
seguono due slide con alcune immagini
Come Funziona
• L’environment mapping permette di
realizzare superfici apparentemente
riflettenti utilizzando delle textures
rappresentanti l’ambiente da riflettere
• La riflessione dipende/e'data da una
environment map nella quale è
proiettata l’immagine da riflettere
• In base al punto di vista, si effettuano i
calcoli per determinare l’immagine
riflessa, e poi questa viene usata come
txtr
Tecniche più Diffuse
• Standard Environment Mapping, o più
comunemente detta Spherical
Environment Mapping.
• Cube Environment Mapping
Spherical Environment
Mapping
• Sviluppata da Blinn e Newell
• Si basa sull’utilizzo come environment
map di una sfera “texturizzata”
• Spesso la texture di partenza consiste
in un’immagine ottenuta con una
macchina fotografica con lenti a
grandangolo
Effetto ottenuto con l' E.M. sferico
Foto ottenuta con lente “fisheye”
Spherical Environment
Mapping
• Questa tecnica porta con se' delle
grosse limitazioni legate al punto di
vista dell’utente nella scena 3D
• Una volta che il punto di vista cambia,
cambia l'immagine riflessa e sarebbe
necessario disporre di una texture
diversa per ogni angolazione
Fronte
Riflessione corretta
Retro
Riflessione incoerente
Cube Environment Mapping
• Tecnica che utilizza il cube mapping per
ottenere oggetti riflettenti
• Una cube map consiste in 6 textures
quadrate che vanno a formare una
environment map cubica
( predisposto in OpenGL)
Esempio: environment map di un paesaggio da riflettere ottenibile con sei foto
fatte in sei direzioni diverse
Cube Environment Mapping
• Per realizzare una superficie riflettente
si calcola il raggio dal punto di vista
all’oggetto ed, in base alla normale, il
raggio riflesso che va a intercettare un
punto su una delle sei facce del cubo.
• Il colore intercettato sulla texture sarà il
colore da riportare sull’oggetto nel punto
di riflessione
Cube Mapping In OpenGL
Creazione Cube Map (predisposto in OGL)
per ognuna delle sei facce (+X,-X,+Y,-Y,+Z,-Z) :
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE
_X,
0, GL_RGBA, imageSize, 0, GL_RGBA,
GL_UNSIGNED_BYTE, image1);
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIV
E_X,
0, GL_RGBA, imageSize, 0,GL_RGBA,
GL_UNSIGNED_BYTE, image2);
. . . . .
Cube Mapping In OpenGL
• Settaggio wrapping e filtering
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER,
GL_NEAREST);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER,
GL_NEAREST);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_REPEAT);
si ricorda che (S,T,R,Q) sono le coordinate (x,y,z,w) della texture
Cube Mapping In OpenGL
• Generazione delle coordinate (S,T,R)
della cube map texture
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE,
GL_REFLECTION_MAP);
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE,
GL_REFLECTION_MAP);
glTexGeni(GL_R, GL_TEXTURE_GEN_MODE,
GL_REFLECTION_MAP);
GL_REFLECTION_MAP vs
GL_NORMAL_MAP
GL_REFLECTION_MAP
GL_NORMAL_MAP
Immagini realizzate con programma cubemap.c da http://developer.nvidia.com/
Cube Mapping In OpenGL
Abilitazione texturing
glEnable(GL_TEXTURE_CUBE_MAP_EXT);
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
glEnable(GL_TEXTURE_GEN_R);
(S,T,R) coordinate della (cube map) texture
Applicazioni Cinematografiche
Flight of the navigator, 1986:
Superficie della navicella realizzata
Con l’uso dell’ environment mapping
Terminator 2: Judgement Day-1991
Il cyborg T1000 nelle sue metamorfosi è una delle più
celebri applicazioni dell’environment mapping
Bibliografia
• Libri - il manuale
“OpenGl Programming Guide”
di Shreiner, Woo, Neider, Davis (red-book)
• Rete:
http://www.debevec.org/ReflectionMapping/
http://www.developer.com
http://en.wikipedia.org/wiki/Reflection_mapping
http://developer.nvidia.com
BUMP MAPPING
seminario
Tubini maggio 2006
BUMP-maps
invece che come colori di pixel
(talvolta in mescolanza come il blending dei colori)
una tessitura si puo' applicare all' oggetto
come funzione che cambia la direzione della normale
N alla superficie, (ricordiamo che N e' alla base del
calcolo della luce riflessa / diffusa) creando effetti di
ombre e di rugosita'
questa tecnica si dice bump-mapping
il materiale seguente e' del seminario di
Stefano Tubini, corso EGD maggio 2006
ricordiamo la formula di Gouraud
per l'intensita' di luce in un punto:
per una sorgente di luce, N = normale alla superfice:
I = Iambiente + I Diffusa + I Speculare
= Ka * Ia + I Incidente Kd * cos(a) + W(a) * I Incidente * Ks* cosn(x)
= Ka * Ia + I Incidente Kd * N . L + W(a) * I Incidente * Ks* (N.H)n
in generale, con ns sorgenti di luce,
avremo la luce in un punto P della superficie
di un oggetto data da:
I = Iambiente + somma k (
I Diffusa k (N) + I Speculare k (N) )
per tutte le luci k da 1 a ns;
Il bump mapping è un metodo per simulare superfici
scabrose, con rilievi, con textures bidimensionali. Per
esempio: se realizziamo un oggetto che rappresenta un
tronco di legno, le fenditure della corteccia, grazie al
bump mapping, possono apparire tridimensionali anche
se non sono realizzate realmente con poligoni.
In questo modo, eventuali cambi di illuminazione possono
far apparire tali solchi profondi anche se sono
assolutamente piatti;
con il bump mapping si possono utilizzare molti meno
poligoni per disegnare un oggetto 3D,
come mostrato dalla immagine seguente: l' immagine
originale (non mostrata nella slide) viene semplificata in
un' immagine con superfici a triangoli "grandi", poi questa
viene resa con il bump-mapping che alla fine da'
quasi la stessa qualita' con 10 volte meno triangoli!
Dot3 Bump Mapping :
Questo metodo di bump mapping è anche detto
Dot Product Perturbed Bump Mapping o
Per-pixel lighting.
L'algoritmo alla base del Dot3 mapping è relativamente
semplice e si basa sulla creazione di una normal map, vale
a dire una mappa dove i valori di ogni singolo pixel non
rappresentano un colore come nelle texture convenzionali
(secondo il classico schema RGB [red-green-blue]) ma
vettori 3D, o normali (rette perpendicolari). A questo punto
si esegue un prodotto (da cui "dot product") tra queste
normali ed il vettore della luce: il risultato indica l'intensità
di riflessione della luce per ogni pixel trattato.
Modulando questo valore con il pixel della texture di base
si ottiene la texture finale che sarà applicata all'oggetto.
Dot3 Bump Mapping
• Texture
• Normal Map
Final Image
texture 2D e bump-maps
quindi si usa il bump-mapping per una
buona resa di superfici rugose:
si alterano le normali alla superfice in
funzione dei valori di una tessitura
"bump-texture" = un' immagine
monocromatica che fornisce la
"rugosita' " come ombre locali, e
quindi il calcolo dell'intensita' di luce
locale varia da punto a punto, in quanto
varia la direzione della normale nel
punto in funzione della bump-map; due
esempi di texture + bump-map son
riportati qui a fianco
(manca la combinazione delle due
tessiture, sorry)
e nella pagina seguente
texture 2D e bump-maps
per superfici rugose si usa la tecnica detta bump-mapping;
qui un secondo esempio di texture + bump-map;
ricordiamo che l'intensita' di luce locale I e' funzione di N,
normale alla superficie; il bump mapping altera questa N, da cui
segue un alterazione dell' intensita' della luce locale (diffusa e
riflessa)
texture 2D e bump-maps
il bump-mapping:
ricordiamo che l'intensita' di luce locale I e' funzione di N,
normale alla superficie; nel bump-mapping si usa una normale
N' = N + Nb ,
con N normale alla superficie e
Nb funzione di (u,v), coordinate del punto nella superficie,
appunto la bump-map data con un' immagine
(come negli esempi visti)
oppure
- caso delle tessiture procedurali la Nb puo' esser data con una funzione o procedura cioe'
calcolata invece che data da un'immagine
(effetti di particolari rugosita' date con sinusoidi "irregolari")
nota: la parte ARB che appare nei nomi e' per le estensioni gia'
approvate dal comitato OGL Architecture Review Board, ma non
ancora messe in una delle librerie gl, glu, glut ...
Dot3 Mapping (Codice)
Associo la normal map alla texture unit 0 :
glActiveTextureARB(GL_TEXTURE0_ARB);
glBindTexture(GL_TEXTURE_2D, oggetto3D->normalMap);
glEnable(GL_TEXTURE_2D);
// Associo normalisation cube map alla texture unit 1. Dove la normalisation
// cube map: penso come 6 textr 2D posizionate in modo da formare un cubo.
glActiveTextureARB(GL_TEXTURE1_ARB);
glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, normalisationCubeMap);
glEnable(GL_TEXTURE_CUBE_MAP_ARB);
… Dot 3 Bump Mapping
glActiveTextureARB(GL_TEXTURE1_ARB);
…
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB,
GL_DOT3_RGB_ARB);
…
… Texture Rendering
tessiture procedurali
per motivi di spazio (una procedura occupa meno spazio
di un'immagine) o per motivi di effetti speciali (non
ottenibili da un'immagine fissa) si usano tessiture
costruite al momento con apposite procedure
sul bump-mapping esistono molte varianti,
con uso di piu' "mappe" o immagini - tessiture da
combinare per ottenere effetti realistici
di seguito due cenni
Environment
map bump mapping :
è uno tra i metodi più nuovi apparsi nel campo della grafica 3D.
L'environment map bump mapping utilizza 3 texture diverse: la texture
di base, una bump map ed una environment map. La bump map
contiene i valori di altezza dei particolari della texture di base. Tra i
primi ad aver utilizzato questo metodo è il G400, un chip Matrox che per
prima ne ha diffuso in modo significativo l'utilizzo.
Per capire meglio riprendiamo l'esempio della texture della corteccia:
avremo i solchi più profondi che rappresenteranno il livello di base,
avremo i rilievi più alti che potranno sporgere di 10 unità, quelli
intermedi di 5 unità, ecc... Tutti questi valori sono raccolti nella height
map sotto forma di una matrice di valori.
L'environment map è la matrice che contiene le informazioni su cosa
deve essere fatto: in genere, l'environment map può essere una
semplice mappa di illuminazione, ma può contenere anche altri effetti
da applicare. Alla fine, quando le 3 texture sono combinate insieme, si
ottiene quella finale che sarà applicata sul poligono.
segue esempio
Environment map bump mapping
Parallax Mapping
• Parallax Mapping è un miglioramento della tecnica del
bump mapping applicata alle textures nelle applicazione
di 3D rendering come i video games.
Le textures, con l’utilizzo di questa tecnica avranno una
maggiore profondità e realismo senza aumentare la loro
complessità poligonale.
• Il Parallax mapping agisce su di una texture modificando
le coordinate di ogni punto che la compone di un valore
uguale a quello riportato nella normal map associata.
Parallax Mapping
Senza Parallax
Mapping
Con Parallax Mapping
Image Based Realtime
Rendering
seminario di A. Signoretti
L.S. Ingegneria Informatica
Corso di Elementi di Grafica Digitale
Anno Accademico 2006 - 2007
rivedere !!
Obiettivo
• Sviluppare applicazioni di Grafica Digitale, con RealTime Rendering, sempre più realistiche e dettagliate
– Possibile aumentando a dismisura il numero di poligoni
delle “Mesh” degli oggetti…
– …ma l’Hardware attuale non è in grado di gestirne così
tanti in Real-Time
Tecniche per simulare scabrosità
•
Utilizzo di tecniche basate su:
–
–
•
•
Modelli locali di illuminazione (Shading models)
Texture Mapping
Implementate negli attuali linguaggi (OpenGL, Direct3D e loro
estensioni) e supportate dai moderni hardware grafici
Buone prestazioni nelle elaborazioni Real-Time, ma danno una resa
della scena peggiore rispetto alle tecniche off-line (Ray-tracing,
Radiosity,…)
Modelli di Illuminazione
• Determinano il colore e l’intensità luminosa di una
superficie, rendendo realistica la scena e dando agli
oggetti bidimensionale un aspetto 3D
• Dipende dalla superficie:
–
–
–
–
(a) Lucida o Speculare (specchio)
(b) Opaca o Diffusiva (gesso, carta)
(c) Traslucente o Traslucida
Trasparente (vetro)
Modello di Phong (1975)
•
L’intensità di illuminazione di un punto dipende da:
–
–
•
Distanza e angolazione della sorgente luminosa rispetto al punto (attenuazione)
Tipologie di riflessione della specifica superficie
Attenuazione
–
Distanza: l’intensità luminosa si attenua col quadrato della distanza. Aumenta l’effetto
di profondità. Punto di vista all’infinito ⇒ No attenuazione
–
Angolo: posizione della sorgente luminosa rispetto al punto
fATT.DIST
1
a bd cd 2
fATT.ANG Kang cos k ( x)
Modello di Phong [2]
Tipologie di riflessione (componenti):
–
–
–
Luce Ambientale: approssima il fenomeno della inter-riflessione diffusa tra oggetti della scena,
uniforme in ogni punto
IAMBIENTE Ka Ia
Luce Riflessa Diffusa: riflessa da una
superficie perfettamente diffusiva
IDIFFUSA IINCIDENTE Kd (N L)
ugualmente verso qualsiasi direzione
Luce Riflessa Speculare: la luce riflessa (versore r) esce dalla superficie come cono di luce,
con intensità funzione dell'angolo Φ (tra v, osservatore, e r, simmetrico rispetto la normale del
versore L, luce incidente)
Valido per k sorgenti luminose.
Il calcolo va effettuato per ognuno dei canali RGB.
ISPECULARE W( ) IINCIDENTE Ks (N H) n
I IAMBIENTE k [fATT.DIST k fATT.ANG k (IDIFFUSAk ISPECULAREk)]
Metodi di Illuminazione
• Flat Shading: si calcola Phong su un punto per ogni
poligono e si assegna il valore risultante a tutti i punti del
poligono
• Metodo di Gouraud
– Si definisce il vettore n in ciascun vertice
di
un poligono come media pesata delle
normali dei
poligoni attorno al vertice stesso
e si applica
Phong su ciascuno dei vertici
– Trovo la I per ogni punto interpolando linearmente le I dei vertici
• Metodo di Phong: simile a Gouraud, ma vengono
interpolate le normali dei vertici per trovare la normale di
ogni punto con cui si ricalcola Phong. Richiede un numero
maggiore di calcoli ma dà risultati migliori.
Texture Mapping (Catmull ’74)
• Tecnica che consiste nell’applicare un’immagine bidimensionale su un oggetto 3D composto da uno o
più poligoni
Texture Map
• Funzione che associa un textel (punto della texture) ad ogni
punto della superficie di un oggetto geometrico e poi proietta
questi punti sullo schermo
• In pratica è una matrice bi-dimensionale contenente dati
indirizzati dalle coordinate s e t
• Vi sono tipicamente due strategie per poter mappare una texture
su una superficie:
– Mappatura diretta: dato un textel (s, t) nella texture si trova il punto
(x, y, z) dell’oggetto su cui tale pixel viene mappato e, con una
funzione di proiezione, si trova il suo corrispondente (xs, ys).
– Mappatura indiretta: Per ogni pixel (xs, ys) si trova nella texture la
corrispondente coordinata (s, t).
• Non è detto che numero e coordinate dei textel corrispondano a
quelle dei pixel e viceversa: si usano tecniche di aliasing
(Magnification e Minification - MIPMAPping)
Rendering
• L’ultima fase della pipeline di rendering assegna una gradazione
di colore ad ogni fragment tramite il modello di shading
• Invece di incrementare la complessità della Mesh, si
aggiungono particolari alla scena come parte del processo di
Rendering
• Gli algoritmi di mapping modificano i risultati dello shading sulla
base di un vettore bidimensionale (map) che contiene, in ogni
elemento, diversi tipi di dati
• La map viene applicata dopo il calcolo dell’illuminazione per
modificare:
– colore, luminosità, trasparenza… (scalari -> texture mapping)
– Parametri utilizzati nel modello di Phong (normali -> bump
mapping)
Bump Mapping (Blinn ’78)
•
•
•
Tecnica che perturba la normale in un punto tramite il valore
corrispondente nella Bump Map (texture)
Altera lo shading della superficie senza modificarne la geometria (il
modello locale di illuminazione usa la normale per calcolare l’intensità
di colore), simulando un effetto di profondità
Non proietta alcuna ombra, non copre altri oggetti
Bump Mapping (Blinn ’78)
Bump Mapping [2]
• Sia P(u,v) un generico punto della superficie (parametrizzata)
da perturbare
• Sia data la mappa B(u,v) che specifica la perturbazione
(virtuale) da applicare alla superficie, spostando il punto P(u,v)
lungo la sua normale della quantità B(u,v)
• La normale in P è dunque (normalizzata)
dove Pu e Pv sono le derivate parziali rispetto ai due parametri
Bump Mapping [3]
•
Se spostassimo P lungo n di un valore B(u,v) si otterrebbe:
•
Per calcolare la nuova normale n’ derivo P’(u,v) rispetto a u e v:
•
Supponendo che B(u,v) sia sufficientemente piccola e la superficie
sufficientemente regolare da poter trascurare l’ultimo termine:
•
Se applicando il modello di illuminazione a P si usa n’ al posto di n si
ottiene l’impressione che il punto sia stato perturbato.
Bump Map
• Le Bump Map sono immagini in scala di grigio (usano un
solo canale per i dati di perturbazione)
• Le aree più chiare (bianco) sono renderizzate come aree
che “escono dalla superficie” mentre le aree più scure
(nero) sono renderizzate come depressioni
Texture
Map
Bump
Map
Difetti del Bump Mapping
•
Se il punto di vista è troppo vicino o quasi parallelo rispetto alla
superficie si nota chiaramente che essa è piatta
•
Necessario utilizzare due textures (texture map classica + height
map), ricalcolare le normali su tutti i punti e riapplicare l’algoritmo di
shading
•
Utilizzabile solamente per simulare limitate scabrosità, rugosità
Normal Mapping (Peercy ’97)
• Miglioramento del Bump Mapping:
– più preciso in quanto usa delle Normal Map “colorate” con 3
canali
– più rapido in quanto la Normal Map contiene già le normali
perturbate (non sono necessari ulteriori calcoli)
Normal Map
•
Texture che codifica le coordinate delle normali alla superficie
già perturbate, nei 3 canali RGB (al posto di valori di colore)
–
–
–
•
Red: coordinate x, destra-sinistra
Green: coordinate y, giù-su
Blue: coordinate z, solo positive, fuoriesce
I valori dei 3 canali, che sono riferiti allo Spazio Texture,
devono essere trasformati in coordinate nello Spazio Tangente:
–
–
Spazio Texture: range di valori [0-255]
Spazio Tangente: range di valori [-1,1]
Creare una Normal Map
•
Detail Preservation
•
Da una High map: non si migliora il dettaglio, ma velocizza i
calcoli
Si usano generalmente dei tool forniti dai programmi di grafica
•
Displacement Mapping (Cook
’84)
• Tecnica di Rendering Geometry-Based, modifica la
geometria di una superfice in base ad una immagine
presente su di una texture
• Durante il rendering, le displacement map modificano la
geometria, producendo effetti di qualità più elevata, al
prezzo di un maggior numero di triangoli
• Non utilizzabile nelle applicazioni Real Time
Parallax Mapping (Kaneko ’01)
• Parallasse: fenomeno per cui un oggetto sembra spostarsi
rispetto allo sfondo se si cambia il punto di osservazione
• Tecnica che approssima la parallasse su una superficie come se
fosse scabrosa, in modo da aumentarne il dettaglio
• Non simula Occlusions o Self Shadowing
• Quando si osserva una superficie su cui è stato applicato il
Parallax Mapping da un certo angolo, i punti più alti oscureranno
i punti più bassi dietro di loro
Parallax Mapping (Idea)
• Se guardassimo la superficie piatta, dalla direzione
dell’osservatore, vedremmo il punto A
• Se, osservando nella stessa direzione il poligono, fossero
presenti anche le scabrosità che vorremmo ottenere, non
vedremmo più il punto A bensì il B
• Potremmo “spostare” di un certo offset la coordinata texture
(applicata alla superficie) corrispondente al punto A
• L’offset di ogni textel viene calcolato in funzione dell’Height Map
associata
Height Map
• Mappa di elevazione:
– Rappresenta la variazione di altezza della superficie
– Correlata con la texture map
– Contiene un valore di altezza per ogni textel [0.0 - 1.0]
Calcolo dell’offset
• Dati:
– V = vettore Osservatore normalizzato
– Hsb = altezza scalata del punto T0 dalla height map
• Si traccia un vettore parallelo (offset) al poligono dal
punto A al vettore Osservatore
Per-Pixel Texture
Coordinate Addressing
• Bisogna indirizzare le coordinate della texture per ogni
pixel
• u e v sono le coordinate texture sorgente e u’ e v’ sono
quelle risultanti
• M è una matrice 2x2, definita dall’utente, per scalare e
ruotare le coordinate texture (in base a particolarità della
superficie da rappresentare)
• Δu e Δv sono dei valori di variazione delle coordinate
texture (trovate con il calcolo dell’offset)
• I risultato è inserito in una distortion map
Parallax VS Bump
Pro e Contro del Parallax
• Vantaggi:
– Costo elaborativo molto basso: vengono solamente
modificate delle coordinate texture producendo una texture
distorta
– Può essere usata con tutti i tipi di mapping
– Possibile aumentare la complessità della geometria
• Svantaggi:
– Le modifiche alla texture non sono perfette
– E’ errata l’assunzione che l’altezza del punto, dopo aver
distorto la texture, rimanga la stessa (può andare bene per
punti molto vicini)
– Funziona male con height maps che variano continuamente
il valore di altezza
Offset-limited Parallax
Mapping
• Attenua ma non elimina il problema dell’altezza
• Vettore offset non deve mai essere maggiore di hsb
• Se T0 e Tn sono vicini, è più probabile che la loro
altezza sia simile
• L’equazione da usare è la seguente:
Conclusioni
•
•
•
Negli ultimi anni (dal 2001 in poi) si sono sviluppate molte
tecniche basate su Bump e Parallax Mapping
Queste tecniche hanno tipicamente l’obiettivo di migliorare il
rendering o di aggiungere algoritmi per calcoli più precisi su
diverse componenti della superficie, senza arrivare a calcoli
troppo onerosi
Alcune di esse:
–
–
–
–
Relief Texture Mapping
Iterative Parallax Mapping
Interval Mapping
Steep Parallax Mapping
fine parte cenni di tessiture