Nozioni di base sull'illuminazione in OpenGL. Illuminazione in opengl es - sviluppo di giochi per sistema operativo Android Come funziona l'illuminazione

OpenGL utilizza il modello di illuminazione Phong, in cui il colore di un punto è determinato da diversi fattori: proprietà del materiale e della trama, l'entità della normale in quel punto e la posizione della sorgente luminosa e dell'osservatore. Per calcolare correttamente l'illuminazione in un punto, è necessario utilizzare singole normali, tuttavia comandi come glScale..() possono modificare la lunghezza delle normali. Per tenerne conto viene utilizzata la modalità di normalizzazione già menzionata, che viene abilitata richiamando il comando glEnable(GL_NORMALIZE).

OpenGL prevede l'impostazione di tre parametri che determinano le leggi generali di applicazione del modello illuminotecnico. Questi parametri vengono passati alla funzione glLightModel() e ad alcune delle sue modifiche. Per impostare i parametri di illuminazione globali, utilizzare i seguenti comandi:

void glLightModel(GLenum nome p, GLenum param)

void glLightModelv(GLenum pname, const GLtype *params)

L'argomento pname specifica quale parametro del modello di illuminazione verrà modificato e può assumere i seguenti valori:

GL_LIGHT_MODEL_LOCAL_VIEWER - se il punto di vista è locale o remoto. OpenGL calcola le riflessioni speculari utilizzando il "vettore intermedio" h=s+v descritto in precedenza. Le direzioni reali s e v sono diverse per ciascun vertice della mesh. Se la sorgente luminosa è direzionale, il vettore magnitudine s è costante, ma v varia ancora da vertice a vertice. La velocità di rendering aumenta se si rende il vettore v costante per tutti i vertici. Per impostazione predefinita, OpenGL utilizza v=(0,0,1), con il vettore che punta verso l'asse z positivo nelle coordinate della fotocamera. Allo stesso tempo, puoi forzare la pipeline grafica a calcolare il vero valore del vettore v per ciascun vertice eseguendo l'istruzione:

GlLightModel(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);

Il parametro param deve essere booleano e specifica la posizione dell'osservatore. Se è FALSO, la direzione della vista è considerata parallela all'asse z, indipendentemente dalla posizione nelle coordinate della vista. Se è TRUE, allora l'osservatore si trova all'origine del sistema di coordinate della vista. Ciò può migliorare la qualità dell'illuminazione, ma rende più difficile il calcolo. Valore predefinito: FALSO.;

GL_LIGHT_MODEL_TWO_SIDE - se entrambi i lati del poligono sono dipinti correttamente. Il parametro param deve essere booleano e controlla la modalità di calcolo dell'illuminazione sia per la faccia anteriore che per quella posteriore. Se è FALSO, l'illuminazione viene calcolata solo per le facce anteriori. Se è VERO il calcolo viene effettuato anche per le facce rovesce. Valore predefinito: FALSO. Ciascuna faccia poligonale del modello ha due lati. Durante la modellazione, puoi considerare l'interno e l'esterno. È consuetudine elencare questi vertici in senso antiorario se visti dall'esterno dell'oggetto. La maggior parte degli oggetti wireframe rappresentano corpi solidi che racchiudono uno spazio, in modo che i concetti di esterno e interno siano chiaramente definiti. Per tali oggetti, la telecamera può osservare solo la superficie esterna di ciascuna faccia (a meno che, ovviamente, la telecamera non si trovi all'interno dell'oggetto). Con la corretta rimozione delle superfici invisibili, la superficie interna di ciascuna faccia viene nascosta alla vista da una faccia più vicina.

OpenGL non ha il concetto di "interno" e "esterno", può solo distinguere tra "facce anteriori" e "facce non facciali". Una faccia è frontale se i suoi vertici sono elencati in senso antiorario, nell'ordine in cui li vedono l'occhio. Puoi invertire questo ordine utilizzando la funzione glFrontFace(GL_CW), che specifica che una faccia è frontale solo se i suoi vertici sono elencati in ordine orario. Per un oggetto che racchiude uno spazio, tutti i bordi che l'occhio vede sono facce anteriori e OpenGL li disegna e li ombreggia correttamente. Anche le facce non facciali vengono disegnate in OpenGL, ma finiscono per essere nascoste dietro le facce più vicine. Puoi velocizzare il processore disabilitando il rendering OpenGL dei volti diversi dai volti. Viene utilizzato il seguente codice:

