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.
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:
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.