ROBOTICA

video
immagini
papers
progettati
costruiti
toolbox
vrml
simulatori

links

 

Papers
meccanica
sistemi
documents

Capitolo 11° Rendi realistico il tuo mondo aggiungendo textures Capitolo 13°

Cerchiamo ora di rappresentare in maniera più realistica le superfici dei nostri oggetti. Il mezzo migliore è quello di mappare sopra di essi delle textures. Facendola breve, ricopriamo una superficie con una immagine, mappando i pixels dell’immagine in maniera opportuna.

Nei precedenti esempi avevamo associato dei colori alle superfici tramite il nodo Material (contenuto a sua volta nel nodo Appearance). Nella realtà è però difficile trovare delle superfici a colore uniforme ; è per questo che Vrml consente l’impiego di textures. Il nodo Appearance non contiene solo il field material. Infatti vi sono altri 2 campi, uno dei quali analizziamo in questo paragrafo.

In particolare la defizione del nodo Appearance è la seguente :

Appearance {
	exposedField SFNode material            NULL
	exposedField SFNode texture             NULL
	exposedField SFNode textureTransform    NULL
}

Tralasciamo per il momento la parte sinistra delle dichiarazioni : le analizzeremo più in là nel corso del tutorial. Quello che ora mi interessa evidenziare è la presenza dei campi texture e textureTransform.

Se vogliamo dunque caratterizzare una superficie con una texture, basta introdurre nel nodo Appearance il field texture e fornire delle indicazioni sull’immagine da usare. Il seguente esempio chiarisce l’uso di tale campo.

#VRML V2.0 utf8
# esempio di utilizzo di textures
Shape {
	appearance Appearance {
		material Material { emissiveColor 1 0 0 }
		texture ImageTexture {url  “texture.gif”}
	}
	geometry Sphere { }
}

In questo semplice esempio, ricopro la superficie della sfera con l’immagine contenuta nel file ‘texture.gif’.

Il field texture contiene al suo interno il nodo ImageTexture il quale a sua volta contiene il field url che specifica il pathname del file da usare come texture.

L’immagine viene mappata in maniera tale da ricoprire tutta la superficie della sfera. I formati di files supportati sono GIF e JPG.

Come si può notare, utilizzo anche il campo material e attribuisco un colore rosso alla sfera. Tale azione sembrerebbe perfettamente inutile in quanto l’immagine che andrà a ricoprire la sfera annullerà qualsiasi componente di colore sottostante. Quando però si hanno molte textures da caricare, il browser consente all’utente di navigare la scena ancor prima che queste siano state caricate ; in questi momenti la superficie apparirà del colore specificato nel campo material.

L’impiego di textures può far fare un salto di qualità al vostro mondo, contribuendo a fornire un forte impatto realistico. Alcuni blocchi di granito per esempio, potrebbero essere resi semplicemente creando una box e applicando una texture rappresentante appunto questo materiale. Oppure ancora, tornando all’esempio della banale casa visto in precedenza, potremmo migliorare di molto la situazione mappando sui lati della box l’immagine della facciata di una casa.

Sembrerebbe dunque conveniente usare sempre e ovunque textures. Il problema è che ogni texture introdotta nel mondo deve essere caricata dal browser. Trovandoci su Internet il dover downloadare un sacco di textures potrebbe rallentare di molto il caricamento. Un altro grosso problema è che inserendo molte textures si diminuisce di molto il frame rate in fase di rendering, arrivando ben presto ad una sensazione di movimento a scatti. Inutile dire che la cosa è molto fastidiosa. Questo problema potrà essere limitato o anche annullato per stazioni grafiche ad alte prestazioni, ma per le grandi masse la situazione non è ottimale.

Per cui l’ideale è impiegare textures piccole e solo dove occorre. Evitare dunque grosse immagini.

Vediamo ora un semplice esempio di utilizzo di textures. Supponiamo di voler creare una colonna (non sono un architetto per cui non lamentatevi delle imprecisioni che farò in questo esempio).
Rappresentiamo la colonna in maniera molto semplice. Un cilindro alla base ; un cilindro più sottile e lungo centrale e un cilindro più corto posto in alto. Guardate la figura e capirete certo meglio.
Su ognuno di questi cilindri mappiamo una piccola texture caratterizzante un particolare marmo. Si faccia particolare attenzione a come sono collegati i vari cilindri fra di loro.

