Update gitattributes
[opengl.git] / assignment-3 / report.latex
1 \documentclass{article}
2 \usepackage{fullpage}
3 \usepackage{graphicx}
4 \usepackage{minted}
5 \begin{document}
6
7 \title{Assignment 3}
8 \author{Luke Lau 15336810}
9 \maketitle
10
11 \begin{figure}[!htb]
12 \includegraphics[width=\textwidth]{final}
13                 \caption{The final product}
14 \end{figure}
15
16 \section{Normal generation}
17 In order to calculate the lighting on the pyramids, I needed to work out their normals.
18 The tutorial I've been following, \texttt{http://learnopengl.com}, has the normals for a cube
19 pre-calculated in an array, and this also seems to be the standard way they are loaded from
20 .obj and other model files.
21
22 However I did not know the normals for the pyramid, and wanted to use something more dynamic in case
23 I decide to change the shape later, so I wrote a function to calculate them:
24
25 \inputminted[firstline=441,lastline=453,gobble=1]{c++}{../main.cpp}
26
27 \section{Phong Lighting}
28 Now that I had the normals for the pyramid, I was able to add some lighting.
29 It's built up out of three components.
30
31 \begin{figure}[!htb]
32 \minipage{0.32\textwidth}
33   \includegraphics[width=\linewidth]{ambient}
34   \caption{Simple, global ambient lighting. The white cube is the light source.}
35 \endminipage\hfill
36 \minipage{0.32\textwidth}
37   \includegraphics[width=\linewidth]{diffuse}
38   \caption{Ambient with diffuse lighting. Sides facing the light are brighter.}
39 \endminipage\hfill
40 \minipage{0.32\textwidth}
41   \includegraphics[width=\linewidth]{specular}
42   \caption{Ambient, diffuse and specular lighting, giving a shiny appearance.}
43 \endminipage
44 \end{figure}
45
46 \subsection{Ambient}
47 Ambient lighting provides the global background lighting even when there's no direct light source.
48 It is described as being similar to the light reflected from the moon during night time.
49
50 \begin{minted}{c++}
51 void main() {
52         float ambient = 0.1;
53         FragColor = ambient * color;
54 }
55 \end{minted}
56
57 \subsection{Diffuse}
58 Diffuse lighting is the lighting calculated for each surface.
59 It's strongest whenever the light direction is facing the normal, and so can be calculated
60 with the dot product of the two vertices.
61
62 \begin{minted}{c++}
63 void main() {
64         float ambient = 0.1;
65         vec3 lightDir = normalize(fragPos - lightPos);
66         float diffuse = max(0, dot(-normal, lightDir));
67         FragColor = (ambient + diffuse) * color;
68 }
69 \end{minted}
70
71 \subsection{Specular}
72 Specular lighting gives objects a sheen. It takes into account the angle that the surface is being viewed at, 
73 so the shader needs this information passed in as a uniform.
74 The vector that the light reflects off of the normal is calculated,
75 and then if the camera angle/vector is facing at this, then the lighting is intensified exponentially.
76
77 \begin{minted}{c++}
78 void main() {
79         float ambient = 0.1;
80         vec3 lightDir = normalize(fragPos - lightPos);
81         float diffuse = max(0, dot(-normal, lightDir));
82
83         float specularStrength = 0.5;
84         vec3 viewDir = normalize(fragPos - viewPos);
85         vec3 reflectDir = reflect(-lightDir, normal);
86         float specular = pow(max(0, dot(viewDir, reflectDir)), 256);    
87
88         FragColor = (ambient + diffuse + specular) * color;
89 }
90 \end{minted}
91
92 \section{Multiple shader programs}
93 This program uses three shader programs in total:
94
95 \begin{enumerate}
96                 \item The previous "rainbow" shader program for the pyramids
97                 \item A flat "solid" shader for the light source cube which is just one colour with no lighting.
98                 \item A normal shader where the fragment depends on the normal, used for the teapot. This shader has lighting
99 \end{enumerate}
100
101 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.
102 To switch between the different programs when drawing, the program calls \mintinline{cpp}{glUseProgram}.
103
104 \section{Interesting things}
105 The light source is animated, and seems to be correctly updated even when applying transformations such as and scales rotations to the pyramids.
106
107 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.
108
109 \section{Projection}
110 I wrote up about projection and the camera in the second assignment report, and so haven't included it here.
111
112 \end{document}