En entornos "modernos", la extensión "NV Occlusion Query" proporciona un método para obtener el número de fragmentos que pasaron la prueba de profundidad. Sin embargo, en el iPad / iPhone que usa OpenGL ES, la extensión no está disponible.
¿Cuál es el enfoque más eficaz para implementar un comportamiento similar en el sombreador de fragmentos?
Algunas de mis ideas
Renderice el objeto completamente en blanco, luego cuente todos los colores juntos usando un sombreador de dos pasadas donde primero se representa una línea vertical y para cada fragmento el sombreador calcula la suma en toda la fila. Luego, se representa un único vértice cuyo fragmento suma todas las sumas parciales de la primera pasada. No parece ser muy eficiente.
Renderice el objeto completamente en blanco sobre un fondo negro. Reduzca la muestra de forma recursiva, abusando de la interpolación lineal de hardware entre texturas hasta obtener una resolución razonablemente pequeña. Esto conduce a fragmentos que tienen un nivel de escala de grises dependiendo del número de píxeles blancos en su región correspondiente. ¿Es esto lo suficientemente preciso?
Use mipmaps y simplemente lea el píxel en el nivel 1x1. Nuevamente, la cuestión de la precisión y si es posible usar texturas que no sean potencia de dos.
El problema con estos enfoques es que la tubería se estanca, lo que resulta en importantes problemas de rendimiento. Por lo tanto, estoy buscando una forma más eficaz de lograr mi objetivo.
Usando la extensión EXT_OCCLUSION_QUERY_BOOLEAN
Apple presentó EXT_OCCLUSION_QUERY_BOOLEAN en iOS 5.0 para 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 primera oración insinúa un comportamiento que es exactamente lo que estoy buscando: obtener el número de píxeles que pasaron la prueba de profundidad de manera asincrónica sin mucha pérdida de rendimiento. Sin embargo, el resto del documento describe solo cómo obtener resultados booleanos.
¿Es posible explotar esta extensión para obtener el recuento de píxeles? ¿El hardware lo admite para que pueda haber una API oculta para obtener acceso al recuento de píxeles?
Otras extensiones que podrían ser explotables serían las funciones de depuración, como la cantidad de veces que se invocó el sombreador de fragmentos (PSInvocations en DirectX, no estoy seguro de si hay algo similar disponible en OpenGL ES). Sin embargo, esto también daría como resultado un bloqueo de la tubería.