Wie werden Einheitenauswahlkreise zusammengeführt?


16

Ich würde gerne wissen, wie dieser Effekt bei der Auswahl zusammengeführter Kreise erzielt wird. Hier sind Bilder zur Veranschaulichung:

Bildbeschreibung hier eingeben Bildbeschreibung hier eingeben

Grundsätzlich suche ich diesen Effekt:

Bildbeschreibung hier eingeben

Wie kann der Zusammenführungseffekt der Kreise erreicht werden? Ich habe keine Erklärung für diesen Effekt gefunden. Ich weiß, dass ich zur Projektion dieser Textur ein Abziehbildsystem entwickeln kann, aber ich weiß nicht, wie ich den Verschmelzungseffekt erzeugen kann.

Wenn möglich, suche ich nach einer reinen Shader-Lösung.


Können Sie erklären, was Sie unter "Zusammenführungseffekt" verstehen?
Wondra

Wenn Sie sich die oberen rechten Zeichen des Screenshots ansehen, kreuzen sich die Abziehbilder natürlich nicht, sondern die beiden linken kreuzen ihren blauen Kreis und werden zusammengeführt. Ich habe einen neuen Screenshot hinzugefügt, um den Effekt zu zeigen.
MaT

Bestehen Sie auf Shader-Lösung? Wenn nicht, haben Sie es gerade in Ihrem letzten Bild gelöst.
Wondra

Der letzte Screenshot zeigt nur den Effekt, den ich anvisiere. Das Endergebnis sollte wie in den vorherigen Screenshots aussehen.
MaT

1
Ja, ich stimme zu, ich denke, dass sie dynamisch einen Netzkreis mit der Textur bilden und dann das Netz zuschneiden, um sie zusammenzuführen. Es ist auch eine gute Lösung, aber ich denke, es ist in Bezug auf die Wirkung, die Sie erzielen können, eingeschränkter.
MaT

Antworten:


8

Es gibt ein paar Tricks, die du machen kannst:

Z-Puffer

Nachdem Sie alle anderen Objekte gerendert haben, rendern Sie für jede Einheit einen kleineren transparenten Kreis mit maximalem Z-Wert. Dann rendern Auswahlkreise Decals auf den Boden. Da sie in der Z-Reihenfolge darunter liegen, werden sie bei Untereinheiten verworfen.

Vollständig transparent zu sein bedeutet, dass der Kreis nur in den Z-Puffer geschrieben wird (maximaler Z-Wert). Wenn Sie jetzt Abziehbilder rendern, werden diese gegen Z-Pufferwerte getestet. Wenn sie den Test bestehen, werden sie gerendert (was nur außerhalb der Kreise geschieht).

Schablone

Wie bei der vorherigen Vorgehensweise, diesmal jedoch mit einem Schablonenpuffer. Rendern Sie kleinere Kreise für Einheiten mit einem Schablonenwert und rendern Sie dann Auswahlabziehbilder. Richten Sie die Schablone ein, um alle Elemente mit Ihrem Schablonenwert zu verwerfen.


Die Z-Buffer-Technik ist interessant, aber ich verstehe nicht, wie der erste transparente Kreis die Bodenabziehbilder abschneiden kann.
MaT

0

Sie können beispielsweise im Pixel-Shader für die Darstellung von Abziehbildern prüfen, ob es eine Schnittmenge mit anderen Abziehbildern gibt, und in diesem Fall das Pixel entfernen. Für diese Art von kreisförmigen Abziehbildern ist es ziemlich effizient.


1
Ich gehe davon aus, dass Sie den Teil Ihrer Antwort übersprungen haben, um alle Kreise und Radien an Shader zu übergeben.
Kromster sagt Unterstützung Monica

@Krom Wenn OP Interesse an der Lösung zeigt, gebe ich gerne nähere Informationen.
JarkkoL

0

Meinen Sie diese blauen Kreise auf dem Boden?

