Beste Möglichkeit, um Spielern das Färben von Bildern zu ermöglichen, ohne die Farbqualität zu verlieren?

41

Ich erstelle ein isometrisches 2.5D-Spiel (2D-Bilder).

Ich möchte, dass die Spieler ihre Rüstung, Kleidung und andere Dinge "färben" können. Ich finde, dass Graustufen alles dazu führt, dass einige der "natürlicheren" Farben verloren gehen. Wenn Sie beispielsweise einen Drachen mit rot / gelbem Graustufenmuster und anschließendem Farbauftrag herstellen, entsteht ein rein roter Drache, bei dem die Sekundärfarbe vollständig verloren geht. Wenn Sie das gleiche Rot / Gelb-Drachenblau sterben, wird es blau / weiß, was großartig aussieht.

Die Charaktere in meinem Spiel haben keine große Auswahl an Ausrüstung. Das Spiel ist näher an der Art und Weise, wie League of Legends mit Charakteren und Grafiken umgeht. Es kann einen einzelnen Charaktertyp geben (z. B. Held), aber mehrere Outfits für den Charakter als Optionen. Ich möchte, dass die Spieler in der begrenzten Anzahl von "Outfits" und Charakteren so viele Anpassungen wie möglich vornehmen können.

Ich möchte, dass Spieler in der Lage sind, einen Charakter auszuwählen, eine von mehreren Waffen auszuwählen, zwischen einer Handvoll Kostümen zu wechseln (auf die Charaktere geschichtet) und dann fast alles zu färben (eine bestimmte Metallic-Farbe für Waffen auswählen, eine beliebige Farbe auswählen) überhaupt für Kleidung).

Wenn ich in der Lage wäre, Graustufen zu verwenden, ohne etwas von der Färbung zu verlieren, würde ich.

Hier ist ein Beispiel dafür, wovon ich spreche:

Bildbeschreibung hier eingeben Bildbeschreibung hier eingeben Bildbeschreibung hier eingeben

Es ist nicht einmal möglich, den Drachen zu "färben", egal was ich in Photoshops "Color Overlay" -Optionen verwende. Offensichtlich mache ich es falsch, wenn es möglich ist, es besser mit Graustufen zu färben. Für eine Farbe wie Grün oder Gelb oder ein helleres Lila funktioniert dies in Ordnung. Für jede andere Farbe zerstört es die Kunst.

Es sieht jedoch viel besser aus, wenn ich es NICHT in Graustufen ansetze und stattdessen einfach eine "HUE" -Farbe auf das Originalbild (Rot / Gelb) auftrage.

Rote Farbe Bildbeschreibung hier eingeben

Lila Farbe Bildbeschreibung hier eingeben

Jetzt könnten die Spieler den Drachen JEDE Farbe färben, und es würde immer noch großartig aussehen! (Das Gelb wird weiß, während das Rot eine beliebige Farbe des Regenbogens annimmt.)

Bedeutet dies, dass WEISS oder SCHWARZ die beste Sekundärfarbe ist? Verwenden Sie dann eine Methode oder einen Shader, um die weiße (sekundäre) Farbe in etwas anderes zu ändern?

Gibt es Artikel zu dieser komplexen Methode, ein einzelnes Bild aufzunehmen und basierend auf der Färbung verschiedene Pixel einzufärben?

Wäre es für den Drachen am besten als weiß / schwarzer Drache mit hohem Kontrast geeignet? Ist Rot / Gelb die beste Farbeinstellung? Für Bilder ist es viel besser als für einige andere Farben, die ich ausprobiert habe. Ist Graustufen immer noch überlegen?

Enthält Photoshops "Mischoptionen" nicht die Methode, um Bilder für ein Videospiel entsprechend "einzufärben"? Gibt es komplexe Shader / Methoden, mit denen ich einen besseren Erfolg erzielen kann?

Hinweis: Wenn GrayScale es mir ermöglicht, den RAM-Verbrauch meiner Bilder zu verringern oder Qualitätsverluste bei der verlustbehafteten Komprimierung zu vermeiden, würde ich dies ernsthaft in Erwägung ziehen.

