[Projekt] YAGE

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.
Antworten
RazorX
Establishment
Beiträge: 156
Registriert: 23.12.2010, 14:13
Kontaktdaten:

[Projekt] YAGE

Beitrag von RazorX »

YAGE - Yet Another Game Engine
Den Namen hatte ich schon bevor hier YADC auftauchte mal benutzt :P[/size]

Wie ich bereits im Thread von Artificial Mind erwähnt habe, möchte ich es auch mal versuchen eine Game/Graphics Engine mit C# aufzuziehen. Bis jetzt ist nicht viel geschehen, eher grundlegende Strukturen geschaffen und ein bisschen an Tools gebastelt. Wie vielleicht der eine oder andere weiß hatte ich schonmal ein Thread geöffnet mit dem Thema "Foo Engine", dies war eine C++ Iteration (durch private Umstände nicht weit gekommen) und ist im Prinzip ad acta gelegt.

Also grundlegende Technik:
  • C# mit .NET 4.0
  • OpenTK (aktuell Nightlys von Feb '12)
  • Scintillar für Codeeditierung
Da ich in den letzten Wochen mich hier viel durchgelesen habe und mir vorallem die Signed Distance Fonts von Artificial Mind sehr gefallen haben, habe ich heute an einem Tool gearbeitet, das eben diese generieren kann. Ausgelesen werden alle installierten Schriftarten, von jeder kann dann ein Vorschaubild generiert werden. Die fertige Textur beinhaltet dann nur Buchstaben die auch vom Benutzer eingegeben wurden. Um die Textur hinterher im Font-Renderer benutzen zu können, wird zu der Textur eine Xml-Datei generiert, in der jeder Buchstabe mit seinen Texturkoordinaten aufgelistet wird.
004 - Tools - SDF Font Generator.png
005 - Tools - SDF Font Generator.png
Was ich unbedingt noch optimieren muss ist die Anordnung der Buchstaben auf der fertigen Textur, momentan werden die nur zeilenweise aneinander gehängt, ohne Optimierung. Sieht in dem Beispiel noch ganz aus, jedoch hab ich auch schon Konstellationen gesehen wo dann ~60% der Textur leer ist.

Wie immer freue ich mich über Kritik, Verbesserungsvorschläge, etc. und hoffe, dass es dem einen oder anderen gefällt was ich so mache. Ich habe mich dazu entschlossen hier (wieder) einen Thread auzumachen, um auch so meine eigene Motivation wieder zu pushen.

Gruß
Benutzeravatar
Artificial Mind
Establishment
Beiträge: 802
Registriert: 17.12.2007, 17:51
Wohnort: Aachen

Re: [Projekt] YAGE

Beitrag von Artificial Mind »

Hi RazorX,

cool, dass meine Motivation ansteckend ist ;)

Was die Anordnung der Buchstaben angeht: Ich habe alle Buchstaben mit einer festen Höhe generiert (bzw. auf die kleinste gemeinsame Höhe gebracht). Dann habe ich ausgerechnet wieviel Pixel alle Buchstaben zusammen brauchen. Die Wurzel daraus ist die Anzahl von Pixeln einer quadratischen Textur. Wenn du diese Anzahl auf die nächste power-of-two Höhe rundest, hast du einen guten Ausgangspunkt für das "Einsortieren" der einzelnen Buchstaben. Nun hast du also eine Anzahl N von vertikalen "Slots", in die du die Buchstaben reinpacken willst. (Aus der Informatik: das ist das Scheduling-Problem mit N Maschinen) Ein sehr schneller und relativ guter Approximationsalgorithmus ist das sogenannte LPT-Scheduling (Longest Processing Time) und funktioniert in unserem Fall so: Du sortierst alle Buchstaben nach ihrer Breite und fängst mit dem Breitesten an. Dann gehst du nach absteigender Breite alle Buchstaben entlang und packst sie immer in den "Slot", der momentan am kürzesten ist. Man kann zeigen, dass man damit mindestens 4/3 genau an die optimale Lösung kommt, also maximal 33% verschenkten Raum hat. In Wirklichkeit ist es meist wesentlich weniger. Jetzt hast du also alle Buchstaben auf die Slots verteilt und die Breite deiner Textur ist eigentlich der breiteste Slot. Allerdings will man ja power-of-two-Texturen haben, womit du hier halt aufrunden musst. Damit hast du im Worst-Case Texturen, wo nur die linke Hälfte gefüllt ist und eine Pixelzeile der rechten Hälfte, aber so mache ich das momentan. Ich will das noch einfach erweitern, indem ich für die Höhe (und damit die Anzahl der Slots) nicht nur diese eine (über die Wurzel der Gesamtpixel) versuche, sondern im Prinzip alle Zweierpotenzen ausprobiere, die zwischen einer Buchstabenhöhe und 8192 (inklusive) liegen und im Endeffekt die Größe mit der besten Auslastung nehme.