Es gibt vielleicht einen intelligenteren Weg, dies zu tun, aber betrachten Sie meine Lösung als ein Beispiel, wie dies getan werden kann. Rendern Sie Ihre Kreise in einer separaten leeren Textur von der Größe des Bildschirms. Jetzt können Sie sie beliebig mischen. Abhängig von Ihren Anforderungen können Sie die Vollfarbe oder nur die Information schreiben, dass ein Kreis bei einem bestimmten Pixel vorhanden ist. Sie benötigen jedoch auf jeden Fall eine Tiefeninformation für jedes Pixel, das Sie schreiben, wenn Sie einen Z-Test-Effekt wünschen.

Wenn Sie das Terrain nach dem vorherigen Schritt rendern, können Sie die zuvor erstellte Textur unter Verwendung der Bildschirmkoordinaten im Pixel-Shader als UVs abtasten. Jetzt wissen Sie, dass der Kreis auf ein bestimmtes Pixel des Geländes projiziert werden soll oder nicht. Auf diese Weise funktioniert es jedoch so, als wäre der Z-Test deaktiviert, sodass ein Gelände keinen Kreis verbergen kann. Wenn ein Gelände dahinter liegende Kreise verbergen soll, führen Sie einen Tiefentest durch, bevor Sie einen Kreis mit der Geländetextur mischen. Sie können eine kleine Abweichung verwenden, um das Rendern von Kreisen zu ermöglichen, die sich nur ein wenig unterhalb des Geländes befinden, aber dennoch gerendert werden sollen.


Bearbeiten: Um nun den Effekt von zusammengeführten Kreisen zu erzielen, müssen Sie Folgendes tun: Wenn Sie in die separate Textur rendern, müssen Sie überprüfen, ob bereits ein Kreis gerendert wurde, in dem Sie versuchen, einen neuen zu rendern. (Überprüfen Sie, ob die Textur dort einen Wert hat) Wenn ja, löschen Sie dieses Pixel. Dies sollte den Effekt eines "Umrisses" ergeben, wenn sich zwei oder mehr Kreise überlappen. Damit dies korrekt funktioniert, müssen Sie diesen Test jedoch nur für das Innere des Kreises und nicht für den Rand durchführen. Schreiben Sie also beim Rendern von Kreisen einen bestimmten Wert in die Ausgabetextur, der angibt, dass es sich um einen Kreis im Inneren handelt. Dann brauchen Sie nur nichts auf dem inneren Kreis zu rendern und Sie sollten gut sein.

Edit2: Für Ihr einfaches rot / grün-Beispiel: Bevor Sie ein Pixel rendern, prüfen Sie, ob dieses Pixel noch nicht grün ist. Wenn ja, nicht rendern. Dies wird den Trick machen. Tatsächlich können Sie beim Schreiben in die Textur sogar Rot / Grün für außerhalb / innerhalb des Kreises verwenden und dann beim Rendern des Geländes diese Werte lesen und in eine gewünschte Farbe konvertieren.

Wenn meine Antwort zufällig zu abstrakt ist, lassen Sie es mich wissen.


Ich habe eine allgemeine Vorstellung, aber wie Sie sagen, ist es für mich ein bisschen zu abstrakt, was die zusammengeführten Kreise betrifft :)
MaT

0

Es gibt einige Möglichkeiten. Als allgemeine Methode bieten sich Schablonenpuffer oft an, wenn bestimmte Zeichnungen ausgeblendet werden müssen, z. B. der Umriss, in dem sich die Kreise in Ihrem Beispiel überlappen.

In diesem Fall denke ich, kann dies genauso einfach ohne einen Schablonenpuffer durchgeführt werden. Sie können den Tiefenpuffer verwenden, um den Umriss zu entfernen, an dem sich die Kreise überlappen. Die Idee ist, dass Sie das Innere der Kreise nur in den Tiefenpuffer zeichnen (da wir das Innere nicht sehen wollen) und dann den Umriss zeichnen. Auf diese Weise wird der Teil der Kontur, der sich mit einem anderen Kreis überlappt, durch den Tiefentest entfernt.