Carter81
quelle
5
Das ist zu Recht interessant. Ich werde darüber abstimmen und hoffe, dass es mehr Aufmerksamkeit bekommt. Die Farbtheorie ist ein großartiges Thema.
Evan
Farbtonrotation ist eine Möglichkeit, wenn auch in 2D - ich weiß nicht, ob es in 3D funktionieren würde.
Asche999
Vielen Dank, Evan. Ich stimme auch zu, dass dies äußerst interessant ist und eines der besten Themen ist, die ich in meiner Freizeit untersucht habe. Ich stelle mir vor, dass diese Art von Arbeit selten gemacht wird, weil dafür ein Künstler - aber nicht irgendein Künstler - erforderlich wäre, der sich mit Farbtheorie, Videospiel-Shader oder sogar einem Künstler-Kodierer befasst. Ich kann mir nur vorstellen, dass es selten ist, jemanden zu finden, der sich sowohl in Kunst als auch in Programmierung auszeichnet. Es gibt so gut wie keine auffindbare Forschung zu diesem Thema auf Google. Besonders für jemanden, der keine Ahnung hat, welche Schlüsselbegriffe zu erforschen sind. Ich bin sicher kein Künstler.
Carter81

Antworten:

19

Farbtonverschiebung ist eine Möglichkeit, mit der Sie eine Reihe von Farben erhalten, ohne die Farbdetails zu verlieren. Die Grundidee besteht darin, jedes Pixel von RGB in den HSV-Raum umzuwandeln, dann den Farbton um einen benutzerdefinierten Betrag zu verschieben und dann wieder in RGB umzuwandeln. Tatsächlich kann dies effizienter durchgeführt werden, indem eine Rotationsmatrix auf die RGB-Werte angewendet wird: Erstellen Sie eine Matrix, die sich um den benutzerdefinierten Farbtonwinkel um die (1, 1, 1) -Achse dreht. Dann können Sie diese Matrix einfach auf jeden RGB-Wert in Ihrem Pixel-Shader anwenden.

Dadurch kann der rot-gelbe Drache in einen gelb-grünen, grün-cyan-blauen, cyan-blauen, blau-magentaroten oder magentaroten Drachen verschoben werden. Dies ist ein wenig einschränkend, da die beiden Farben bei diesem Ansatz nicht unabhängig voneinander geändert werden können. Sie behalten ihren relativen Farbton bei, wenn sie im Originalbild erstellt werden. Es gibt auch einige Farben, auf die Sie keinen Zugriff haben, z. B. können Sie auf diese Weise keinen Schwarz-Weiß-Drachen herstellen. Dies kann jedoch für Ihre Zwecke ausreichen.

Eine andere Möglichkeit: Wenn Ihre Modelle zwei oder drei "Schlüsselfarben" haben (hier Rot und Gelb), können Sie das Originalbild mit einem separaten Farbkanal für jede Schlüsselfarbe erstellen. In diesem Fall würden Sie den Drachen in Rot und Grün anstatt in Rot und Gelb erstellen, und wenn Sie eine dritte Farbe hätten, könnten Sie ihn in Blau erstellen. Anschließend können Sie den Benutzer die drei Schlüsselfarben auswählen lassen und die Werte für Rot, Grün und Blau im Bild als Anzahl der zu überblendenden benutzerdefinierten Farben verwenden. Ihr Pixel-Shader würde also ungefähr so ​​aussehen

finalColor = image.r * userColor1 + image.g * userColor2 + image.b * userColor3;

Auf diese Weise können die Benutzer jede gewünschte Farbkombination auswählen, einschließlich schwarz-weiß oder lila-gold.

Nathan Reed
quelle
1
+1 für nicht nur eine gute Antwort, sondern eine Antwort auf ein seltenes Thema (Farbtheorie). Ich habe keine Ahnung, warum ich vorher nicht daran gedacht habe. RGB. Rot grün blau. DUH! Die besten Farben sind wahrscheinlich genau diese drei Farben, da die einzelnen Kanäle manipuliert werden können.
Carter81
1
Die Farbverschiebung ist ein sehr schwieriges Thema, da die meisten Bildinformationen durch die Helligkeit vermittelt werden und eine einfache Farbtonverschiebung die Helligkeit nicht bewahrt. Unterschiedliche Farbtöne haben unterschiedliche inhärente Helligkeitswerte. Dafür benötigen Sie ausgefeiltere Algorithmen.
API-Beast
10

