Wie senkt Unity3D die Anzahl importierter OBJ-Vertexs?

8

Ich habe eine Frage dazu, wie Unity3D den Import von OBJ-Dateien handhabt. Ich importiere diese Teekanne: http://groups.csail.mit.edu/graphics/classes/6.837/F03/models/teapot.obj

Die Anzahl der Scheitelpunkte dieser Teekanne beträgt 3644. Ich weiß, dass die Mesh-Klasse von Unity diese Scheitelpunkte für jedes Gesicht replizieren muss, das von demselben Scheitelpunkt geteilt wird. Ich habe dies mit einem aus einem .obj importierten Cube versucht und mit Debug.Log () die Anzahl der Scheitelpunkte gedruckt. Dabei habe ich festgestellt, dass das Scheitelpunktarray des Netzes 24 Scheitelpunkte enthält.

Bei der Teekanne hatte die Originaldatei jedoch 3644 Scheitelpunkte, sodass in Unity die Scheitelpunktzahl 18960 betragen sollte. Wenn ich stattdessen die Länge des Scheitelpunktarrays des Netzes drucke, werden 3260 (sogar weniger als die Originaldatei) gedruckt.

Das letzte Ziel hierfür ist, dass ich versuche, ein OBJ-Importer-Skript aus dem Unity-Wiki so zu ändern, dass die Anzahl der aus diesem Skript resultierenden Scheitelpunkte der Anzahl des nativen Importers von Unity entspricht. Referenz: http://wiki.unity3d.com/index.php?title=ObjImporter Hinweis: Ich habe die Scheitelpunktanzahl mit diesem Importer gedruckt und das Ergebnis war 18960.

Hat jemand eine Idee, wie diese Vertexreduktion erreicht werden könnte?

VitorOliveira
quelle
Komplexe Algorithmen, ich bin mir nicht sicher, was Unity verwendet, aber Sie können sie online finden.
MickLH

Antworten:

5

Es gibt mehrere Faktoren, die dazu beitragen, wie die Geometrie in verschiedenen Medien (Programme, Dateiformate, APIs) gespeichert und verarbeitet wird. Ich habe mehrere kommerzielle Geometrieanalyseprogramme implementiert, daher habe ich einige Erfahrungen damit.

Zunächst bin ich sicher, dass dies nichts damit zu tun hat, dass Unity irgendetwas vereinfacht. Falls dies der Fall sein sollte, können mehrere Dezimierungsalgorithmen implementiert werden, aber ich bin sicher, dass dies nicht der Fall ist, da eine Spiel-Engine die Form (geometrische Eigenschaften eines Netzes) nicht ändern soll, sondern normalerweise seine Konnektivität ändern kann zu seiner optimalen Struktur passen.

Einige dieser Faktoren sind:

Was macht einen Scheitelpunkt einzigartig?

Dies kann sehr unterschiedlich sein, je nachdem, wie das Programm, die API oder das Dateiformat mit einem Scheitelpunkt umgehen. Ein Scheitelpunkt kann eindeutig sein, wenn er eine eindeutige Position hat, in anderen Fällen ist er eindeutig, wenn er ein eindeutiges Attribut hat. Wenn beispielsweise zwei Scheitelpunkte dieselbe Position haben, aber unterschiedliche Normalen haben, sollten sie im Fall von OpenGL "dupliziert" werden. Dies ist besonders im Fall des von Ihnen erwähnten Würfels offensichtlich.

Geben Sie hier die Bildbeschreibung ein Harte vs glatte Kanten.

Normalen können bestimmen, ob eine Kante als hart oder glatt angesehen wird. Wenn ein Scheitelpunkt zur harten Kante beiträgt, muss er dupliziert werden, damit die aktuellen Rendering-APIs verstehen, wie diese Fläche korrekt gerendert (schattiert) wird.

Geben Sie hier die Bildbeschreibung ein

Indizes

In vielen Dateiformaten kann ein Gesichtsscheitelpunkt mehrere Indizes für die Scheitelpunktposition / texCoords / normals haben. Dies ist bei aktuellen Rendering-APIs nicht der Fall. Ein gutes Beispiel hierfür ist die Obj-Datei. Dadurch wird Unity gezwungen, die Indizes neu zu erstellen und häufig viele Attribute zu duplizieren, um sie an die Scheitelpunktindizes anzupassen.

Konnektivität

Viele der tatsächlich verbundenen und eindeutigen Scheitelpunkte werden mehrmals gespeichert. Dies hängt davon ab, wie der ursprüngliche Dateischreiber das Netz verarbeitet und gespeichert hat. Unity reduziert die Anzahl doppelter Scheitelpunkte (denken Sie daran, wenn es ein anderes Attribut hat als nicht eindeutig), um es für die Speicherung und Verarbeitung effizienter zu gestalten, ohne die Qualität zu beeinträchtigen.

Dies hängt auch damit zusammen, wie viele Polygonseiten die Originaldatei zulässt. Obj beispielsweise erlaubt N-seitige Polygone, was jede vernünftige Spiel-Engine nicht möchte. Daher wird das Netz trianguliert und viele seiner Attribute werden häufig neu berechnet Ändern Sie die Anzahl der Scheitelpunkte.

concept3d
quelle
Oh, ich verstehe es jetzt! In dem von mir verwendeten .obj-Importer werden die Scheitelpunkte immer für jedes Gesicht dupliziert, in dem sie verwendet werden, und deshalb bekomme ich immer harte Kanten an meiner Teekanne (habe dies vorher nicht erwähnt, weil ich dachte, es sei ein anderes Problem). Gute Antwort!
VitorOliveira
2

Objektformate sind insbesondere deshalb seltsam, weil die Positionen, Normalen und Texturkoordinaten getrennt sind und jedes Gesicht aus jedem Stream einen beliebigen Index auswählen kann. Wenn Sie sich auf die Anzahl der Scheitelpunkte beziehen, denken Sie, dass die Anzahl der Scheitelpunkte und Normalen nicht gleich ist und Sie sich nicht wirklich auf die gesamte Anzahl beziehen können.

Während des Ladens müssen alle diese drei Attribute zusammengeführt werden, damit eine Scheitelpunktposition dupliziert werden kann, da die dieser Scheitelpunktposition zugeordnete Fläche zwei Normalen zugeordnet ist . Dies kann auch umgekehrt geschehen, sodass die meisten Lader einen Schritt zur Optimierung des Objekts haben. Im Fall Ihres Würfels funktioniert die Optimierung jedoch nicht, da der Würfel harte Kanten hat und jeder Scheitelpunkt eine andere Normal- (oder Texturkoordinate) hat. Aus diesem Grund haben Sie 6 Scheitelpunktpositionen gezählt, aber die Einheit hat diese Positionen dupliziert, was zu 24 Scheitelpunkten führte.

Um ein Netz zu laden, können Sie Positionen / Normalen oder Texturkoordinaten duplizieren, sodass die Optimierung nicht einfach ist. Es läuft darauf hinaus, die Mindestanzahl von Duplikaten aus diesen drei Streams auszuwählen.

Raxvan
quelle
Diese Antwort war eine großartige Ergänzung zu den Aussagen von concept3d und hat mir geholfen, dieses Problem zu verstehen. Ich denke, mein .obj-Importer wird vorerst immer harte Kanten haben, aber wenn ich ihn verbessern möchte, sollte ich nach Algorithmen suchen, um zu wissen, welche Scheitelpunkte dupliziert werden sollten oder nicht, um ein glattkantiges Modell mit Minimum zu erhalten ( oder zumindest optimierte) Scheitelpunktzahl.
VitorOliveira