5.6. Basata su immagini

5
Il tuo voto: Nessuno Media: 5 (1 vote)

L'image-based lighting (illuminazione basata su immagini) è una tecnica che viene utilizzata, sia in ambito real-time che con motori di rendering off-line, quando c'è bisogno dell'integrazione convincente tra una scena che può essere reale ed uno o più modelli virtuali creati con pacchetti 3D (come 3D Studio MAX, Maya, Blender, ecc...). Abbiamo in realtà gia visto fugacemente questa tecnica nella sezione dedicata ai materiali, più precisamente nella trattazione della componente riflettente, tuttavia in questo capitolo approfondiremo il suo utilizzo sia per l'illuminazione diffusa che per quella speculare e riflettente; in questo caso specifico infatti, e per tutto il resto di questo capitolo le due ultime componenti si riuniranno in una sola.

L'immagine grazie alla quale viene calcolata l'illuminazione è una environmental-map, spesso in formato HDR (16 o 32-bit in floating-point per componente di colore) strutturata come una cube-map; questo prevede che la texture sia composta da sei superfici quadrate di uguale dimensione disposte parallelamente alle facce di un cubo. Il formato HDR non è obbligatorio e non sarà utilizzato in questa sede perchè richiederebbe la presenza di successive elaborazioni come il tone-mapping per far si che un oggetto sia visualizzato correttamente in un monitor.

Nei pacchetti 3D vengono spesso utilizzate delle fotografie opportunamente arrangiate, mentre per gli engine real-time queste textures sono generate separatamente da apposite applicazioni, oppure calcolate all'interno del'engine stesso renderizzando la scena circostante lungo i sei punti di vista che costituiscono le normali delle facce del cubo con impostazione del campo visivo della telecamera pari a 90°.

Tralasciando l'utilizzo che ne viene fatto nei pacchetti 3D, l'implementazione di questa tecnica per l'illuminazione diffusa e speculare/riflettente di un oggetto è davvero semplice. Per la prima è sufficente utilizzare la normale locale in world-space; per la seconda, come abbiamo già visto precedentemente, dobbiamo calcolare il riflesso del vettore vista in world-space rispetto alla normale locale in world-space. Questi due vettori andranno utilizzati nel parametro vec della funzione texCUBE(sampler s, float3 vec) per recuperare il colore della luce che proviene dalla direzione specificata.

  // Recupero texel per l'illuminazione diffusa
  float4 diffCube = texCUBE(diffuseCubeSampler, WorldNormalVec);

  // Recupero texel per l'illuminazione speculare
  float3 reflVec = reflect(WorldViewVec, WorldNormalVec);
  float4 reflCube = texCUBE(specularCubeSampler, reflVec);

Entrando nello specifico, questa tecnica non presenta nessun problema di implementazione per l'illuminazione speculare/riflettente, mentre per l'illuminazione diffusa si rende necessario che la texture utilizzata come environmental-map sia stata precedentemente "sfocata" con un filtro gaussiano che sia applicato anche tra una superficie e quelle adiacenti della texture rendendo proprio per questo problematica, se non impossibile, l'implementazione real-time. È infatti possibile forzare da Pixel Shader quale livello di mip-map utilizzare (un livello più alto produce un'illuminazione diffusa anche da una texture non filtrata, solo Shader Model 3.0 e superiore), il problema maggiore è che le sei superfici restano indipendenti con la consequente visibilità netta dei bordi tra una superficie e l'altra (tra due faccie del cubo della environmental-map). Una buona applicazione che esegue il filtraggio come descritto sopra è CubeMapGen di ATI/AMD.

Per ottenere il colore definitivo di un dato punto della geometria basterà modulare il colore recuperato dalla environmental-map diffusa o speculare/riflettente rispettivamente con quello della texture riguardante la componente diffusa o speculare di un materiale.