2009-06-27 6 views
8

prima volta qui. Sedendosi oggi e insegnando a me stesso OpenGL. Ma ho trovato una domanda a cui non riesco a trovare risposta. Mi chiedo perché il test di profondità sembra essere incompatibile con oggetti semi-trasparenti in OpenGL. La documentazione sembra suggerire che è necessario disattivare i test di profondità, quindi disegnare oggetti in ordine inverso e la fusione funzionerà correttamente.Test Z-Depth in OpenGL

Ma perché openGL non può usare solo lo stesso test di profondità che fa sempre per capire cosa c'è di più indietro nell'ordine inverso e farlo per te? È solo una limitazione del framework, o è qualcosa a che fare con ciò che puoi fare efficientemente nell'hardware grafico, o qualcosa del genere?

Solo chiedendo. Spero che qualcuno qui possa chiarire.

risposta

11

Buona domanda.

La risposta breve è che il buffer Z memorizza un singolo valore (solo) per ciascun pixel nel frame buffer. Data la modalità di funzionamento "normale" (per gli oggetti opachi - GL_DEPTH_TEST attivato, glDepthFunc impostato su GL_LESS), tale valore sarà la profondità del frammento più vicino mappato a quel pixel.

Il frame buffer è un dispositivo "stupido" - ogni frammento rasterizza e approfondisce indipendentemente da tutti gli altri, e separato da qualsiasi concetto del primitivo che lo ha prodotto. Quindi, non c'è spazio per le informazioni sulle primitive precedenti, l'ordinamento di profondità, ecc. Da tenere, come sarebbe necessario per implementare la funzione di "trasparenza automatica".

Si potrebbe voler esaminare i "grafici di scena" come aiuto per l'ordinamento di profondità. Queste sono librerie che aggiungono funzionalità di "livello superiore" oltre il materiale base T & L fornito da OpenGL.

Spero che questo aiuti.

2

Non ho sentito parlare di disattivazione dei test di profondità. Vuoi test di profondità di oggetti trasparenti.

Non vuoi che gli oggetti trasparenti scrivano sullo z-buffer, perché in seguito punteranno buchi in qualsiasi cosa dietro di loro.

+0

Mi chiedo perché questo è stato up-votato, dal momento che se si utilizzava OpenGL come suggerisce, tutto ciò che viene disegnato dopo l'oggetto trasparente ma dietro, occulterebbe completamente l'oggetto trasparente, chiaramente non inteso. – Blindy

+1

Questo è il punto - si disegna il materiale trasparente per ultimo, con il test di profondità abilitato ma la scrittura in profondità disabilitata. In questo modo le cose trasparenti sono ancora occluse da cose opache che si trovano di fronte. –

+0

Si disegnano gli oggetti trasparenti per ultimi, di nuovo in primo piano. Immaginavo che lo sapesse già, dal momento che ha menzionato l'ordine inverso e mi chiedeva del buffering z. – David

3

OpenGL scrive nel buffer di profondità un pixel alla volta e restituisce i triangoli che producono i pixel nell'ordine in cui vengono presentati a OpenGL. OpenGL non esegue alcun ordinamento in profondità dei triangoli, è compito del framework chiamante gestirlo nel modo più efficiente per quella applicazione. Questo è per lo scopo della velocità e della flessibilità, poiché il modo più efficiente per eseguire il rendering di molti triangoli è archiviarli in buffer contigui di vertici e indici, e se l'API deve preoccuparsi di ordinarli tutti i frame, ciò renderebbe le cose molto più lente.

Inoltre, i materiali non sono associati direttamente ai triangoli nell'API, quindi OpenGL non ha davvero alcun modo di sapere quali sono trasparenti e quali sono opachi fino al momento in cui vengono effettivamente visualizzati.

Un buon modo per gestirlo è disegnare prima tutti i triangoli opachi, quindi disegnare tutti i triangoli trasparenti/alfa miscelati per ultimi. In genere si desidera attivare il test di profondità, ma disabilitare la scrittura in profondità e ordinare i triangoli trasparenti dal retro all'ordine anteriore per una fusione corretta. Il modo in cui solitamente gestisco questo è di avere un grafico di scena con un numero di bucket, e quando aggiungo triangoli al grafico di scena, li separerà automaticamente nei bucket appropriati che verranno renderizzati nell'ordine corretto.