[Projekt] breeze 2.0

Hier könnt ihr euch selbst, eure Homepage, euren Entwicklerstammtisch, Termine oder eure Projekte vorstellen.
Forumsregeln
Bitte Präfixe benutzen. Das Präfix "[Projekt]" bewirkt die Aufnahme von Bildern aus den Beiträgen des Themenerstellers in den Showroom. Alle Bilder aus dem Thema Showroom erscheinen ebenfalls im Showroom auf der Frontpage. Es werden nur Bilder berücksichtigt, die entweder mit dem attachement- oder dem img-BBCode im Beitrag angezeigt werden.

Die Bildersammelfunktion muss manuell ausgeführt werden, die URL dazu und weitere Details zum Showroom sind hier zu finden.

This forum is primarily intended for German-language video game developers. Please don't post promotional information targeted at end users.
Benutzeravatar
eXile
Establishment
Beiträge: 1136
Registriert: 28.02.2009, 13:27

Re: [Projekt] breeze 2.0

Beitrag von eXile »

Das PSBilateralAverage für das ShadowTarget. So wie ich das auf die schnelle sehe, benutzt das auch Geometrieinformationen für den bilateralen Blur. Ich frage mich aber, ob das tatsächlich die richtige Lösung ist. Schatten können sich um Geometrie herumwinden, wie sie lustig sind, ohne dass das jetzt auf den Blurradius einen Einfluss hat.

Ich kann mich aber auch irren; ich habe deinen Code nicht ausprobiert, sondern nur überflogen. ;)
Benutzeravatar
CodingCat
Establishment
Beiträge: 1857
Registriert: 02.03.2009, 21:25
Wohnort: Student @ KIT
Kontaktdaten:

Re: [Projekt] breeze 2.0

Beitrag von CodingCat »

Der Blur ist grundsätzlich eigentlich immer falsch. Er dient nur der Rauschverminderung, der bilaterale Anteil passt auf, dass dabei kein Schatten leckt. Hast du z.B. im Hintergrund einen sehr langen Schatten quer übers Bild, dann sollte deshalb kein Schatten aus dem Hintergrund auf ein nicht beschattetes Objekt im Vordergrund verschmiert werden.

Noch falscher ist im übrigen die Wahl des PCF-Radius; um mir dir Blockersuche ersparen zu können, berechne ich diesen einfach aus dem Tiefendelta des Mittelpixels, wodurch ich maximal den halben Halbschatten rekonstruiert bekomme.
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
Benutzeravatar
eXile
Establishment
Beiträge: 1136
Registriert: 28.02.2009, 13:27

Re: [Projekt] breeze 2.0

Beitrag von eXile »

OK, also alles noch WiP und ich kann meine Verwirrung eine Zeit lang zurückstellen.
Benutzeravatar
CodingCat
Establishment
Beiträge: 1857
Registriert: 02.03.2009, 21:25
Wohnort: Student @ KIT
Kontaktdaten:

Re: [Projekt] breeze 2.0

Beitrag von CodingCat »

Nachdem ich mich entschlossen habe, dass ich nicht für jede Ressource (Effekte, Materialien, Meshes, PhysX-Shapes, PhysX-Materialien, ...) dieselbe Funktionalität zum Speichern, Laden, Benennen, Erzeugen und Setzen derselben implementieren möchte, habe ich der Engine eine weitere Reflection-Schnittstelle verpasst. Ich nenne das entsprechende Interface schnöde ComponentReflector. Der Name Component ist zwar wenig aussagekräftig, in dieser Hinsicht jedoch auch durchaus treffend, denn letztlich gibt es keinerlei festen Bedingungen oder Eigenschaften für die jeweils beschriebenen Komponententypen. Alles, was der ComponentReflector zur jeweiligen Komponente anbietet, ist optional. Momentan sind mögliche Operationen das Erzeugen neuer, Laden gespeicherter und Suchen benanntern Komponenten.

Zusätzlich gibt es ein ReflectedComponent-Interface, welches die bisherige Property-Reflection um Hierarchie erweitert. So kann jede abgeleitete Klasse auf Kindobjekte verweisen, die wiederum einfach nur existieren (Meshes, Texturen) oder optional Properties und gar weitere Kindkomponenten anbieten. So bieten MeshControllers über das ReflectedComponent-Interface die Materialien ihrer Subsets an. Materialien bieten über dasselbe Interface die darin gespeicherten Effektkonfigurationen an. Effektkonfiguration bieten über das Interface Effekteigenschaften als Properties und Texturen als Kindkomponenten an. Komponenten sind dabei nur über einfache Strings typisiert ("Texture", "Effect", "Material"), die ebenfalls zur jeweiligen Komponente über das Interface abgefragt werden können. Herumgereicht werden Komponenten in any-Objekten. Wem das zu schwammig ist, dem kann ich eigentlich nur zustimmen, aber ohne Laufzeittypisierung wird mir das alles erst recht zu viel Einzelaufwand. Im übrigen ist das ausschließlich für die Tool-Chain gedacht, die tatsächliche Funktionalität bleibt auch weiterhin ausschließlich in stark typisierten einfachen C++-Methoden und Funktionen implementiert.

