Ombreggiatura differita: come combinare più luci?


9

Sto iniziando con GLSL e ho implementato una semplice ombreggiatura differita che genera G-buffer con posizioni, normali e albedo.

Ho anche scritto un semplice punto luce shader.

Ora disegno una sfera per la luce del punto e l'uscita va in un buffer di illuminazione.

Il problema è come combinare i risultati del buffer di illuminazione quando si disegnano più luci?

Ad esempio, quando sto disegnando la seconda luce sul soffiatore con lo shader di luce puntiforme, come posso aggiungere la prima luce alla seconda luce nel buffer di illuminazione. Voglio dire, non puoi leggere e scrivere nello stesso buffer di output?

Risposte:


12

Miscela additiva, ovvero glBlendFunc (GL_ONE, GL_ONE) e glEnable (GL_BLEND).


per questo è necessario disabilitare i test di profondità?
woojoo666,

1
@ woojoo666 No. In effetti, dovrebbe essere abilitato con il test di profondità impostato su meno uguale, in modo che le superfici che corrispondono esattamente al passaggio precedente passino. Se il test di profondità è disattivato, le superfici accumuleranno in modo errato la luce da qualsiasi cosa ci sia dietro. :)
Nathan Reed

hmm, sembra proprio quello che sta succedendo. l'attivazione della fusione fa sì che le facce frontali si fondano con quelle posteriori, anche se ho tenuto abilitato il test di profondità. devo fare qualcosa anche con la maschera di profondità?
woojoo666,

ha fatto un po 'più di test, sembra che l'ordine dei disegni sia importante (il disegno fronte-retro fa funzionare correttamente i test di profondità e la fusione avviene solo se le facce sono complanari, la parte frontale fa tutto insieme). C'è un modo per farlo senza ordinare tutto?
woojoo666,

2
@ woojoo666 Aha, sembra che tu l'abbia risolto da solo. Sì, devi stabilire la profondità in un passaggio opaco prima di poter utilizzare qualsiasi tipo di fusione. Può essere una prepass z con le scritture a colori disabilitate o un altro modo comune è fare luce ambientale / direzionale in un primo passaggio senza fusione, quindi aggiungere luci punto / punto in passaggi successivi con fusione.
Nathan Reed,

2

Per il mio renderer differito, aggrego tutte le luci in un target di rendering della luce utilizzando le informazioni dal buffer g, quindi campiono quel render per intensità della luce mentre creo la mia immagine di backbuffer finale.

Quindi, fondamentalmente, eseguo tutta la mia geometria di gioco attraverso il mio passaggio di geometria per costruire i g-buffers. Da lì nutro i g-buffers al mio shader passa-luce. Ogni luce viene fatta passare attraverso il passaggio utilizzando un quad a schermo intero. In questo modo il mio pixel shader può calcolare l'intensità della luce per tutte le superfici visibili dal buffer g e quindi aggiungerle al target di rendering della luce. È sufficiente aggiungere l'intensità della luce per ciascuna luce al buffer della luce, ma assicurarsi di bloccare l'intensità da 0 a 1.

Tutto ciò che dovresti fare per gestire diversi tipi di luci (punto, riflettore, parallelo) è rendere il passaggio della luce più robusto, usando eventualmente un buffer costante per designare quali procedure di illuminazione eseguire.


Sì, e la domanda è: come si aggiunge l'obiettivo di rendering della luce? Usando la miscelazione alfa come suggerito da Nathan Reed? Perché per quanto ne so non puoi leggere e scrivere nello stesso buffer di output (che in questo caso è il buffer di luce).
JBeurer,

Oops, si. Lascio che la fusione dell'output gestisca ciò con la fusione additiva. Quando si campiona per l'immagine finale è quando si desidera bloccare il valore su uno che funziona per me come la massima intensità di luce possibile che una superficie può ricevere. Da lì puoi semplicemente ridimensionare le tue luci secondo necessità.
KlashnikovKid

Come gestite i casi in cui una luce è dietro un muro e non dovrebbe illuminare le cose sull'altro lato del muro?
jjxtra,

@PsychoDad Questo è il dominio delle ombre, che è ... un argomento più complicato. :)
Nathan Reed

0

Probabilmente c'è una risposta migliore di questa, ma so che se nel tuo shader ripeti il ​​codice necessario per fare una seconda luce, puoi quindi elaborare due luci su un singolo oggetto anziché uno. Richiede il recupero di un sacco di codice per la seconda luce e le cuciture un po 'ridondanti, ma so che funziona. Tuttavia, credo, come qualcuno indicherà per te, potrebbe esserci una soluzione più elegante.


No, non funziona così. Traccio una sfera per ogni punto luce. A meno che la luce del secondo punto non si trovi all'interno della sfera di influenza della prima luce, la seconda luce non sarà semplicemente disegnata. Il tuo metodo funzionerebbe se disegnassi un quad a schermo intero per tutti i punti di luce, tuttavia, questo non è l'approccio corretto perché i quad a schermo intero sono usati per l'illuminazione globale. Supponiamo che io abbia 16 piccole luci puntiformi, che mi costringerebbero ad attraversarle per ogni pixel anche se il pixel non è illuminato da esso. E di solito direi che ogni pixel è illuminato da una o due luci. E se avessi 100 luci? NO
JBeurer il

Il motivo principale per cui ho dichiarato questo è che se stai usando solo due o poche luci, può essere d'aiuto. Soprattutto se stai strappando molti oggetti, usare una fusione significa che devi ridisegnare la scena per ogni luce, quindi se hai molte forme, diciamo un milione, o dieci milioni o un miliardo, ogni disegno costa molto di più da fare . Farlo nello shader causa problemi se vuoi molte luci, ma la fusione causa problemi se vuoi molte forme. Se hai molti di entrambi, devi trovare una via di mezzo, ma di solito hai alcune luci e molti oggetti nei giochi.
Neko

No, l'ombreggiatura differita non funziona in questo modo. Devo disegnare la scena solo una volta e memorizzare le informazioni rilevanti in G-Buffer. Quindi una sfera di influenza per ogni luce e mescolarla con il buffer di luce. E infine combinando il buffer di luce con colorbuffer ottengo il buffer di colore sfumato finale. La quantità di calcoli di illuminazione non dipende dalla complessità della scena. Questo è il vantaggio principale dell'ombreggiatura differita in primo luogo.
JBeurer

Ah, questo ha molto più senso e sarebbe molto meglio.
Neko,
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.