glCullFace(GL_BACK);

glAbilita(GL_CULL_FACE);.

La situazione è diversa in Errore: Fonte di riferimento non trovata, b, dove viene mostrato un parallelepipedo con una faccia rimossa. Come prima, le frecce mostrano l'ordine in cui i vertici di ciascuna faccia vengono inviati alla pipeline grafica. Tre dei volti visibili non sono rivolti. Per impostazione predefinita, OpenGL non può ombreggiare correttamente i bordi. Per dipingere correttamente le facce non facciali, è necessario istruire OpenGL utilizzando l'istruzione glLightModel (GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE). Quando viene eseguito questo comando, OpenGL cambia la direzione delle normali di tutte le facce non facciali in modo che puntino verso l'osservatore, dopodiché l'ombreggiatura avviene correttamente. La modifica del valore GL_TRUE in GL_FALSE disabilita questa opzione. I bordi disegnati con OpenGL non proiettano ombre, quindi tutte le facce non facciate ricevono la stessa luce dalla sorgente, anche se c'è un'altra faccia tra loro e la sorgente luminosa;

GL_LIGHT_MODEL_AMBIENT: colore della luce di sfondo globale. Il parametro params deve contenere quattro numeri interi o reali che specificano il colore dell'illuminazione di fondo anche in assenza di determinate sorgenti luminose. Per ogni scena è possibile impostare una luce di sfondo globale indipendente da qualsiasi fonte specifica. Per creare tale illuminazione, impostane il colore utilizzando i seguenti comandi:

GLfloat amb = (0,2, 0,3, 0,1, 1,0);

glLightModelfv(GL_LIGHT_MODEL_AMBIENT, amb);

Questo codice conferisce alla sorgente luminosa di sfondo un colore pari a (0,2, 0,3, 0,1). Il valore predefinito è (0.2, 0.2, 0.2, 0.1), quindi la luce di sfondo è sempre presente a meno che non la modifichi deliberatamente. L'impostazione della sorgente di sfondo su un valore diverso da zero garantisce che gli oggetti nella scena siano visibili anche se non è stata attivata alcuna funzione di illuminazione;

GL_LIGHT_MODEL_COLOR_CONTROL separazione della componente speculare del colore. Per i calcoli dell'illuminazione convenzionale, le componenti di fondo, diffusa, speculare ed emissiva vengono calcolate e semplicemente sommate. Per impostazione predefinita, la mappatura delle texture viene applicata dopo l'illuminazione, quindi le luci speculari potrebbero apparire disattivate o le texture avranno un aspetto diverso. La successiva chiamata a glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL,GL_SEPARATE_SPECULAR_COLOR) OpenGL separa il calcolo del colore speculare dall'applicazione. L'illuminazione genera quindi due colori per ciascun vertice: un colore iniziale costituito dalle componenti dell'illuminamento non riflesso, e un secondo colore che è la somma delle componenti dell'illuminamento speculare. Durante il rendering delle texture, solo il primo colore viene combinato con i colori della texture. Una volta completata l'operazione di testurizzazione, il secondo colore viene aggiunto alla combinazione finale del primo e dei componenti del colore della texture. Gli oggetti illuminati e strutturati con separazione dei colori speculari sono in genere più visibili e presentano riflessi speculari più evidenti. Per tornare alle impostazioni predefinite, è necessario chiamare glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL,GL_SINGLE_COLOR). Successivamente, ancora una volta il colore originale sarà costituito da tutte le componenti del colore: diffuso, diffuso, emissivo e speculare. I componenti di illuminazione non vengono aggiunti dopo la creazione delle texture.

L'illuminazione di uno spazio è un processo attraverso il quale questo spazio viene riempito di luce e tutti gli oggetti in esso contenuti vengono resi visibili.
L'illuminazione di qualsiasi oggetto dipende da due fattori:

  • Il primo è il materiale con cui è realizzato l'oggetto.
  • La seconda è la luce con cui viene illuminato.

A seconda dell'implementazione OpenGL, nella scena potrebbero essere presenti otto o più luci. L'illuminazione è disabilitata per impostazione predefinita. Puoi abilitare la sorgente luminosa nulla con il comando:

  • glAbilita(GL_LIGHT0);

