Wie texturiere ich eine Oberfläche, die durch den Algorithmus für Marschwürfel erzeugt wurde?

8

Ich arbeite an einem Voxel-Spiel und habe einige Probleme mit der Texturierung. Ich habe die zugehörigen Fragen zu diesem Stapelaustausch gelesen, aber sie scheinen ein allgemeines Problem (unter Verwendung der triplanaren Texturierung) anzusprechen, und ich denke, meine ist einfacher.

Polygonisierungsausgabe

Sie können sehen, dass die resultierende Geometrie einen begrenzten Satz von Polygonen enthält. Zuletzt habe ich überprüft, dass ich nur 44 von ihnen gesehen habe. Meine Idee war es, diese Polygone mithilfe einer statischen Kartentabelle einer regulären Textur zuzuordnen, ohne eine triplanare Texturierung verwenden zu müssen (derzeit wird jedes Polygon denselben Werten zugeordnet, daher ist es hässlich).

Meine Fragen :

  • Ist es gültig? Es scheint viel einfacher zu sein als die triplanare Texturierung, aber ich kann keine einzige Ressource zu diesem Thema finden, daher frage ich mich, ob es ein richtiger Ansatz ist.
  • Wo finde ich / Wie kann ich eine UV-Karte für diese Art von geometrischer Figur erstellen? Ich habe versucht, Mixer zu verwenden, aber es scheint, dass mein Mixer-Fu nicht stark genug ist. Gibt es eine einfachere Software zum Generieren von UV-Karten mit Modellen wie diesem?
Nison Maël
quelle
4
Ich werde dies nicht als Antwort veröffentlichen, aber dieser Link beschreibt den Prozess der tri-planaren Texturierung in genau demselben Kontext, in dem Sie versuchen, ihn in http.developer.nvidia.com/GPUGems3/gpugems3_ch01.html
Evan
Dies scheint mir die gleiche Art von Problem zu sein als eine Kachel-Sets mit Übergang Fliesen für eine 2D - Karte Konstruktion: für jede Art von Kante , müssen Sie entscheiden , was das Rand aussieht, dann eine Reihe von Textur Fliesen + UVs Unabhängig davon, was das benachbarte Polygon ist, weist seine Kante (dieses Typs) immer das gleiche Muster auf. Es hört sich so an, als ob Sie dies nur mit einer einzigen Textur erreichen und nur die UV-Strahlen anpassen möchten, aber das ist möglicherweise nicht möglich (außer in dem trivialen Fall, in dem jede Kante das gleiche Muster hat).
Kevin Reid
Ein Problem bei diesem Ansatz ist die Auswahl der richtigen Textur für jeden Scheitelpunkt bei mehreren Optionen. Sie können nicht einfach die Textur des Voxels auswählen, das diesem Scheitelpunkt am nächsten liegt, da "Luft" -Voxel keine Textur haben. Im Luftfall muss man sich zu einem anderen Voxel auflösen, und ich zerbreche mir den Kopf, um etwas Effizientes zu finden. Sie können ein Luftvoxel nicht einfach für alle Scheitelpunkte einem anderen Voxel zuordnen, daher müssen Sie entweder eine spezifischere Logik codieren oder eine Nachschlagetabelle verwenden. Hmm ...
Philip Guin

Antworten:

5

Eine andere Möglichkeit wäre, Ihre Texturen prozedural zu generieren. Dieser Ansatz hat seine Vor- und Nachteile. Der wichtigste Nachteil ist, dass Sie Ihre Texturen nicht in einem Editor zeichnen können, sondern sie mithilfe von Rauschfunktionen codieren müssen.

Der große Vorteil Ihrer Situation besteht darin, dass Sie Ihr Gelände völlig unabhängig von der Ausrichtung strukturieren können. Dies geschieht unter Verwendung von sogenanntem festem Rauschen. Es ist eine dreidimensionale Rauschfunktion.

Damit können Sie eine Funktion codieren, um den Farbwert einer bestimmten Position im 3D-Raum zu generieren . Dann probieren Sie nur die Punkte aus, die auf den Netzflächen liegen. Mit anderen Worten, Sie schnitzen aus der dreidimensionalen Textur heraus.

Dies ist aus dem libnoise Glossar .

Das folgende Bild zeigt ein Objekt mit einer festen Rauschstruktur. Beachten Sie, dass sich die Textur nirgendwo auf dem Objekt verzieht. es ist im gesamten Objekt einheitlich. Es wäre sehr schwierig, eine nicht verziehende zweidimensionale Texturkarte für dieses Objekt zu erstellen.

Geben Sie hier die Bildbeschreibung ein

Ich weiß, dass es möglicherweise nicht Ihr Ziel ist, Anweisungen zum Generieren jeder Textur zu codieren, die Sie verwenden möchten. Es kann aber auch eine Herausforderung sein und bringt nicht nur den orientierungsunabhängigen Vorteil mit sich, sondern auch den stark reduzierten Speicherplatz und die unbegrenzten Vergrößerungsdetails.

Es würde mich sehr interessieren, wenn Sie versuchen würden, solide Geräuschstrukturen für Ihr Gelände zu implementieren.

