Ist es möglich herauszufinden, wie viele Fragmente den Schablonentest bestanden haben?


11

Ich habe eine OpenGL-Anwendung, die Schablonentests ziemlich häufig verwendet, um unregelmäßige Formen zu rendern (ein bisschen wie ein einfaches 2-D- CSG ). Wenn ich herausfinden könnte, wie viele Fragmente den Schablonentest bestanden und tatsächlich gerendert wurden, wäre dies sehr hilfreich, um einige Berechnungen auf der ganzen Linie zu vereinfachen. Insbesondere würde es mir ermöglichen, den Bereich der gerenderten Form kostenlos zu bestimmen, anstatt ihn später mit einer Monte-Carlo-Simulation approximieren zu müssen.

Ich weiß, dass es ein ähnliches Konzept für vom Geometrie-Shader emittierte Grundelemente gibt, das als Transformations-Feedback bezeichnet wird . Ich würde gerne wissen, ob es ein ähnliches Konzept für Fragmente und den Schablonentest gibt.


Eine grobe Lösung wäre, einfach eine Kontrastfarbe durch die Schablone auf eine andere zu malen, diesen Puffer zu speichern und die Anzahl der Pixel zu zählen, die geändert wurden.
TheBuzzSaw

Hmm, die Spezifikation besagt, dass Okklusionsabfragen die Anzahl der Fragmente zählen, die den Tiefentest bestehen , aber ich bin mir nicht sicher, wie das im Moment mit dem Schablonentest interagiert.
Chris sagt Reinstate Monica

@ChristianRau Es scheint, dass nur die Fragmente gezählt werden, die die Tiefentests bestehen, aber Schablonen-, Verwerfungs- und Alpha-Tests werden ignoriert.
Maurice Laveaux

2
@ChristianRau und Maurice, die ursprüngliche ARB_occlusion_query- Spezifikation besagt ausdrücklich, dass Proben gezählt werden, die sowohl Tiefen- als auch Schablonentests bestehen. Siehe auch diese StackOverflow-Frage .
Nathan Reed

@ NathanReed Klingt so, als würden Sie gleich eine Antwort schreiben.
Chris sagt Reinstate Monica

Antworten:


10

Ein möglicher Ansatz könnte die Verwendung von Hardware Occlusion Query sein.

Sie können die Fakten verwenden, dass der Schablonentest gemäß Spezifikation vor dem Tiefentest ausgeführt wird und nur die Fragmente, die den Tiefentest bestehen, von der Okklusionsabfrage gezählt werden.

Ein einfaches Beispiel (nicht getestet) wäre:

    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);

Beachten Sie, dass der Aufruf zum Abrufen der Anzahl der Proben den Flush der Pipeline zwangsweise aufruft und auf den Abschluss der Abfrage wartet. Wenn Sie einen asynchroneren Ansatz benötigen, können Sie abfragen, ob die Okklusionsabfrage durchgeführt wird oder nicht, indem Sie Folgendes verwenden:

    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?

2

Wenn Sie sich für den Bereich interessieren, können Sie den Schablonenpuffer verkleinern, bis Sie ein Pixel erreichen, und diesen Bereich aus seiner Farbe ableiten.

Schritte wären:

  • Kopieren Sie die Schablone in eine Textur, wobei Sie ein Format mit ausreichender Genauigkeit verwenden.
  • Laden Sie einen Shader, der eine Farbe ausgibt, die proportional zur Anzahl der Texel mit einer bestimmten Farbe ist.
  • Ping-Pong zwischen den Framebuffern, um die Größe um die Hälfte zu reduzieren, bis ein Pixel erreicht ist.
  • Die Farbe des Pixels ist der Prozentsatz des Ansichtsfensters, der vom Bereich abgedeckt wird: Multiplizieren Sie ihn einfach mit dem Bereich des Ansichtsfensters.
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.