Il resto è abilitato in modo simile, dove è specificato GL_LIGHTi invece di GL_LIGHT0. Dopo aver abilitato la sorgente, è necessario impostarne i parametri. Se il tuo corpo monotono è illuminato uniformemente, non puoi vederne il sollievo. Pertanto è necessario utilizzare fonti di luce.
Esistono tre tipi di sorgenti luminose in OpenGL:

  • sorgente luminosa direzionale: situata all'infinito e dotata di una direzione di illuminazione dedicata.
  • sorgente luminosa puntiforme: situata in un punto specifico dello spazio e brilla uniformemente in tutte le direzioni. È possibile impostare l'effetto della dissolvenza della luce in base alla distanza
  • riflettore: è un caso speciale di sorgente puntiforme, ma la luce da essa si propaga solo all'interno del cono di delimitazione e non in tutte le direzioni.

Per controllare le proprietà di una sorgente luminosa, utilizzare i comandi glLight*:

  • glLightf(GLenum light, GLenum pname, GLfloat param);
    glLightfv(GLenum light, GLenum pname, const GLfloat *param);

Il parametro light indica a OpenGL per quale sorgente luminosa impostare i parametri. Il comando glLightf viene utilizzato per impostare i parametri scalari e glLightfv viene utilizzato per impostare le caratteristiche vettoriali delle sorgenti luminose.

Per prima cosa, diamo un'occhiata alla funzione che definisce le impostazioni di base. Una volta abilitata l'illuminazione, è già possibile impostare l'illuminazione di sfondo. Per impostazione predefinita, il valore della luce di sfondo è (0,2, 0,2, 0,2, 1). Creare nuovo progetto, copia lì il file modello e spegni l'illuminazione. Avrai difficoltà a distinguere la sfera sullo schermo. Con la funzione glLightModel è possibile impostare l'illuminazione dello sfondo. Se lo aumenti a (1,1,1,1), cioè al massimo, non è necessario accendere le fonti luminose. Semplicemente non noterai le loro azioni, perché... l'oggetto è già illuminato al massimo. E si scopre che hai spento l'illuminazione. Fondamentalmente, aggiungi una chiamata alla seguente funzione in main:

  • ambiente float = (0,5, 0,5, 0,5, 1);
    ...
    glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambiente);

Prova a cambiare le impostazioni e guarda il risultato.

Materiale
Il materiale può disperdere, riflettere ed emettere luce. Le proprietà del materiale vengono impostate utilizzando la funzione

  • glMaterialfv(GLenum face, GLenum pname, GLtype* params)

Il primo parametro specifica la faccia per la quale sono impostate le proprietà. Può assumere uno dei seguenti valori:

  • GL_BACK faccia posteriore
    GL_FONT faccia anteriore
    GL_FRONT_AND_BACK entrambe le facce

Il secondo parametro della funzione glMaterialfv specifica la proprietà del materiale da impostare e può assumere i seguenti valori.

  • GL_AMBIENT luce ambientale
    GL_DIFFUSE è anche luce diffusa
    GL_SPECULAR luce riflessa
    GL_EMISSION luce emessa
    GL_SHININESS grado di luce riflessa
    GL_AMBIENT_AND_DIFFUSE entrambe le luci ambientali

Il colore è specificato come un array di quattro elementi: RGBA. Nel caso di GL_SHININESS, params punta a un numero float, che deve essere compreso tra 0 e 128.
Hai solo bisogno di modificare la funzione di visualizzazione.

  • void visualizzazione CALLBACK(void)
    {
    GLUquadricObj *quadObj;
    GLfloat front_color = (0,1,0,1);
    GLfloat back_color = (0,0,1,1);
    quadObj = gluNewQuadric();
    glCancella(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glMaterialfv(GL_FRONT, GL_DIFFUSE, colore_fronte);
    glMaterialfv(GL_BACK, GL_DIFFUSE, back_color);
    glPushMatrice();
    glRuotato(110, -1,1,0);
    gluCylinder(quadObj, 1, 0.5, 2, 10, 10);
    glPopMatrice();
    gluDeleteQuadric(quadObj);
    auxSwapBuffer();
    }

E devi abilitare la modalità di illuminazione per due volti. Per impostazione predefinita è disabilitato. Aggiungi la seguente riga alla funzione main.

  • glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);

