Integration eines Augmented Reality Tracking Frameworks in die Unreal Engine

Zahlreiche Augmented Reality (AR) Entwickler bieten auch AR Frameworks an. Eine Integration des Frameworks mit verschiedenen Graphic- und Gameengines (etwa Unity) ist dabei fast selbstverständlich. Doch nicht für die wohl bekannteste Game Engine, die Unreal Engine. Bis jetzt!

Geschafft: Augmented Reality mit der Unreal Engine

Geschafft: Augmented Reality mit der Unreal Engine

 

 

 

 

Mit der Änderung der Lizenz der Unreal Engine zu einem liberaleren Lizenzmodell beschlossen wir, diese Integration als kleines Nebenprojekt durchzuführen. Für das Tracking verwendeten wir das Metaio SDK als Framework, welches zu diesem Zeitpunkt am geeignetsten schien. Es enthält bereits Beispiele, wie eine solche Integration in eine Grafik Engine ablaufen könnte. Diese Beispiele gibt es für Windows (über das native C++ Interface der Bibliothek) und auch als Java Code für Android (welches zunächst die Hauptplattform war).

Metaio & Unreal Engine Modul

Da die Unreal Engine natürlich auch auf Android den performanteren C++ Code verwendet, musste zunächst das Metaio SDK als C++ Modul für die Unreal Engine zum Laufen gebracht werden.

Metaio wird auch auf Android als native C++ Bibliothek ausgeliefert, wobei sich diese über eine JNI Bridge aus Java aufrufen lässt. Es gibt für Android keine nativen Header. Diese man benötigt, um Funktionen der Bibliothek vom C++ Code aus aufrufen zu können. Da sich die Bibliotheken zwischen den Plattformen (zumindest äußerlich) nicht deutlich unterscheiden, kann man die mit der Windows Version ausgelieferten Header verwenden, um die Bibliothek auf Android im native Code aufzurufen. So konnte man das Metaio SDK nach der Initialisierung der Bibliothek vom Java Code aus im Unreal Engine Modul verwenden. Dadurch besteht die Möglichkeit in jedem „tick“ der Engine ein neues Bild des Kamerastreams sowie die dazugehörige Pose zu bekommen.

Kamera-Echtzeit mit Mediatexture?

Nun waren zwar die benötigten Daten in der Engine, doch wie sollte man diese verwenden? Zunächst widmeten wir uns dem Problem, wie die Bilder des Kamerastreams in Echtzeit dargestellt werden können. Eine geeignete Lösung vermuteten wir in der Mediatexture – mit dieser kann man beliebige Videos auf Objekten abspielen. Somit kann man das Video auf einem Objekt im Hintergrund der Szenen rendern. Leider stellte sich heraus, das Mediatexture auf mobilen Geräten nur bedingt funktioniert und damit für die weitere Entwicklung nicht weiter in Frage kam.

Konzept „2 Kameras“

Die nächste Idee kam uns bei der näheren Betrachtung der Unity Integration auf. Hierbei muss man zwei „Kameras“ verwenden, um zunächst den Videohintergrund zu zeichnen und anschließend die Szene darüber zu rendern. Da auch Unreal das Konzept von „Kameras“ im Editor kennt, sollte dasselbe auch hier angewendet werden. Allerdings führte auch dies nicht zum Erfolg.

„Übermalen“ mit Postprocessing Shader

Das zugrunde liegende Konzept des Übermalens sollte aber auf jeden Fall möglich sein. Daher versuchten wir das Problem mit den Postprocessing Shadern des Editors zu lösen. Mit Hilfe dieser kleinen Programme ist es möglich das Rendern der Szene auf der Grafikkarte direkt zu beeinflussen. Damit gelang es uns, das Video mit der Szene zu kombinieren und gemeinsam darzustellen. Einen erneuten Rückschlag gab es allerdings, als wir versuchten, das soeben Geschaffene auf Android zu testen. Das Video wurde nicht angezeigt, da manche Postprocessing Shader auf Mobilen Plattformen zu diesem Zeitpunkt (noch) nicht zur Verfügung stehen.

Der zusätzliche Shader

Da es über die Editor Effekte nicht klappte, haben wir den Engine Render Code der mobilen Plattformen so abgeändert, dass ein zusätzlicher postprocessing Step durchgeführt wird. In diesen wird an den Stellen (Pixel), die nicht von der Szene überdeckt werden, der Videostream gerendert. Dabei ließen wir nach dem Rendern der soliden Objekte und vor dem Rendern der transparenten Objekten einen eigenen Shader über das Zwischenergebnis laufen. Damit war es nun möglich, den Kamerastream in Echtzeit als Hintergrund in der Unreal Engine anzeigen zu lassen.

Unser Shader

Unser Shader

Finalisierung: Perspektive wechseln

Was nun noch fehlte, war die virtuellen Objekte aus der richtige Perspektive zu rendern. Dies sollte eigentlich eine kleine Nebenaufgabe sein, da Metaio die Transformationsmatrix übernimmt und diese nur in der Unreal Engine setzten müsste. Das Problem dabei war jedoch, dass die von Metaio gelieferte Matrix eine Transformation im rechtshändigen Koordinatensystem darstellt, während die Unreal Engine ein linkshändiges Koordinatensystem verwendet. Somit musste die Transformationsmatrix umgewandelt werden.

Umwandlung der Metaio Transformation Matrix in die Unreal Engine Transformation Matrix

Umwandlung der Metaio Transformation Matrix in die Unreal Engine Transformation Matrix

Als wir schließlich auch dieses Problem gelöst hatten, entstand eine funktionierende Augmented Reality-Anwendung, welche die Unreal Engine für die grafische Darstellung nutzt.