Danijar
quelle
3

So dies bietet keine Details zu jedem Problem , das Sie mit Ihrem Ansatz begegnen werden, aber , wenn Sie jede Ecke zur nächsten nicht-Luft Voxel , um zu schaben Informationen von ihm (wie die Textur Probe) zuordnen mögen, Hier ist ein Beweis für die effiziente Methode, die ich mir ausgedacht habe:

Für jeden gegebenen Scheitelpunkt der Marschwürfel möchten wir ein Voxel auswählen, mit dem auf die Attribute des Scheitelpunkts geschlossen werden kann. Wir wählen das nächstgelegene Nicht-Luft-Voxel, das sich per Definition an derselben Kante befinden muss, auf der sich der Scheitelpunkt befindet. Da die von uns erzeugte „Oberfläche“ Luft aus Festkörpern abgrenzt, müssen die beiden Voxel entlang einer Kante, die einen Scheitelpunkt enthält, ein Festkörper und eine Luft sein. Wenn daher jedes Voxel neben dem aktuellen Würfel durch die Kombination seiner Neigungen entlang jeder Achse indiziert wird, können wir zwei seiner Neigungen durch die bestimmte Kante ableiten, auf der der Scheitelpunkt ruht, und die dritte Neigung durch Abtasten beider möglicher Ecken und Wählen Sie nur diejenige aus, die fest ist. Um das gewünschte Voxel effizient abzutasten, Wir erstellen eine Nachschlagetabelle, die jede der zwölf Würfelkanten jeweils zwei möglichen Voxelindizes zuordnet, wobei die oberen und unteren vier Bits jeweils Indizes in der Menge von acht möglichen Voxeln sind. Nachdem wir beide Voxel abgetastet haben, können wir die beiden Proben addieren, anstatt sie zu verzweigen, um die feste auszuwählen. Wenn 'Luft' ein Wert ungleich Null ist, können wir ihn einfach vom Endergebnis abziehen, da garantiert ist, dass einer der Operanden dieser Wert ist.

Hier ist meine Implementierung in Java, vorausgesetzt, Ecken und Kanten werden wie in Paul Bourkes populärem Artikel beschrieben indiziert (Ecke Null ist -X -Y -Z):

Paul Bourkes beliebte Referenz zu Marschwürfeln

..und unter der Annahme, dass blockIdses sich um a handelt, longdessen Bytes jeweils einer Ecke entsprechen, von höchst bis niedrigstwertig, 0, 1, 4, 5, 3, 2, 7 und 6. (In Bezug auf die Neigungen XYZ sind die geordneten Werte 000 100, 010, 110, 001, 101, 011 und 111.)

private static final byte[] BLOCK_PICK_BITS_BY_VERT_INDEX = new byte[]{
    (byte)0x67,
    (byte)0x26,
    (byte)0x23,
    (byte)0x37,
    (byte)0x45,
    (byte)0x04,
    (byte)0x01,
    (byte)0x15,
    (byte)0x57,
    (byte)0x46,
    (byte)0x02,
    (byte)0x13
};

private static final int pickBlockIdForVertex(long blockIds, int vertIndex)
{
    int bits = BLOCK_PICK_BITS_BY_VERT_INDEX[vertIndex];
    int blockIndexA = bits >> 4;
    int blockIndexB = bits & 0xf;
    int blockIdA = (int)(blockIds >> 8 * blockIndexA) & 0xff;
    int blockIdB = (int)(blockIds >> 8 * blockIndexB) & 0xff;

    //assert (blockIdA == airBlockId) != (blockIdB == airBlockId);
    //return blockIdA - nonZeroAirBlockId + blockIdB; 
    return blockIdA + blockIdB;
}

In C / C ++ kann es sinnvoll sein, long blockIdsin ein Array von Bytes / Kurzschlüssen / Zeigern zu wechseln und jeden Vier-Bit-Wert in der Tabelle entsprechend neu zuzuordnen bits = 7 - bits. Ich habe es jedoch nicht profiliert, daher ist es longmöglicherweise noch schneller , alles in ein zu packen . Schließlich wird eine Luftblock-ID ungleich Null neu angeordnet, sodass bei einer großen Domäne von Block-IDs kein Überlauf auftritt. Würde im obigen Code nicht passieren, da ich intsblockIds speichere, die es sind bytes, aber es ist etwas zu beachten.

(Um 100% klar zu sein, trage ich diese Methode zur Public Domain bei und verzichte auf die Haftung gemäß der hier beschriebenen vollständigen Lizenz: http://unlicense.org/ )

Philip Guin
quelle
-2

UV-Mapping scheint der richtige Weg zu sein. Ich glaube, dies beantwortet Ihre erste Frage (aber ich kann mich irren). Der Grund, warum Blender dies nicht für Sie UV-kartiert, liegt darin, dass versucht wird, es als ein riesiges Klumpensache auszupacken. Sie müssen dem Modell Nähte hinzufügen, damit Blender es entsprechend aufteilen kann. Weitere Informationen hierzu finden Sie im offiziellen Blender- Handbuch für UV-Mapping .

Polar
quelle