Sorgenti luminose direzionali
Una sorgente luminosa di questo tipo si trova all'infinito e la luce da essa si propaga in una determinata direzione. Ideale per creare un'illuminazione uniforme. Un buon esempio di sorgente luminosa direzionale è il Sole. Per una sorgente luminosa direzionale, oltre ai componenti della radiazione, è possibile impostare solo la direzione.

  • GL_POSITION (0.0, 0.0, 1.0, 0.0) //(x, y, z, w) direzione della sorgente luminosa direzionale

Le prime tre componenti (x, y, z) definiscono il vettore direzione e la componente w è sempre uguale a zero (altrimenti la sorgente si trasformerà in una sorgente puntiforme).

Funzioni di decadimento
Si tratta di una funzione che modifica l'intensità della luce (l'intensità della luce non diminuisce con la distanza), utilizzata insieme all'illuminazione spot

  • GL_POSITION(0.0, 0.0, 1.0, 0.0)//posizione della sorgente luminosa (per impostazione predefinita la sorgente luminosa è direzionale)
  • GL_CONSTANT_ATTENUATION 1.0 //costante k_const nella funzione di attenuazione f(d)
  • GL_LINEAR_ATTENUATION 0.0 //coefficiente k_lineare per il termine lineare nella funzione di attenuazione f(d)
  • GL_QUADRATIC_ATTENUATION 0.0 //coefficiente k_quadratico con il quadrato della distanza nella funzione di attenuazione f(d)

Faretti
Un tipo di sorgente puntiforme è un riflettore. Tutti i parametri sono applicabili ad esso come per una sorgente puntiforme, ma in più il faretto consente di limitare la diffusione della luce a un cono. Per questo cono è possibile impostare il coefficiente di diminuzione dell'intensità, in funzione dell'angolo tra l'asse del cono e il fascio di propagazione della luce.

  • GL_SPOT_DIRECTION (0.0, 0.0, -1.0) //(x, y, z) - direzione del riflettore (asse del cono delimitante)
  • GL_SPOT_CUTOFF 180.0 //angolo tra l'asse e il lato del cono (ovvero metà dell'angolo al vertice)
  • GL_SPOT_EXPONENT 0.0 //decadimento dell'intensità esponenziale

Ombre
Le ombre non sono supportate direttamente dalla libreria OpenGL, quindi devono essere gestite separatamente.

Senza una fonte di luce, l'immagine non è visibile. Per inizializzare la sorgente e abilitare il processore al calcolo dell'impatto della sorgente sugli oggetti è sufficiente eseguire i comandi: glEnable(gl_lighting); // abilita la modalità di analisi dell'illuminazione

AbilitaGl(gl_luce0); // include una sorgente specifica (zero) nella scena, con le sue caratteristiche

Per disabilitare una fonte, utilizzare la funzione Disable(). Per impostazione predefinita, la sorgente luminosa si trova nello spazio con coordinate (0,0,∞). Puoi creare una fonte di luce ovunque nello spazio dell'immagine.

La libreria OpenGl supporta quattro tipi di sorgenti luminose:

  • illuminazione di fondo (illuminazione ambientale),
  • fonti puntiformi,
  • faretti,
  • sorgenti luminose remote (luce distante).
Ogni sorgente luminosa ha il proprio insieme di caratteristiche.
Le caratteristiche della sorgente luminosa corrispondono ai parametri del modello Phong.
Per impostare i parametri del vettore, utilizzare la funzione glLightfv(), che ha il seguente formato:

glLightfv(sorgente, parametro, puntatore_a_array);

Esistono quattro parametri vettoriali che determinano la posizione e la direzione dei raggi della sorgente e la composizione cromatica dei suoi componenti: sfondo, diffuso e speculare.
Per impostare parametri scalari in OpenGL, utilizzare la funzione glLightf():

glLightf(sorgente, parametro, valore);

Supponiamo, ad esempio, di voler includere nella scena la sorgente GL_LIGHT0, che dovrebbe trovarsi nel punto (1.0, 2.0, 3.0). La posizione sorgente viene salvata nel programma come punto in coordinate uniformi:

GLfloat light0_pos=(1.0, 2.0, 3.0, 1.0);