Wall-Of-Text, aber sollte eigentlich ziemlich genau mein Vorgehen beschreiben, falls du ein wenig Ideen-Hilfe brauchst xD
RazorX
Establishment
Beiträge: 156
Registriert: 23.12.2010, 14:13
Kontaktdaten:

Re: [Projekt] YAGE

Beitrag von RazorX »

Sehr gute Idee, interessanterweise ist das ein Sheduling Verfahren (von gefühlt sehr vielen), welches wir damals nicht durchgenommen haben :D. Habs aber verstanden und werde es dann mal so umsetzen.
Benutzeravatar
Artificial Mind
Establishment
Beiträge: 802
Registriert: 17.12.2007, 17:51
Wohnort: Aachen

Re: [Projekt] YAGE

Beitrag von Artificial Mind »

Das ist auch kein Scheduling Algorithmus, den ich aus Betriebssysteme und Rechnernetze oder so kenne, sondern aus Effiziente Algorithmen, Teilgebiet Approximationsalgorithmen ;)
RazorX
Establishment
Beiträge: 156
Registriert: 23.12.2010, 14:13
Kontaktdaten:

Re: [Projekt] YAGE

Beitrag von RazorX »

Ich muss sagen ich bin echt begeistert von dem Algorithmus. Ging in dem Beispiel jetzt super auf und es sieht so schön geordnet aus :D

006 - Tools - SDF Font Generator.png
Benutzeravatar
Artificial Mind
Establishment
Beiträge: 802
Registriert: 17.12.2007, 17:51
Wohnort: Aachen

Re: [Projekt] YAGE

Beitrag von Artificial Mind »

Ja das sieht doch gut aus :) Ja das ist total lustig wenn du mal mehr Buchstaben reinpackst, dann glaubst du nicht mehr dass da alles drin ist weils so ungeordnet ist :D
RazorX
Establishment
Beiträge: 156
Registriert: 23.12.2010, 14:13
Kontaktdaten:

Re: [Projekt] YAGE

Beitrag von RazorX »

So habe das Einlesen in die Engine geschaft und die erste Textausgabe ist schon möglich. Der Shader benötigte sehr viel Feintuning, damit das Ergebnis (zumindest in 3D) gut aussieht. Wie man auf dem Bild erkennen kann ist es in 2D auf Grund der geringen Auslösung nicht wirklich schön. Ich denke da müsste ich vlt mit anderen Parametern heran gehen und den Glow weglassen.

007 - Core - SDF Font.png
008 - Core - SDF Font.png
Benutzeravatar
Artificial Mind
Establishment
Beiträge: 802
Registriert: 17.12.2007, 17:51
Wohnort: Aachen

Re: [Projekt] YAGE

Beitrag von Artificial Mind »

Also mal ein paar allgemeine Tipps:
- Anisotropisches Filtering und Mip-Maps sind dein Freund in 3D (Natürlich keine Mipmaps auf der Collage-Font-Textur, das macht keinen Sinn ;) )
- Es sieht so aus als wenn du im Shader harte Entscheidungen triffst, welche Farbe es sein soll. Schlechte Idee. smoothstep und alpha blending (manuelles im Shader) helfen. z. B. smoothstep(0.48,0.52,distance) für die normale Schriftfarbe gibt eine relativ schöne antialiased Schrift für die meisten Größen
- Wenn es wirklich zu klein wird, hilft das aber auch nicht, du hast deine Font-Textur wahrscheinlich mit relativ großen Buchstaben (ich nehme mal so min. 100px in den Mund) erstellt und versuchst die auf 32 Pixel abzubilden. Lineares Texturfiltern hilft relativ gut bis ca. die Hälfte deiner Originalbuchstaben, danach wird es schwieriger. Entweder erstellst du eine zweite Font-Textur extra für kleinere Schriften oder du samplest manuell mehrfach.
- Wieso meine Schrift in 3D relativ gut aussieht, liegt daran, dass die Textur, auf die die Schrift gerendert wird, eine relativ große (1024²) Auflösung hat, obwohl es ca. auf 50% der Größe angezeigt wird. Und da ich Mip-Maps und anisotropisches Filtern an habe auf der angezeigten Textur, filtert das ganz gut