#VRML V2.0 utf8
# una semplice colonna con texture
Transform {
  translation 0 .2 0
  children [
    Shape {
      appearance Appearance {
	texture ImageTexture {url “marble.jpg”}
      }
      geometry Cylinder {
	radius 1
	height .4
      }
    }
    Transform {
	translation 0 2.7 0
	children [
	  Shape {
	    appearance Appearance {
	      texture ImageTexture {url  “marble.jpg”}
	    }
	    geometry Cylinder {
	      radius .7
	      height 5
	    }
	  }
	  Transform { 
	    translation 0 2.7 0
	    children [
	      Shape {
		appearance Appearance {
		  texture ImageTexture {url  “marble.jpg”}
		}
		geometry Cylinder {
		  radius 1
		  height .4
		}
	      }
	    ]
	  }
	]
     } 
   ]
}

L’esempio è particolarmente semplice e non è scritto pensando ad ottimizzare. Si potrebbe accorciare di molto il sorgente per ottenere lo stesso effetto ma ancora non abbiamo visto ciò che ci serve.

colonna

Vrml si comporta in maniera diversa nel mapping delle textures a seconda delle primitive su cui vengono applicate. Abbiamo già visto che con sfere e cilindri l’immagine viene adattata per ricoprire l’intera superficie. Lo stesso accade con il cono. Suggerirei di fare delle prove per vedere come di fatto avviene il mapping su queste primitive.
Su una box invece, la texture viene ripetuta su tutte le facce.
Infine, su un oggetto creato con IndexedFaceSet l’immagine viene adattata in modo da ricoprire tutte le facce.

Questo modo di usare textures risulterà quello più utilizzato. Non sempre però risulta l’approccio più soddisfacente per quello che ci proponiamo ; soprattutto per quanto riguarda il mapping su IndexedFaceSet. Quello che occorre è un maggior controllo su come vengono mappate le immagini.

Non affronteremo ora questi e altri argomenti che riguardano textures. Verso la fine del tutorial verranno approfondite queste tematiche, soprattutto per quanto riguarda l’introduzione delle coordinate s,t per assumere controllo sul come vengano mappate le immagini sulle facce che costituiscono il nostro oggetto.

Per chiudere questo primo approccio all’introduzione di textures nei nostri mondi consideriamo l’utilizzo di textures trasparenti e l’introduzione di movie.

Come texture nel campo url si può specificare un’immagine con attributi di trasparenza. Se per esempio usiamo una texture contenente una scritta su sfondo bianco, potremmo rendere il bianco trasparente e poi mappare la texture su una box. A questo punto si osserveranno soltanto le scritte sulle facce della scatola creata.

L’ultimo argomento visto in questo capitolo riguarda l’aggiunta di textures animate. Per l’aggiunta di questo ulteriore effetto serve ben poco oltre a quello che già conosciamo. Basta specificare nel nodo Appearance un field texture contenente un nodo MovieTexture. Il formato supportato è MPEG-1.

Il seguente semplice esempio mappa il filmato MPEG-1 su una faccia.

#VRML V2.0 utf8
Shape {
  appearance Appearance {
     texture MovieTexture {
       url “movie.mpg”
       loop TRUE
       startTime 1
     }
  }
  geometry IndexedFaceSet {
    coord Coordinate {
      point [ 0 0 0, 20 0 0, 20 20 0, 0 20 0 ]
    }
    coordIndex [0, 1, 2, 3, -1]
}

La sintassi e le opzioni sono molti banali. Il campo loop impostato a TRUE indica che il video è da ripetere in continuazione. startTime indica invece il punto da cui inizialmente partire. Analizzeremo meglio il concetto di tempo e di come esso trascorra nei mondi Vrml più in là nel tutorial. A maggior ragione qui valgono le considerazioni circa la cautela con cui usare textures. Impiegare video MPEG nei nostri mondi può portare ad estenuanti tempi di download e a eccessivi rallentamenti in fase di rendering.