Die einzige Einschränkung ist, dass Sie vorsichtig mit Tiefenkämpfen umgehen müssen. Sie können einen kleinen Versatz verwenden, um sicherzustellen, dass sich die Konturen tatsächlich hinter dem Innenraum befinden, und durch den Tiefentest eliminiert werden. Eine Alternative wäre zu verwenden glPolygonOffset().

Angenommen, Sie haben zwei Kreise, die parallel zur xy-Ebene verlaufen, mit Mittelpunkten bei (x1, y1, z) und (x2, y2, z). Und Sie haben diese Zeichenfunktionen:

// Draw interior part of circle, shown in green in the schematic in the question.
drawInterior(x, y, z);

// Draw outline of circle, shown in red in the schematic in the question.
drawOutline(x, y, z);

Die Zeichenfolge sieht dann so aus, mit deltaeinem kleinen Versatz:

glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
drawInterior(x1, y1, z + delta);
drawInterior(x2, y2, z + delta);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
drawOutline(x1, y1, z);
drawOutline(x2, y2, z);

0

Wenn diese Abziehbilder als Scheiben gezeichnet werden, prüfe ich jeden Kreis auf Überschneidungen und setze die Überschneidungspunkte in ein Array. Zeichnen Sie dann Bögen, die sich nicht innerhalb einer Kreuzung befinden. Dies ist jedoch keine Shader-Lösung.


Ja, darüber habe ich auch nachgedacht :) aber wie Sie sagten, ist es keine Shader-Lösung und auch keine sehr generische Lösung. Aber danke !
MaT

Das ist ziemlich vage Beschreibung
Kromster sagt Unterstützung Monica

0

Sie möchten hier schablonieren. Ihr erster Durchgang rendert die Kreise in den Schablonenpuffer. Der zweite Durchgang rendert den sichtbaren Umriss an einer beliebigen Stelle, an der sich der Schablonenpuffer nicht geändert hat. Der zweite Durchgang muss eine Geometrie verwenden, die größer als der erste Durchgang ist. In diesem Fall ist ein einfacher linearer Skalar ausreichend.

Die Lösung, die ich hier zum Zeichnen von Konturen habe, ist zwar mehr als erforderlich (da dieser Shader jede Netzkante in ein vollständiges Quad verwandelt), folgt jedoch diesem Ansatz: Zeichnen des Originalmodells in den Schablonenpuffer und Rendern einer größeren Version, in der der Schablonenpuffer ist immer noch 0.


Vielen Dank! Anstatt also zuerst die sichtbaren Teile zu zeichnen, sollte ich damit beginnen, die transparenten Kreise in die Schablone zu rendern. Aber wie rendere ich transparente Kreise? Ich kann nicht festlegen, dass Teile des Bildes in die Schablone gerendert werden. Wenn ich auf die Schablone rendere, ist alles da, oder?
Doodlemeat

Ja, deshalb wird der zweite Durchgang (der sichtbare Teil) größer skaliert: Die Grenzen sind also größer als der Schablonenpuffer. Sie müssen lediglich im zweiten Durchgang einen Scheitelpunktskalar anwenden (suchen Sie nach Gliederungsshadern, die meisten verwenden den einfacheren Skalar, auf den ich mich beziehe). Sie können den Schablonenpuffer auch nicht ändern, wenn die Farbe transparent ist. In diesem Fall benötigen Sie wahrscheinlich eine zweite Texturmaske, oder Sie können eine Abstandsberechnung durchführen, um stattdessen den Kreis zu bestimmen. Ich brauche ein paar Stunden und Zugriff auf Unity, um Code bereitzustellen.
Draco18s

Hmm, was ist mit einem Schwarz / Weiß-Bild, das im ersten Durchgang nur in den Schablonenpuffer geschrieben werden soll, damit Schwarz zu 0 wird und Weiß zu 1 in der Schablone. Ist das überhaupt möglich?
Doodlemeat

Das habe ich mit einer zweiten Textur-Maske gemeint. Ich bin mir ziemlich sicher, dass es funktionieren würde. Ich kann es einfach nicht überprüfen, ohne Unity vor mir zu haben, was ich für mehr als 24 Stunden nicht haben werde.
Draco18s
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.