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):
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:
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?
quelle
Antworten:
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.
quelle
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.
quelle