Können (und wie) Shader Bildschirmpixel malen, die über die Pixel des schattierten Netzes hinausgehen?


8

Ich habe einige Erfahrung mit dem Programmieren von Geometrie und dem Berechnen von Shadern - habe mich aber nie daran gewöhnt, wirklich mit den Fragment-Shadern zu spielen. Derzeit versuche ich besser zu verstehen, wie sie funktionieren und welches Potenzial sie haben. Eines der Dinge, die ich an mehreren Stellen gelesen habe, ist, dass ein Fragment (dh ein Bildschirmpixel) innerhalb des Fragment-Shaders nicht über sich hinausgehen kann. Das heißt, ein bestimmtes Fragment, das iteriert wird, kann sich nur auf sich selbst auswirken.

Aus diesem Grund und zum Zwecke des Lernens möchte ich wissen, ob Folgendes möglich ist (und wenn ja, wie dies im Allgemeinen erreicht werden kann). Nehmen wir an, wir haben der Einfachheit halber ein Punktnetz, das nur aus zwei Eckpunkten besteht (im 3D-Weltraum). Können wir einen Shader so programmieren, dass jeder dieser beiden Scheitelpunkte an der exakten WorldToViewport-Position auf dem Bildschirm gezeichnet wird, aber auch, dass ein Kreis um jeden von ihnen mit dem Radius = R auch in den umgebenden Pixeln gezeichnet wird, selbst wenn sie sich erstrecken jenseits des ursprünglichen Netzes, an dem der Shader befestigt ist? Wie in der folgenden Abbildung (wobei das rote Quadrat in der Mitte der Kreise die auf dem Bildschirm gemalten Scheitelpunkte darstellt):

Geben Sie hier die Bildbeschreibung ein

Wenn dies möglich ist, kann ein Shader auch so programmiert werden, dass diese Kreise, die sich über die Eckpunkte hinaus erstrecken, die Farbe (RGBA) voneinander beeinflussen? Wie in der folgenden Abbildung:

Geben Sie hier die Bildbeschreibung ein

Wie gesagt, wenn dies mögliche Dinge sind, würde ich gerne ein bisschen hören, wie man so etwas erreicht - entweder in konzeptioneller oder praktischer Hinsicht. Wird es im Fragment-Shader ausgeführt oder muss es zuvor am Vertex- oder Geometrie-Shader berechnet werden? Wie kann man "zusätzliche Fragmente" berechnen und übergeben, die über die vom Netzkörper besetzten Fragmente hinausgehen?


Ein Geometrie-Shader kann mehr Grundelemente hinzufügen als im ursprünglichen Netz. Tut das für Sie?
Andreas

Antworten:


6

Wenn Sie Linienbreite oder Linien-Antialiasing oder Punktbreite oder Punktprites verwenden, erstellt OpenGL für Sie ein kleines Rechteck anstelle der Linie oder des Punkts mit Texturkoordinaten. Heutzutage können Sie dies sogar selbst mit Geometrie-Shadern oder sogar dem Tesselator programmieren.

Ein völlig anderer Ansatz besteht darin, eine verzögerte Schattierung zu verwenden, wobei ein geometrischer Durchgang nur zum Speichern von Informationen im RGBAZ-Puffer verwendet wird, und dann ein zweiter Durchgang, als Sie auf allen Pixeln des Bildschirms ausführen, um einen Prozess auszuführen. (Um auf alle Pixel zu wirken, zeichnen Sie einfach ein Vollbild-Rechteck). Heutzutage können Sie sogar den ersten Durchgang als einen oder mehrere "Render to Texture" ausführen und dann diese Texturen mit MIP zuordnen, sodass der letzte Durchgang leicht auf weniger lokale Werte zugreifen kann.


Vielen Dank! Ich habe das getan, was Sie am Anfang gesagt haben, und Geometrie-Shader verwendet, um Geometrie um die Punkte herum zu erstellen und so das Zeichnen von Pixeln um den Punkt zu ermöglichen. Es funktioniert natürlich, aber es ist eine umständlichere Lösung. Ich habe mich besonders für die letzten Teile von dem interessiert, was Sie gesagt haben: Wenn ich Sie richtig verstanden habe, können Sie die gesamte Szene rendern und dann einen Bildschirm-Shader verwenden, der auf den interessierenden Bereich ausgerichtet ist, und dann einen Pass über das machen gerenderter Rahmen, um zu bearbeiten, wie viele Pixel man um die Punkte in der Mitte haben möchte?
AndrewSteer

Sie können den ersten Durchgang in einer Textur rendern. Im zweiten Durchgang im Vollbildmodus können Sie dann in jedem Pixel den Texturinhalt auf einer Festplatte um das Pixel herum untersuchen und das tun, was Sie möchten (z. B. Farbe entsprechend dem am nächsten gefüllten Pixel oder nur Weiß malen, wenn der Abstand unter einem bestimmten Schwellenwert liegt). . Natürlich ist dies für das Zeichnen von Datenträgern
alles andere

Klar, ich habe nur das einfache Beispiel gegeben, an das ich denken konnte. Aber ja, ich denke, was Sie sagen, stimmt mit dem überein, was ich gedacht habe, dh in einem Durchgang zu einer Textur rendern, und später haben wir die Information, in anderen Durchgängen Pixel in Bezug auf das zu ändern, was in den umgebenden Pixeln liegt . Danke vielmals.
AndrewSteer

3

Eine gute Möglichkeit, einen Kreis (oder eine andere Form) für jeden Scheitelpunkt in einem Netz zu zeichnen, ist die Verwendung der Geometrieinstanz . Dies ist eine GPU-Funktion, mit der mehrere Instanzen (Kopien) eines Netzes gleichzeitig gezeichnet werden können, wobei die Scheitelpunkte / Indizes des Netzes durch einen Satz von Puffern und einen anderen Scheitelpunktpuffer angegeben werden, der zusätzliche Daten pro Instanz liefern kann. Der Vertex-Shader kann verwendet werden, um die Daten aus beiden Puffern nach Belieben zu kombinieren.

Um konkret zu sein, können Sie in Ihrem Fall ein Netz erstellen, das einen Kreis mit dem gewünschten Radius darstellt, dessen Scheitelpunkte direkt in Bildschirmraumkoordinaten angegeben und am Ursprung zentriert sind. Dann würden Sie die Instanz verwenden, um die GPU eine neue Kopie des Kreisnetzes für jeden Scheitelpunkt Ihres ursprünglichen Punktnetzes rendern zu lassen. Im Vertex-Shader berechnen Sie die Bildschirmraumposition des Punkts (wie gewohnt mithilfe der Weltanschauungsprojektionstransformationen) und übersetzen dann das Kreisnetz, das an dieser Position zentriert werden soll.

Was den zweiten Teil Ihrer Frage betrifft, wie die Kreise die Farbe des anderen beeinflussen sollen: Es hängt davon ab, was Sie speziell tun möchten. Hardware-Blending kann verwendet werden, um einfache Fälle wie das Hinzufügen oder Multiplizieren der Farben oder das Alpha-Blending zu behandeln. Wenn Sie etwas Komplizierteres wünschen, können Sie dies möglicherweise mit einem Multi-Pass-Algorithmus oder (auf den neuesten GPUs) mit programmierbarem Blending tun.

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.