Welche Art von Schattierungsalgorithmus könnte verwendet werden, um solche Schatten zu erzeugen?
Das, was ich mache, ist ähnlich, aber es wird alles mit einer 2D-Zeichnungs-API durchgeführt, die von OpenGL unterstützt wird, sodass es keine Z-Koordinate gibt.
Zusätzlich möchte ich für die Hand selbst ein schattiertes Gefühl wie hier erhalten:
Ich bin mir nur nicht sicher, wie ich einen schattierten Look in der Nähe erzielen soll.
Die Anzahl der Karten wird sich zwangsläufig ändern und die Karten werden auf den Tisch geworfen, so dass ich keine Art von Lichtkarte verwenden kann.
Welche Art von Algorithmen sollte ich untersuchen (abgesehen von Unschärfe, die ich wissen muss?)
Vielen Dank
Aktualisieren
Ich mache ein 2D-Kartenspiel. Ich möchte Dropshadows-Offset von den Karten hinzufügen, ein bisschen wie:
Die Art und Weise, wie ich daran denke, ist:
- Behalten Sie eine Textur bei, die dieselbe Größe wie der Backbuffer hat.
Zeichne dunkle Rechtecke als provisorische Karten auf diese Textur.
Verwischen Sie diese Textur.
- Ziehe meine Karten auf diese Textur.
- Beleuchten Sie die Karten zusätzlich.
- Zeichne diese Textur in den Backbuffer.
Meine Fragen sind:
Ist das der richtige Weg, um dies zu tun?
Gibt es eine Möglichkeit, dies zu tun, ohne die Textur zu rendern (eine Bitmap
so groß wie der Backbuffer zu halten)?Ist es sicher anzunehmen, dass die maximale Texturgröße
von der Backbuffer-Größe nicht überschritten wird? (Was ich meine ist, wenn der Backbuffer
2000x3000 ist, kann ich dann mit Sicherheit sagen, dass ich eine Textur in einem
Videospeicher dieser Größe erstellen kann ?
Vielen Dank
quelle
Antworten:
Ich denke, alle geben zu komplizierten Lösungen für dieses Problem nach.
Wir haben also zuerst die Karte (oder was auch immer Sie ziehen möchten), die hier durch (a) dargestellt ist. Als nächstes nehmen wir eine Kopie davon, füllen sie schwarz aus und lassen eine Gaußsche Unschärfe auf ihr entstehen (b). All dies geschieht in Photoshop oder einem beliebigen anderen Kunstwerkzeug.
Wenn wir im Spiel die Karte ziehen möchten, zeichnen Sie zuerst das verschwommene schwarze Bild mit multiplikativer (oder Alpha) Mischung, etwas versetzt in eine Richtung, und ziehen Sie dann die Karte darüber. Voilá.
Für weitere Tricks kannst du zwischen Schatten und Karten-Render wechseln, um einen Effekt wie (d) zu erzielen, oder erst alle Schatten und dann die Karten wie in (e) zeichnen (ich habe die Karten in der (e) -Hülle gefärbt, um zu zeigen, dass sie sind bist noch getrennt =)
Es ist auch am besten, kein reines Schwarz (oder vollständiges Alpha) für den Schatten zu verwenden, um subtilere, transparentere Schatten zu erzeugen.
quelle
Der erste ist nicht zu schwer. Wenn Sie einen Alphakanal für Ihre Kartenhand rendern (der für ein Pixel mit einer Karte so einfach wie Schwarz und für Transparent weiß sein kann), können Sie jede Art von Unschärfe nur für den Alphakanal und ausführen Versetzen Sie ihn dann und steuern Sie damit die Beleuchtung des Tisches. (Vermutlich müssten Sie, wenn Sie keinen Z-Buffer haben, zuerst den Alphakanal außerhalb des Bildschirms rendern, dann die Tabelle mit der Maske erstellen und dann die eigentlichen Karten rendern.)
Der zweite sieht ein bisschen aus wie SSAO (Screen-Space Ambient Occlusion). Diese Technik erfordert eine Z-Koordinate. Wenn Sie jedoch nicht die unterschiedlichen Winkel zwischen den Karten haben (was ich denke, wenn Sie keinen Z-Puffer haben), können Sie wahrscheinlich eine ziemlich gute Annäherung treffen, indem Sie für jede Karte einen Schlagschatten (wie den ersten) rendern Karte. Die Leistung könnte jedoch etwas schwierig sein - jedes Flugzeug würde einen unscharfen Alphakanal für alle darüber liegenden Flugzeuge benötigen, und wenn ein Bündel Karten auf dem Tisch liegt, könnte dies eine ganze Reihe von Renderpässen bedeuten.
quelle
Könntest du keine Schattenkarte machen? Rendern Sie die Szene in einem FBO. Speichern Sie nur die Tiefenwerte und führen Sie im Shader die normale Tiefenwertprüfung durch, um festzustellen, ob ein Schatten gerendert werden soll oder nicht.
quelle
Für den folgenden Vorgang ist kein Off-Screen-Rendering-Ziel erforderlich. Doch dabei gewinnt er die Forderung , dass der Tisch gezogen wird zuerst . Oder es wird zumindest nichts auf die Pixel gezeichnet, die die Tabelle abdeckt, bevor die Tabelle gezeichnet wird. Es ist auch erforderlich, dass der Tisch selbst ein einzelnes, nicht überlappendes Teil ist: ein Bild.
Außerdem benötigt Ihr Framebuffer eine Alpha-Komponente.
Erhalten Sie ein Graustufenbild einer Karte. Machen Sie es an den Rändern verschwommen und vergrößern Sie es möglicherweise. Dies ist Ihr Schattenkartenbild. Beachten Sie, dass dies ein Einkanalbild ist. Wenn Sie in Ihrem Shader auf diese Textur zugreifen, sollten Sie sicherstellen, dass Sie den Einzelwert in die Alpha-Komponente einfügen. Dies kann in Ihrem Shader oder anderswo erfolgen.
Ein Wert von 0,0 im Bild bedeutet, dass kein Schatten vorhanden ist. Ein Wert von 1,0 im Bild bedeutet Gesamtschatten . Das heißt, völlig pechschwarz. Sie möchten wahrscheinlich einen Wert von etwa 0,5 als dunkelste Farbe.
Löschen Sie den Bildschirm, sodass das Alpha auf Null gesetzt wird .
Bevor Sie etwas rendern (oder zumindest etwas, das "unter" der Tabelle gerendert wird), rendern Sie für jede Karte die unscharfe Textur, versetzt von der tatsächlichen Position der Karte (aber mit derselben Ausrichtung). Die vom Shader ausgegebene Farbe sollte lauten. Die Mischkonfiguration dafür sollte lauten (in OpenGL):
Dieser Mischmodus verhindert, dass überlappende Schatten immer dunkler oder heller werden. Es wird einfach der dunkelste Wert verwendet, der in dieses Pixel geschrieben wurde. Es sollte gut genug aussehen.
Sie sollten auch die Farbschreibmaske verwenden, um Farbschreibvorgänge zu deaktivieren.
Rendern Sie die Tabelle. Dabei sollte das Blending wie folgt eingestellt werden:
Wenn die Einschränkungen für Sie zu restriktiv sind, müssen Sie ein Renderziel verwenden. Dies geschieht wie folgt:
Erstellen Sie das Schattenkartenbild wie zuvor.
Rendern Sie zuerst die Schatten. Binden Sie den Schatten-Framebuffer (der nur ein Einkanal-Image sein muss, wenn Ihre Hardware auf einen von diesen rendern kann). Löschen Sie den Wert auf Null.
Rendern Sie für jede Karte das Schattenkartenbild wie zuvor versetzt. Ihr Shader sollte auf alle vier Komponenten der Ausgabefarbe den gleichen Wert schreiben. Der Mischmodus sollte wieder sein
glBlendEquation(GL_MAX)
.Wechseln Sie zurück zum normalen Framebuffer. Zeichne alles, was du beschatten möchtest.
Zeichnen Sie nun ein Vollbild-Quad mit dem von uns gerenderten Schattenbild. Der Shader sollte das aus dem Schattenbild abgerufene Texel im Alpha der Ausgabe speichern. das RGB ist irrelevant. Der Mischmodus sollte sein:
quelle
Ich würde den Schablonenpuffer verwenden. Löschen Sie es auf 1 (vorzugsweise zur gleichen Zeit, wenn Sie die Tiefe löschen), und zeichnen Sie Ihren Tisch. Aktivieren Sie dann den Schablonentest, zeichnen Sie die Schatten mit einer verschwommenen Rechtecktextur, erhöhen Sie sie, wenn Schablone und Tiefe durchlaufen, tun Sie nichts, wenn Schablone fehlschlagen, nichts, wenn Tiefe fehlschlägt, und setzen Sie die Schablonenfunktion auf GL_EQUAL (Ref. 1, Maske 0xff). Deaktivieren Sie den Schablonentest . (Ich habe das noch nicht vollständig getestet, aber es ist von Code abgeleitet, der sich ähnlich verhält und gut funktionieren sollte. Möglicherweise müssen Sie die Parameter anpassen.) Dann zeichne alles andere.
Die Anrufe wären:
Dies kann nur dann zu Problemen führen, wenn sich zwei unscharfe Kanten leicht überlappen. Ansonsten braucht es nichts Besonderes als das, was OpenGL 1.1 anbietet und funktioniert auf jeder Hardware. (Erwarten Sie vielleicht alte 3DFX-Karten, von denen ich annehme, dass Sie sich keine Sorgen um die Unterstützung machen ...)
Eine zweite Alternative, die in einem nicht leistungskritischen Spiel sehr gut funktionieren sollte, ist glCopyTexSubImage2D. Das funktioniert auch mit einer Textur, die kleiner als der Backbuffer ist, und wird auch auf jeder Hardware gut unterstützt (sie ist Teil von OpenGL 1.1 und wird von Doom 3 verwendet, sodass Sie erwarten können, dass die Unterstützung sehr gut ist).
Das Grundsetup würde so aussehen:
Das sollte auch sehr gut funktionieren, es ist ein bisschen GPU-intensiver als die Stencil-Buffer-Methode, behandelt aber den überlappenden Fall korrekt und - wie gesagt - ich denke, ein Spiel wie Ihr wird GPU-Power zum Brennen haben, auch auf einem Low-End Karte.
quelle