Se la quarta componente di questo punto è zero, allora la sorgente puntiforme si trasforma in una sorgente remota, per la quale è significativa solo la direzione dei raggi:

GLfloat light0_dir=(1.0, 2.0, 3.0, 0.0);

Successivamente, viene determinata la composizione cromatica dello sfondo, della diffusione e dei componenti speculari della sorgente. Se nell'esempio in esame la sorgente ha una componente speculare di colore bianco, e le componenti di sfondo e diffusione dovrebbero essere rosse, allora il frammento di programma che forma la sorgente assomiglia a questo:

GLfloat diffise0= (1.0, 0.0, 0.0, 1.0);

GLfloat ambiente0=(1.0, 0.0, 0.0, 1.0);

GLfloat speculare0=(1.0, 1.0, 1.0, 1.0);

GlAbilita(GL_LIGHTING);

GlAbilita(GL_LIGHT0);

GlLightfv(GL_LIGHT0, GL_POSITION, light0_pos);

GlLightfv(GL_LIGHT0, GL_AMBIENT, ambient0);

GlLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse0);

GlLightfv(GL_LIGHT0, GL_SPECULAR, speculare0);

Puoi anche includere nella scena un'illuminazione di sfondo globale, che non è associata ad alcuna fonte di luce individuale. Se, ad esempio, vuoi evidenziare in modo sfumato tutti gli oggetti nella scena con il bianco, dovresti includere il seguente pezzo di codice nel programma:

GLfloat ambiente_globale=(0.1, 0.1, 0.1, 1.0);

GlLightModelfv(GL_LIGHT_MODEL_AMBIENT, global_ambient);

Nel modello illuminotecnico il termine che tiene conto della distanza dalla sorgente ha la forma:

K= 1/(a+ b*d+ c*d^2)

E componenti costanti, lineari e quadratiche. I coefficienti corrispondenti per ciascuna sorgente vengono impostati individualmente utilizzando la funzione di impostazione dei parametri scalari, ad esempio:

GlLucef(GL_LUCE0, GL_COSTANTE_ATTENZIONE, a);

Per convertire una sorgente puntiforme in un faretto, è necessario specificare la direzione del raggio del faretto (GL_SPOT_DIRECTION), l'indicatore della funzione di distribuzione dell'intensità (GL_SPOT_EXPONENT) e l'angolo di diffusione del raggio (GL_SPOT_CUTTOF). Questi parametri vengono impostati utilizzando le funzioni glLightf() e glLightfv().

I parametri predefiniti per le sorgenti luminose sono mostrati nella Tabella 3.

Impostazioni predefinite per le luci

Tabella 3

Nome del parametro Valore di default Contenuto
GL_AMBIENTE (0.0, 0.0, 0.0, 1.0) intensità della luce ambientale RGBA
GL_DIFFUSA (1.0, 1.0, 1.0, 1.0) intensità di luce diffusa RGBA
GL_SPECOLARE (1.0, 1.0, 1.0, 1.0) intensità speculare della luce RGBA
GL_POSIZIONE (0.0, 0.0, 1.0, 0.0) (x, y, z, w) posizione della luce
GL_SPOT_DIREZIONE (0.0, 0.0, -1.0) (x, y, z) direzione del riflettore
GL_SPOT_EXPONENTE 0.0 esponente dei riflettori
GL_SPOT_CUTOFF 180.0 angolo di taglio del faretto
GL_COSTANTE_ATTENUAZIONE 1.0 fattore di attenuazione costante
GL_LINEAR_ATTENUAZIONE 0.0 fattore di attenuazione lineare
GL_QUADRATIC_ATTENUAZIONE 0.0 fattore di attenuazione quadratico

Per creare immagini realistiche, è necessario determinare sia le proprietà dell'oggetto stesso sia le proprietà dell'ambiente in cui si trova. Il primo gruppo di proprietà comprende i parametri del materiale con cui è realizzato l'oggetto, i metodi per applicare la trama alla sua superficie e il grado di trasparenza dell'oggetto. Il secondo gruppo comprende il numero e le proprietà delle sorgenti luminose, il livello di trasparenza dell'ambiente. Tutte queste proprietà possono essere impostate utilizzando gli appositi comandi OpenGL.

Proprietà dei materiali

Per impostare i parametri del materiale corrente utilizzare i comandi

