In diesem Kapittel Wird die Visualisrung der Punktwolke in der Unreal Engine 4 \cite{UE4} erklärt.
Die Unreal Engine ist ein mächtige Game Engine die unter anderm Support für verscheidene Virtual Reality System bietet.
Durch die Verwendung einer Game Engine muss kein eigener performanter Renderer geschrieben werden der den Anforderungen für Virtual Realit entspricht.
In diesem Kapitel wird die Visualisrung der Punktwolke in der Unreal Engine 4 \cite{UE4} erklärt.
Die Unreal Engine ist eine mächtige Game Engine, die unter anderem Support für verschiedene Virtual Reality Systeme bietet.
Durch die Verwendung einer Game Engine muss kein eigener performanter Renderer geschrieben werden, der den Anforderungen für Virtual Realit entspricht.
\section{UE4 Rendering System}
Die Unreal Engine verwendet ein Redner System das auf DirextX aufgebaut ist.
Die gesammte Rendering ist Abstrahiert und aus der Engine hat man keinen direkten Zugriff auf die Grafikkarte und die Shader.
Das Unreal Engine Materialsystem ist der vorgesehene Weg um Shader zu Implementieren.
Im Stil der UE4 Blueprints lassen sich damit grafisch Materialiern definieren die von der Engine in zugehörige Shader umgewandelt werden.
\section{3D Tiles Laden und vorbereiten}
Die Punktwolken könne als Array direkt geladen werden, jedoch lässt die Unreal Engien nicht zu diese auch direkt auf die Grafikkarte zu laden und zu verwenden.
Als Alternative wurde das eindimensionale Buffer in eine quadratische 2D Textur umgewandelt.
Die Unreal Engine verwendet ein Redner System, das auf DirectX aufgebaut ist.
Die gesamte Rendering ist abstrahiert und aus der Engine hat man keinen direkten Zugriff auf die Grafikkarte und die Shader.
Das Unreal Engine Materialsystem ist der vorgesehene Weg, um Shader zu implementieren.
Im Stil der UE4 Blueprints lassen sich damit grafisch Materialien definieren, die von der Engine in zugehörige Shader umgewandelt werden.
\section{3D Tiles laden und vorbereiten}
Die Punktwolken könne als Array direkt geladen werden, jedoch lässt die Unreal Engien nicht zu, diese auch direkt auf die Grafikkarte zu laden und zu verwenden.
Als Alternative wurde das eindimensionale Buffer in eine quadratische 2D Textur umgewandelt.%@@@ das Buffer? Klingt außerdem nicht logisch 1D --> 2D...
Jeder Pixel der Textur besteht aus 3 Werten, jeweils einen für die 3 Farbkanäle Rot, Grün und Blau.
Ein Punkt im 3D Raum besteht ebenfalls aus 3 Werten für die Achsen X,Y und Z.
Um die Daten auf die Grafikkarte zu laden codieren wir die Positionen in den Farbkanälen.
Farbwerte sind im Wetebereich $[0-1]$ und werden in unterschiedlichen Datenformaten gespeichert.
Für die Implementierung wurde das HDR Datenvormat der Unreal Engine verwendet.
Um die Daten auf die Grafikkarte zu laden, codieren wir die Positionen in den Farbkanälen.
Farbwerte sind im Wertebereich $[0-1]$ und werden in unterschiedlichen Datenformaten gespeichert.
Für die Implementierung wurde das HDR Datenformat der Unreal Engine verwendet.
Dabei wird jeder Farbkanal in einer 16 Bit Integer codiert und ergibt damit pro Farbkanal $2^16$ diskrete Farbwerte.
Das bedeute auch für eine Punktwolke die wir als Farbtexture codieren haben wir eine maximale Auflösung pro Achse.
Das bedeutet auch für eine Punktwolke, die wir als Farbtextur codieren, haben wir eine maximale Auflösung pro Achse.
Um die Daten in eine Textur zu überführen müssen wir diese vorbereiten.
Um die Daten in eine Textur zu überführen, müssen wir diese vorbereiten.
Zunächst wird das Minimum und die Größe entlang jeder Achse bestimmt.
Mit diesen Daten lässt sich die gesamte Punktwolke in den Einheitswürfel transformieren.
\begin{equation}
...
...
@@ -44,16 +44,16 @@ Die so codierten Punkte lassen sich in einer Textur abspeichern und im Shader wi
Das Aufbereiten der Farbtextur ist einfach.
Die Farben sind im 3D Tile als Byte große Integer gespeichert und können direkt in eine Unreal Textur konvertiert werden.
Die erzeugten Texturen sind immer quadratisch aber die Anzahl Punkte ist nicht vorgegeben.
Für die Implementeirung wurde immer die Quadratische Textur bestimmt die genug Platz für alle Punkte bietet und die nicht verwendeten Punkte haben in der Farbtextur einen $\alpha$ Wert (4. Farbkanal, Transparenz) von 0 sonst 1.
Die erzeugten Texturen sind immer quadratisch aber die Anzahl der Punkte ist nicht vorgegeben.
Für die Implementeirung wurde immer die quadratische Textur bestimmt, die genug Platz für alle Punkte bietet und die nicht verwendeten Punkte haben in der Farbtextur einen $\alpha$ Wert (4. Farbkanal, Transparenz) von 0 sonst 1.
\section{Rendering}
In der Unreal Engine ist das Rendern von Punktwolken nicht vorgesehen und deshalb gibt es keinen Punkt Modus wie in OpenGL.
Als Basis für den Rederingprozess wurde deshalb eine Quadchain verwendet (Siehe Abbilduung \ref{ing:quadchain})
Als Basis für den Renderingprozess wurde deshalb eine Quadchain verwendet (Siehe Abbilduung \ref{ing:quadchain})
Diese Quadchain besteht aus $2^20$ einzelnen Quadraten entlang der Z Achse.
Jedes Quad ist dabei an einer Ganzzahligen Z Position und die Ecken sind bei 1 und -1.
Jedes Quad ist dabei an einer ganzzahligen Z Position und die Ecken sind bei 1 und -1.
\begin{figure}
\begin{center}
...
...
@@ -63,19 +63,19 @@ Jedes Quad ist dabei an einer Ganzzahligen Z Position und die Ecken sind bei 1 u
\end{center}
\end{figure}
Beim eigentlichen Rendervorgang kann im Shader, also in UE4 Material jedes Quad an eine Position einse Punktes geschoben werden.
Beim eigentlichen Rendervorgang kann im Shader, also in UE4 Material jedes Quads an eine Position eines Punktes geschoben werden.
Hierbei wird die X-Position des Quads als Index in die Punktwolke verwendet.
Aus der größe der quadratischen Textur und dem Index können die Texturkoordinaten (uv) in der 2D Textur berechnet werden.
Aus der Größe der quadratischen Textur und dem Index können die Texturkoordinaten (uv) in der 2D Textur berechnet werden.
\todo{Formel?}
Mit den Texturkoordinaten kann die Position und die Farbe des Punktes ausgelesen werden.
bevor die Position verwendet werden kann muss diese aus dem Einheiswüfel in die wirklichen Koordinaten zurück transformiert werden.
Das Minimum und die Größe aus Gleichung \cite{eq:Bounding} der Vorbereitung lässt sich das einfach zurückrechnen.
Bevor die Position verwendet werden kann, muss diese aus dem Einheitswürfel in die wirklichen Koordinaten zurück transformiert werden.
Das Minimum und die Größe aus Gleichung \cite{eq:Bounding} der Vorbereitung lässt sich das einfach zurückrechnen.%@@@ Satz bitte prüfen
Anschließend fehlt nur noch die Translation und Rotation der Punktwolke in der Welt.
Auch hier lässt die Unreal Engine nicht zu das direkt eine Matrix als Parameter für das Material übergeben werden kann, aber durch eine Postion und eine Rotation lässt sich die Transformation im Material ausrechnen.
Die berechnete Endpostion wird als WorldPositionOffset an die Grafikkarte weitergegeben, die damit den Punkt an die richtige Weltpositon setzt.
Auch hier lässt die Unreal Engine nicht zu, das direkt eine Matrix als Parameter für das Material übergeben werden kann, aber durch eine Postion und eine Rotation lässt sich die Transformation im Material ausrechnen.
Die berechnete Endpostion wird als WorldPositionOffset an die Grafikkarte weitergegeben, die damit den Punkt an die richtige Weltposition setzt.
Für die Sichtbarkeit wird der Quads zu dem Betrachter gedreht und in der Größe skaliert.
Für die Sichtbarkeit wird der Quad zu dem Betrachter gedreht und in der Größe skaliert.
Zusätzlich wird das Quad noch durch eine runde Maske zu einem kleinen Kreis umgewandelt und mit der entsprechenden Farbe texturiert.
Die Quadchain hat eine feste Länge und die Punktwolke hat eine veränderbare Größe.
...
...
@@ -83,20 +83,20 @@ Deshalb werden größere Punktwolken in 2 aufgeteilt.
Bei kleineren Punktwolken werden die nicht verwendeten Quadrate verworfen.
\section{Ergebnisse}
Die resultiernden Punktwolken sehen gut aus und die in dieser Arbeite verwendeten relativ kleinen Punktwolken sind in VR visualisierbar.
Außer das Deaktivieren von Schattenberechnungen wurden keine Performance Optimierungen vorgenommen.
Die Beispielwerte wurden mit einem i7 6700 und eine GTX 1070 aufgenommen, eine genaue Analyse ist nicht erfolgt.
Eine Punktwolke mit 1596685 einzelnen Punkten erreicht ca 60fps (siehe Bild \ref{img:Pnts1}. Hierbei ist zu bedenken das die ganze Quadchain von $2^20$ Punkten gerendert wird und überflüssige Geometrie erst im Shader/Material verworfen wird.
Die resultierenden Punktwolken sehen gut aus und die in dieser Arbeite verwendeten relativ kleinen Punktwolken sind in VR visualisierbar. %@@@ sieht ``gut'' aus. Musst du konkret sagen was dir gefällt? Wissenschaftlicher Anspruch
Außer dem Deaktivieren von Schattenberechnungen wurden keine Performance Optimierungen vorgenommen.
Die Beispielwerte wurden mit einem i7 6700 und eine GTX 1070 aufgenommen. Eine genaue Analyse ist nicht erfolgt.
Eine Punktwolke mit 1596685 einzelnen Punkten erreicht ca 60fps (siehe Bild \ref{img:Pnts1}. Hierbei ist zu bedenken, das die ganze Quadchain von $2^20$ Punkten gerendert wird und überflüssige Geometrie erst im Shader/Material verworfen wird.
Bei 4 einzelnen Punktwolken mit 443175 Punkten ( 110369, 115991, 110377, 106438; 4 Instanzen der Quadchain) erreicht dieses vorgehen ca 44 fps.
Für eine Große Punktwolke mit 1797690 Punkten gesplittet in 2 Instanzen sind es ebenfalls 44 fps.
Für eine große Punktwolke mit 1797690 Punkten gesplittet in 2 Instanzen sind es ebenfalls 44 fps.
\caption{Punkwolke mit 1596685 Punkten. Die Textur im Hintergund ist die zugehörige Positionstextur, Rechts oben ist FPS und die Renderzeit in ms zu sehen }
\caption{Punktwolke mit 1596685 Punkten. Die Textur im Hintergrund ist die zugehörige Positionstextur, Rechts oben ist FPS und die Renderzeit in ms zu sehen }