Come implementare correttamente la fusione alfa in una complessa scena 3D?


11

So che a questa domanda potrebbe sembrare un po 'facile rispondere ma mi sta facendo impazzire. Ci sono troppe possibili situazioni che un buon meccanismo di miscelazione alfa dovrebbe gestire, e per ogni algoritmo posso pensare che manchi qualcosa.

Questi sono i metodi che ho pensato finora:

  • Prima di tutto, però, per quanto riguarda l'ordinamento degli oggetti in base alla profondità, questo semplicemente non riesce perché gli oggetti non sono forme semplici, potrebbero avere curve e potrebbero scorrere l'uno all'interno dell'altro. Quindi non posso sempre dire quale è più vicino alla fotocamera.

  • Poi ho pensato di ordinare i triangoli, ma anche questo potrebbe fallire, ho pensato che non sono sicuro di come implementarlo, c'è un raro caso che potrebbe nuovamente causare un problema, in cui due triangoli si incrociano. Ancora una volta nessuno può dire quale è più vicino.

  • La cosa successiva è stata usare il buffer di profondità, almeno il motivo principale per cui abbiamo il buffer di profondità è a causa dei problemi con l'ordinamento che ho citato, ma ora abbiamo un altro problema. Poiché gli oggetti potrebbero essere trasparenti, in un singolo pixel potrebbero essere visibili più oggetti. Quindi per quale oggetto devo memorizzare la profondità dei pixel?

  • Quindi ho pensato che forse avrei potuto solo memorizzare la profondità dell'oggetto più frontale, e usando quello determinerei come avrei dovuto unire le successive chiamate di disegno a quel pixel. Ma ancora una volta c'era un problema, pensa a due piani semitrasparenti con un piano solido al centro di essi. Stavo per rendere il piano solido alla fine, si può vedere il piano più distante. Nota che avrei unito ogni due piani fino a quando non rimane un solo colore per quel pixel. Ovviamente posso usare anche i metodi di ordinamento per le stesse ragioni che ho spiegato sopra.

  • Infine, l'unica cosa che immagino di essere in grado di funzionare è rendere tutti gli oggetti in diverse destinazioni di rendering, quindi ordinare quei livelli e visualizzare l'output finale. Ma questa volta non so come posso implementare questo algoritmo.

Risposte:


11

Risposta breve

Guarda in profondità peeling . Dalla mia ricerca sembra essere la migliore alternativa, sebbene computazionalmente costosa perché richiede più passaggi di rendering. Ecco un'altra implementazione più recente e più veloce , anche di NVIDIA.

Risposta lunga

Questa è una domanda difficile . La maggior parte dei libri che ho letto sfoglia l'argomento e lo lascia a:

Inizia eseguendo il rendering di tutti gli oggetti opachi e quindi fondi gli oggetti trasparenti su di essi in ordine inverso.

Più facile a dirsi che a farsi, però, perché l'approccio ovvio di ordinare gli oggetti in base ai loro centroidi non garantisce il corretto ordinamento.

È esattamente lo stesso problema per cui l' algoritmo del pittore non funziona per il caso generale ed è necessario un buffer di profondità .

Detto questo, uno dei libri che ho citato alcune soluzioni:

  • Depth Peeling : una soluzione multi-pass che supera la limitazione del buffer di profondità dandoci l'ennesimo frammento più vicino, non solo quello più vicino. Il più grande vantaggio è che puoi renderizzare gli oggetti trasparenti in qualsiasi ordine e non c'è bisogno di ordinare. Può essere costoso a causa dei passaggi multipli ma il link che ho dato in alto sembra migliorare le prestazioni.

  • K-Buffer con routing di stencil: utilizza il routing di stencil per acquisire multipli strati di frammenti per pixel per passaggio di geometria. Lo svantaggio principale è che i frammenti devono essere ordinati in un passaggio di post-elaborazione.

Menziona anche una soluzione hardware al problema, ma non penso che sia effettivamente disponibile:

  • F-Buffer : un buffer FIFO di ordine di rasterizzazione per il rendering multi-pass. Tuttavia una buona lettura e l'introduzione parla anche un po 'del problema dell'ordinamento per trasparenza e delle soluzioni attuali.

Altre soluzioni alternative che non forniscono risultati perfetti ma sono meglio di niente:

  • Dopo il rendering tutti gli oggetti opachi, continuare ad usare Z-buffer test per oggetti trasparenti ma disabilitazione scrittura Z-buffer . Potresti ottenere alcuni artefatti da un ordinamento errato, ma almeno tutti gli oggetti trasparenti saranno visibili.

E citando il white paper sul buffer F sopra:

La soluzione più semplice è rendere ogni poligono parzialmente trasparente in modo completamente indipendente (ovvero rendere tutti i suoi passaggi prima di procedere al poligono successivo). Questa soluzione è generalmente proibitiva a causa del costo del cambio di stato che si sostiene. In alternativa, l'applicazione o la libreria di ombreggiatura può raggruppare i poligoni per garantire che vengano rappresentati insieme solo poligoni non sovrapposti. Nella maggior parte dei casi, questa soluzione non è neppure interessante, poiché richiede al software di eseguire analisi dello spazio dello schermo dei poligoni.


11

La risposta corretta è # 1: ordina tutte le tue cose per profondità e renderle (ovviamente disattiva la scrittura di profondità, ma non i test). Che cos'è una "cosa"?

Ogni "cosa" deve essere un oggetto convesso; non può sovrapporsi. Se hai un oggetto che è concavo, deve quindi essere suddiviso in pezzi convessi.

Questo è il modo standard di rendere una scena trasparente. Risolve i casi di compenetrazione? No. Risolve i casi in cui sono presenti 3 oggetti in cui non è possibile determinare l'ordine di profondità? No. Risolve i casi in cui hai un oggetto lungo che si sovrappone a uno piccolo più vicino alla sua profondità centrale? No.

Ma funziona abbastanza bene . I giochi non usano il peeling di profondità. Non usano k-buffer indirizzati allo stencil. Non usano i buffer F. Perché? Perché queste cose sono incredibilmente lente.

Puoi ottenere artefatti con il metodo standard. Ma almeno il tuo gioco funziona abbastanza velocemente.

Se sei disposto a limitarti a DX11 o hardware migliore, ci sono modi per implementare la fusione con l'ordinamento corretto. Sono più lenti, ma non così lenti come le tecniche precedenti. E a differenza del peeling profondo che può introdurre artefatti, questo è accurato dal campione. Inoltre, le prestazioni dell'algoritmo sono generalmente per frammento (e in una certa misura per sovrapposizione all'interno di ciascun frammento). Quindi, se non hai disegnato molte cose trasparenti, le prestazioni sono minime.

Non so se la tecnica abbia un nome spiffy, ma una implementazione per pre-GL4.2 può essere trovata qui. Una versione D3D11 è disponibile qui (Powerpoint, PPSX, compatibile Libre).


Buoni punti su questa risposta. Personalmente mi accontenterei anche di qualcosa di abbastanza buono (che ho descritto nella mia risposta, come una soluzione alternativa) poiché la maggior parte delle tecniche che ho elencato sono probabilmente più problemi di quanto valgono. Inoltre, tecnica interessante alla fine, non credo sia stata elencata sul rendering in tempo reale su cui ho ricercato la mia risposta. Sono un noob completo quando si tratta di funzionalità di livello DX11.
David Gouveia,

"una implementazione per pre-GL4.2 può essere trovata qui" 404
Jeroen van Langen,
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.