vuoto glMateriale(GLenum face, GLenum pname, GLtype param)
vuoto glMaterialv(GLenum face, GLenum pname, GLtype *params)

Con il loro aiuto è possibile determinare i colori sparsi, diffusi e speculari del materiale, nonché il colore, il grado di riflessione speculare e l'intensità dell'emissione di luce se l'oggetto dovesse brillare. Quale parametro sarà determinato dal valore di param dipende dal valore di pname:

GL_AMBIENTE Il parametro params deve contenere quattro valori di colore RGBA interi o reali che definiscono il colore diffuso del materiale (il colore del materiale in ombra).

Valore predefinito: (0,2, 0,2, 0,2, 1,0).

GL_DIFFUSA Il parametro params deve contenere quattro valori di colore RGBA interi o reali che specificano il colore di riflessione diffusa del materiale.

Valore predefinito: (0,8, 0,8, 0,8, 1,0).

GL_SPECOLARE Il parametro params deve contenere quattro valori di colore RGBA interi o reali che specificano il colore speculare del materiale.

GL_LUCIDEZZA Il parametro params deve contenere un singolo valore intero o reale compreso tra 0 e 128, che determina il grado di riflessione speculare del materiale.

Valore predefinito: 0.

GL_EMISSIONE Il parametro params deve contenere quattro valori di colore RGBA interi o reali che definiscono l'intensità della luce emessa dal materiale.

Valore predefinito: (0,0, 0,0, 0,0, 1,0).

GL_AMBIENT_AND_DIFFUSE equivale a due chiamate al comando glMaterial...() con pname GL_AMBIENT e GL_DIFFUSE e gli stessi valori params.

Ne consegue che il comando glMaterial() può essere richiamato solo per impostare il grado di riflessione speculare del materiale. La maggior parte dei modelli tiene conto della luce riflessa diffusa e speculare; il primo determina il colore naturale dell'oggetto e il secondo determina la dimensione e la forma dei punti salienti sulla sua superficie.

Il parametro face determina il tipo di facce per le quali è specificato questo materiale e può assumere i valori GL_FRONT, GL_BACK o GL_FRONT_AND_BACK.

Se i materiali dell'oggetto nella scena differiscono solo in un parametro, si consiglia di impostare prima la modalità desiderata chiamando glEnable() con il parametro GL_COLOR_MATERIAL, quindi utilizzare il comando

vuoto glColorMaterial(Faccia GLenum, nome GLenum)

dove il parametro face ha un significato simile e il parametro pname può assumere tutti i valori elencati. Il valore della proprietà materiale selezionata da pname per un particolare oggetto (o vertice) viene quindi impostato chiamando glColor...(), evitando chiamate al comando glMaterial...() che richiede più risorse e aumentando l'efficienza del programma.

Puoi aggiungere una fonte di luce alla scena usando i comandi

vuoto glLight(GLenum light, GLenum pname, GLfloat param)
vuoto glLight(GLenum light, GLenum pname, GLfloat *params)

Il parametro luce identifica in modo univoco la sorgente ed è selezionato da un insieme di nomi simbolici speciali come GL_LIGHTi, dove i deve essere compreso tra 0 e GL_MAX_LIGHT, che non supera otto.

I restanti due parametri hanno lo stesso significato del comando glMaterial...(). Vediamo il loro scopo (prima vengono descritti i parametri per il primo comando, poi per il secondo):

GL_SPOT_EXPONENTE il parametro param deve contenere un numero intero o reale da 0 a 128 che specifica la distribuzione dell'intensità luminosa. Questo parametro descrive il livello di messa a fuoco della sorgente luminosa.

Valore di default: 0 (luce diffusa).

GL_SPOT_CUTOFF param deve contenere un numero intero o reale compreso tra 0 e 90 o uguale a 180, che definisce l'angolo massimo di diffusione della luce. Il valore di questo parametro è la metà dell'angolo al vertice del flusso luminoso a forma di cono creato dalla sorgente.

Valore di default: 180 (luce diffusa).

GL_AMBIENTE Il parametro params deve contenere quattro valori di colore RGBA interi o reali che specificano il colore dell'illuminazione di sfondo.

Valore predefinito: (0,0, 0,0, 0,0, 1,0).

GL_DIFFUSA Il parametro params deve contenere quattro valori di colore RGBA interi o reali che specificano il colore dell'illuminazione diffusa.

