Texturesynthesis

Aus DGL Wiki
Version vom 5. Februar 2009, 21:33 Uhr von Coolcat (Diskussion | Beiträge) (Die Seite wurde neu angelegt: {{Offline}} == Was ist Texturesynthesis? == Häufig steht man vor dem Problem, dass man zwar in Textursammlung XY eine vom Prinzip eine schöne Textur gefunden hat, di...)

(Unterschied) ← Nächstältere Version | Aktuelle Version (Unterschied) | Nächstjüngere Version → (Unterschied)
Wechseln zu: Navigation, Suche
Hinweis: Dieser Artikel wird gerade Offline bearbeitet!

Bitte haben Sie etwas Geduld und nehmen Sie keine Änderungen vor, bis der Artikel hochgeladen wurde.

(weitere Artikel)
WIP Offline.jpg

Was ist Texturesynthesis?

Häufig steht man vor dem Problem, dass man zwar in Textursammlung XY eine vom Prinzip eine schöne Textur gefunden hat, diese jedoch aus diversen Gründen nicht sinnvoll nutzbar ist. Ein paar Beispiele:

  • die Textur ist zu klein, würde man die Textur kacheln, sähe man dies sofort
  • die Textur ist ein Foto und daher gar nicht kachelbar
  • die Textur hat einige kleinere Stellen die "doof" aussehen. Beispielsweise größere Schatten in einer Fototextur können merkwürdig aussehen wenn das Licht in der Szene nicht aus der entsprechenden Richtung kommt. Gleiches gilt für besonders auffällige Elemente deren Wiederholung man sofort sehen würde.

Sofern es sich um eine Textur mit nur lokaler Struktur handelt und man etwas Rechenleistung invertiert kann man diese Mängel ohne Verlust an Qualität beheben!

Texturesynthesis ist die Wissenschaft die sich damit beschäftigt die grundlegende Struktur einer Textur weiterzuführen OHNE Wiederholungen zu erzeugen. Der Standardalgorithmus beginnt mit einer Zufallstextur mit RGB-rauschen. Nun wird die Textur Pixel für Pixel durchlaufen und jeweils der Pixel aus der Inputtextur gewählt, dessen lokale Nachbarschaft best-möglich zum aktuellen Pixel passt.

Das ganze klappt nicht bei jeder Textur, erfordert eine Menge Rechenleistung, aber prinzipiell kann man aus einer kleinen Quelltextur beliebig große, kachelbare Texturen zu erzeugen!

Eine Menge Rechenleistung bedeutet folgendes: Angenommen wir haben eine 1024x1024 Inputtextur und wollen daraus eine gleichgroße Outputtextur erzeugen. Für jeden Pixel in der Outputtextur müssen wir die Nachbarschaft jedes Pixels in der Inputtextur anschauen. Also 1024*1024*1024*1024 = 1 Billion Operationen. Natürlich lässt sich das ganze etwas optimieren, indem man beispielsweise eine Baumstruktur einsetzt, trotzdem kann das auf aktueller Hardware durchaus ein paar Stunden dauern.

Beispiele

Info DGL.png Dank freundlicher Genehmigung von cgtextures.com kann ich hier einige Beispiele präsentieren. Die folgenden Beispiel-Texturen unterliegen wie das gesamte Wiki der GNU Free Documentation License 1.2. Dies gilt jedoch ausschließlich für die Texturen in diesem Artikel. Texturen die von cgtextures.com heruntergeladen werden unterliegen nicht dieser Lizenz!

Input-Textur links, in der Masken-Textur rechts sind unerwünschte Bereiche mit schwarz (RGB: 0,0,0) übermalt. Die Textur hatte eine Originalgröße von 1600x1200 und wurden vor Anwendung des Tools auf 683x512 herunterskaliert.
Rock-input.jpg Rock-mask.jpg
Als Output bekommt man diese kachelbare Textur. Sie hat im Original eine Auflösung von 1300x1300.
Rock-output.jpg




Cool, und wie geht das nun?

Es gibt viele verschiedene Tools die sowas können. Ich habe mich für das folgende entschieden, es gibt aber viele, einfach googlen. http://www.texturesynthesis.com/texture.htm Man muss das ganze selbst kompilieren und da aus dem Jahr 2002 ist leider etwas am Quellcode fummeln bis aktuelle Compiler den Code akzeptieren. Sollte aber ziemlich offensichtlich sein, in Option.h musste ich ein using namespace std; hinzufügen und in nr.h zweimal eine ungenutzte Funktion fmin auskommentieren. (ich nutze Fedora 10 Linux mit gcc 4.3.2)

Leider ist das ganze nicht für Mehrkern-CPUs geschrieben, man kann aber einfach für jeden Kern das Programm einmal starten. Man muss sowieso immer ziemlich an den Parametern spielen, bis man ein sinnvolles Ergebnis erhält. Je nach verwendetem Algorithmus und Größe der Textur kann das ganze durchaus ein paar Stunden dauern.

Als Inputdatei sollte man ein PNG wählen. Zum einen geht so keine Qualität verloren, zum anderen produziert das Programm beim speichern von JPG Dateien einen schwarzen Balken am oberen Bildrand. Wenn man Probleme mit Rauschen im Ergebnis hat, kann man die Ausgabeauflösung etwas höher wählen und nachher das Bild runterskalieren.

Parameter Ein Beispielaufruf sieht so aus: Code:

nonparaMRF_fast -n 2 -square -cyclic -x 1300 -y 1300 texinput1.png

Der Parameter -n ist der wichtigste, er gibt den Radius an in dem die Pixel verglichen werden. Möglich sind 1,2,3 und 4. Ein größerer Wert erfordert mehr Rechenleistung. Es hängt aber von der Struktur der Textur ab, ob man ein schöneres Ergebnis erhält. Man sollte mal 2 und 3 probieren. Der Parameter -square bewirkt das statt der üblichen 2-norm die Manhattandistanz verwendet wird. Was das heißt sieht man am besten hier.

Der Parameter -cyclic bewirkt das die Textur kachelbar wird. Mit -x und -y gibt man die Größe der Ausgabetextur an.

Praktisch ist ebenfalls der -m Parameter. Damit kann man "doofe" Stellen in der Inputtextur ausblenden. Einfach die Inputtextur nehmen und mit schwarzer Farbe alles ausradieren was nicht gefällt. Alle Pixel die Farbe RGB 0,0,0 haben werden ignoriert.

Beispiel Ich habe mal ein Beispielbild angehängt. Input, Mask und Output sind skaliert. Input bzw. Mask hatten eine Auflösung von 683x512, die Outputtextur hat eine Auflösung von 1300x1300. Rechenzeit etwa 2-3 Stunden auf meinem Intel Core 2 Quad Q9300, allerdings natürlich nur ein Core genutzt und die CPU läuft bei mir auf 2.0 GHz statt 2.5 GHz. Code:

nonparaMRF_fast -n 2 -square -cyclic -x 1300 -y 1300 -m rock_mask.png rock_input.png



Verbesserungen

Es gibt sogar mittlerweile Programme die eine Perspektivenkorrektur verwenden. Zum Beispiel kann man das Colosseum in Rom virtuell wieder aufbauen. Bilder gibts hier. Sowas wollen wir aber gar nicht, uns reicht die uralte Technik ohne Perspektive.