So verbergen Sie einen nachbearbeiteten Netzumriss, wenn das Netz ausgeblendet ist

10

Ich arbeite daran, eine aktive Gliederung in meiner 3D-Engine einzurichten, einen Hervorhebungseffekt für ausgewählte 3D-Zeichen oder Landschaften auf dem Bildschirm. Nachdem ich mit dem Schablonenpuffer gearbeitet und einige unbefriedigende Ergebnisse erzielt hatte (Probleme mit konkaven Formen, Konturdicke aufgrund des Abstands von der Kamera und Inkonsistenzen zwischen meinem Desktop und meinem Laptop), wechselte ich zur Kantenerkennung und zum Abtasten des Bildpuffers und erhielt einen Überblick, den ich habe ziemlich zufrieden mit.

Ich kann den Umriss jedoch nicht ausblenden, wenn sich das ausgewählte Netz hinter einem anderen Netz befindet. Dies ist angesichts meines Prozesses sinnvoll, da ich nach dem Rendern des Restes der Szene einfach einen 2D-Shader-Umriss aus einem Bildpuffer rendere.

Unten sind zwei Screenshots meiner Ergebnisse zu sehen. Der erste ist ein "guter" Umriss, der zweite ist der Punkt, an dem der Umriss über einem Netz angezeigt wird, das die Umrissquelle blockiert.

Geben Sie hier die Bildbeschreibung ein

Der Rendervorgang läuft folgendermaßen ab: 1) Zeichnen Sie nur das Alpha des hervorgehobenen Netzes und erfassen Sie eine schwarze Silhouette in einem Bildpuffer (Bildpuffer1).

2) Übergeben Sie die Textur von Framebuffer1 an einen zweiten Shader, der die Kantenerkennung durchführt. Kante in Framebuffer2 erfassen.

3) Rendern Sie die gesamte Szene.

4) Rendern Sie die Textur von Framebuffer2 über der Szene.

Ich habe einige Ideen, wie dies erreicht werden kann, und hoffe, Feedback zu ihrer Gültigkeit oder zu einfacheren oder besseren Methoden zu erhalten.

Zuerst habe ich darüber nachgedacht, die gesamte Szene in einen Bildpuffer zu rendern und die sichtbare Silhouette des hervorgehobenen Netzes im Alphakanal zu speichern (alles weiß, außer dort, wo das hervorgehobene Netz sichtbar ist). Ich würde dann die Kantenerkennung auf dem Alphakanal durchführen, den Szenenbildpuffer rendern und dann die Kante oben rendern. Das Ergebnis ist so etwas:

Ergebnis

Um dies zu erreichen, dachte ich daran, nur während des Renderdurchlaufs des hervorgehobenen Objekts eine Definition festzulegen, die für alle sichtbaren Pixel alles Schwarz im Alpha zeichnet.

Meine zweite Idee ist, den oben beschriebenen aktuellen Renderprozess zu verwenden, aber auch die X-, Y- und Z-Koordinaten in den R-, G- und B-Kanälen von Framebuffer1 zu speichern, wenn die Silhouette des ausgewählten Netzes gerendert wird. Kantenerkennungen würden durchgeführt und in Framebuffer2 gespeichert, aber ich würde die RGB / XYZ-Werte von den Kanten des Alphas an die Silhouette weitergeben. Beim Rendern der Szene würde ich dann testen, ob sich die Koordinate innerhalb der in Framebuffer2 gespeicherten Kante befindet. In diesem Fall würde ich die Tiefe des aktuellen Fragments testen, um festzustellen, ob es vor oder hinter den Koordinaten liegt, die aus den RGB-Kanälen extrahiert wurden (konvertiert in Kameraraum). Wenn sich das Fragment vor den Tiefenkoordinaten befindet, wird das Fragment normal gerendert. Wenn sich das Fragment dahinter befindet, wird es als durchgezogene Umrissfarbe gerendert.

Ich verwende LibGDX für dieses Projekt und möchte WebGL und OpenGL ES unterstützen, sodass mir keine der Lösungen mit Geometrie-Shadern oder neueren GLSL-Funktionen zur Verfügung steht. Wenn jemand meine vorgeschlagenen Ansätze kommentieren oder etwas Besseres vorschlagen könnte, würde ich es wirklich schätzen.

nils
quelle
Schau dir dein Repo an. Haben Sie jemals eine akzeptable Problemumgehung gefunden?
iKlsR

Antworten:

0

Ich würde die gesamte Szene in einen Schablonenpuffer mit dem gewünschten umrissenen Objekt rendern, um ein Bit zu setzen und für alles andere das Bit zu verwerfen / entfernen.

Dann entfernen Sie die Kantenerkennung, das brauchen Sie nicht, stattdessen können Sie den Puffer ein wenig vergrößern. Jedes Objekt wächst also nur leicht.

Von dort aus kann Ihr Schablonenpuffer den Umriss haben, den Sie benötigen. Es geht darum sicherzustellen, dass die anderen Objekte, die Sie rendern, die Bits in Ihrem Schablonenpuffer ausschalten.

NeomerArcana
quelle
2
Danke für die Antwort. Würde diese Methode nicht auf ähnliche Probleme mit Umrissdicke und konkaven Formen stoßen, wenn die Skalierung in 3D erfolgt? Oder Verschiebungsprobleme, wenn es in 2d gemacht wurde und sich das umrissene Objekt nicht im Totpunkt des Bildschirms befindet?
Null
0

1) In einem Frame Buffer-Objekt können Sie einen Laplace-Shader in der GPU ausführen, um die Kontur zu erhalten.

2) Sie müssen den endgültigen Tiefenpuffer verwenden, wenn Sie Ihr Objekt im FBO zeichnen. Auf diese Weise zeichnen Sie nur den sichtbaren Teil Ihres Objekts im FBO, und der Laplace-Kontur konturiert nur den sichtbaren Teil.

winzige Dialoge
quelle
Hallo, danke für die Antwort. Ich mache das bereits, um den Umriss zu erreichen, den ich habe. Ich denke nicht, dass Sie eine Ablehnung für diese Antwort verdienen, also eine positive Abstimmung.
Null
0

Ich hoffe, ich kann dies klarstellen, aber im Grunde müssen Sie eine Schablone beider Objekte erstellen, als ob beide ausgewählt wären, und dann nur die Bereiche im Begrenzungsrahmen des Elements behalten, das Sie tatsächlich hervorheben möchten.

Im Grunde genommen erstellen Sie einen Schablonenpuffer für beide ausgewählten Objekte (oder für alle Objekte, die das Objekt verschließen, wirklich ... aber ich würde mir über diese Fälle keine Sorgen machen, es sei denn, es kommt tatsächlich häufig vor - wenn verschlossene Personen dies nicht erwarten so viel Hilfe), dann und es mit einer Schablone des Begrenzungsrahmens für Ihr Objekt.

Das sollte den gewünschten Effekt erzielen.

Alternativ können Sie einfach das "schlechte" Ergebnis hinterlassen und ich denke nicht, dass die meisten Leute sich zu sehr darum kümmern werden, obwohl dies von Ihren Daten / Ihrem Spiel und insbesondere von der Größe der Objekte abhängt.

Yudrist
quelle