GL_SPECOLARE Il parametro params deve contenere quattro valori di colore RGBA interi o reali che specificano il colore della riflessione speculare.

Valore predefinito: (1.0, 1.0, 1.0, 1.0) per LIGHT0 e (0.0, 0.0, 0.0, 1.0) per gli altri.

GL_POSIZIONE il parametro params deve contenere quattro numeri interi o reali che definiscono la posizione della sorgente luminosa. Se il valore della componente w è 0,0, allora la sorgente è considerata infinitamente distante e nel calcolo dell'illuminazione viene presa in considerazione solo la direzione verso il punto (x,y,z), altrimenti la sorgente è considerata situato nel punto (x,y,z,w).

Valore predefinito: (0,0, 0,0, 1,0, 0,0).

GL_SPOT_DIREZIONE Il parametro params deve contenere quattro numeri interi o reali che specificano la direzione della luce.

Valore predefinito: (0,0, 0,0, -1,0, 1,0).

Quando si modifica la posizione della sorgente luminosa, è necessario tenere conto dei seguenti fatti: se la posizione viene specificata con il comando glLight...() prima di determinare l'orientamento dello sguardo (con il comando glLookAt()), allora la sorgente essere considerato al punto di osservazione. Se la posizione è impostata tra la specifica dell'orientamento e le trasformazioni della matrice della vista, allora è fissa e non dipende dalle trasformazioni della vista. In quest'ultimo caso, quando la posizione viene specificata dopo l'orientamento e la matrice di vista, la sua posizione può essere modificata impostando sia un nuovo orientamento dell'osservatore che cambiando la matrice di vista.

Per utilizzare l'illuminazione, è necessario prima impostare la modalità appropriata chiamando il comando glEnable (GL_LIGHTNING), quindi abilitare la sorgente desiderata con il comando glEnable(GL_LIGHTn).

Modello di illuminazione

OpenGL utilizza il modello di illuminazione Phong, in cui il colore di un punto è determinato da diversi fattori: proprietà del materiale e della trama, l'entità della normale in quel punto e la posizione della sorgente luminosa e dell'osservatore. Per calcolare correttamente l'illuminazione in un punto, è necessario utilizzare singole normali, tuttavia comandi come glScale...() possono modificare la lunghezza delle normali. Per tenerne conto viene utilizzata la modalità di normalizzazione già menzionata, che viene abilitata richiamando il comando glEnable(GL_NORMALIZE).

Per impostare i parametri di illuminazione globali, utilizzare i comandi

vuoto glLightModel(nome GLenum, parametro GLenum)
vuoto glLightModelv(GLenum pname, const GLtype *params)

L'argomento pname specifica quale parametro del modello di illuminazione verrà modificato e può assumere i seguenti valori:

GL_LIGHT_MODEL_LOCAL_VIEWER param deve essere un valore booleano e specifica la posizione dell'osservatore. Se è FALSE, la direzione di visualizzazione è considerata parallela all'asse -z, indipendentemente dalla posizione nelle coordinate di visualizzazione. Se è TRUE, allora l'osservatore si trova all'origine del sistema di coordinate della vista. Ciò può migliorare la qualità dell'illuminazione, ma rende più difficile il calcolo.

Valore predefinito: FALSO.

GL_LIGHT_MODEL_TWO_SIDE Il parametro param deve essere booleano e controlla la modalità di calcolo dell'illuminazione sia per la faccia anteriore che per quella posteriore. Se è FALSO, l'illuminazione viene calcolata solo per le facce anteriori. Se è VERO il calcolo viene effettuato anche per le facce rovesce. Valore predefinito: FALSO.

GL_LIGHT_MODEL_AMBIENT Il parametro params deve contenere quattro numeri interi o reali che specificano il colore dell'illuminazione di fondo anche in assenza di determinate sorgenti luminose.

Valore predefinito: (0,2, 0,2, 0,2,1,0).

Come puoi vedere, abbiamo introdotto una matrice normale aggiuntiva, è necessaria per trasferire le normali dell'oggetto dal sistema di coordinate locali dell'oggetto a quello mondiale, questo è necessario per calcolare l'illuminazione nel sistema di coordinate mondiali.

