Dans les environnements "modernes", l' extension "NV Occlusion Query" fournit une méthode pour obtenir le nombre de fragments qui ont réussi le test de profondeur. Cependant, sur l'iPad / iPhone utilisant OpenGL ES, l'extension n'est pas disponible.
Quelle est l'approche la plus performante pour implémenter un comportement similaire dans le shader de fragments?
Certaines de mes idées:
Rendez l'objet complètement en blanc, puis comptez toutes les couleurs ensemble à l'aide d'un shader à deux passes où une ligne verticale est d'abord rendue et pour chaque fragment, le shader calcule la somme sur toute la ligne. Ensuite, un seul sommet est rendu dont le fragment additionne toutes les sommes partielles de la première passe. Ne semble pas très efficace.
Rendez l'objet complètement en blanc sur un fond noir. Sous-échantillonner récursivement, en abusant de l'interpolation linéaire matérielle entre les textures jusqu'à atteindre une résolution raisonnablement petite. Cela conduit à des fragments qui ont un niveau de gris en fonction du nombre de pixels blancs dans leur région correspondante. Est-ce même assez précis?
Utilisez des mipmaps et lisez simplement le pixel au niveau 1x1. Encore une fois, la question de la précision et s'il est même possible d'utiliser des textures sans puissance de deux.
Le problème avec ces approches est que le pipeline est bloqué, ce qui entraîne des problèmes de performances majeurs. Par conséquent, je recherche un moyen plus performant pour atteindre mon objectif.
Utilisation de l'extension EXT_OCCLUSION_QUERY_BOOLEAN
Apple a introduit EXT_OCCLUSION_QUERY_BOOLEAN dans iOS 5.0 pour 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 première phrase fait allusion à un comportement qui est exactement ce que je recherche: obtenir le nombre de pixels qui ont réussi le test de profondeur de manière asynchrone sans beaucoup de perte de performances. Cependant, le reste du document décrit uniquement comment obtenir des résultats booléens.
Est-il possible d'exploiter cette extension pour obtenir le nombre de pixels? Le matériel le prend-il en charge afin qu'il puisse y avoir une API cachée pour accéder au nombre de pixels?
D'autres extensions qui pourraient être exploitables seraient le débogage de fonctionnalités comme le nombre de fois où le shader de fragment a été invoqué (PSInvocations dans DirectX - je ne sais pas si quelque chose de similaire est disponible dans OpenGL ES). Cependant, cela entraînerait également un blocage du pipeline.