Das Problem, dem Sie gegenüberstehen, ist, dass Sie nicht einfach das gesamte Bild "tönen" können. Das Erscheinungsbild, das Sie sehen, ist mehr als nur eine Grundfarbe. Zum einen haben Sie feine Verläufe von einem Material zum anderen, zum anderen aber auch Reflexionen, Glanzlichter und Schatten, die nicht von der Grundfarbe beeinflusst werden. (Diese werden im Grunde darüber hinzugefügt.)

Sie müssen das Bild also in seine Komponenten zerlegen.

Ein Beispiel :

Dekonstruiertes Bild Getönte Beispiele

In diesem Fall haben wir 3 Schichten:

  • Der Hintergrund - Dies enthält die Elemente, die nicht eingefärbt werden sollen.
  • Der Teil, der gefärbt werden soll - Dies wird mit der Farbe multipliziert. (OpenGL wird standardmäßig multipliziert, wenn Sie eine andere Farbe als Weiß angeben.)
  • Die Highlights - Diese werden additiv über das gesamte Bild gezeichnet. Es ist nicht weiß, sondern gelb, um eine Farbtonänderung zu emulieren. Objekte sind nicht nur eine einzige Farbe, der Farbton ändert sich zusammen mit der Helligkeit.
API-Biest
quelle
+1. Aber "man kann nicht einfach" das ganze Bild "tönen" ist ein bisschen irreführend. Es hängt alles von der Wahl des OP für sein Spiel ab. Zum Beispiel hat es Diablo II getan. Ich wäre also nicht so streng mit "Sie können nicht / Sie brauchen" -Teilen. Dies ist nur eine der Optionen, die besser aussehen, aber mehr RAM verbrauchen.
Kromster sagt Unterstützung Monica
1
@KromStern Punkt ist, es sieht schrecklich aus, wenn Sie es immer tun.
API-Beast
Gute Antwort. Ist dies jedoch durch Automatisierung möglich? Wenn man Tausende von animierten Bildern für einen einzelnen Charakter hat, ist es nicht möglich, jede Ebene von Hand auszuwählen oder das Bild einzeln zu zerlegen. Trotzdem kann ich einige Problemumgehungen finden, um die Automatisierung beim Rendern aus 3D mithilfe der Maskierung zu unterstützen, aber es ist trotzdem eine großartige Antwort.
Carter81
Es ist möglicherweise möglich, es zu automatisieren, indem die dominanten Farben gefunden und extrahiert werden (indem ein umgekehrter "Color to Alpha" -Algorithmus verwendet wird). Aber es ist nicht so, als hätte ich jemals so etwas implementiert.
API-Beast
Zum Extrahieren der Glanzlichter können Sie die zuvor extrahierte Maske nehmen und filtern, sodass nur die hellsten Komponenten übrig bleiben.
API-Beast
3

Ich würde persönlich empfehlen, Maskentexturen zu verwenden, um das zu erreichen, was Sie wollen. Dadurch wird sichergestellt, dass Ihre RGB24-Haupttextur ihre ursprüngliche Farbqualität beibehält, ohne an Präzision zu verlieren. Es gibt Ihnen auch viel künstlerische Freiheit, um Ihre Haupttextur mit Ihrer Farbmaske zu mischen.

Jede Maske kann als Graustufentextur betrachtet werden, die die Farbe Ihrer Basistextur linear mit Ihrer benutzerdefinierten Farbe interpoliert. Angenommen, Sie lassen Ihre Benutzer zwei Farben anpassen. Der Pixel-Shader sieht ungefähr so ​​aus:

Eingänge: MainTexture (RGB), Mask1Texture (A), Mask2Texture (A), Colour1 (float), Colour2 (float)

Ausgabe: (Mask1Texture + Mask2Texture) -MainTexture + Colour1 * Mask1Texture + Colour2 * Mask2Texture

