E' incredibile quanto le ombre all'interno di una scena in tre dimensioni possano aumentare il livello di realismo. In questo progetto ho implementato un metodo per la visualizzazione delle ombre all'interno di una scena OpenGL basandomi sui principi della tecnica denominata Shadow Mapping.
La prima cosa che ho fatto è stato preparare il codice per importare e visualizzare degli oggetti 3D nel formato obj.
Come oggetti di prova cosa c'è di meglio di una bella scacchiera? Ecco come si presenta il re in wireframe con l'algoritmo di importazione di ShdowPlace.
Visualizzazione in wireframe.
Visualizzazione a punti.
Visualizzazione solida.
Una scena più complessa con diversi elementi.
L'aggiunta delle luci comincia a dare realismo alla scena.
Aggiunta delle texture.
Ho deciso di approfittare di questo progetto per studiare un sistema di visualizzazione delle ombre. E' la prima volta che mi avventuro in questo campo. Dopo alcune ricerche sono arrivato alla conclusione che principalmente ci sono due sistemi per visualizzare delle ombre.
Questa tecnica prevede la costruzione di un contorno d'ombra per ogni singolo oggetto. Questo contorno viene poi proiettata sulla scena. Il problema di questa tecnica è che per ogni oggetto bisogna ricostruire l'ombra e con molti oggetti questo potrebbe risultare troppo pesante dal punto di vista di calcolo.
La tecnica dello shadow mapping mi è parsa molto interessante. In pratica questa tecnica può venire applicata su una qualsiasi scena, senza dover aggiunggere del codice aggiuntivo durante la fase di visualizzazione degli oggetti. Il funzionamento è il seguente: la scena viene renderizzata una prima volta dal punto di vista della luce. In questo modo possiamo vedere quali punti della scena sono illuminati perchè tutto quello che "vede" la luce non può essere in ombra. A questo punto i livelli di profondità (deep values) vengono memorizzati in una apposita texture (non tutte le schede grafiche supportano questa funzionalità). A questo punto la scena viene renderizzata dal punto di vista della camera e la texture generata in precedenza viene proiettata sulla scena. Sulle zone della scena su cui viene proiettata la texture non dovrà venire visualizzata alcuna ombra.
Lo svantaggio di questa tecnica è che ogni scena deve venire renderizzata due volte (o meglio una in più per ogni luce) ma ha il grande vantaggio di permettere la visualizzazione delle ombre senza dover in alcun caso tenere conto del numero di poligoni della scena.
La prossima immagine mostra una prima implementazione di questa tecnica. Nell'immagine si può notare come le ombre risultino seghettate. Questo problema è dovuto dalla dimensione della shadow map (texture). In pratica più la texture è grande e più la risoluzione delle ombre sarà migliore. Questo è il problema più grande di questa tecnica. Ultimamente sono state sviluppate alcune tecniche che permettono di ridurre al minimo questo problema come la tecnica di Perspective shadow mapping oppure la più recente Trapezoidal Shadow Maps che sembra essere la migliore tecnica per la visualizzazione di ombre. Al momento non ho intenzione di programmare questa tecnica per via della sua complessita di implementazione.
La scena con una deep map a bassa risoluzione. Do notare come questa tecnica proietta le ombre, oltre che sul fondo, anche sugli oggeti stessi.
Aumentando la risoluzione della deep map otteniamo dei bordi molto più definiti.
La stessa scena con una deep map con una risoluzione ancora più alta. La qualità delle ombre risultà davvero ottima.