In ambienti "moderni", l' estensione "NV Occlusion Query" fornisce un metodo per ottenere il numero di frammenti che hanno superato il test di profondità. Tuttavia, su iPad / iPhone che utilizza OpenGL ES, l'estensione non è disponibile.
Qual è l'approccio più efficace per implementare un comportamento simile nello shader di frammenti?
Alcune delle mie idee:
Rendi l'oggetto completamente in bianco, quindi conta tutti i colori insieme usando uno shader a due passaggi in cui viene rappresentata prima una linea verticale e per ogni frammento lo shader calcola la somma sull'intera riga. Quindi, viene visualizzato un singolo vertice il cui frammento somma tutte le somme parziali del primo passaggio. Non sembra essere molto efficiente.
Rende l'oggetto completamente in bianco su uno sfondo nero. Sottocampionare ricorsivamente, abusando dell'interpolazione lineare hardware tra le trame fino a raggiungere una risoluzione ragionevolmente piccola. Questo porta a frammenti che hanno un livello di scala di grigi a seconda del numero di pixel bianchi nella loro regione corrispondente. È anche abbastanza preciso?
Usa le mipmap e leggi semplicemente il pixel sul livello 1x1. Ancora una volta la questione dell'accuratezza e se è persino possibile usare trame senza potenza di due.
Il problema con questi approcci è che la pipeline viene bloccata e ciò comporta gravi problemi di prestazioni. Pertanto, sto cercando un modo più performante per raggiungere il mio obiettivo.
Utilizzo dell'estensione EXT_OCCLUSION_QUERY_BOOLEAN
Apple ha introdotto EXT_OCCLUSION_QUERY_BOOLEAN in iOS 5.0 per iPad 2.
"4.1.6 Occlusion Queries Occlusion queries use query objects to track the number of fragments or samples that pass the depth test. An occlusion query can be started and finished by calling BeginQueryEXT and EndQueryEXT, respectively, with a target of ANY_SAMPLES_PASSED_EXT or ANY_SAMPLES_PASSED_CONSERVATIVE_EXT. When an occlusion query is started with the target ANY_SAMPLES_PASSED_EXT, the samples-boolean state maintained by the GL is set to FALSE. While that occlusion query is active, the samples-boolean state is set to TRUE if any fragment or sample passes the depth test. When the occlusion query finishes, the samples-boolean state of FALSE or TRUE is written to the corresponding query object as the query result value, and the query result for that object is marked as available. If the target of the query is ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, an implementation may choose to use a less precise version of the test which can additionally set the samples-boolean state to TRUE in some other implementation dependent cases."
La prima frase suggerisce un comportamento che è esattamente quello che sto cercando: ottenere il numero di pixel che hanno superato il test di profondità in modo asincrono senza troppe perdite di prestazioni. Tuttavia, il resto del documento descrive solo come ottenere risultati booleani.
È possibile sfruttare questa estensione per ottenere il conteggio dei pixel? L'hardware lo supporta in modo che ci possa essere un'API nascosta per ottenere l'accesso al conteggio dei pixel?
Altre estensioni che potrebbero essere sfruttabili sarebbero funzioni di debug come il numero di volte in cui è stato invocato il framment shader (PSInvocations in DirectX - non sono sicuro che qualcosa di simile sia disponibile in OpenGL ES). Tuttavia, ciò comporterebbe anche uno stallo della pipeline.