Cerchi di capire la luce su Opengl, come simulare una luce solare realistica?


13

Non so se sto facendo qualcosa di sbagliato o mi manca qualcosa, ma voglio simulare la luce del sole, come in una giornata di sole.

Quando l'oggetto è rivolto verso la luce direzionale, è ben illuminato e non ci sono problemi. Se giro intorno all'oggetto e guardo che è tornato, è buio. Non è troppo buio perché lo sto usando GL_AMBIENTma è ancora troppo buio per una giornata di sole. Se aumento il valore, non sembrerà mai migliore perché il lato dell'oggetto rivolto verso la luce sarà troppo luminoso.

E c'è un altro fastidioso problema con la luce ambientale, quando guardo il retro dell'oggetto, non riesco a vedere alcuna forma, solo un colore semplice. Difficile da spiegare, ecco alcune immagini:

Parte anteriore dell'oggetto: http://i.stack.imgur.com/YW53X.png
Parte posteriore dell'oggetto: http://i.stack.imgur.com/Qufha.png

Come puoi facilmente vedere, il lato anteriore sembra carino, puoi vedere la forma di quella cosa rossa. Sul retro, è semplice, non puoi vedere la stessa forma.

Ora, so che sto guardando il retro di un oggetto e sto guardando nella direzione della luce e dovrebbe essere più scuro del lato anteriore. Ma non dovrebbe apparire così semplice. Non è quello che vediamo quando andiamo contro la luce del sole guardando un oggetto, vediamo che gli oggetti formano una forma.

Come posso avere lo stesso (o simile) effetto su OpenGL?

La mia luce è attualmente definita in questo modo:

float posLight0[4] = {-1.0f, 1.0f, 1.0f, 0.0f};
float ambLight0[4] = {0.5f, 0.5f, 0.5f, 0.5f};

glLightfv(GL_LIGHT0, GL_POSITION, posLight0);
glLightfv(GL_LIGHT0, GL_AMBIENT, ambLight0);

Ti suggerisco di prendere in considerazione l'uso di shader, se possibile. La pipeline OpenGL a funzione fissa utilizza un modello di illuminazione abbastanza semplice, mentre gli shader ti danno il pieno controllo della matematica.
Incredibile monaco

Risposte:


11

Con la luce ambientale i tuoi oggetti appaiono troppo luminosi perché la luce diffusa viene aggiunta alla luce ambientale e la luce diffusa viene impostata automaticamente su 1,0. Questo aggiunge fino a 1,5 e tutto sopra 1.0 è bloccato. Impostare la luce diffusa su 0,5:

float difLight0[4] = {0.5f, 0.5f, 0.5f, 1.0f};
glLightfv(GL_LIGHT0, GL_DIFFUSE, difLight0);

Il secondo problema è più difficile da risolvere. Puoi provare ad aggiungere alcuni dettagli fini alla superficie, come trama o mappa a sbalzo. In OpenGL la luce ambientale è costante, ma nel mondo reale non è mai così. Per simulare il mondo reale, è necessaria una qualche forma di soluzione di illuminazione globale . L'occlusione ambientale aiuta molto qui, ma è più difficile da implementare rispetto alla semplice impostazione degli stati OpenGL. Puoi creare l'occlusione ambientale ai vertici del tuo modello nel tuo software di modellazione 3D o utilizzare SSAO , ma non vado ai dettagli.

Quello che puoi facilmente fare è aggiungere un'altra fonte di luce dimmer da un'altra direzione (es. Direzione opposta). Questo non sarà realistico, ma almeno darà una forma anche ai lati posteriori dei tuoi oggetti.

Considera anche di aggiungere punti salienti speculari alla tua applicazione. Farà brillare gli oggetti.

float specLight0[4] = {0.5f, 0.5f, 0.5f, 1.0f};
glLightfv(GL_LIGHT0, GL_SPECULAR, specLight0);
glMaterialfv(GL_FRONT, GL_SHININESS, 10.0f); // Shininess between 0 and 128

Puoi anche specificare i colori della luce e del materiale separatamente, specialmente se le impostazioni predefinite non sono adatte a te.


Quindi non esiste un modo semplice e diretto per fare ciò che voglio in OpengGL ... Peccato. Forse proverò ad aggiungere un'altra fonte di luce, ma come posso specificare esattamente l'intensità della luce?
rfgamaral,

La GL_SPECULARe GL_SHININESSnon sembrano produrre alcun effetto se ... ho cambiato glMaterialfvper glMaterialiperché non stava compilando. E ho anche provato un valore più grande come 128. Mi sembra lo stesso ... Forse il problema è sul mio modello caricato (obj / mtl), dovremo dare un'occhiata.
rfgamaral,

1
@Nazgulled Ho appena verificato che il default speculare di light0 sia 1.0, ma il default speculare del materiale sia 0.0. Quindi cambia glLightfv (GL_LIGHT0, GL_SPECULAR, specLight0); a glMaterialfv (GL_FRONT, GL_SPECULAR, specLight0); È anche utile impostare glLightModeli (GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE); oppure lo speculare potrebbe essere calcolato in modo errato quando la telecamera sta ruotando.
msell,

1
@Nazgulled Per la luce secondaria, impostare l'ambiente e il speculare su zero e un valore piccolo come 0,2 per il diffuso. Puoi anche impostare l'ambiente di tutte le luci su zero e utilizzare invece l'ambiente globale con GL_LIGHT_MODEL_AMBIENT.
msell,

2

La luce ambientale di OpenGL è un singolo colore, ma la luce ambientale nel mondo reale è generalmente più luminosa dall'alto e più scura dal basso. Puoi approssimarlo in OpenGL impostando la luce ambientale su blu molto scuro e aggiungendo una luce direzionale blu scuro che punta verso il basso. Questo, oltre a una luce direzionale bianca brillante proveniente da qualsiasi parte del sole, può approssimare abbastanza bene la luce esterna.

Quello che dovresti davvero fare è scrivere uno shader che calcola la luce per pixel, ma arrivare da dove ti trovi richiederà un po 'di tempo.


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.