Damit ein Experte assistierend zugeschaltet werden kann, benötigt dieser Informationen zu dem problematischen Objekt.
Diese Daten sollen dem Experten anschließend in einer VR Umgebung präsentiert werden. Deshalb sollte die Aufnahme ein 3D Scan sein.
Diese Daten sollen dem Experten in einer VR Umgebung präsentiert werden. Deshalb sollte die Aufnahme ein 3D Scan sein.
Ziel der Arbeit war es, eine Lösung für das Aufnehmen der benötigten 3D Daten zu finden, die einfach bedienbar ist und ohne aufwendige Nachbearbeitung oder Berechnungen auskommt.
Die Entscheidung fiel auf die Aufnahme und Visualisierung von 3D Punktwolken.
Als Sensor wurde die Kinect ausgewählt. Diese ist günstig, portabel und wird in der Forschung häufig als 3D Sensor eingesetzt.
Die Kinect als Sensor bietet die Möglichkeit, aus einzelnen Aufnahmen, bestehend aus einem Farbbild und einem Tiefeinbild, eine Punktwolke aus der Perspektive der Kinect zu errechnen.
Eine Aufnahme (ein Frame) beinhaltet aber nur alle Informationen, die aus der Perspektive der Kamera sichtbar sind.
Die Kinect als Sensor bietet die Möglichkeit, aus einzelnen Aufnahmen, bestehend aus einem Farbbild und einem Tiefenbild, eine Punktwolke aus der Perspektive der Kinect zu errechnen.
Eine Aufnahme (ein Frame) beinhaltet aber nur die Informationen, die aus der Perspektive der Kamera sichtbar sind.
Das beinhaltet zum einen die Flächen der nächsten Oberfläche. % @@@ zum anderen fehlt
Dahinterliegende Geometrie wird verdeckt und ist aus einer Perspektive nicht sichtbar(siehe \ref{img:KinectSides} (a)).
Dahinterliegende Geometrie wird verdeckt und ist aus einer Perspektive nicht sichtbar(siehe \ref{img:KinectSides} (a)).
Außerdem sind an Kanten meist nicht genügend Informationen in der Aufnahme enthalten, sodass seitliche Flächen richtig in Punkte konvertiert werden können. %@@@ statt ``sodass'' muss des doch ``damit'' heißen, oder?
In vielen Fällen führt das zu falschen und nicht existierenden Flächen der errechneten Punktwolke (siehe \ref{img:KinectSides} (b)).
Diese Informationen aus einer Aufnahme reichen für die Visualisierung in VR für den Experten nicht aus.
...
...
@@ -17,7 +17,7 @@ Das Objekt sollte von allen Seiten gescannt werden, damit der Experte frei entsc
Um eine Punktwolke zu erhalten, die das gesamte Objekt abdeckt, werden mehrere Aufnahmen aus unterschiedlichen Perspektiven gemacht.
Diese Aufnahmen müssen aber anschließend richtig zu einer großen Punktwolke zusammengefügt werden.
Eine Möglichkeit 2 Aufnahmen zusammenzufügen, ist über die Transformation zwischen den Kamerapositionen.
Eine Möglichkeit,2 Aufnahmen zusammenzufügen, ist über die Transformation zwischen den Kamerapositionen.
Mit dieser Transformation lässt sich eine Punktwolke aus einem Frame in das Koordinatensystem einer anderen Aufnahme transformieren.
Um diese Transformation zu errechnen, gibt es einige Ansätze, die aber meist rechenaufwändig und fehleranfällig sind.\todo{ref realted work}
In dieser Arbeit wurde die Kinect mit dem Lighthouse Tracking der HTC Vive verbunden.
...
...
@@ -37,34 +37,34 @@ Das spart Zeit und Rechenleistung und bietet somit eine einfache und schnelle MÃ
\section{Frames aufnehmen und bereinigen}
Im ersten Schritt wird ein Frame mit der Kinect aufgenommen.
Die Rohdaten der Kinect sind verrauscht und deshalb wird das Tiefenbild geglättet.
Anschließend wird das Tiefen- und Farbbild in 3D Punkte umgewandelt und unerwünschte Punkte verworfen.
Anschließend wird das Tiefen- und Farbbild in 3D Punkte umgewandelt und unerwünschte Punkte verworfen.
\subsection{Aufnahme und Glättung}
Zum Aufnehmen einer Punktwolke aus einem Frame wird das Kinect SDK verwendet.
Sowohl das Tiefeinbild auch als auch das Farbbild kann man aus der API erhalten.
Anschließend wird das Tiefenbild geglättet um glattere Oberflächen in der Punktwolke zu erhalten.
Anschließend wird das Tiefenbild geglättet, um glattere Oberflächen in der Punktwolke zu erhalten.
Hierfür braucht man einen Filter, der zwar die Flächen glättet, aber gleichzeitig die Objektkanten erhält.
Ein bilateraler Filter erzielt den gewünschten Effekt ist aber relativ rechenaufwändig.
Im Paper \cite{Martin:2014:RTH} wird hierfür ein Filter vorgestellt den auch in dieser Ausarbeitung verwendet wurde.
Im Paper \cite{Martin:2014:RTH} wird hierfür ein Filter vorgestellt, der auch in dieser Ausarbeitung verwendet wurde.
Hierbei wird zunächst das Bild mit einem Gauß-Filter geglättet.
Dieser ist nicht kantenerhaltend. Deshalb wird das geglättet Bild anschließend mit dem Original verglichen.
Bei zu starker Abweichung vom Original wird der Wert des Pixels auf das Original zurückgesetzt.
Bei zu starker Abweichung vom Original wird der Wert des Pixels auf das Original zurückgesetzt. %@@@ Wann ist eine Abweichung stark? Und über welches Pixel sprichst du?
Nach der Glättung des Tiefenbildes wird dieses in eine Punktwolke umgewandelt.
Hierfür wurde ebenfalls das Microsoft Kinect SDK verwendet, das alle benötigten Methoden bereitstellt.
Nach der Umwandlung werden noch weitere Punkte verworfen:
Zunächst werden alle Punkte ohne zuordnungsfähige Farbe verworfen um ein schönere Aufnahme zu erhalten.
Der Farbsensor ist nicht an der gleichen Stelle der Kinect und deshalb kann es vorkommen, dass die Tiefeinkamera Geometrie aufnimmt, die aus Sicht der Farbkamera verdenkt ist.
Außerdem hat der Tiefeinsensor eine andere Auflösung und ein anderes Seitenverhältnis als die Farbkamera, sodass es am oberen und unteren Rand zu nicht farbigen punkten kommt.
Zunächst werden alle Punkte ohne zuordnungsfähige Farbe verworfen, um ein schönere Aufnahme zu erhalten.
Der Farbsensor ist nicht an der gleichen Stelle der Kinect und deshalb kann es vorkommen, dass die Tiefenkamera Geometrie aufnimmt, die aus Sicht der Farbkamera verdenkt ist.
Außerdem hat der Tiefeinsensor eine andere Auflösung und ein anderes Seitenverhältnis als die Farbkamera, sodass es am oberen und unteren Rand zu nicht farbigen Punkten kommt.
Auch alle Punkte, die zu nah oder zu weit vom Sensor entfernt sind, werden nicht weiter betrachtet.
Je weiter das Objekt entfernt ist, desto ungenauer werden die Aufnahmen.
Im folgenden wurde ein Mindestabstand von 30cm und ein Maximalabstand von 90cm verwendet.
Als letztes werden alle Flächen deren Oberflächennormale zu weit von dem Kameravektor abweicht (siehe Abb \ref{img:KinectSides} b)
Als letztes werden alle Flächen, deren Oberflächennormale zu weit von dem Kameravektor abweicht (siehe Abb \ref{img:KinectSides} b), %@@@ wie geht der Satz weiter?
Diese Flächen entstehen durch die Umwandlung des 2D Tiefenbildes in eine 3D Punktwolke.
Die benötigten Informationen fehlen an dieser Stelle und Punkte werden auf die Fläche zwischen Oberflächenobjekt und Hintergrund gesetzt.
Diese Ebene stimmt nicht mit der wirklichen Oberfläche überein und diese falschen Punkte müssen entfernt werden.
Diese Ebene stimmt nicht mit der wirklichen Oberfläche überein. Diese falschen Punkte müssen entfernt werden.
Hierfür wird die Oberflächennormale verwendet.
Die Normale wird aus dem Tiefenbild geschätzt.
\begin{equation}
...
...
@@ -106,21 +106,21 @@ Der Fehler im lokalen Koordinatensystem wird in das globale transformiert und is
\end{center}
\end{figure}
In der offiziellen Dokumentation der Kinect ist beschrieben, dass der Ursprung von Punktwolken imTiefensensor liegt (siehe \cite{KinectDoku}).
In der offiziellen Dokumentation der Kinect ist beschrieben, dass der Ursprung von Punktwolken imTiefensensor liegt (siehe \cite{KinectDoku}).
Leider fehlt die exakte Positionsangabe im Gehäuse.
Im Bild \ref{img:KinectOrigin} aus dem chinesischen Microsoft Forum ist eine von Benutzern vermessene schematische Darstellung der Kinect abgebildet.
Der Tiefensensor liegt hinter der kleineren runden Öffnung.
Die exakte Position ließ sich ohne die Kienct zu zerlegen nicht ermitteln, da auch Fertigungsungenauigkeiten die genaue Position beeinflussen können.
Die exakte Position ließ sich nicht ermitteln, ohne die Kinect zu zerlegen, da auch Fertigungsungenauigkeiten die genaue Position beeinflussen können.
Für die Implementation wurde angenommen, dass er sich mittig hinter der Öffnung befindet.
Eine digitale Kalibrierung gestaltet sich schwierig, da das Lighhouse Tracking des Controllers zusätzlich einige Ungenauigkeiten mit sich bringt.
Eine digitale Kalibrierung gestaltet sich schwierig, da das Lighthouse Tracking des Controllers zusätzlich einige Ungenauigkeiten mit sich bringt.
Der Ursprung des Controllers lässt sich aus den Modellen von Steam VR auslesen (siehe Abb.\ref{img:KinecttoVive} (c))
Dieser liegt geschickt für VR Anwendungen da die Z-Achse in der Hand liegt.
Aber das für das Tracking von Objekten liegt der Ursprung ungeschickt, da er im inneren des Controllers liegt und es keine ebene Auflagefläche parallel zu den Achsen gibt.
Dieser liegt geschickt für VR Anwendungen,da die Z-Achse in der Hand liegt.
Aber für das Tracking von Objekten liegt der Ursprung ungeschickt, da er im Inneren des Controllers liegt und es keine ebene Auflagefläche parallel zu den Achsen gibt.
Bei der Implementation stand noch kein Vive Tracker zur Verfügung.
Die Tracker sind extra Sensoren die für das Tracken von Objekten mit dem Lighthouse System entwickelt wurden.
Die Tracker sind zusätzliche Sensoren, die für das Tracken von Objekten mit dem Lighthouse System entwickelt wurden.
Bei diesen ist der Ursprung in der Schraube und parallel zur Auflagefläche (siehe Abb. \ref{img:Tracker}).
Für die Arbeit wurde der Controller so nah wie möglich an dem Tiefensensor, also direkt darüber angebracht (siehe Abb. \ref{img:KinecttoVive}).
Als Hilfe wurde ein 3D gedruckter Zylinder verwendet der in den Ring des Controllers passt.
Als Hilfe wurde ein 3D gedruckter Zylinder verwendet, der in den Ring des Controllers passt.
\begin{figure}
...
...
@@ -137,14 +137,14 @@ Als Hilfe wurde ein 3D gedruckter Zylinder verwendet der in den Ring des Control
\subfigure[Kinect mit Controller]{\includegraphics[width=0.32\textwidth]{Bilder/KinecController1.JPG}}
\subfigure[Relative Position in 3D\label{img:KinecttoVive-3D}]{\includegraphics[width=0.32\textwidth]{Bilder/KinectToVive.png}}
\caption{Befestigung des Controllers an der Kinect. Die Mitte des Controllers ist direkt über dem Tiefensensor.
In Bild \ref{img:KinecttoVive-Befestigung} ist die 3D gedruckte Halterung zu sehen. Der Controller wird auf den Zylinder gesteckt. In \ref{img:KinecttoVive-3D} ist die Virtuelle Repräsentation. Koordinatenkreuze zeigen den jeweiligen Ursprung des Geräts (X-, Y- und Z-Achse in rot, grün und blau)}
In Bild \ref{img:KinecttoVive-Befestigung} ist die 3D gedruckte Halterung zu sehen. Der Controller wird auf den Zylinder gesteckt. In \ref{img:KinecttoVive-3D} ist die virtuelle Repräsentation. Koordinatenkreuze zeigen den jeweiligen Ursprung des Geräts (X-, Y- und Z-Achse in rot, grün und blau)}
\caption{Ursprung des Vive Trackers aus der offiziellen Dokumentation. Er ist in der Befestigungschraube und parallel zu der Auflagefläche.}
\caption{Ursprung des Vive Trackers aus der offiziellen Dokumentation. Er ist in der Befestigungsschraube und parallel zu der Auflagefläche.}
\label{img:Tracker}
\end{center}
\end{figure}
...
...
@@ -156,10 +156,10 @@ Die Ungenauigkeiten des Trackings und Fehler in der Kalibrierung führen aber zu
Zwischen 2 Aufnahmen und den daraus resultierenden Punktwolken ist ein Versatz bis zu 2--3 cm sichtbar.
In einer 3D-Umgebung, insbesondere in VR, ist das eine zu große Ungenauigkeit.
Durch die Ungenauigkeiten des Trackings verändert sich die Genauigkeit und damit der Versatz der Punktwolken ständig.
Vergleicht man mit einem 2m Meterstab die reale Distanz mit der realtiven Distanz in VR, so erhält man in VR eine Länge von 1,98 bis 2 m
Die Distanz ist hierbei abhängig von der Orientierung zu den Basisstationen und der aktuellen Kalibrierung des Lighthous Tracking Systems.
Vergleicht man mit einem 2m Meterstab die reale Distanz mit der relativen Distanz in VR, so erhält man in VR eine Länge von 1,98 bis 2 m
Die Distanz ist hierbei abhängig von der Orientierung zu den Basisstationen und der aktuellen Kalibrierung des LighthouseTracking Systems.
Dieses Problem erschwert es, die Kalibrierung zwischen Controller und Kinect zu überprüfen.
Im Gegensatz zur Translation war die Messung der Rotation sehr genau und erzeugte keine Sichtbaren Fehler beim Zusammenfügen der unterschiedlichen Punktwolken.
Im Gegensatz zur Translation war die Messung der Rotation sehr genau und erzeugte keine sichtbaren Fehler beim Zusammenfügen der unterschiedlichen Punktwolken.
In diesem Kapitel wird ein grober Überblick über die Struktur und die Komponenten des GL-Transmission Formats (glTF) und der 3D Tiles gegeben. Diese wurden verwendet, um die Punktwolken zu speichern.
\section{3D Tiles}
3D Tiles \cite{3DTiles} ist eine neue, offene Spezifikation für das Streamen von massiven, heterogenen, geospatialen 3D Datensätzen.
3D Tiles \cite{3DTiles} ist eine neue, offene Spezifikation für das Streamen von massiven, heterogenen, geospatialen 3D Datensätzen. %@@@ statt ``neu'' könntest du schreiben ``aus dem Jahr xyz'' oder ``veröffentlicht inm Jahr xyz''
Die 3D Tiles können genutzt werden, um Gelände, Gebäude, Bäume und Punktwolken zu streamen und bieten Features wie zum Beispiel Level of Detail (LOD).
Für die Arbeit wurde erwartet, das insbesondere LOD notwendig werden könnte.
Es stellte sich allerdings heraus, dass die Datenmengen, die für die Arbeit benötigt wurden, auch ohne LOD bewältigt werden können.
...
...
@@ -14,19 +14,19 @@ Deswegen wurde auf dieses Feature verzichtet.
\label{gltf}
Das GL Transmission Format (glTF \cite{GLTF}) ist ein Format zum effizienten Übertragen von 3D Szenen für OpenGL-APIs wie WebGL. OpenGl ES und OpenGL.
glTF dient als effizientes, einheitliches und erweiterbares Format zur Übertragung und Laden von komplexen 3D Daten.
Dieses wird in den 3D Tiels verwendet um komplexe Geometrie wie Gebäude zu übertragen.
Dieses wird in den 3D Tiles verwendet, um komplexe Geometrie wie Gebäude zu übertragen.
In dieser Arbeit kamen aber nur Punktwolken zum Einsatz.
Im Vergleich zu aktuellen Standards wie COLADA ist glTF optimiert, schnell übertragen und kann schnell in eine Applikation geladen werden.
In einer JSON formatierten Datei (.gltf) wird eine komplette Szene samt Szenengraf, Materialien und deren zugehörigen Shadern, Kamerapositionen, Animationen und Skinning Informationen übertragen.
Dabei kann auf externe Dateien verwiesen werden. Diese sind zum Beispiel Binärdaten oder Bilder, die für das einfache und effiziente Übertragen von Geometrie, Texturen oder den nötigen GLSL Shadern genutzt werden.
Eine .gltf-Datei ist JSON formatiert und bildet den Kern jedes glTF Modells.
Eine .gltf-Datei ist JSON formatiert und bildet den Kern jedes glTF Modells.%@@@ teilweise Wiederholung zu Zeile 20
In ihr werden alle grundlegenden Informationen wie zum Beispiel die Baumstruktur des Szenengrafen und die Materialien gespeichert (siehe Abb. \ref{img:glTFOverview}).
Eine Szene bildet hierbei den Startpunkt für die zu rendernde Geometrie.
Szenen bestehen aus Knoten (Nodes), die beliebig viele Knoten als Kinder haben können.
Jeder Knoten kann eine Transformation im lokalen Raum definieren, bestehend aus einer Translation, einer Rotation und einer Skalierung.
Die Knoten können ein Mesh und damit die eigentliche Geometrie referenzieren.
Diese Geometrie wird in Buffern als Binärdaten gespeichert, welche wiederumentweder als Base64 String direkt im JSON oder als zusätzliche Binärdatei gespeichert.
Diese Geometrie wird in Buffern als Binärdaten gespeichert, welche wiederum entweder als Base64 String direkt im JSON oder als zusätzliche Binärdatei gespeichert wird.
Auf einen Buffer wird mit einem Accessor und einer Bufferview zugegriffen. In diesen ist spezifiziert, in welchem Format die Daten vorliegen (z.B. ein Array aus 2D-Vektoren (VEC2) aus UNSIGNED SHORT).
Alle Datenformate entsprechen Formaten, die in OpenGL vorliegen, sodass die Daten ohne Konvertierung in OpenGL Vertex Array Objetkts (VAO), \bzw{} Vertex Buffer Objekts (VBO) umgewandelt werden können.
...
...
@@ -34,7 +34,7 @@ Jedes Mesh kann auf ein Material referenzieren. Materialien bestehen aus Materia
Techniken bestehen hauptsächlich aus GLSL Shader Programmen, das ebenfalls im glTF mitgeliefert wird.
Außerdem wird spezifiziert, wie die VAO und VBO des Meshes bei dem Rendervorgang an den Shader gebunden werden müssen.
Ein weiteres Feature von glTF Datein ist die Möglichkeit, Animationen und Skinning Informationen zu übertragen.
Ein weiteres Feature von glTF Dateien ist die Möglichkeit, Animationen und Skinning Informationen zu übertragen.
\begin{figure}
\begin{center}
...
...
@@ -44,8 +44,8 @@ Ein weiteres Feature von glTF Datein ist die Möglichkeit, Animationen und Skinn
\end{center}
\end{figure}
Buffer sind die eigentlichen Daten in einem Binären Block.
Diese können entweder als externe Datei (.bin) oder als BASE64 codierter String in der JSON Datei angefügt werden.
Buffer sind die eigentlichen Daten in einem binären Block.
Diese können entweder als externe Datei (.bin) oder als BASE64 codierter String in der JSON Datei angefügt werden.%@@@ Wiederholung zu Zeile 29 ?
Die Hauptaufgabe der Buffer ist es, große Mengen an Daten wie die Geometrie effizient zu übertragen.
\subsection{Tileset und Tiles}
...
...
@@ -53,7 +53,7 @@ Als Basis der 3D Tiles wird ein in JSON beschriebenes Tileset verwendet, das auf
Das Tileset hat eine baumartige Struktur aus Tiles und deren Metadaten.
Jedes Tile hat hierbei ein 3D Volumen, das den geografischen Bereich beschreibt, und einen geometrischen Fehler des Tiles zur Echtwelt.
Außerdem können Kinder und deren Transformationen zu dem Elterntile angegeben werden.
Alle Kinder liegen hierbei in dem Volumen des Elternknotens und können mit verschiedenen Datenstrukturen, wie k-d-Bäumen Quadtrees oder ähnlichem die Region genauer spezifizieren (siehe Bild \ref{img:nonunifomQuad}.
Alle Kinder liegen hierbei in dem Volumen des Elternknotens und können mit verschiedenen Datenstrukturen, wie k-d-Bäumen Quadtrees oder ähnlichem die Region genauer spezifizieren (siehe Bild \ref{img:nonunifomQuad}.%@@@ Komma zwischen ``k-d-Bäumen'' und ``Quadtrees'' ?
Hierbei können die Kinder das Elterntile ersetzen (replace, z.B. ein genaueres Mesh) oder das bestehende Tile ergänzen (refine, zusätzliche Gebäude oder Details).
Die eigentlichen Daten der Tiles sind durch eine URL verlinkt und können dynamisch nachgeladen werden.
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.
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}
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.
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 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.
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.
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.
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.
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.
...
...
@@ -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 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.
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.
Durch das Verwerfen von falschen Punkten und das Zusammenfügen von mehreren Aufnahmen kann die Größe der Punktwolke variieren.
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
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.
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{center}
...
...
@@ -68,16 +68,16 @@ Diese Indizierung wird verwendet um jedes Quadrate einem Punkt zuzuordnen und da
\end{center}
\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.
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 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.
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.
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
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.
\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.
Bei 4 einzelnen Punktwolken mit 443175 Punkten ( 110369, 115991, 110377, 106438; 4 Instanzen der Quadchain) erreicht dieses vorgehen ca 44 fps.
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.
Für eine große Punktwolke mit 1797690 Punkten gesplittet in 2 Instanzen sind es ebenfalls 44 fps.