Index: shaders/model.frag
===================================================================
--- shaders/model.frag	(revision 914bb995364b78b9b9cef8950e8062ab7384a491)
+++ shaders/model.frag	(revision a00eb0672f52310ddbe89f59abd3191cb3c993ed)
@@ -6,8 +6,9 @@
 layout(location = 0) in vec3 fragColor;
 layout(location = 1) in vec2 fragTexCoord;
+layout(location = 2) in vec3 normal_eye;
 
 layout(location = 0) out vec4 outColor;
 
 void main() {
-   outColor = vec4(fragColor * texture(texSampler, fragTexCoord).rgb, 1.0);
+   outColor = vec4(fragColor * texture(texSampler, fragTexCoord).rgb, 1.0) + vec4(normal_eye, 0.0) - vec4(normal_eye, 0.0);
 }
Index: shaders/model.vert
===================================================================
--- shaders/model.vert	(revision 914bb995364b78b9b9cef8950e8062ab7384a491)
+++ shaders/model.vert	(revision a00eb0672f52310ddbe89f59abd3191cb3c993ed)
@@ -15,13 +15,22 @@
 } sbo;
 
+layout (binding = 2) uniform UboInstance {
+	mat4 model;
+} uboInstance;
+
 layout(location = 0) in vec3 inPosition;
 layout(location = 1) in vec3 inColor;
 layout(location = 2) in vec2 inTexCoord;
-layout(location = 3) in uint obj_index;
+layout(location = 3) in vec3 vertex_normal;
+layout(location = 4) in uint obj_index;
 
 layout(location = 0) out vec3 fragColor;
 layout(location = 1) out vec2 fragTexCoord;
+layout(location = 2) out vec3 normal_eye;
 
 void main() {
+   // Using 0.0 instead of 1.0 means translations won't effect the normal
+   normal_eye = normalize(vec3(ubo.view * sbo.objects[obj_index].model * vec4(vertex_normal, 0.0)));
+
    fragColor = inColor;
    fragTexCoord = inTexCoord;
Index: vulkan-game.cpp
===================================================================
--- vulkan-game.cpp	(revision 914bb995364b78b9b9cef8950e8062ab7384a491)
+++ vulkan-game.cpp	(revision a00eb0672f52310ddbe89f59abd3191cb3c993ed)
@@ -117,4 +117,5 @@
    modelPipeline.addAttribute(VK_FORMAT_R32G32B32_SFLOAT, offset_of(&ModelVertex::color));
    modelPipeline.addAttribute(VK_FORMAT_R32G32_SFLOAT, offset_of(&ModelVertex::texCoord));
+   modelPipeline.addAttribute(VK_FORMAT_R32G32B32_SFLOAT, offset_of(&ModelVertex::normal));
    modelPipeline.addAttribute(VK_FORMAT_R32_UINT, offset_of(&ModelVertex::objIndex));
 
@@ -131,16 +132,17 @@
 
    texturedSquare = &addObject(modelObjects, modelPipeline,
-      addObjectIndex<ModelVertex>(modelObjects.size(), {
-         {{-0.5f, -0.5f,  0.0f}, {1.0f, 0.0f, 0.0f}, {0.0f, 1.0f}},
-         {{ 0.5f, -0.5f,  0.0f}, {0.0f, 1.0f, 0.0f}, {1.0f, 1.0f}},
-         {{ 0.5f,  0.5f,  0.0f}, {0.0f, 0.0f, 1.0f}, {1.0f, 0.0f}},
-         {{ 0.5f,  0.5f,  0.0f}, {0.0f, 0.0f, 1.0f}, {1.0f, 0.0f}},
-         {{-0.5f,  0.5f,  0.0f}, {1.0f, 1.0f, 1.0f}, {0.0f, 0.0f}},
-         {{-0.5f, -0.5f,  0.0f}, {1.0f, 0.0f, 0.0f}, {0.0f, 1.0f}}
-      }), {
-         0, 1, 2, 3, 4, 5
-      }, {
-         mat4(1.0f)
-      }, false);
+      addObjectIndex<ModelVertex>(modelObjects.size(),
+         addVertexNormals<ModelVertex>({
+            {{-0.5f, -0.5f,  0.0f}, {1.0f, 0.0f, 0.0f}, {0.0f, 1.0f}},
+            {{ 0.5f, -0.5f,  0.0f}, {0.0f, 1.0f, 0.0f}, {1.0f, 1.0f}},
+            {{ 0.5f,  0.5f,  0.0f}, {0.0f, 0.0f, 1.0f}, {1.0f, 0.0f}},
+            {{ 0.5f,  0.5f,  0.0f}, {0.0f, 0.0f, 1.0f}, {1.0f, 0.0f}},
+            {{-0.5f,  0.5f,  0.0f}, {1.0f, 1.0f, 1.0f}, {0.0f, 0.0f}},
+            {{-0.5f, -0.5f,  0.0f}, {1.0f, 0.0f, 0.0f}, {0.0f, 1.0f}}
+         })), {
+            0, 1, 2, 3, 4, 5
+         }, {
+            mat4(1.0f)
+         }, false);
 
    texturedSquare->model_base =
