Work on assignment 4
[opengl.git] / assignment-3 / report.latex
diff --git a/assignment-3/report.latex b/assignment-3/report.latex
new file mode 100644 (file)
index 0000000..5117b7a
--- /dev/null
@@ -0,0 +1,112 @@
+\documentclass{article}
+\usepackage{fullpage}
+\usepackage{graphicx}
+\usepackage{minted}
+\begin{document}
+
+\title{Assignment 3}
+\author{Luke Lau 15336810}
+\maketitle
+
+\begin{figure}[!htb]
+\includegraphics[width=\textwidth]{final}
+               \caption{The final product}
+\end{figure}
+
+\section{Normal generation}
+In order to calculate the lighting on the pyramids, I needed to work out their normals.
+The tutorial I've been following, \texttt{http://learnopengl.com}, has the normals for a cube
+pre-calculated in an array, and this also seems to be the standard way they are loaded from
+.obj and other model files.
+
+However I did not know the normals for the pyramid, and wanted to use something more dynamic in case
+I decide to change the shape later, so I wrote a function to calculate them:
+
+\inputminted[firstline=441,lastline=453,gobble=1]{c++}{../main.cpp}
+
+\section{Phong Lighting}
+Now that I had the normals for the pyramid, I was able to add some lighting.
+It's built up out of three components.
+
+\begin{figure}[!htb]
+\minipage{0.32\textwidth}
+  \includegraphics[width=\linewidth]{ambient}
+  \caption{Simple, global ambient lighting. The white cube is the light source.}
+\endminipage\hfill
+\minipage{0.32\textwidth}
+  \includegraphics[width=\linewidth]{diffuse}
+  \caption{Ambient with diffuse lighting. Sides facing the light are brighter.}
+\endminipage\hfill
+\minipage{0.32\textwidth}
+  \includegraphics[width=\linewidth]{specular}
+  \caption{Ambient, diffuse and specular lighting, giving a shiny appearance.}
+\endminipage
+\end{figure}
+
+\subsection{Ambient}
+Ambient lighting provides the global background lighting even when there's no direct light source.
+It is described as being similar to the light reflected from the moon during night time.
+
+\begin{minted}{c++}
+void main() {
+       float ambient = 0.1;
+       FragColor = ambient * color;
+}
+\end{minted}
+
+\subsection{Diffuse}
+Diffuse lighting is the lighting calculated for each surface.
+It's strongest whenever the light direction is facing the normal, and so can be calculated
+with the dot product of the two vertices.
+
+\begin{minted}{c++}
+void main() {
+       float ambient = 0.1;
+       vec3 lightDir = normalize(fragPos - lightPos);
+       float diffuse = max(0, dot(-normal, lightDir));
+       FragColor = (ambient + diffuse) * color;
+}
+\end{minted}
+
+\subsection{Specular}
+Specular lighting gives objects a sheen. It takes into account the angle that the surface is being viewed at, 
+so the shader needs this information passed in as a uniform.
+The vector that the light reflects off of the normal is calculated,
+and then if the camera angle/vector is facing at this, then the lighting is intensified exponentially.
+
+\begin{minted}{c++}
+void main() {
+       float ambient = 0.1;
+       vec3 lightDir = normalize(fragPos - lightPos);
+       float diffuse = max(0, dot(-normal, lightDir));
+
+       float specularStrength = 0.5;
+       vec3 viewDir = normalize(fragPos - viewPos);
+       vec3 reflectDir = reflect(-lightDir, normal);
+       float specular = pow(max(0, dot(viewDir, reflectDir)), 256);    
+
+       FragColor = (ambient + diffuse + specular) * color;
+}
+\end{minted}
+
+\section{Multiple shader programs}
+This program uses three shader programs in total:
+
+\begin{enumerate}
+               \item The previous "rainbow" shader program for the pyramids
+               \item A flat "solid" shader for the light source cube which is just one colour with no lighting.
+               \item A normal shader where the fragment depends on the normal, used for the teapot. This shader has lighting
+\end{enumerate}
+
+I was able to reuse the same vector shader for both the rainbow and normal shader, since they took in the same uniforms and inputs.
+To switch between the different programs when drawing, the program calls \mintinline{cpp}{glUseProgram}.
+
+\section{Interesting things}
+The light source is animated, and seems to be correctly updated even when applying transformations such as and scales rotations to the pyramids.
+
+When drawing the four other teapots in the smaller viewports, I found myself having to clear the depth buffer with \mintinline{cpp}{glClear(GL_DEPTH_BUFFER_BIT)} before drawing them, otherwise they would sometimes draw behind the pyramids/big teapot in the main viewport.
+
+\section{Projection}
+I wrote up about projection and the camera in the second assignment report, and so haven't included it here.
+
+\end{document}