- unrelated: deine XML hat Komma als Dezimaltrennzeichen... Setzt mal alle Threads die du benutzt per Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture; auf Invariant Culture, dann wird immer und auf jedem System einheitlich der Punkt als Dezimaltrennzeichen benutzt, dann bist du kompatibler.
RazorX
Establishment
Beiträge: 156
Registriert: 23.12.2010, 14:13
Kontaktdaten:

Re: [Projekt] YAGE

Beitrag von RazorX »

Zur Textur: Also ich erstelle die Buchstaben auf 512² und breche die auf 128² runter bzw passe die in der Breite noch an den Buchstaben an. Wäre natürlich mal einen Versuch wert noch eine kleinere zu erstellen. Was mich momentan noch ein bisschen nervt (ist aber nicht weiter tragisch, da die Textur im Vorfeld generiert wird) ist, dass ich pro Buchstaben knapp 4 Sekunden Rechenzeit benötige. Bei einem Zeichenvorrat > 90 Zeichen dauert die Generierung schon ziemlich lange. Das Sortieren, Zusammenfügen und Generieren der Xml hingegen ist in einem Bruchteil einer Sekunde dann erledigt.

Zum Shader: Ich habe mich da ziemlich an das Paper von Valve gehalten und habe nur smoothstep Anweisungen drin. Es wird eigentlich super interpoliert, sonst wären bei den großen Buchstaben Pixel an den Kurven zu sehen. Jedoch hab ich nicht so einen großen Farbverlauf gerade eingestellt, deswegen der Eindruck das da keine Interpolation vorliegt.

Zur Xml: Auf den Screenshots hab ich den Xml noch per XmlDocument gebaut und den Float über Convert.ToString() umgewandelt. Mittlerweiler mache ich das über einen XmlSerializer und in der Ausgabe sind nun "." als Dezimaltrennzeichen.
Benutzeravatar
Artificial Mind
Establishment
Beiträge: 802
Registriert: 17.12.2007, 17:51
Wohnort: Aachen

Re: [Projekt] YAGE

Beitrag von Artificial Mind »

Zur Textur: Ja, ich generier das auf ähnlicher Größe und komme auf ca. 1 sec pro char... Dazu benutze ich noch Parallel.For um das automatisch zu parallelisieren. Dauert allerdings immer noch relativ lange und ich versuche es zu vermeiden, die Font-Textur neu zu generieren ;) (ich habe ca. 300 Buchstaben momentan drauf)

Zum Shader: Mich wundert einfach, dass bei die die 3D-Schrift so stark nach normalem linearen Textufiltern aussieht und dass die kleinen Buchstaben so verpixelt sind. Ich habe auch mal Buchstaben auf dem Bildschirm ausgeben lassen, die deiner Größe ähnlich sind.
Font Test
Font Test
Und das sieht irgendwie wesentlich weniger verpixelt aus, deswegen dachte ich, du hättest die smoothsteps und/oder das alpha blending irgendwie rausgelassen.
Wie interpolierst du eigentlich zwischen innerer Farbe, Outline und Glow? Ich berechne quasi alle drei Farben mit Alpha-Channel und mache dann alpha-over-blending in der Reihenfolge Glow->Outline->Inneres.

Zur Xml: Ok der XmlSerializer geht natürlich, den benutze ich nämlich auch ;)

Nachtrag: Aber es ist halt wirklich ein Problem die Font-Textur mit so großen Buchstaben zu generieren und die dann so stark zu undersamplen, wenn man kleine Schriften zeichnet. Deswegen zeichne ich auch wie gesagt meine GUIs in 3D mit einer etwas höheren Auflösung als notwendig wäre und lasse dann das Texturfiltering davon Wunder wirken ;)
RazorX
Establishment
Beiträge: 156
Registriert: 23.12.2010, 14:13
Kontaktdaten:

Re: [Projekt] YAGE

Beitrag von RazorX »

Wow, gut zu Wissen das es sowas von Haus aus gibt, hab nun auch Paralell.Foreach einbaut und es geht enorm viel schneller (nun sind auch alle 4 Kerne ausgelastet :D).