Über die genannten Schnittstellen ist es nun möglich, dass die Gesamtheit aller Entity-, Controller- und Materialeigenschaften generisch über ein vergleichsweise einfaches Property-Control (ein schnöder QTreeView, siehe frühere Posts) zur gleichen Zeit bearbeitet werden können. Das macht schon ordentlich Spaß, weil lästiges Rumgeschalte in Einzeleditoren für die jeweiligen Komponententypen entfällt.

Aus den eingangs erwähnten, zentral registrierten ComponentReflector-Objekten wird zum Setzen neuer Komponenten on-the-fly abhängig vom Typ rekursiv ein Komponentenselektions-Editor im Property-Control erzeugt, welcher Namens- und Dateiauswahl zur Selektion sowie Parameter zur Erzeugung neuer Komponenten (inklusive deren Erzeugungsparameter, deshalb rekursiv) automatisch aus den Verfügbarkeitsangaben des ComponentReflector zusammensteckt.

editor11.png

Vielleicht sollte ich doch Mesh-Subset-Namen importieren. :P Das rekursiv erzeugte Komponentenauswahlfeld findet sich unten rechts. Links im Controller-Baukasten ist der Ressourcentyp Material noch unbekannt, weil dort das neue Reflection-System noch nicht integriert ist.

Noch einige Bilder aus meinen ersten Testläufen, in denen ich prompt auch noch einige Bugs in der Serialisierung gefunden habe. :mrgreen:
editor12.png
editor13.png
editor14.png
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
Benutzeravatar
CodingCat
Establishment
Beiträge: 1857
Registriert: 02.03.2009, 21:25
Wohnort: Student @ KIT
Kontaktdaten:

Re: [Projekt] breeze 2.0

Beitrag von CodingCat »

Assets (oder auch Prefabs?) sind wirklich eine harte Nuss. Zunächst mal will ich am Ende natürlich niemandem zumuten, permanent bei jedem Einfügen alle Entities von Hand aus Controllern zusammenzubasteln (insbesondere auch Materialzuweisung, Konfiguration etc.!). Mein Plan ist also, dass praktisch jedes Entity bzw. jede wiederkehrende Entity-Gruppe einmal zusammengebaut und als Asset abgespeichert wird, um dann beliebig oft eingefügt zu werden.

Nun gibt es eine Vielzahl von Optionen bei der Umsetzung, bei denen insbesondere folgende Punkte wichtig sind:
  • Assets können dynamische Objekte enthalten, folglich müssen enthaltene Entities zur Speicherung von Simulations- und Spielzuständen für jede Asset-Instanz eigene eindeutige persistente IDs erhalten.
  • Assets sollten sich nachbessern lassen, ohne dass anschließend zum Update alle Instanzen in allen Maps neu eingefügt und platziert werden müssen.
Der zweite Punkt legt erstmal die Umsetzung durch einen klassischen Szenengraphen nahe, der für jedes Asset einen Entity-Knoten enthält, dessen Transformation hierarchisch auf alle durch ihn referenzierten Asset-internen Kindknoten angewandt wird. Problematisch ist, dass jede Asset-Instanz für alle Kindelemente eigene persistente IDs benötigt. Zudem hat im Rahmen der Physiksimulation in der Regel sowieso jede Instanz eines jeden Asset-Elements einen eigenen Zustand, um eine Kopie aller Asset-Elemente für alle Asset-Instanzen komme ich also ohnehin kaum drumrum.

Wenn ich nun aber für jede Asset-Instanz alle enthaltenen Entities kopieren muss, besteht eine Szenenhierarchie eigentlich nur noch zu Bearbeitungszwecken auf dem Papier, im Rahmen jeder normalen Anwendungen ist sie dagegen nur Balast. Damit liegt nun eine vollständig gegenteilige Umsetzung nahe, die beim Einfügen von Assets im Editor einfach nur noch alle Entities aus der jeweiligen Asset-Datei in die Welt kopiert, das klassische Prefab. Ein Vorzug dieser Umsetzung wäre die extrem einfache Implementierung sowie der Wegfall jeglichen Laufzeitoverheads. Um nachträgliche Updates von Instanzen nach dem Einfügen veränderter Assets zu erlauben, müsste jedoch zumindest ein Vermerk gespeichert werden, woher die jeweiligen Entities ursprünglich entstammen. Ein automatisches Update wäre in diesem Fall kaum sinnvoll, schon eher ein Editor-Kommando "Update all instances of asset ...". Das macht den Workflow nicht unbedingt besser. Auch hier fällt wohl ein gewisser Aufwand für das Remapping von persistenten Asset-Element-IDs auf die neue veränderte Version des jeweiligen Assets an.