@@ -149,16 +151,17 @@
 
    texturedSquare = &addObject(modelObjects, modelPipeline,
-      addObjectIndex<ModelVertex>(modelObjects.size(), {
-         {{-0.5f, -0.5f,  0.0f}, {1.0f, 0.0f, 0.0f}, {0.0f, 1.0f}},
-         {{ 0.5f, -0.5f,  0.0f}, {0.0f, 1.0f, 0.0f}, {1.0f, 1.0f}},
-         {{ 0.5f,  0.5f,  0.0f}, {0.0f, 0.0f, 1.0f}, {1.0f, 0.0f}},
-         {{ 0.5f,  0.5f,  0.0f}, {0.0f, 0.0f, 1.0f}, {1.0f, 0.0f}},
-         {{-0.5f,  0.5f,  0.0f}, {1.0f, 1.0f, 1.0f}, {0.0f, 0.0f}},
-         {{-0.5f, -0.5f,  0.0f}, {1.0f, 0.0f, 0.0f}, {0.0f, 1.0f}}
-      }), {
-         0, 1, 2, 3, 4, 5
-      }, {
-         mat4(1.0f)
-      }, false);
+      addObjectIndex<ModelVertex>(modelObjects.size(),
+         addVertexNormals<ModelVertex>({
+            {{-0.5f, -0.5f,  0.0f}, {1.0f, 0.0f, 0.0f}, {0.0f, 1.0f}},
+            {{ 0.5f, -0.5f,  0.0f}, {0.0f, 1.0f, 0.0f}, {1.0f, 1.0f}},
+            {{ 0.5f,  0.5f,  0.0f}, {0.0f, 0.0f, 1.0f}, {1.0f, 0.0f}},
+            {{ 0.5f,  0.5f,  0.0f}, {0.0f, 0.0f, 1.0f}, {1.0f, 0.0f}},
+            {{-0.5f,  0.5f,  0.0f}, {1.0f, 1.0f, 1.0f}, {0.0f, 0.0f}},
+            {{-0.5f, -0.5f,  0.0f}, {1.0f, 0.0f, 0.0f}, {0.0f, 1.0f}}
+         })), {
+            0, 1, 2, 3, 4, 5
+         }, {
+            mat4(1.0f)
+         }, false);
 
    texturedSquare->model_base =
@@ -534,5 +537,5 @@
    }
 
-   window = (SDL_Window*) gui->createWindow("Vulkan Game", width, height, guiFlags & GUI_FLAGS_WINDOW_FULLSCREEN);
+   window = (SDL_Window*)gui->createWindow("Vulkan Game", width, height, guiFlags & GUI_FLAGS_WINDOW_FULLSCREEN);
    if (window == nullptr) {
       cout << "Window could not be created!" << endl;
@@ -703,16 +706,17 @@
                   SceneObject<ModelVertex, SSBO_ModelObject>& texturedSquare =
                      addObject(modelObjects, modelPipeline,
-                        addObjectIndex<ModelVertex>(modelObjects.size(), {
-                           {{-0.5f, -0.5f,  0.0f}, {1.0f, 0.0f, 0.0f}, {0.0f, 1.0f}},
-                           {{ 0.5f, -0.5f,  0.0f}, {0.0f, 1.0f, 0.0f}, {1.0f, 1.0f}},
-                           {{ 0.5f,  0.5f,  0.0f}, {0.0f, 0.0f, 1.0f}, {1.0f, 0.0f}},
-                           {{ 0.5f,  0.5f,  0.0f}, {0.0f, 0.0f, 1.0f}, {1.0f, 0.0f}},
-                           {{-0.5f,  0.5f,  0.0f}, {1.0f, 1.0f, 1.0f}, {0.0f, 0.0f}},
-                           {{-0.5f, -0.5f,  0.0f}, {1.0f, 0.0f, 0.0f}, {0.0f, 1.0f}}
-                        }), {
-                           0, 1, 2, 3, 4, 5
-                        }, {
-                           mat4(1.0f)
-                        }, true);
+                        addObjectIndex<ModelVertex>(modelObjects.size(),
+                           addVertexNormals<ModelVertex>({
+                              {{-0.5f, -0.5f,  0.0f}, {1.0f, 0.0f, 0.0f}, {0.0f, 1.0f}},
+                              {{ 0.5f, -0.5f,  0.0f}, {0.0f, 1.0f, 0.0f}, {1.0f, 1.0f}},
+                              {{ 0.5f,  0.5f,  0.0f}, {0.0f, 0.0f, 1.0f}, {1.0f, 0.0f}},
+                              {{ 0.5f,  0.5f,  0.0f}, {0.0f, 0.0f, 1.0f}, {1.0f, 0.0f}},
+                              {{-0.5f,  0.5f,  0.0f}, {1.0f, 1.0f, 1.0f}, {0.0f, 0.0f}},
+                              {{-0.5f, -0.5f,  0.0f}, {1.0f, 0.0f, 0.0f}, {0.0f, 1.0f}}
+                           })), {
+                              0, 1, 2, 3, 4, 5
+                           }, {
+                              mat4(1.0f)
+                           }, true);
 
                   texturedSquare.model_base =
Index: vulkan-game.hpp
===================================================================
--- vulkan-game.hpp	(revision 914bb995364b78b9b9cef8950e8062ab7384a491)
+++ vulkan-game.hpp	(revision a00eb0672f52310ddbe89f59abd3191cb3c993ed)
@@ -47,4 +47,5 @@
    vec3 color;
    vec2 texCoord;
+   vec3 normal;
    unsigned int objIndex;
 };
