X-Git-Url: http://git.lukelau.me/?p=opengl.git;a=blobdiff_plain;f=assignment-3%2Freport.latex;fp=assignment-3%2Freport.latex;h=5117b7a4930e85a520536a3c2068e356f4298282;hp=0000000000000000000000000000000000000000;hb=b64cd5a5ec09e6f051583371045ef7080c69b776;hpb=da829a43b9ab76ce8830bd83760e59f016787727 diff --git a/assignment-3/report.latex b/assignment-3/report.latex new file mode 100644 index 0000000..5117b7a --- /dev/null +++ b/assignment-3/report.latex @@ -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}