5.3. Omnidirezionale

5
Il tuo voto: Nessuno Media: 5 (2 voti)

Questo tipo di sorgente luminosa è caratterizzata dalla presenza di un vettore che ne specifica la posizione; da questa posizione i raggi luminosi si irradiano in qualsiasi direzione con uguale intensità. Un tale tipo di sorgente si adatta bene ad essere utilizzato come punto di illuminazione locale e non di rado è accoppiato con sistemi di particelle per la simulazione di effetti luminosi.

L'intensità di questo tipo di sorgenti è determinata da due fattori: l'angolo di incidenza (secondo la legge di Lambert già vista in precedenza) e la distanza di una geometria dall'origine della sorgente stessa. Quest'ultimo parametro può essere controllato in differenti modi: seguendo le leggi della fisica per cui l'intensità decade secondo l'inverso del quadrato della distanza in metri; secondo l'inverso della distanza; tramite un raggio che definisce la distanza massima oltre la quale l'intensità luminosa è pari a zero.

decadimento = 1 / dist2  oppure  1 / dist  oppure  1 - min(raggio / dist, 1)
intensità = (normale · LightVec) * decadimento

Questi tre metodi permettono rispettivamente un controllo sempre crescente sia dell'intensità luminosa che dell'illuminazione globale di una scena quando più sorgenti concorrono; tuttavia se sono utilizzati congiuntamente a modelli di illuminazione avanzati per la geometria statica (radiosity, global-illumination, ecc...) solamente il primo o al massimo il secondo metodo permettono un'integrazione convincente.

  // Calcolo della distanza dalla sorgente luminosa in metri
  // ammettendo che il modello sia in centimetri
  float dist = length(LightVec) * 0.01;
  // Calcolo del decadimento dovuto alla distanza, in questo
  // caso rispettando la fisica, ma il decadimento può essere
  // anche lineare (1.0 / dist)
  float decay = 1.0 / (dist * dist);

  // Normalizzo i vettori provenienti dal VertexShader
  NormalVec = normalize(NormalVec);
  LightVec = normalize(LightVec);

  // Intensità secondo Lambert
  float intensity = saturate(dot(NormalVec, LightVec));

Risultato dell'implementazione:

Nell'immagine precedente è presente una componente ambientale azzurra per evitare che il modello sia parzialmente invisibile.