In diesem Kapitel wird die Visualisrung der Punktwolke in der Unreal Engine 4 \cite{UE4} beschrieben.
In diesem Kapitel wird die Visualisierung der Punktwolke in der Unreal Engine 4 \cite{UE4} beschrieben.
Die Unreal Engine ist eine mächtige Game Engine, die unter anderem Support für verschiedene Virtual Reality Systeme bietet.
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.
Durch die Verwendung einer Game Engine muss kein eigener performanter Renderer geschrieben werden, der den Anforderungen für Virtual Reality entspricht.
\section{UE4 Rendering System}
\section{UE4 Rendering System}
Die Unreal Engine 4 verwendet ein Render System, das auf DirectX aufgebaut ist.
Die Unreal Engine 4 verwendet ein Render 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 gesamte Rendering ist abstrahiert und aus der Engine heraus hat man keinen direkten Zugriff auf die Grafikkarte und die Shader.
Das Unreal Engine Materialsystem ist der vorgesehene Weg, um Shader zu implementieren.
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.
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}
\section{3D Tiles laden und vorbereiten}
Die Punktwolken könne als Array direkt geladen werden, jedoch lässt die Unreal Engine nicht zu, diese auch direkt als 1D Buffer auf die Grafikkarte zu laden und zu verwenden.
Die Punktwolken können als Array direkt geladen werden, jedoch lässt die Unreal Engine nicht zu, diese auch direkt als 1D Buffer auf die Grafikkarte zu laden und zu verwenden.
Als Alternative wurde der eindimensionale Array an Punkten in eine quadratische 2D Textur umgewandelt.
Als Alternative wurde der eindimensionale Array an Punkten in eine quadratische 2D Textur umgewandelt.
Jeder Pixel der Textur besteht aus 4 Werten, jeweils einen für die 3 Farbkanäle Rot, Grün, Blau und $\alpha$ (Transparenz)
Jeder Pixel der Textur besteht aus 4 Werten, jeweils einen für die 3 Farbkanäle Rot, Grün, Blau und $\alpha$ (Transparenz).
Ein Punkt im 3D Raum besteht aus 3 Werten für die Achsen X,Y und Z.
Ein Punkt im 3D Raum besteht aus 3 Werten für die Achsen X,Y und Z.
Um die Daten auf die Grafikkarte zu laden, werden die Positionen in den 3 Farbkanälen codiert.
Um die Daten auf die Grafikkarte zu laden, werden die Positionen in den 3 Farbkanälen codiert.
Farbwerte sind im Wertebereich $[0-1]$ und werden in unterschiedlichen Datenformaten gespeichert.
Farbwerte sind im Wertebereich $[0-1]$ und werden in unterschiedlichen Datenformaten gespeichert.
Für die Implementierung wurde das HDR Datenformat der Unreal Engine verwendet.
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.
Dabei wird jeder Farbkanal in einer 16 Bit Integer codiert und ergibt damit pro Farbkanal $2^{16}$ diskrete Farbwerte.
Da wir die Koordinaten in der Farbtextur speichern ist der 3D Raum der Punktwolke ebenfalls in $2^{16}$ diskrete Schritte pro Achse unterteilt.
Da wir die Koordinaten in der Farbtextur speichern, ist der 3D Raum der Punktwolke ebenfalls in $2^{16}$ diskrete Schritte pro Achse unterteilt.
Um die Daten in eine Textur zu überführen werden diese vorbereitet.
Um die Daten in eine Textur zu überführen werden diese vorbereitet.
...
@@ -46,8 +46,8 @@ Das Aufbereiten der Farbtextur ist einfach.
...
@@ -46,8 +46,8 @@ 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 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 der Punkte ist nicht immer gleich.
Die erzeugten Texturen sind immer quadratisch aber die Anzahl der Punkte ist nicht immer gleich.
Durch das verwerfen von falschen Punkten und das zusammenfügen von mehreren Aufnahmen kann die Größe der Punktwolke variieren.
Durch das Verwerfen von falschen Punkten und das Zusammenfügen von mehreren Aufnahmen kann die Größe der Punktwolke variieren.
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$ Wertvon 0 sonst 1.
Für die Implementierung 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 von 0 sonst 1.
...
@@ -57,7 +57,7 @@ Als Basis für den Renderingprozess wurde deshalb eine Quadchain verwendet (Sieh
...
@@ -57,7 +57,7 @@ Als Basis für den Renderingprozess wurde deshalb eine Quadchain verwendet (Sieh
Diese Quadchain besteht aus $2^{20}$ einzelnen Quadraten entlang der Z Achse.
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.
Durch diese Anordnung hat jedes Quadrat einen Index, die Z Position.
Durch diese Anordnung hat jedes Quadrat einen Index, die Z Position.
Diese Indizierung wird verwendet um jedes Quadrate einem Punkt zuzuordnen und das Quadrat anschließend an die gewünschte Position zu transformieren.
Diese Indizierung wird verwendet, um jedes Quadrate einem Punkt zuzuordnen und das Quadrat anschließend an die gewünschte Position zu transformieren.
\begin{figure}
\begin{figure}
\begin{center}
\begin{center}
...
@@ -68,16 +68,16 @@ Diese Indizierung wird verwendet um jedes Quadrate einem Punkt zuzuordnen und da
...
@@ -68,16 +68,16 @@ Diese Indizierung wird verwendet um jedes Quadrate einem Punkt zuzuordnen und da
\end{center}
\end{center}
\end{figure}
\end{figure}
Beim eigentlichen Rendervorgang kann im Shader, also in UE4 Material jedes Quads an eine Position eines 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.
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?}
\todo{Formel?}
Mit den Texturkoordinaten kann die Position und die Farbe des Punktes ausgelesen werden.
Mit den Texturkoordinaten kann die Position und die Farbe des Punktes ausgelesen werden.
Bevor die Position verwendet werden kann, muss diese aus dem Einheitswürfel in die wirklichen Koordinaten zurück transformiert werden.
Bevor die Position verwendet werden kann, muss diese aus dem Einheitswürfel in die wirklichen Koordinaten zurück transformiert werden.
Die in der Vorberitung errechnete Größe udn das Minimum können verwendet werden um die Gleichung \ref{eq:Bounding} umzukehren.n
Die in der Vorbereitung errechnete Größe und das Minimum können verwendet werden, um die Gleichung \ref{eq:Bounding} umzukehren.
Anschließend fehlt nur noch die Translation und Rotation der Punktwolke in der Welt.
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.
Auch hier lässt die Unreal Engine nicht zu, dass 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.
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 Quad 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.
...
@@ -92,8 +92,8 @@ Die resultierenden Punktwolken funktionieren für den Anwendungsfall und die in
...
@@ -92,8 +92,8 @@ Die resultierenden Punktwolken funktionieren für den Anwendungsfall und die in
Außer dem Deaktivieren von Schattenberechnungen wurden keine Performance Optimierungen vorgenommen.
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.
Die Beispielwerte wurden mit einem i7 6700 und eine GTX 1070 aufgenommen. Eine genaue Analyse ist nicht erfolgt.
\todo{punktwolkengröße}
\todo{punktwolkengröße}
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.
Eine Punktwolke mit 1596685 einzelnen Punkten erreicht ca. 60fps (siehe Bild \ref{img:Pnts1}. Hierbei ist zu bedenken, dass 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.
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.