www.rolandk.de
- Aktuelle Themen zu .Net -
Achtung: Hier handelt es sich um meine alte Seite.
Die aktuelle ist unter folgendem Link erreichbar: www.rolandk.de/wp/
Home Blog Rendern von 3D-Text (Part 2)




















































Rendern von 3D-Text (Part 2)
Sonntag, den 24. Februar 2013 um 07:30 Uhr

Seit mehreren Wochen bastle ich jetzt an den Sachen rum, jetzt kann ich aber das Ergebnis präsentieren. Ich bin jetzt soweit, dass ich Text in einer beliebigen Schriftart und –größe in ein 3D-Objekt umwandeln kann. Nachfolgende Screenshots zeigen den aktuellen Stand.

 

 

Coding-technisch bin ich auch irgendwo da angekommen, wo ich ursprünglich hin wollte. Um obige 3D-Szene anzulegen, musste ich folgenden Code schreiben.

  1. TextGeometryOptions geoOptions = TextGeometryOptions.Default;
  2. geoOptions.GenerateCubesOnVertices = true;
  3. geoOptions.SurfaceVertexColor = Color4.DarkBlue;
  4. geoOptions.VolumetricSideSurfaceVertexColor = Color4.LightSteelBlue;
  5. geoOptions.VolumetricTextDepth = 3f;
  6.  
  7. m_direct3DImage.Resources.AddTextGeometry("TextGeometry", "Game board", geoOptions);
  8. m_direct3DImage.Scene.Add(new GenericObject("TextGeometry"));
  9.  
  10. m_direct3DImage.Resources.AddTextGeometry("TextGeometry2", "abcdefghijklmnopqrstuvwxyz", geoOptions);
  11. m_direct3DImage.Scene.Add(new GenericObject("TextGeometry2") { Position = new Vector3(0f, 0f, 1f) });
  12.  
  13. m_direct3DImage.Resources.AddTextGeometry("TextGeometry3", "ABCDEFGHIJKLMNOPQRSTUVWXYZ", geoOptions);
  14. m_direct3DImage.Scene.Add(new GenericObject("TextGeometry3") { Position = new Vector3(0f, 0f, 2f) });
  15.  
  16. m_direct3DImage.Resources.AddTextGeometry("TextGeometry4", "0123456789", geoOptions);
  17. m_direct3DImage.Scene.Add(new GenericObject("TextGeometry4") { Position = new Vector3(0f, 0f, 3f) });

Mit einigen Zeilen Code entsteht also ein hübsches 3D-Model. Zur Erläuterung des obigen Quellcodes: Mit dem TextGeometryOptions Objekt werden einige Einstellungen festgelegt, welche die Erstellung der Text-Geometrie beeinflussen. Im Anschluss daran werden für jede Text-Zeile die entsprechende Ressource und das jeweilige 3D-Objekt in der Szene angelegt.

 

Der Weg zu diesem Ergebnis war allerdings – wie bereits im letzten Blogeintrag beschrieben – nicht so leicht. Nachfolgend beschreibe ich dazu zwei Probleme: Die Beschaffung der Rohdaten und die Triangulation.

 

Rohdaten

Hierbei geht es darum, einen beliebigen Text nicht in sichtbare Pixel (wie sonst üblich), sondern in Vektordaten umzuwandeln. Im ersten Versuch habe ich mir diese Vektordaten für einen Text von Wpf geholt, also mit dem Ansatz des folgenden Artikels vom MSDN Magazin: http://msdn.microsoft.com/de-de/magazine/cc163349.aspx. Für mich war dieser Ansatz aber nicht ausreichend, da er unter WinRT nicht funktioniert. Ich benötige diese Unterstützung aber, da ich meine 3D-Engine auch für WinRT auslege. So möchte ich – und mache mittlerweile auch – solche 3D-Text-Objekte in meinem WinRT basierten Spiel Mosaic Snake 3D einbinden. Hier ein Screenshot dazu:

 

 

Die obigen Text-Zeilen sind dynamisch erzeugt, also ähnlich wie im Quellcode oben. Damit das so funktioniert, darf man sich die Vektor-Daten der Text-Geometrie aber nicht von Wpf holen, sondern von DirectWrite. In DirectWrite kann man die Vektor-Daten über einen benutzerdefinierten Textrenderer abgreifen. Hier gibt es ein paar nützliche Hinweise dazu: http://msdn.microsoft.com/de-de/library/dd941787(v=vs.85).aspx. Glücklicherweise funktioniert das auch reibungslos über SharpDX (hätte ich anfangs nicht gedacht!).

 

Triangulation

Bei diesem Problem wird es etwas komplizierter, und zwar geht es darum, aus den Vektordaten (zweidimensional) ein 3D-Objekt zu bekommen. Die Schwierigkeit liegt daran, dass man als Input eine oder mehrere Außenlinien in Form von 2D-Vektoren hat, und daraus dann ein 3D-Objekt, aufgebaut aus Dreiecken, errechnen muss (Dieser Prozess wird auch kurz als Triangulation bezeichnet).

 

Wie bereits im letzten Blogeintrag beschrieben, verwende ich für die Triangulation den CuttingEars Algorithmus. Entsprechende Verweise zu Information lassen sich dort auch allesamt finden, daher will ich sie an dieser Stelle hier nicht wiederholen. Was ich hier erwähnen möchte: Die große Herausforderung an dieser Stelle war nicht, aus einem zusammenhängenden Pfad an Vektoren (Außenlinie des Textes) ein 3D-Objekt zu erzeugen. Das Problem waren mehr die Löcher in den Objekten, Im O also etwa der innere Kreis. Im B sind es sogar zwei. Um dieses Thema noch einmal zu verdeutlichen, möchte ich wiederholt folgendes Bild aus dem letzten Blogeintrag zeigen:

 

 

Das mittlere Dreieck im A muss wieder aus der Geometrie, welche durch die Außenlinie des A definiert wird, ausgeschnitten werden. Wie man das machen kann, ist in folgendem Dokument unter Punkt 5 „Polygons with Multiple Holes“ beschrieben: http://www.geometrictools.com/Documentation/TriangulationByEarClipping.pdf. Aber auch mit dieser Beschreibung war dieses Thema alles andere als einfach und erforderte viele Tests. Ich persönlich bezweifle, dass ich an der Stelle im Moment eine 100% Lösung habe, in meinen Versuchen konnte ich aber das komplette Alphabet und alle Ziffern ohne Fehler in 3D-Objekte umwandeln, und genau das war mein Ziel.

 

Der Nutzen

Zum Abschluss dieses Themas will ich auch kurz einige Worte dazu verlieren, warum dieses doch recht komplizierte Vorgehen hier Sinn macht. Mein Vorteil mit diesen Funktionen ist, dass ich 3D-Text dynamisch ohne Umweg über einen 3D-Modeller erzeugen kann. Das ist etwa ein großer Vorteil, wenn man in der 3D-Szene auf die Art dynamische Inhalte wie div. Werte o. Ä. anzeigen möchte. Weiterhin ist das hilfreich bei der Übersetzung von solchen Texten, denn auch der übersetzte Text kann genauso, wie das Original einfach dynamisch erzeugt werden.

 

Kommentar hinzufügen

Ihr Name:
Kommentar: