Est-il possible de savoir combien de fragments ont réussi le test au pochoir?

11

J'ai une application OpenGL qui utilise assez largement les tests de pochoir pour rendre des formes irrégulières (un peu comme un simple CSG 2D ). Si je pouvais savoir combien de fragments ont réussi le test de stencil et ont été rendus, cela serait très utile pour simplifier certains calculs sur toute la ligne. Plus précisément, cela me permettrait de déterminer la zone de la forme rendue gratuitement au lieu d'avoir à l'approximer avec une simulation de Monte Carlo plus tard.

Je sais qu'il existe un concept similaire pour les primitives émises par le shader de géométrie, appelé rétroaction de transformation . Je voudrais savoir s'il existe un concept similaire pour les fragments et le test au pochoir.

Martin Ender
la source
Une solution grossière serait de simplement peindre une couleur contrastante sur une autre à travers le pochoir, de sauvegarder ce tampon et de compter le nombre de pixels qui ont été modifiés.
TheBuzzSaw
Hmm, la spécification dit que les requêtes d'occulsion comptent le nombre de fragments qui réussissent le test de profondeur , mais du haut de ma tête, je ne sais pas comment cela interagit avec le test du pochoir en ce moment.
Chris dit de réintégrer Monica
@ChristianRau Il semble que seuls les fragments qui réussissent les tests de profondeur seront comptés, mais les tests stencil, discard et alpha sont ignorés.
Maurice Laveaux
2
@ChristianRau et Maurice, la spécification ARB_occlusion_query originale dit explicitement qu'elle compte les échantillons réussissant à la fois les tests de profondeur et de stencil. Voir aussi cette question StackOverflow .
Nathan Reed
@NathanReed On dirait que vous êtes sur le point d'écrire une réponse.
Chris dit de réintégrer Monica

Réponses:

10

Une approche possible pourrait être l'utilisation de la requête d'occlusion matérielle.

Vous pouvez utiliser les faits selon lesquels, par spécification, le test de gabarit est exécuté avant le test de profondeur, et seuls les fragments qui réussissent le test de profondeur sont comptés par la requête d'occlusion.

Un exemple simple (non testé) serait comme:

    GLuint samples_query = 0;
    GLuint samples_passed = 0;
    glGenQueries(1, &samples_query);
    // Initialize your buffers and textures ...
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_STENCIL_TEST);

    // Set up the values on the stencil buffer ...

    // Now we count the fragments that pass the stencil test
    glDepthFunc(GL_ALWAYS); // Set up the depth test to always pass
    glBeginQuery(GL_SAMPLES_PASSED, samples_query);
    // Render your meshes here
    glEndQuery(GL_SAMPLES_PASSED);
    glGetQueryObjectuiv(samples_query, GL_QUERY_RESULT, &samples_passed);
    // samples_passed holds the number of fragments that passed the stencil test (if any)

    // Release your resources ...
    glDeleteQueries(1, &samples_query);

Notez que l'appel pour obtenir le nombre d'échantillons appellera de force le vidage du pipeline et attendra la fin de la requête. Si vous avez besoin d'une approche plus asynchrone, vous pouvez demander si la requête d'occlusion est effectuée ou non en utilisant:

    GLuint query_done = 0;
    glGetQueryObjectuiv(samples_query, GL_QUERY_RESULT_AVAILABLE, &query_done);
    if (query_done != 0)
        // Your query result is ready
    else
        // Maybe check the next frame?
Matteo Bertello
la source
2

Si ce qui vous intéresse est la zone, vous pouvez réduire la taille du tampon de gabarit jusqu'à atteindre un pixel et déduire cette zone de sa couleur.

Les étapes seraient:

  • Copiez le pochoir dans une texture, en utilisant un format avec suffisamment de précision.
  • Chargez un shader qui produit une couleur proportionnelle au nombre de texels avec une couleur donnée.
  • Ping-pong entre les tampons d'image pour réduire la taille de moitié jusqu'à atteindre un pixel.
  • La couleur du pixel est le pourcentage de la fenêtre couverte par la zone: il suffit de le multiplier par la zone de la fenêtre.
Julien Guertault
la source