Wie kann ich einen Glitzereffekt erzeugen?


9

Ich versuche, einen Glitzereffekt für meinen Echtzeit-Shader zu erzeugen, aber ich weiß nicht wie.

Hier ist ein Beispiel und ein anderes Beispiel .

Geben Sie hier die Bildbeschreibung ein

Mit welcher Technik kann ich dies implementieren?


Dies könnte über einen Nachbearbeitungseffekt erreicht werden, der der Blüte ähnelt, jedoch ein Muster (eine Sterntextur) auf die Down-Sample-Phase anwendet. Das ist alles nur Spekulation.
Akaltar

1
Würde eine normale und spiegelnde Karte dies nicht über eine Textur ermöglichen?
JohnB

Ich habe einen Test mit normaler Karte gemacht. Das Schwierige ist jedoch, sie je nach Blickrichtung und Lichtausrichtung zum Glitzern zu bringen.
MaT

Antworten:


10

Wenn wir gebeten werden, einen Shader zu entwerfen, sollten wir zunächst kleinere Probleme aufteilen. Und genau wie der Glitzereffekt den Shader nicht wirklich gut aussehen lässt, aber die Gesamtbeleuchtung und der Effekt, wenn nur einer von ihnen verwendet wird, sehen nicht so gut aus.

Lassen Sie uns zunächst feststellen, was nicht direkt Teil des Shaders ist:

  1. Das Shadowing ist nicht Teil des Shaders und erfolgt über einen separaten Shadowing-Durchgang.
  2. Ich gehe davon aus, dass es eine Umgebungsokklusion gibt (insbesondere, dass dieses in der Frage gezeigte Bild keinen Echtzeit-Renderer verwendet, aber das ist eine Annahme).

Zweitens teilen wir den eigentlichen Shader in separate Effekte auf:

  1. Es gibt eine anisotrope Beleuchtung, die für das Gesamtbild des Shaders sehr wichtig ist. Der Grund dafür ist, dass das eigentliche Material Stoffe enthält. Diese glänzenden Stoffe bewirken, dass die Lichtreflexion eine gerichtete Vorspannung aufweist, wodurch die größte Menge an reflektiertem Licht in dieser bestimmten Richtung erzeugt wird.

Geben Sie hier die Bildbeschreibung ein

Geben Sie hier die Bildbeschreibung ein Es ist zu beachten, dass solche Stoffe unendlich viele Normalen haben, aber die hier beschriebene Technik nähert sich der signifikantesten Normalen an

Um die höchstwertige Normale zu approximieren, besteht eine Möglichkeit darin, Texturkoordinaten zu verwenden und Tangenten des Netzes zu berechnen, anstatt N zu berechnen . L Sie berechnen 1- (NT).

Vollständige Erklärung hier . Und Sie müssen dies wahrscheinlich im Fragment-Shader implementieren und nicht in der Vertex-Technik, über die sie sprechen. Andere anisotrope Modelle können ebenfalls angewendet werden.

Nun zum Glitzereffekt:

Dies kann im Weltraum / lokalen Texturraum oder im Bildschirmraum als separater Durchgang erfolgen.

Der Algorithmus, an den ich denken kann, verwendet eine Bildverarbeitungstechnik (vorausgesetzt, das Netz hat Texturkoordinaten).

  • Erzeugen Sie mithilfe der Texturkoordinaten ein hochfrequentes 2D-Rauschen auf der Netzoberfläche. Perlin-Rauschen scheint ein guter Kandidat zu sein.
  • Wenden Sie einen Max-Filter mit einem 3x3-Kernel auf das Rauschen an. Dies erzeugt einen ähnlichen Effekt wie im folgenden Bild, und der Max-Filter wird hier beschrieben .

Geben Sie hier die Bildbeschreibung ein

Beachten Sie, dass das obige Bild nur ein Beispiel für den Max-Filter ist. Wenn Sie es auf das Rauschen anwenden, erhalten Sie etwas, das einem Sternfeld ähnelt.

  • Wenden Sie anschließend einen Gaußschen Filter mit einer bestimmten Abweichung auf das Rauschen an, um eine sternförmige Form zu erhalten.

Geben Sie hier die Bildbeschreibung ein

Beispiel eines Gausschen Filters, der auf maximales (ed) Rauschen angewendet wird.

  • Der letzte Schritt besteht darin, dies mit der ursprünglichen Maschentextur und dem Licht zu kombinieren. Dies geschieht am besten mit einer (|) oder einer binären Operation mit der ursprünglichen Netztextur / -farbe. Dadurch wird nur das Weiß aus dem Rauschen entfernt und alle schwarzen Pixel entfernt. In Bezug auf das Licht (und möglicherweise andere Spiegelkarten) ist es am besten, es hinzuzufügen oder mit Ihren zuvor kombinierten Pixeln zu modulieren. Möglicherweise benötigen Sie auch einen Nachbearbeitungseffekt für ein besseres Leuchten.

Beachten Sie, dass diese Technik möglicherweise eine erhebliche Optimierung für einen Echtzeit-Shader erfordert.


3

Es gibt einen interessanten Artikel AMD - Getting Procedural .

Es scheint, dass Funkeln härter sind als ich denke.
Anständige Lösung: Verwenden Sie die 3D-Position, um die 3D-Rauschfunktion zu indizieren, fügen Sie den Ansichtsvektor hinzu und verwenden Sie die Frac-Funktion, um die Dinge weiter zu randomisieren.

Sparkle:
float specBase = saturate(dot(reflect(-normalize(viewVec), normal),
lightDir));
// Perturb a grid pattern with some noise and with the view-vector
// to let the glittering change with view.
float3 fp = frac(0.7 * pos + 9 * Noise3D( pos * 0.04).r + 0.1 * viewVec);
fp *= (1 - fp);
float glitter = saturate(1 - 7 * (fp.x + fp.y + fp.z));
float sparkle = glitter * pow(specBase, 1.5);
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.