Dies legt nahe, dass je mehr eine Maske einen großen Wert für ein Pixel hat, desto weniger wirkt sich Ihre Haupttextur auf die Ausgabefarbe dieses Pixels aus. Zum Beispiel könnten Sie Ihre Drachentextur in eine Graustufe umwandeln und alles außer Ihren Flügeln löschen, um eine benutzerdefinierte Flügelfarbe zu erhalten, unabhängig von der Körperfarbe.

Ich habe diese Technik für mobile Spiele verwendet und sie hat keinen Einfluss auf Ihre Gesamtleistung. Es kostet Sie vielleicht 33% mehr RAM pro Textur, aber der Kompromiss mit der Qualität ist es wahrscheinlich wert.

Ps Wenn Sie nur eine benutzerdefinierte Farbe verwenden möchten, können Sie einfach den Alpha-Kanal Ihrer RGBA32-Haupttextur als Maske verwenden.

MrXee
quelle
2

Sie können Farbpaletten verwenden und den Player die Palette bearbeiten lassen. Wenn Sie Shader verwenden, können Sie 1D-Texturen als Paletten und den ursprünglichen Grauwert als Index verwenden.

Um ein Echtfarbenbild in ein Bild mit 255 Farben umzuwandeln, können Sie alle Ihre Pixelfarbwerte nehmen und sie im 3D-Farbraum mit dem k-means-Algorithmus in 255 Cluster gruppieren. Oder verwenden Sie allgemeine Bildkonvertierungstools. Dann ist es wichtig zu erwähnen, dass die Interpolation der Grauwerttextur eine Interpolation der Indizes in Ihren Farbtexturen ist. Dies kann zu einem Ergebnis führen, bei dem Sie mehrere Farben zwischen zwei Texeln Ihres Originalbilds haben. Dies kann gelöst werden, indem die Interpolation deaktiviert wird (ich glaube, das möchten Sie nicht) oder indem Sie Ihre Farbpalette auf nützliche Weise sortieren.

Arne
quelle
Dies ist im Grunde das, was ich auch gedacht habe. Möglicherweise möchten Sie die Antwort auf etwas Vollständigeres erweitern. Grundsätzlich können Sie den Benutzer zwei Farben auswählen lassen (oder mehr oder weniger, aber aus Gründen des Arguments 2), um eine 1D-Textur zu erstellen, die aus den beiden Farben verblasst. Verwenden Sie eine Graustufentextur für die Geometrie, die als Referenz in der 1D-Textur dient. Der Benutzer kann zwar immer noch hässliche Farben einstellen, hat aber zumindest die Möglichkeit, schöne Kontrastfarben auszuwählen.
Wrosecrans
ja, Sie können auch die volle 255-Farben-Palette aus weniger Benutzerfarben ableiten, aber hier kann ich Ihnen nur raten, es auszuprobieren. Ich weiß, dass viele alte Spiele Änderungen in der Farbpalette verwendeten, um Variationen in ihren Monstern vorzunehmen. Ich denke, Diablo hat das getan.
Arne
1

Sie können das Bild in ein graues Bild konvertieren, es jedoch mit RGBA-Kanälen speichern. Speichern Sie einen Gewichtswert im Alpha-Kanal und legen Sie dann fest, wie viel Farbstoff auf ein Pixel angewendet werden soll. Dieses Gewicht kann basierend darauf berechnet werden, wie nah die Farbe an Weiß ist. Je näher das Pixel an Weiß liegt, desto weniger Farbe sollte aufgetragen werden oder desto geringer sollte das Gewicht sein. Dadurch bleiben die meisten Glanzlichter in ihrer ursprünglichen Helligkeit erhalten, aber Sie können etwas Farbe darauf auftragen. Die endgültige Pixelfarbe kann dann durch Berechnen jedes Kanals Ro + (Rd * Ao) ermittelt werden, wobei Ro das ursprüngliche Rot ist, Rd das Rot in der Farbstofffarbe ist und Ao das Alpha des Originals ist. So erhalten alle weißen Pixel keine neue Farbe und alle schwarzen Pixel nehmen die Farbfarbe an.

Phil
quelle