Ausarbeitung 2. Teil

parent 14c3bdd7
\documentclass[]{article}
\usepackage[
colorlinks=true,
urlcolor=blue,
linkcolor=black
]{hyperref}
%opening
\title{Multimedia Ausarbeitung}
\author{Gehirnzelle Nr. 3}
\begin{document}
\maketitle
\tableofcontents
\section{Allgemeines zum Projekt}
OpenGL ist nicht für Raytracing gebaut, sondern in erster Linie für Rasterisierung. Um dieses Problem zu umgehen, erstellen wir ein Quad mit Textur, welches wir in Fenstergröße rasterisieren. Das Raytracing wird im Compute Shader erledigt, der die eigentliche Szene dann in die Textur des Quads schreibt.\\
Als Bibliotheken haben wir wie in der Übung GLFW und GLAD benutzt.\\
Wir haben in Visual Studio programmiert, weil es unter Linux größere Probleme mit der Nutzung von OpenGL 4.3 auf modernen Grafikkarten gibt, welches wir für den Compute Shader benötigen.
\subsection{Raytracing}
Raytracing ist mehr an die physikalische Beschaffenheit des Lichts angelehnt als Rasterisierung. Objekte können wie bei der Rasterisierung mithilfe von Dreiecken/ Quads beschrieben werden oder aber auch über beliebige mathematische Körper (in unserem Fall Sphären) unter der Voraussetzung, dass man berechnen kann, ob und an welchem Punkt eine Linie diesen Körper schneidet.\\
Um eine Szene zu rendern, wird pro Pixel ein Vektor/ eine Linie (genannt Ray) mit Ursprung beim Auge und Richtung des entsprechenden Pixels im Fenster bzw. in dem "Near Plane"\footnote{\url{https://en.wikipedia.org/wiki/Viewing_frustum}} gelegt und überprüft, ob dieser Vektor auf ein Objekt in der Szene trifft und ob dieser Punkt im Frustum liegt.\\
Ab hier wird die Definition verschwommen. In vielen Beispielen zu Raytracing wird der Pixel dann direkt entsprechend der Farbe und des Materials des Körpers eingefärbt, andere Quellen nennen diesen Schritt aber "Raycasting" und sprechen erst von "Raytracing", wenn von diesem Punkt aus Vektoren zu allen Lichtquellen in der Szene gelegt werden und überprüft wird, ob sie diese treffen, bevor sie ein Objekt der Szene schneiden. Darauf basierend wird der Pixel dann schattiert.\\
Darauf aufbauend kann man auch das Material des Körpers berücksichtigen und bei Spiegelung rekursiv einen "Spiegelray" in Richtung der Spiegelung schicken, der die Farbe des gespiegelten Körpers miteinbezieht. Weiterhin gibt es durchsichtige Materialien, in denen der Ray gebrochen wird und ebenfalls rekursiv andere Rays durch den Körper schickt, deren Werte miteinfließen.\\
Wir möchten bei unserem Programm jedoch erst mal die grundsätzliche Funktionalität des raytracings mit OpenGL gewährleisten - also Rays verschicken, deren Rückgabewert die Farbe des getroffenen Körpers beziehungsweise die Hintergrundfarbe enthält - und dann eventuell in der Zukunft weiter darauf aufbauen.
\subsection{Compute Shader}
\label{subsec:computeShader}
Der Compute Shader wurde erst mit OpenGL Version 4.3 eingeführt und man kann mit ihm frei entscheiden, was auf der Grafikkarte berechnet und wie es parallelisiert wird.\\
Die Parallelisierung erfolgt über \textbf{Global Work Groups}, die jeweils unterschiedliche Aufgaben lösen und über \textbf{Local Work Groups}, welche diese Aufgabe in voneinander unabhängigen Teilaufgaben berechnen.\\
In unserem Fall haben wir eine global work group für das berechnen der Textur und Fensterbreite $\cdot$ Fensterhöhe local work groups - jeweils eine pro Pixel der Textur.
\section{Aufbau}
\subsection{Allgemeines}
Als Programmiersprache haben wir C++ verwendet. Wir haben uns an dem C Code aus der Übung orientiert und das ganze für mehr Übersichtlichkeit objektorientiert aufgebaut. Die meisten Teile des Codes zur Initialisierung von OpenGL und der Shader konnten aus der Übung übernommen werden, allerdings wurde die C Funktion zum Einlesen der Shaderdateien neu geschrieben, sodass sie die C++ Stream Operationen nutzt.\\
%TODO falls ihr das anders macht: hier ändern
Für den Compute Shader orientieren wir uns an einem einem \href{http://antongerdelan.net/opengl/compute.html}{Post} von Dr. Anton Gerdelan.
\subsection{Programmablauf}
Wir haben das ganze Programm in der Klasse \verb|rt_window| untergebracht.
\paragraph*{Initialisierung der Klasse}
Es wird entsprechend der Übung zuerst GLFW initialisiert und ein Fenster erstellt (Die Fenstergröße bleibt in unserem Programm unverändert, weil sonst immer die Textur neu erstellt werden müsste). \\
Daraufhin wird das Quad in die VertexData geschrieben. Da die Vertices in unserem Fall unverändert bleiben und es sich nur um vier Stück handelt, haben wir diesen Teil hardcoded.\\
Dann werden der Vertex- und Fragment Shader gelesen, kompiliert und zu einem Programm (\verb|programObjectNonCompute|) hinzugefügt, welches gelinked und benutzt wird.\\
Auch die Zeit wird hier initialisiert, weil wir anfangs überlegt hatten, die Zeit auszugeben, die das Programm benötigt, um einen Frame zu rendern.\\
Anschließend wird der Vertex Array, der Vertex Buffer und die Attribut Pointer für die Positionen der Vertices und der Texturkoordinaten erstellt.\\
Nachdem der Viewport und die Hintergrundfarbe gesetzt wurden, wird die Textur (Format float32 RGBA) für den Quad generiert.\\
Zuletzt wird der Compute Shader gelesen, kompiliert und zu einem eigenen Programm (\verb|programObjectCompute|) hinzugefügt.
\paragraph*{Main Loop}
Der Ablauf der Hauptschleife in OpenGL ist auch entsprechend der Übung in \verb|update()|, \verb|draw()|, \verb|glfwPollEvents()| und \verb|glfwSwapBuffers()| unterteilt.\\
\textbf{update:} Zuerst wird das Program des Compute Shaders benutzt. Der \hyperref[subsec:computeShader]{\textit{Compute Shader}} wird dann ausgeführt mit Fensterhöhe $\cdot$ Fensterbreite lokalen work groups. Sobald der Shader die Textur fertig beschrieben hat, wird die \verb|draw|-Methode aufgerufen.\\
\textbf{draw:} der Color Buffer wird auf die Ausgangsfarbe gesetzt. Nachdem das Program des Vertex- und Fragment Shaders und die Textur benutzt wird, werden die Vertices und die Textur gezeichnet.\\
\textbf{glfwPollEvents:} Beim Drücken von Escape wird der \verb|WindowShouldClose| Event getriggert.\\
\textbf{glfwSwapBuffers:} Front- und nun fertiger Backbuffer werden getauscht.
\paragraph*{Programmende/ Destruktion der Klasse:}
Der Vertex Data Array mit den Vertices des Quads, der Vertex Array und der Vertex Buffer werden gelöscht, das Fenster geschlossen und glfw wird beendet.
\end{document}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment