Ich bin gerade in der konzeptionellen Phase für mein erstes simples export script / modelformat für blender und openGL (habe noch keinerlei Erfahrungen auf dem Gebiet). Ich bin über diverse Seiten aus dem DGL wiki gestolpert, die schonmal sehr hilfreich waren, um ein paar Dinge für mich zu klären. Vor allem diese Einträge waren sehr hilfreich:
http://wiki.delphigl.com/index.php/Modelformat http://wiki.delphigl.com/index.php/Blenderexporter
Allerdings habe ich noch zwei Fragen, die ich gerne grob klären würde bevor ich mich ans Coden mache. Die erste ist bezüglich verschiedener Materialien in einem Model:
In dem ersten Link wird in jedem face eine Material id gespeichert, die dann auf eine Datei verweist, die alle möglichen Resourcen wie Texuren und Shader zur Verfügung stellt, wenn ich das richtig verstehe. Das klingt logisch, aber ich kann nicht richtig nachvollziehen auf welchem Weg ich in Blender auf die richtige Materialdatei verweise. In dem angehängten Exportscript scheint die MaterialId einfach die id der Textur zu sein, die das Model an dem bestimmten face zur verfügung stellt. Müsste ich dann in meinem loader quasi manuell die richtige Materialfile mit der id von Blender verlinken? Oder übersehe ich hier irgendeinen praktischen Mechanismus, der das automatisch macht?
Ein simples Beispiel wäre wenn ich einen baum habe, dessen blätter von einem vertex shader animiert werden soll (beispielsweise wind). Dann hätte ich eine Material file für den stamm und eine für alles was animiert werden soll. Wie würde die Methode in dem angesprochenen link das lösen bzw. auf die entsprechenden Material files verlinken? Was für Alternativen gibt es?
Meine zweite frage sollte etwas simpler sein. Wenn ich ich die Vertex Daten (erstmal nur texCoords, Position und Normale) für openGL als indexed Arrays zur Verfügung stellen möchte, würde das so funktionieren?
1. Faces vom blender Mesh durchgehen.
2. Wenn die aktuelle Position, Normale und TexCoords identisch mit denen eines schon abgelegten Vertex sind, dann füge ich einen index zum index array, der auf das identische Vertex verweist.
3. Ist dies nicht der Fall, dann füge ich das Vertex neu hinzu, und füge ein index, der auf das neue vertex verweist zum index array hinzu.
Ist das in der Theorie soweit korrekt?
Ich wäre sehr dankbar, wenn mir hier jemand ein paar Tipps geben könnte!
Registriert: Di Mai 18, 2004 16:45 Beiträge: 2623 Wohnort: Berlin
Programmiersprache: Go, C/C++
Der Gedanke, als ich das geschrieben hatte, war das ich anhand einer zugewiesenen Textur später daraus den Materialnamen generiert. Sprich das Face hat ein Materialnamen "Wood.jpg" zu "Wood" gemacht und der loader sucht dann nach "Wood.mat". Das war ein Lua Script, welches die Texturen, Sounds, Physikinfos und so weiter geladen und gesetzt hat sowie die Zeichenroutine für bestimmte Renderpasses bereit stellt. Unglücklicherweise habe ich den Code nicht ausreichend kommentiert. Die MaterialID ist ledeglich der Indexwert, des Arrays, der auf die Materialnamen verweist. Strings sind größer als integer und daher habe ich bei den Faces integer genommen statt direkt den Namen hin zu schreiben. Der Sinn hier war, dass man ohne groß zu überlegen alle Materials vom Materialarray laden kann und Bindingbefehle Performance einsparen, indem man nur ein integer vergleicht, statt ein string(Bindings laufen in der Loop immer und in sehr großer Anzahl durch, das macht große unterschiede in der FPS, gerade ab OpenGL2.0).
Man kann natürlich auch den Materialnamen statt Texturnamen speichern, dann ist man aber gezwungen immer ein Material an zu legen und es reicht nicht mehr aus nur UV-Koordinaten und eine Textur zu zuweisen, da ja noch ein Material benötigt wird.
Ja diese Reihenfolge ist so korrekt. Blender hat für jedes Mesh eine Indicesliste und speichert auch entsprechend die Vertice und so ab aber komischer weise prüft es nur, ob die Vertexposition gleich ist, Texturkoordinaten, Normalen werden völlig ignoriert und deswegen dieser etwas längere Check am ende des Exporters.
Mein neuer Exporter ist um einiges umfangreicher aber noch nicht fertig. Speichern tue ich nun die Strukturinformationen in einer xml Datei und die Arraydaten selber in einer Binärfile.
Es ist ein GUI Frontend hinzu gekommen, wo man selektieren kann, welche "Streams"(Tangent,Color,Normal,...) exportiert werden sollen und welche Nacharbeiten noch an den Daten gemacht werden sollen(z.B. YZ swap und sortieren nach Materialien).
_________________ "Wer die Freiheit aufgibt um Sicherheit zu gewinnen, der wird am Ende beides verlieren" Benjamin Franklin
ah okay, dann habe ich das im groben richtig verstanden.- Es bleibt mir also nicht wirklich was anderes übrig als manuell die materialien mit den faces zu verknüpfen (bei dir ist es im endeffekt ja auch manuell, da du die material file mit dem textur namen zur verfügung stellen musst). Da ich an einem kleinen deferred renderer arbeite, wird aber wahrscheinlich bis auf die transparenten teile eh ersteinmal alles mit ein und dem selben phong shader beleuchtet, und der rest über BRDF maps gelöst. Das wahrscheinlichste wo ich verschiedene shader bräuchte, wäre für prozedurell animierte teile, wie die äste eines Baumes im Wind.- Dafür erscheint mir deine Methode ganz gut, oder ich verlinke die verschiedenen modelteile manuell im programm mit den richtigen materialien.
Wie machen denn beispielsweise spielefirmen das? haben die so eine art material editor, in den man models reinläd und dann per hand die gewünschten materialien für die entsprechenden faces auswählt?
Vielen dank für deine Hilfe, das wahr schonmal sehr informativ. Ich hab übrigens auch schon viel mit lua und bindings zu c++ gemacht, und plane das in ferner zukunft auch in meinem renderer zu verwenden
Achja, was ist der Vorteil eines Binärformats? Für den Anfang werde ich das erstmal alles in Form einer XML bereitstellen, da das vor allem zum debuggen leichter ist.
Registriert: Di Mai 18, 2004 16:45 Beiträge: 2623 Wohnort: Berlin
Programmiersprache: Go, C/C++
Firmen mit entsprechenden Geld erweitern die Content Tools, ala Max und Maya. Die restlichen Firmen benutzen dann zusätzliche tools oder tricksen.
Ich hab über das zuweisen von Texturen, quasi Materialnamen fest gelegt, also wood.png wird zu wood und dann guckt er ob es z.B. wood.mat gibt oder wood.lua, je nach dem , was man für ein material system man nutzen will. Der Modelloader legt nicht fest, wie Materialien aus zu sehen haben, da oft die materialsysteme mehr tuen als eine Textur zu zuweisen. Da sind dann Shader, Konstanten, mini Funktionen, Physik und Sound Informationen teilweise mit drin. Es lohnt sich also das Mesh in z.B. Blender zu erstellen, UV-Koordinaten drauf zu legen und dann über ein eigenes Tool die Materials zu erstellen. Mein Materialsystem z.B. sagt, wie das Model zu zeichnen ist, also führt die OpenGL Befehle aus und bindet Ressourcen, dass macht Blender nicht mehr mit.
Es kann sich sogar lohnen, nur das Mesh,Rigging und animieren über Blender zu machen, das UV-Koordinaten generieren in das eigene Tool mit ein zu bauen und auch dort erst die Materials zu zu weisen und somit aus einem großen Face viele kleinere zu machen(die anzahl der Faces=anzahl der genutzten Materials). Das erlaubt dir in deinem Tool bessere Kontrolle über den Zeichenprozess.
Blender hat eine Schnittstelle namens Verse, so kann man z.B. Blender und Gimp über ein Verseserver verbinden und die änderungen an der GimpTextur werden live in Blender übernommen und umgekehrt.
Verse erlaubt das austauschen von Meshes,Texturen und ein bischen mehr und ist für das zusammenspiel von verschiedenen Contenttools gedacht wie halt Blender(3D Modelierung) und Gimp(Texturierung).
Sollte man den weg gehen, ein eigenes Tool zu schreiben, dann hat man auch den Vorteil, dass man eine Echtzeitansicht von den Content hat(Thema: "hot assets").
_________________ "Wer die Freiheit aufgibt um Sicherheit zu gewinnen, der wird am Ende beides verlieren" Benjamin Franklin
Soweit so gut, eine erste simplem version mit indices steht nun. Allerdings ist das exportieren super lahm, zum finden eines index benutze ich folgende funktion:
Code:
def findIndex(list, key):
for i in range(0, len(list)):
if list[i]==key: return i
ich bin mir ziemlich sicher, dass diese funktion die performance so drastisch verringert, da sie bei komplexen models sehr oft aufgerufen wird.
Hat irgendein Python guru eine Idee wie man das geschwindigkeitstechnisch verbessern könnte?
Wenn ich die indices nicht exportiere, ist die performance um einiges besser!
Kann es sein, dass es in python sau langsam ist objects zu erzeugen?
unabhängig von den indices erzeuge ich für jedes vertex eine objekt, das Texturcoords normal etc speichert, damit ich das einfacher vergleichen kann. Mir kommt das sehr langsam vor, ist das eine schlechte idee in python?
Also ich bin jetzt nicht (mehr) so fit in Python, aber reicht es nicht vielleicht wenn die Vertices in einem Array sind? "Objekt" klingt für mich jedenfalls stark nach "Klasse" oder "Instanz" und da könnte ich mir schon vorstellen, dass das langsam wird.
Mitglieder in diesem Forum: Bing [Bot] und 2 Gäste
Du darfst keine neuen Themen in diesem Forum erstellen. Du darfst keine Antworten zu Themen in diesem Forum erstellen. Du darfst deine Beiträge in diesem Forum nicht ändern. Du darfst deine Beiträge in diesem Forum nicht löschen. Du darfst keine Dateianhänge in diesem Forum erstellen.