Hat schonmal jemand irgendwas in diese Richtung implementiert? Was sind eure Gedanken/Tipps/Hinweise/Erfahrungen?
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
joeydee
Establishment
Beiträge: 1058
Registriert: 23.04.2003, 15:29
Kontaktdaten:

Re: [Projekt] breeze 2.0

Beitrag von joeydee »

CodingCat hat geschrieben:Was sind eure Gedanken/Tipps/Hinweise/Erfahrungen?
Vielleicht trifft es nicht ganz den Kern deiner Frage, aber evtl. bringt dich dieser Blick über den Tellerrand auf gute Ideen:
Ein ähnliches Problem stellt sich bei Layoutprogrammen (in meinem Fall InDesign) und Musterseitenelementen. Hier "weiß" jede Seite, von welcher Musterseite sie stammt, die Musterseitenelemente sind auf der endgültigen Seite erstmal gesperrt. Können aber per Kommando freigeschaltet und so vom Muster abweichend gestaltet werden. Wenn z.B. eine Musterseite die Elemente A, B und C enthält, und C auf einer konkreten Seite gelöst und in C' verändert wird, dann werden bei einem Update dort nur die noch gesperrten Elemente A und B überschrieben.
Ähnlich auch Formatvorlagen, Objektstile, Tabellenstile etc: Man kann in einem Textabsatz/Rahmen/Tabelle mit direkten Einstellungen "herumspielen" und als Vorlage speichern. Wendet man diese an, "weiß" ein Objekt, woher ab sofort sein Erscheinungsbild stammt. Man kann "weiterspielen" (z.B. die Textfarbe ändern), es erscheint bei markiertem Objekt ein "+" in der Formatpalette als Zeichen, dass hier einzelne Attribute von der Vorlage abweichen. Ändert man nun ein Attribut in der Formatvorlage, wird es überall geupdated, wo speziell dieses Attribut nicht manuell geändert wurde.

Geupdated wird immer automatisch, zurücksetzen aller manuell geänderten Einstellungen auf die Formatvorlage ist jederzeit per Kommando möglich. Änderungen der Vorlage geschehen entweder in einem dafür kenntlich gemachten Zustand mit Vorschau oder wahlweise durch direkte Änderungen an einer konkreten Instanz und anschließender Neudefinition der Vorlage anhand dieses Objekts per Userkommando.
Benutzeravatar
Schrompf
Moderator
Beiträge: 4884
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: [Projekt] breeze 2.0

Beitrag von Schrompf »

Ich muss ehrlich sagen, dass mir Deine Herangehensweise zu abstrakt ist. Ich würde nicht alle Informationen in allen Komponenten über einen Kamm scheren. Bei den Splitterwelten werden z.B. Meshes separat verwaltet. Ein Mesh enthält die 3D-Daten, evtl. Detailstufen, evtl. Eigen-Materialreferenzen (manchmal benutzen LODs andere Materialen als das Haupt-Model), evtl. Physik-Repräsentation.

Objekte referenzieren diese Meshes nun anhand eines 128bit-Identifiers (64Bit UserID, 64Bit ResourceID). Jede Referenz wird bei Einsetzung zu einer Laufzeit-ID aufgelöst, welche einfach nur ein Index in das Array geladener Meshes ist. Die komplexe ID war nötig, damit parallel mehrere Leute an verschiedenen Rechnern Daten in die Engine importieren konnten, ohne gegenseitig Konflikte auszulösen. Die Objekte haben aber auch eigene Einstellungen, die unabhängig von anderen Instanzen des selben Meshes geändert werden können. Dazu zählen das Material, objekt-lokale Überschreibungen von Textur-Slots und Shader-Parametern, globale Physik-Einstellungen (bewegt es sich), Einstellungen zum Umgebungslicht (statische Objekte bekommen das anderes berechnet als bewegliche) und ähnliche Details.

Der Ansatz funktioniert eigentlich gut, aber ich habe festgestellt, dass es echt schwer ist, Nicht-Programmierern beizubringen, welche Informationen nun geteilt sind ("Wenn Du das änderst, werden alle identischen Objekte in allen Welten mitverändert") und welche objekt-individuell sind ("Das kannst Du ändern, die anderen bleiben trotzdem, wie sie sind"). Und das Problem ist, dass beide Varianten auch mal bei Eigenschaften braucht, die der anderen Variante angehören. Mir ist dafür noch keine schöne Lösung eingefallen, der Teil ist bisher Handarbeit. Zum Glück kommt er recht selten vor.