Vale la pena notare che quando si utilizza FFP OpenGL, l'illuminazione non veniva calcolata nel sistema di coordinate globali, ma nel sistema di coordinate della vista. Secondo me questo non è molto conveniente, perché... Il sistema di coordinate della vista è collegato alla telecamera ed è conveniente impostare le fonti di illuminazione nel sistema di coordinate mondiali ed è lì che viene eseguito l'intero calcolo.

Calcolo illuminotecnico

I calcoli dell'illuminazione in questo tutorial utilizzano il modello di ombreggiatura Phong. L'idea principale del modello è che l'illuminazione finale di un oggetto è composta da tre componenti:

  • Luce di fondo (ambiente)
  • Luce diffusa (diffusa)
  • Luce speculare

Oltre a questi parametri, aggiungeremo la nostra luminosità del materiale (emissione), questo parametro consente di evidenziare un oggetto anche se non è illuminato da alcuna fonte luminosa.

Di conseguenza, ciascuno dei componenti viene calcolato tenendo conto dei parametri della sorgente luminosa e del materiale dell'oggetto. Puoi ottenere informazioni più dettagliate su questo modello di illuminazione in questo articolo.

I calcoli dell'illuminazione possono riguardare l'illuminazione per vertice o l'illuminazione per pixel. In questa lezione esamineremo l'illuminazione pixel per pixel; essa consente di appianare i dettagli insufficienti dei modelli poligonali e calcolare con maggiore precisione l'illuminazione in ogni punto dell'oggetto. Il calcolo principale dell'illuminazione per pixel avviene nello shader del frammento.

Prima di iniziare a calcolare l'illuminazione, è necessario calcolare e trasferire alcuni parametri dei vertici dal vertex shader allo shader del frammento:

  • Normale alla superficie di un oggetto in corrispondenza di un vertice (normale)
  • Direzione della luce incidente, dal vertice alla sorgente luminosa (direzione della luce)
  • Direzione della vista, dal vertice all'osservatore (direzione della vista)
  • Distanza da una sorgente luminosa puntiforme al vertice (distanza)

Per calcolare la luce diffusa e speculare vengono utilizzate la normale alla superficie dell'oggetto e la direzione della luce incidente, tuttavia per calcolare la luce riflessa è necessario conoscere anche la direzione della visuale dell'osservatore. La distanza dal vertice alla sorgente luminosa è necessaria per calcolare il coefficiente di attenuazione complessivo. Il vertex shader sarà simile al seguente:

#versione 330 core #define VERT_POSITION 0 #define VERT_TEXCOORD 1 #define VERT_NORMAL 2 layout(location = VERT_POSITION) in posizione vec3; layout(location = VERT_TEXCOORD) in vec2 texcoord; layout(location = VERT_NORMAL) in vec3 normale; // parametri di trasformazione struttura uniforme Trasforma (modello mat4; mat4 viewProjection; mat3 normale; vec3 viewPosition; ) trasforma; // parametri di una sorgente luminosa puntiforme struttura uniforme PointLight ( posizione vec4; ambiente vec4; diffusione vec4; speculare vec4; attenuazione vec3; ) luce; // parametri per lo shader del frammento out Vertice ( vec2 texcoord; vec3 normale; vec3 lightDir; vec3 viewDir; float distance; ) Vert; vuoto principale(vuoto) ( // converte le coordinate del vertice nel sistema di coordinate mondiali vertice vec4 = trasforma.modello * vec4(posizione, 1 .0 ) ; // direzione dal vertice alla sorgente luminosa nel sistema di coordinate globali vec4 lightDir = light.position - vertice; // passa alcuni parametri allo shader del frammento // passa le coordinate della texture Vert.texcoord = texcoord; // passa la normale nel sistema di coordinate mondiali Vert.normal = trasforma.normal * normale; // passa la direzione alla sorgente luminosa Vert.dirdirluce = vec3(dirdirluce) ; // trasmette la direzione dal vertice all'osservatore nel sistema di coordinate mondiali Vert.viewDir = trasforma.viewPosition - vec3(vertice) ; // trasmette la distanza dal vertice alla sorgente luminosa Distanza verticale = lunghezza(dirluce) ; // converte le coordinate del vertice in coordinate omogenee gl_Position = trasforma.viewProjection * vertice; )

Condividi con gli amici o salva per te stesso:

Caricamento...