Zum Shader: Prinzipiell berechne ich nur das was nötig ist und interpoliere dabei immer zwischen den beiden angrenzenden Farben. Das funktioniert wohl nicht mehr bei so einer geringen Auslösung, ist ja im Prinzip von 512² auf 32² runtergerechnet. Ich werd morgen mal versuchen alle drei Komponenten auszurechnen und dann zu kombinieren.

Hier nochmal ein Bild, das deinem ein bisschen nachempfunden ist:

009 - Core - SDF Font.png
Benutzeravatar
Artificial Mind
Establishment
Beiträge: 802
Registriert: 17.12.2007, 17:51
Wohnort: Aachen

Re: [Projekt] YAGE

Beitrag von Artificial Mind »

Ja, ich glaube mein antialias-Bereich ist einfach etwas weiter gewählt als deiner, sodass bei mir der kleinere Text besser geantialiased ist, wohingegen großer Text bei mir "blurriger" ist. Es ist wahrscheinlich eine gute Idee, die "Breite" des Antialiasing abhängig von der Textgröße zu machen (bzw. unabhängig, je nachdem aus welchem Winkel man guckt ;) ), sodass immer ca. 1-2 Pixel Antialias-Streifen da ist, oder soetwas.

Ich finde das immer wieder beeindruckend, wie gut die Signed Distance Fonts bei sehr großen Zeichen aussieht :)
RazorX
Establishment
Beiträge: 156
Registriert: 23.12.2010, 14:13
Kontaktdaten:

Re: [Projekt] YAGE

Beitrag von RazorX »

Soo, habe heute mal an einer schöneren Debugoberfläche gearbeitet, sodass ich nun anfange sämtliche Elemente der Engine in diesem Editor zu visualisieren. Vorallem das PropertyGrid erleichert einem das Leben ja ungemein. Die Engine kann somit nun im Debug-Modus (Editor) gestartet werden, oder in einem nativen Fenster (ohne WinForms) für normalen Spielfluss. Der Editor ist natürlich noch etwas kahl, ist jetzt aber schon deutlich komfortabler^^ (hatte vorher ein zusätzliches Fenster das sich geöffnet hat und ich immer irgendwie unterbringen musste)
009 - Editor - Output.png
@Artifial Mind: Nochmal zurück zur Laufzeit des Algorithmus. Was verwendest du denn für einen Algorithmus, gibt ja eine breite Pallette für die Generierung. Ich für meinen Teil benutze den 8SSEDT Algorithmus, der komplexeste und zeitaufwändigste, jedoch aber auch der präziseste. Für eine 1024² Textur brauch ich dann pro Buchstabe schon so 8-10 Sekunden, parallelisiert bekomme ich natürlich mehr Buchstaben in dem Zeitraum geschaft, aber dennoch ist das nicht so berauschend.
Benutzeravatar
Artificial Mind
Establishment
Beiträge: 802
Registriert: 17.12.2007, 17:51
Wohnort: Aachen

Re: [Projekt] YAGE

Beitrag von Artificial Mind »

Ich benutze Dead Reckoning, das ist wohl nicht besonders präzise aber halt schneller. Aber wie du schon sagtest,als Vorverarbeitungsschritt durchaus ok.
RazorX
Establishment
Beiträge: 156
Registriert: 23.12.2010, 14:13
Kontaktdaten:

Re: [Projekt] YAGE

Beitrag von RazorX »

So, ich arbeite weiterhin daran die Features des Editors auszubauen und habe als nächstes einen Postprocessing Designer in Betracht gezogen. Das Dingen soll ähnlich Cryteks FlowGraphs die Effekte zusammenbauen durch Spezifizierung von Eingangs-/Ausgangstexturen (RenderTargets). Desweiteren soll es möglich sein Konstante Parameter (bei Instantiierung) anzugeben, sowie variable Parameter die in welcher Art auch immer mit dem SceneManager zusammenhängen (Realisierung von Trigger-Effekten). Die Shader bekomme ich mittlerweile schon ganz gut analysiert, sodass ich genau sagen kann auf welchem RenderTarget Index wirklich etwas rausgeschrieben wird. Schön wäre es wenn jemand ein Control oder eine Lib kennt, die die Gestaltung von solchen Graphen übernehmen würde (könnte man sich ne Menge Arbeit mit sparen).

Edit:
Die Analyse von den zwei Zeilen

Code: Alles auswählen

out vec4 color;
layout(location=1)out vec4 color2;
liefert mir folgende Aussagen:
12:25:44 Info RenderTarget: color2 at 1
12:25:44 Info RenderTarget: color at initially 0
Antworten