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?
Antworten:
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.
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.
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.
quelle
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.
quelle