4.4. Componente riflettente

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

Questa componente, come la precedente, è individuata dalla luce riflessa in modo speculare proveniente dall'ambiente circostante, ma in questo caso è influenzata cromaticamente dall'ambiente stesso. La sua intensità può essere costante per tutta la superficie dell'oggetto, quando si vuole creare un materiale assimilabile ad uno specchio o ad un metallo cromato; può invece seguire la legge della riflessione di Fresnel per tutti quei materiali anche non trasparenti che hanno una finitura lucida o semi-lucida. In quest'ultimo caso la quantità di luce riflessa dipende dall'angolo che esiste tra l'inverso del vettore vista e la normale locale producendo l'effetto per cui una superficie risulta non riflettente quando è parallela al piano dello schermo e sempre più riflettente quanto più diviene perpendicolare.

È interessante notare che questo effetto è dovuto ad un fenomeno ottico in cui sono coinvolte sia la riflessione che la rifrazione (per questo è necessario fare riferimento all'indice di rifrazione) e proprio tramite l'applicazione della legge della riflessione di fresnel è possibile determinare la quantità di luce riflessa e la quantità di luce rifratta. Nel nostro caso, essendo la finitura di un materiale molto sottile possiamo ignorare il calcolo della distorsione dovuta alla rifrazione e calcolare solo la quantità di luce riflessa.

 

L'equazione della riflessione di Fresnel presentata qui sopra non può essere eseguita sulle GPU per la sua complessità; per questo normalmente vengono utilizzate delle approssimazioni che gener

ano risultati quanto più fedeli possibile rispetto all'originale intaccando minimamente la performance dello shader.

R(α) = R(0) + (1.0 - R(0))(1.0 - cos(α))5

Utilizzando l'equazione qui sopra basterà calcolare R(0) una sola volta con l'equazione di Fresnel per poi passare il valore al Pixel Shader ed utilizzare l'approssimazione.

Codice HLSL da implementare nel Pixel Shader:

  // Calcolo dell'intensità della riflessione Fresnel
  float fresnel = r0 + (1.0 - r0) * pow(1.0 - saturate(dot(-ViewVec, normal)), 5);

Ora che si conosce l'intensità del riflesso dobbiamo recuperare il colore di un dato punto della scena; questo è possibile, per ora, solamente  tramite l'utilizzo di una cube-map, in questo caso chiamata environmental-map o mappa ambientale. Tale mappa può essere calcolata in tempo reale, ma per poche geometrie, oppure essere precalcolata una sola volta per tutti gli oggetti che necessitano di un materiale riflettente. La differenza tra i due metodi, oltre che nell'impatto in prestazioni, sta nell'esattezza del riflesso prodotto, infatti per far si che la tecnica funzioni correttamente la mappa ambientale deve avere origine esattamente nel centro dell'oggetto su cui è applicata, con la necessità di ricalcolarla ogni volta che l'oggetto si muove; utilizzando la seconda tecnica è palese che più l'oggetto si sposta dalla sua posizione originale e maggiore sarà l'errore nel riflesso. La trattazione di questa tecnica verrà effettuata successivamente in un capitolo separato, è tuttavia utile immaginare le mappe ambientali come un cubo che contenga completamente l'oggetto.

A differenza delle textures bidimensionali, una cube-map è formata da sei superfici quadrate di uguale dimensione (i lati del cubo), ognuna delle quali è rivolta verso uno dei tre assi principali o nella direzione esattamente opposta (x, y, z, -x, -y, -z). Proprio per questa conformazione nella funzione per recuperare il texel ( texCUBE(sampler s, float3 uvw) ) sarà necessario un vettore di tre componenti che nel nostro caso è rappresentato esattamente dal riflesso del vettore vista in world-space rispetto alla normale locale in world-space.

Utilizzando questo vettore nella funzione per recuperare il texel dalla cube-map e modulando il colore ottenuto con l'intensità calcolata precedentemente, avremo l'apporto di colore totale per la componente riflettente.