Allen Objekten können dann noch komponentenweise Spiellogik-Träger eingepflanzt werden, die eigentlich ebenso objekt-individuell verwaltet werden. Die ziehen ihre Eigenschaften abseits des aktuellen Spiel-Zustands aber dann auch wieder aus diversen globalen Managern, so dass man zum Beispiel den Heiltrank doppelt so wirksam machen kann und sich die Änderung vollautomatisch auf alle Heiltränke in allen Welten auswirkt. Auch hier haben wir lange diskutiert, wie wir das gestalten wollen, und sind am Ende bei einem zweistufigen System herausgekommen. Ein Gegenstand hat dann sowohl die Gegenstandswirkungen aus seiner globalen Vorlage als auch potentielle individuelle Wirkungen. Ich weiß nicht, ob das auch ein sinnvoller Ansatz für Meshdaten usw. wäre.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Benutzeravatar
CodingCat
Establishment
Beiträge: 1857
Registriert: 02.03.2009, 21:25
Wohnort: Student @ KIT
Kontaktdaten:

Re: [Projekt] breeze 2.0

Beitrag von CodingCat »

joeydee: Ja, prinzipiell wäre genau das meine Wunschfunktionalität, deren Umsetzung jedoch einiges an Zusatzaufwand einfordern würde. Ich müsste mir zum einen eine Zuordnung von persistenten IDs in der "Vorlage" zu persistenten IDs im "Dokument" speichern, zum anderen müsste dort vermerkt sein, ob und welche Unterobjekte der Vorlage verändert wurden. Auf Eigenschaftenebene kriege ich das wohl kaum sinnvoll umgesetzt, es sei denn ich speichere mir immer noch irgendwo noch die unveränderte Variante der "Vorlage" für Differenzbildung bei der Serialisierung ab. Auf Objektebene könnte ich mir so einen "verändert"-Flag schon eher leisten, und dort könnte das ganze zu Gunsten der Usability durchaus lohnenswert sein.

Letztendlich ist ein Grundproblem, wie schon einmal erwähnt, natürlich die Tatsache, dass ich ein einziges System für Content Creation und Endprodukt entwickle, weswegen ich mir gigantische Zusatzstrukturen zu Gunsten von etwas CC-Usability eigentlich nicht leisten möchte. Da haben rein Editing-fokussierte Tools ohne Laufzeitkomponente wie solche Grafik/Design/Publishing-Programme natürlich etwas mehr Spielraum.

Schrompf:
Schrompf hat geschrieben:Ich muss ehrlich sagen, dass mir Deine Herangehensweise zu abstrakt ist. Ich würde nicht alle Informationen in allen Komponenten über einen Kamm scheren.
In welcher Hinsicht über einen Kamm scheren? Abgesehen von der homogenen Aufbereitung der Daten im Editor sind die Informationen ja alles andere als homogen, Materialeigenschaften werden in Materialien gespeichert, nicht in den Mesh-Controllers oder gar Entities, Mesh-Subsets werden von Mesh-Controllers referenziert, die dazu jeweils Referenzen auf Materialien speichern etc.
Schrompf hat geschrieben:Bei den Splitterwelten werden z.B. Meshes separat verwaltet. Ein Mesh enthält die 3D-Daten, evtl. Detailstufen, evtl. Eigen-Materialreferenzen (manchmal benutzen LODs andere Materialen als das Haupt-Model), evtl. Physik-Repräsentation.
Ja, hier weiche ich mit meinem extrem dezentralen Ansatz natürlich etwas ab. Meine Mesh-Daten sind verstreut in Form von Mesh-Subsets (Mesh-Daten, LOD- und materialunabhängig), Materialien, Shapes (Physik-Repräsentation) etc. und laufen erst in den Controllers zusammen, wodurch ich die Zuordnung von Mesh-Subsets zu Materialien tatsächlich in jeder individuellen MeshController-Instanz redundant gespeichert habe. Sollte das mal zum Problem werden, werde ich diese Zuordnung wohl tatsächlich noch auslagern zu zusammengesetzen Mesh-Material-Objekten, die dann in etwa dem Rendering-Teil eurer geteilt referenzierten Meshes entsprechen dürften.
Schrompf hat geschrieben:Objekte referenzieren diese Meshes nun anhand eines 128bit-Identifiers (64Bit UserID, 64Bit ResourceID). Jede Referenz wird bei Einsetzung zu einer Laufzeit-ID aufgelöst, welche einfach nur ein Index in das Array geladener Meshes ist. Die komplexe ID war nötig, damit parallel mehrere Leute an verschiedenen Rechnern Daten in die Engine importieren konnten, ohne gegenseitig Konflikte auszulösen.
Die User-ID ist eine schöne Idee, ich habe schon von anderen gelesen, die pro Benutzer über SVN-Addins atomar ID-Bereiche alloziiert haben, da ist die User-ID-Lösung wohl wesentlich unproblematischer zu implementieren.
Schrompf hat geschrieben:Die Objekte haben aber auch eigene Einstellungen, die unabhängig von anderen Instanzen des selben Meshes geändert werden können. Dazu zählen das Material, objekt-lokale Überschreibungen von Textur-Slots und Shader-Parametern, globale Physik-Einstellungen (bewegt es sich), Einstellungen zum Umgebungslicht (statische Objekte bekommen das anderes berechnet als bewegliche) und ähnliche Details.
OK, das heißt, ihr speichert im Wesentlichen einfach alle relevanten Informationen zweimal, einmal geteilt, und einmal individuell. Ich habe im Moment abgesehen von geteilt referenzierten Materialien und Mesh-Subsets nur die Individuelle Lösung, die für jede MeshController-Instanz individuell die Zuordnung speichert.

Schlussendlich ist aber die doppelte Speicherung kein Weg, den ich für Assets (= im Vorhinein zusammengestellte und gespeicherte Objektgruppierungen) gehen will. Ich weiß nicht, wie genau das jetzt bei euch mit der Speicherung und späteren Aktualisierung ganzer bereits eingefügter Objektgruppen aussieht, aber hier für alle Assets die Originalobjekte im Speicher zu halten, um sie ggf. mit individuellen Zusatzeinstellungen zu überschreiben, ist mir in Bezug auf die zusätzlich notwendigen Laufzeitverzweigungen zu heftig. Im Rahmen der tatsächlichen Simulation gewinne ich durch Assets de facto nichts, sie sind reiner Tool-Chain-Bonus. Und selbst wenn ich Meshes wie ihr fertig mit LOD- und Materialzuordnung geteilt speichere, löst sich das Problem nicht auf Ebene von Objektgruppierungen, objektspezifischen Eigenschaften etc. Gerade hier liegt meiner Meinung nach die Stärke eines Ansatzes, der alle Daten, egal wie inhomogen, über einen Kamm scheren kann; schlussendlich ist mein Ziel doch, mit möglichst wenig Code möglichst viel universelle Funktionalität rauszuholen.

So denke ich nun, dass ich mit einfachen Asset-ID- zu Weltobjekt-ID-Zuordnungen, redundanter Speicherung der Daten und kruden "verändert"-Flags wohl doch am ehesten da hin komme, wo ich gerne hin möchte (wohl in etwa das, was joeydee beschreibt, mit Abstrichen). Die Implementierung könnte zwar etwas unangenehm werden, aber die vollständige Umsetzung eines Zwei-Ebenen-Informationssystems wäre trotzdem noch wesentlich mehr Aufwand, ganz abgesehen von dem ggf. zusätzlich anfallenden Laufzeitoverhead und der Notwendigkeit größerer zentraler Systeme für jede neue Engine-Funktionalität. Und damit wäre ich dann viele Probleme in Bezug auf das Zusammenspiel größerer vorgefertigter Objektgruppen immer noch nicht los.

Ich danke dir auf jeden Fall für deine ausführliche Beschreibung, immer wieder beeindruckend, was ihr in den Splitterwelten so alles implementiert habt.
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
Benutzeravatar
Schrompf
Moderator
Beiträge: 4884
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: [Projekt] breeze 2.0

Beitrag von Schrompf »

Gern :-)

Wir speichern übrigens mitnichten alles doppelt - da habe ich mich falsch ausgedrückt. In Kurzform: Objekt hat Mesh-Referenz und Material-Referenz (und evtl. lokale Overloads von Material-Parametern), Mesh hat Vertices, LODs, Physik und evtl. eigene Material-Referenz. Letztere ist eigentlich die einzige Dopplung und wird nur in LODs benutzt, wenn die detailreduzierte Mesh-Stufe z.b. als automatisch generiertes MiniObjekt zusammen mit anderen auf einem Texturatlas untergebracht wurde.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Benutzeravatar
CodingCat
Establishment
Beiträge: 1857
Registriert: 02.03.2009, 21:25
Wohnort: Student @ KIT
Kontaktdaten:

Re: [Projekt] breeze 2.0

Beitrag von CodingCat »

Nach viel Fleißarbeit lässt sich der Editor nun einigermaßen bequem bedienen. Das Laden, Setzen und Verändern von Komponenten ist Undo-integriert, viele unfertige Stellen endlich vervollständigt. Bezüglich Assets bin ich leider noch nicht weiter, das steht als nächstes an (das war wohl etwas missverständlich, ich meinte damit vor allem fertig zusammengestellte Gruppen von Objekten, z.B. Laternen mit Licht, aus mehreren Rigid Bodies zusammengesetzte physikalische Objekte etc.). Bei den Normal Maps muss ich wohl auch nochmal ran, irgendwie ist der Tangent Space für manche Faces geflippt ... (evtl. hilft schon, diese einmal mit Assimp zu regenerieren).
sponza7.png
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
Benutzeravatar
CodingCat
Establishment
Beiträge: 1857
Registriert: 02.03.2009, 21:25
Wohnort: Student @ KIT
Kontaktdaten:

Re: [Projekt] breeze 2.0

Beitrag von CodingCat »

Der Tangent Space war doch richtig. Mir war nur bisher nicht bewusst, dass bei teilweise gespiegelten Texturkoordinaten zwei Vektoren gar nicht ausreichen, um den Tangent Space eindeutig aufzuspannen. Ist nur eine der beiden Texturkoordianten gespiegelt, so wechselt der Tangent Space logischerweise von linkshändig zu rechtshändig oder umgekehrt. Mit dem Kreuzprodukt aus Normale und Tangente setze ich aber stets links- oder rechtshändig voraus, um den Tangent Space in allen Fällen richtig zu konstruieren, brauche ich also alle drei Vektoren vorberechnet.
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
Benutzeravatar
Artificial Mind
Establishment
Beiträge: 802
Registriert: 17.12.2007, 17:51
Wohnort: Aachen

Re: [Projekt] breeze 2.0

Beitrag von Artificial Mind »

Ah gut zu wissen! Das wird mich sicher auch noch treffen *g*
Benutzeravatar
CodingCat
Establishment
Beiträge: 1857
Registriert: 02.03.2009, 21:25
Wohnort: Student @ KIT
Kontaktdaten:

Re: [Projekt] breeze 2.0

Beitrag von CodingCat »

Im Übrigen ist es natürlich ausreichend, in einer vierten Komponente der Tangente den Drehsinn der Bitangente abzuspeichern (Spatprodukt), gleich mal den Mesh Compiler anpassen.
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
Benutzeravatar
Schrompf
Moderator
Beiträge: 4884
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: [Projekt] breeze 2.0

Beitrag von Schrompf »

Das tun wir bei den Splitterwelten auch: einfach eine +1 oder -1 anstatt der Bitangente hochladen, dann kann man sie wieder per Kreuzprodukt im Vertexshader generieren.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Benutzeravatar
CodingCat
Establishment
Beiträge: 1857
Registriert: 02.03.2009, 21:25
Wohnort: Student @ KIT
Kontaktdaten:

Re: [Projekt] breeze 2.0

Beitrag von CodingCat »

Ich habe den Zusatzwert gerade wieder rausgeworfen und kodiere ihn jetzt einfach in der Länge der Tangenten. :D
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: [Projekt] breeze 2.0

Beitrag von dot »

Wieso nicht gleich alles in Polarkoordinaten ausdrücken :P
Benutzeravatar
CodingCat
Establishment
Beiträge: 1857
Registriert: 02.03.2009, 21:25
Wohnort: Student @ KIT
Kontaktdaten:

Re: [Projekt] breeze 2.0

Beitrag von CodingCat »

Wäre das geschickt? Ich meine, käme ich davon effizient zurück zu Vektoren?
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: [Projekt] breeze 2.0

Beitrag von dot »

War nur grad so ein Gedanke, habs nich ausprobiert. Du bräuchtest eben nur 2 Koordinaten pro Vektor. Die Bitangente könntest du als Offset zum Phi der Tangente codieren, damit bräuchtest du nur 5 Werte für den ganzen Tangenspace und kannst sogar Tangenten/Bitangenten die nicht orthogonal sind darstellen ;)
Du bezahlst eben mit 2-3 sin() und 2-3 cos() pro Vertex, ich vermute dass es effektiv kaum einen Unterschied macht...
Zuletzt geändert von dot am 05.03.2012, 17:07, insgesamt 3-mal geändert.
Benutzeravatar
CodingCat
Establishment
Beiträge: 1857
Registriert: 02.03.2009, 21:25
Wohnort: Student @ KIT
Kontaktdaten:

Re: [Projekt] breeze 2.0

Beitrag von CodingCat »

Naja, die Argumentation hinter der Kodierung des Drehsinns in den Betrag des Tangentenvektors war folgende: Der Informationsgehalt der zusätzlichen Komponente ist extrem gering (1 Bit!). Normalen- und Tangentenvektoren müssen dabei eigentlich eh immer normiert werden, nachdem sie durch die allgemeine Welttransformation und die Interpolation gegangen sind. Im Vertex Shader aus dem Betrag des Eingabe-Tangentenvektors mittels sign(dot(t,t) - 0.5f) den Drehsinn zu rekonstruieren, kostet mich praktisch nichts. Dafür spare ich sowohl auf der Platte als auch im VRAM bei vielen Vertices eine ganz gehörige Menge Floats, in denen quasi keine Information steckt.
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: [Projekt] breeze 2.0

Beitrag von dot »

