\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}