Jap, schon klar. Darum der (ursprünglich eher im Spaß gemeinte) Vorschlag, alles in Polarkoordinaten darzustellen, da du dadurch noch einen float sparen kannst (du brauchst dann nur 2 für die Normale + 2 für die Tangente + 1 für die Bitangente). Du bezahlst mit 2 bzw. 3 sin() und 2 bzw. 3 cos() (je nachdem wie du die Bitangente berechnest), sparst aber das Normalisieren.
Vermutlich würden sogar 16bit, möglicherweise sogar 8bit UNORMs für die Komponenten ausreichen ;)

Wie gesagt, ursprünglich nicht so ganz ernst gemeint, aber evtl. sogar einen Versuch wert...
Benutzeravatar
Schrompf
Moderator
Beiträge: 4884
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: [Projekt] breeze 2.0

Beitrag von Schrompf »

Eigentlich eine gute Idee, aber ich bin beim Vertexspeicher-Sparen etwas konservativ geworden, seit ich gesehen habe, wie 8Bit-Bone Weights die Mimik eines gesunden jungen Menschen deformieren können.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Benutzeravatar
CodingCat
Establishment
Beiträge: 1857
Registriert: 02.03.2009, 21:25
Wohnort: Student @ KIT
Kontaktdaten:

Re: [Projekt] breeze 2.0

Beitrag von CodingCat »

Ja, das kann ich mir vorstellen. Da es in diesem Fall nur um 1 Bit geht, hoffe ich einfach mal, dass sich das hier nicht noch rächen wird. ;-)

Mir ist gerade aufgefallen, dass ich noch kein Bild mit ordentlichen Normalen da habe, also einfach mal wieder etwas Bildspam.

sponza11.png
sponza12.png
Das Crytek Sponza ist wirklich großartig, was man auch testet, es sieht immer irgendwie gut aus. :mrgreen:
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
Benutzeravatar
Schrompf
Moderator
Beiträge: 4884
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: [Projekt] breeze 2.0

Beitrag von Schrompf »

Ein schöner Anblick! Ich ziehe meinen Hut.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: [Projekt] breeze 2.0

Beitrag von dot »

Schrompf hat geschrieben:Eigentlich eine gute Idee, aber ich bin beim Vertexspeicher-Sparen etwas konservativ geworden, seit ich gesehen habe, wie 8Bit-Bone Weights die Mimik eines gesunden jungen Menschen deformieren können.
Verständlich. Aber mit 16bit UNORMs hab ich eine Winkelauflösung von 360° / 65536 = 0.005°. Die Frage ist eher, wie stark die Sinusse zu Buche schlagen und ob der reduzierte Bandbreitenbedarf das wettmachen kann (und da bin ich eher skeptisch)...

Btw: Herkömmliche Normalmaps speichern Normalen in nur 8bit pro Komponente und nutzen nichtmal die voll aus...
Benutzeravatar
CodingCat
Establishment
Beiträge: 1857
Registriert: 02.03.2009, 21:25
Wohnort: Student @ KIT
Kontaktdaten:

Re: [Projekt] breeze 2.0

Beitrag von CodingCat »

dot hat geschrieben:Jap, schon klar. Darum der (ursprünglich eher im Spaß gemeinte) Vorschlag, alles in Polarkoordinaten darzustellen, da du dadurch noch einen float sparen kannst (du brauchst dann nur 2 für die Normale + 2 für die Tangente + 1 für die Bitangente). Du bezahlst mit 2 bzw. 3 sin() und 2 bzw. 3 cos() (je nachdem wie du die Bitangente berechnest), sparst aber das Normalisieren.
Vermutlich würden sogar 16bit, möglicherweise sogar 8bit UNORMs für die Komponenten ausreichen ;)

Wie gesagt, ursprünglich nicht so ganz ernst gemeint, aber evtl. sogar einen Versuch wert...
Ja, letztlich sind die zwei Winkel wohl eher suboptimal in Bezug auf Platzverbrauch und Rekonstruktionsaufwand. Einen recht vielversprechenden Ansatz habe ich vor einiger Zeit via Twitter aufgeschnappt:
bmcnett hat geschrieben:my fav encoding: 16 bit distance along spiral between poles
- https://twitter.com/#!/bmcnett/status/1 ... 1589410816
Seine genaue Kodierung kenne ich nicht, aber mit einem sincos(2pi * alpha * turns) für den Einheitskreis und einem cos(pi * alpha) für die Y-Koordinate käme man bezüglich Rechenaufwand schonmal ganz gut weg, und das bei dem Speicherbedarf eines halben Floats. Eventuell gibt es auch noch geschicktere Rekonstruktionsabbildungen, die Werteverteilung sollte man auch noch kurz betrachten.
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
Benutzeravatar
CodingCat
Establishment
Beiträge: 1857
Registriert: 02.03.2009, 21:25
Wohnort: Student @ KIT
Kontaktdaten:

Re: [Projekt] breeze 2.0

Beitrag von CodingCat »

Nachträgliche Korrektur: Die Rekonstruktion ist in diesem Fall ja fast die gleiche wie bei der Beschreibung durch 2 Winkel. Ich hatte übersehen, dass du gleich für Tangente und Bitangente gerechnet hattest. Mit 8 Bit pro Winkel bist du auf jeden Fall nah dran. Ein Nachteil, der mir spontan einfällt, ist die etwas weniger geschickte Bitverteilung, weil der Horizontalwinkel eigentlich nur die Hälfte der Werte des Azimutalwinkels benötigt.
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: [Projekt] breeze 2.0

Beitrag von dot »

Ja. Und die Frage ist eben vor allem, inwiefern der Rekunstruktionsaufwand so einen Ansatz rechtfertigt. Meine Vermutung ist, dass es da nicht wirklich was zu gewinnen gibt, sofern man es nicht mit extrem großen Meshes zu tun hat und die Indices einigermaßen gute Lokalität aufweisen...
Benutzeravatar
CodingCat
Establishment
Beiträge: 1857
Registriert: 02.03.2009, 21:25
Wohnort: Student @ KIT
Kontaktdaten:

Re: [Projekt] breeze 2.0

Beitrag von CodingCat »

Leider habe ich im Moment der Klausuren wegen praktisch keine Zeit, produktiv weiterzuarbeiten. In einer kurzen Lernpause habe ich das Serialisierungssystem soweit aufgebogen, dass sich auch beliebige Teile der Welt in Form von Entity-Gruppen abspeichern, laden und einfügen lassen. Damit habe ich insbesondere endlich einen Weg, Objekte fertig mit Materialien abzuspeichern und einzufügen. Die bereits weiter oben im Thread angesprochene Asset-Synchronisierung ist noch in keiner Weise vorhanden, im Moment ist es nicht mehr als ein einfaches Copy & Paste. Das Qt QTreeWidget hat die Sache mal wieder so schmerzhaft wie möglich gemacht. (Item-Indizes ändern sich mit der Sortierung! Nächstes Mal lieber wieder QTreeView mit persistenten QStandardItemModel-Indizes verwenden.) Links befindet sich nun also ein Browser, der alle relevanten Ordner des Dateisystems spiegelt (inkl. Auto-Update), Assets lassen sich per Drag & Drop an gewünschter Stelle direkt in die Szene einfügen. Rechts unten befindet sich das "Selektionslabor", hier lässt sich in der aktuellen Objektauswahl des Editors bei Bedarf nochmal eine Unterauswahl treffen, um die gewählten Objekte dann gemeinsam als Asset in eine Datei zu speichern (landet natürlich direkt im Asset Browser zur Wiederverwendung mit Drag & Drop).

Fazit: UI-Programmierung ist mühsam und frustrierend, wenn man wenig Zeit hat.
assets1.png
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
Benutzeravatar
CodingCat
Establishment
Beiträge: 1857
Registriert: 02.03.2009, 21:25
Wohnort: Student @ KIT
Kontaktdaten:

Re: [Projekt] breeze 2.0

Beitrag von CodingCat »

Nachdem ich endlich Hot Swap/Reload, ein einheitliches Ressourcensystem, eine funktionierende Docking UI sowie ein datenorientiertes Entity- und Rendering-System habe, muss ich mir langsam Gedanken um Content Creation machen. Für prozedurale Texturgenerierung scheint Farbrauschs Werkkzeug 4 eine ganz passable Lösung zu sein. Insbesondere deren automatisierte Export-Operatoren erlauben in Kombination mit Texture Hot Swap einen sehr schönen Workflow mit direktem In-Engine Preview. Meine ersten Gehversuche:
dev3.png
dev4.png


Das einigermaßen physikalisch-basierte Rendering habe ich mir in der Kombination von Reset abgeschaut. Oren-Nayar für diffuse Beleuchtung, Kelemen-Kalos für Specularity und Schlick für Fresnel. Um diffuse und spekuläre Beleuchtung halbwegs normiert zusammenzusetzen, habe ich außerdem Shirleys 21 / 20 (1-r) * f_l * f_c -Koeffizienten gemopst.
alphanew.net (last updated 2011-07-02) | auf Twitter | Source Code: breeze 2 | lean C++ library | D3D Effects Lite
Benutzeravatar
mnemonix
Establishment
Beiträge: 101
Registriert: 09.04.2010, 20:38

Re: [Projekt] breeze 2.0

Beitrag von mnemonix »

Schick, gefällt mir der Editor. Sieht zumindest im Moment recht leichtgewichtig, also nicht überladen, aus. Die Modelle hast in Blender erstellt? Ach, und woher kommen in der Konsole immer diese E_INVALIDARG Fehler? ^^
Antworten