diff --git a/DXCore.h b/DXCore.h
index 534cc1c..4880a06 100644
--- a/DXCore.h
+++ b/DXCore.h
@@ -44,6 +44,13 @@ public:
 	virtual void Update(float deltaTime, float totalTime) = 0;
 	virtual void Draw(float deltaTime, float totalTime) = 0;
 
+	// Helpers for determining the actual path to the executable
+	static std::string GetExePath();
+	static std::wstring GetExePath_Wide();
+
+	static std::string GetFullPathTo(std::string relativeFilePath);
+	static std::wstring GetFullPathTo_Wide(std::wstring relativeFilePath);
+
 protected:
 	HINSTANCE	hInstance;		// The handle to the application
 	HWND		hWnd;			// The handle to the window itself
@@ -70,13 +77,6 @@ protected:
 	// Helper function for allocating a console window
 	void CreateConsoleWindow(int bufferLines, int bufferColumns, int windowLines, int windowColumns);
 
-	// Helpers for determining the actual path to the executable
-	std::string GetExePath();
-	std::wstring GetExePath_Wide();
-
-	std::string GetFullPathTo(std::string relativeFilePath);
-	std::wstring GetFullPathTo_Wide(std::wstring relativeFilePath);
-
 
 private:
 	// Timing related data
diff --git a/Game.cpp b/Game.cpp
index 3cfb69f..1381f94 100644
--- a/Game.cpp
+++ b/Game.cpp
@@ -48,7 +48,6 @@ Game::~Game()
 	// we don't need to explicitly clean up those DirectX objects
 	// - If we weren't using smart pointers, we'd need
 	//   to call Release() on each DirectX object created in Game
-
 }
 
 // --------------------------------------------------------
@@ -57,10 +56,7 @@ Game::~Game()
 // --------------------------------------------------------
 void Game::Init()
 {
-	// Helper methods for loading shaders, creating some basic
-	// geometry to draw and some simple camera matrices.
-	//  - You'll be expanding and/or replacing these later
-	LoadShaders();
+	LoadShadersAndMaterials();
 	LoadTextures();
 	LoadLighting();
 	CreateBasicGeometry();
@@ -72,14 +68,9 @@ void Game::Init()
 }
 
 // --------------------------------------------------------
-// Loads shaders from compiled shader object (.cso) files
-// and also created the Input Layout that describes our 
-// vertex data to the rendering pipeline. 
-// - Input Layout creation is done here because it must 
-//    be verified against vertex shader byte code
-// - We'll have that byte code already loaded below
+// Loads shaders from compiled shader object (.cso) files and pushes them to materials
 // --------------------------------------------------------
-void Game::LoadShaders()
+void Game::LoadShadersAndMaterials()
 {
 	vertexShader = std::make_shared<SimpleVertexShader>(device, context, GetFullPathTo_Wide(L"VertexShader.cso").c_str());
 	pixelShader = std::make_shared<SimplePixelShader>(device, context, GetFullPathTo_Wide(L"SimplePixelShader.cso").c_str());
@@ -92,6 +83,9 @@ void Game::LoadShaders()
 	};
 }
 
+// --------------------------------------------------------
+// Loads textures and pushes them to the loaded materials
+// --------------------------------------------------------
 void Game::LoadTextures()
 {
 	Microsoft::WRL::ComPtr<ID3D11SamplerState> sampler;
@@ -105,76 +99,31 @@ void Game::LoadTextures()
 	sampDesc.MaxLOD = D3D11_FLOAT32_MAX;
 	device->CreateSamplerState(&sampDesc, sampler.GetAddressOf());
 
-	Microsoft::WRL::ComPtr<ID3D11ShaderResourceView>
-		deepFloorEmissive,
-		deepFloorSpecular,
-		deepFloorAlbedo,
-		floorEmissive,
-		floorSpecular,
-		floorAlbedo;
-
-	// taking the preprocessor macro from the demo because I don't like typing
-	#define GetTex(pathToTexture, shaderResourceView) CreateWICTextureFromFile(device.Get(), context.Get(), GetFullPathTo_Wide(pathToTexture).c_str(), 0, shaderResourceView.GetAddressOf());
-
-	GetTex(L"Assets/Textures/HQGame/structure-endgame-deepfloor_emissive.png", deepFloorEmissive);
-	GetTex(L"Assets/Textures/HQGame/structure-endgame-deepfloor_specular.png", deepFloorSpecular);
-	GetTex(L"Assets/Textures/HQGame/structure-endgame-deepfloor_albedo.png", deepFloorAlbedo);
-	GetTex(L"Assets/Textures/HQGame/structure-endgame-floor_emissive.png", floorEmissive);
-	GetTex(L"Assets/Textures/HQGame/structure-endgame-floor_specular.png", floorSpecular);
-	GetTex(L"Assets/Textures/HQGame/structure-endgame-floor_albedo.png", floorAlbedo);
-
 	materials[0]->PushSampler("BasicSampler", sampler);
-	materials[0]->PushTexture("Albedo", deepFloorAlbedo);
-	materials[0]->PushTexture("Specular", deepFloorSpecular);
-	materials[0]->PushTexture("Emissive", deepFloorEmissive);
+	materials[0]->LoadTexture(L"Assets/Textures/HQGame/structure-endgame-deepfloor_albedo.png", TEXTYPE_ALBEDO, device.Get(), context.Get());
+	materials[0]->LoadTexture(L"Assets/Textures/HQGame/structure-endgame-deepfloor_specular.png", TEXTYPE_SPECULAR, device.Get(), context.Get());
+	materials[0]->LoadTexture(L"Assets/Textures/HQGame/structure-endgame-deepfloor_emissive.png", TEXTYPE_EMISSIVE, device.Get(), context.Get());
+
 	materials[1]->PushSampler("BasicSampler", sampler);
-	materials[1]->PushTexture("Albedo", floorAlbedo);
-	materials[1]->PushTexture("Specular", floorSpecular);
-	materials[1]->PushTexture("Emissive", floorEmissive);
+	materials[1]->LoadTexture(L"Assets/Textures/HQGame/structure-endgame-floor_albedo.png", TEXTYPE_ALBEDO, device.Get(), context.Get());
+	materials[1]->LoadTexture(L"Assets/Textures/HQGame/structure-endgame-floor_specular.png", TEXTYPE_SPECULAR, device.Get(), context.Get());
+	materials[1]->LoadTexture(L"Assets/Textures/HQGame/structure-endgame-floor_emissive.png", TEXTYPE_EMISSIVE, device.Get(), context.Get());
 }
 
+// --------------------------------------------------------
+// Instantiates all the lighting in the scene
+// --------------------------------------------------------
 void Game::LoadLighting()
 {
 	ambient = XMFLOAT3(0.1f, 0.1f, 0.15f);
 
-	Light directionalLight0 = {};
-	directionalLight0.Type = LIGHT_TYPE_DIRECTIONAL;
-	directionalLight0.Direction = XMFLOAT3(1, 0.5f, 0.5f);
-	directionalLight0.Color = XMFLOAT3(1, 1, 1);
-	directionalLight0.Intensity = 0.5f;
-
-	Light directionalLight1 = {};
-	directionalLight1.Type = LIGHT_TYPE_DIRECTIONAL;
-	directionalLight1.Direction = XMFLOAT3(-0.25f, -1, 0.75f);
-	directionalLight1.Color = XMFLOAT3(1, 1, 1);
-	directionalLight1.Intensity = 0.5f;
-
-	Light directionalLight2 = {};
-	directionalLight2.Type = LIGHT_TYPE_DIRECTIONAL;
-	directionalLight2.Direction = XMFLOAT3(-1, 1, -0.5f);
-	directionalLight2.Color = XMFLOAT3(1, 1, 1);
-	directionalLight2.Intensity = 0.5f;
-
-	Light pointLight0 = {};
-	pointLight0.Type = LIGHT_TYPE_POINT;
-	pointLight0.Position = XMFLOAT3(-1.5f, 0, 0);
-	pointLight0.Color = XMFLOAT3(1, 1, 1);
-	pointLight0.Intensity = 0.5f;
-	pointLight0.Range = 10;
-
-	Light pointLight1 = {};
-	pointLight1.Type = LIGHT_TYPE_POINT;
-	pointLight1.Position = XMFLOAT3(1.5f, 0, 0);
-	pointLight1.Color = XMFLOAT3(1, 1, 1);
-	pointLight1.Intensity = 0.25f;
-	pointLight1.Range = 10;
-
 	lights = {
-		directionalLight0,
-		directionalLight1,
-		directionalLight2,
-		pointLight0,
-		pointLight1,
+		Light::Directional(XMFLOAT3(1, 0.5f, 0.5f), XMFLOAT3(1, 1, 1), 0.5f),
+		Light::Directional(XMFLOAT3(-0.25f, -1, 0.75f), XMFLOAT3(1, 1, 1), 0.5f),
+		Light::Directional(XMFLOAT3(-1, 1, -0.5f), XMFLOAT3(1, 1, 1), 0.5f),
+		Light::Point(XMFLOAT3(-1.5f, 0, 0), XMFLOAT3(1, 1, 1), 0.5f, 10),
+		Light::Point(XMFLOAT3(1.5f, 0, 0), XMFLOAT3(1, 1, 1), 0.25f, 10),
+		Light::Point(XMFLOAT3(0, 2, 0), XMFLOAT3(1, 0, 0), 0.25f, 10),
 	};
 }
 
@@ -211,7 +160,7 @@ void Game::CreateBasicGeometry()
 		std::make_shared<Entity>(materials[0], shapes[0]),
 		std::make_shared<Entity>(materials[0], shapes[1]),
 		std::make_shared<Entity>(materials[0], shapes[2]),
-		std::make_shared<Entity>(materials[1], shapes[3]),
+		std::make_shared<Entity>(materials[0], shapes[3]),
 		std::make_shared<Entity>(materials[1], shapes[4]),
 		std::make_shared<Entity>(materials[1], shapes[5]),
 		std::make_shared<Entity>(materials[1], shapes[6]),
@@ -220,6 +169,7 @@ void Game::CreateBasicGeometry()
 	for (int i = 0; i < entities.size(); ++i)
 	{
 		entities[i]->GetTransform()->SetPosition((-(int)(entities.size() / 2) + i) * 5, 0, 0);
+		entities[i]->GetMaterial()->SetEmitAmount((entities.size() - i) * 0.25f);
 	}
 }
 
@@ -242,7 +192,6 @@ void Game::OnResize()
 // --------------------------------------------------------
 void Game::Update(float deltaTime, float totalTime)
 {
-	// Example input checking: Quit if the escape key is pressed
 	if (Input::GetInstance().KeyDown(VK_ESCAPE))
 		Quit();
 
@@ -251,10 +200,6 @@ void Game::Update(float deltaTime, float totalTime)
 	for (int i = 0; i < entities.size(); ++i)
 	{
 		entities[i]->GetTransform()->SetRotation(sin(totalTime / 720) * 360, 0, 0);
-		entities[i]->GetMaterial()->SetRoughness(sin(totalTime) * 0.5f + 0.49f);
-		entities[i]->GetMaterial()->SetUVOffset(DirectX::XMFLOAT2(cos(totalTime * 4) * 0.5f + 0.49f, cos(totalTime * 4) * 0.5f + 0.49f));
-		entities[i]->GetMaterial()->SetUVScale(DirectX::XMFLOAT2(sin(totalTime) * 0.5f + 0.49f, sin(totalTime) * 0.5f + 0.49f));
-		entities[i]->GetMaterial()->SetEmitAmount(cos(totalTime) * 0.5f + 0.49f);
 	}
 }
 
diff --git a/Game.h b/Game.h
index b8be745..f62f3f3 100644
--- a/Game.h
+++ b/Game.h
@@ -15,33 +15,23 @@
 class Game 
 	: public DXCore
 {
-
 public:
 	Game(HINSTANCE hInstance);
 	~Game();
 
-	// Overridden setup and game loop methods, which
-	// will be called automatically
 	void Init();
 	void OnResize();
 	void Update(float deltaTime, float totalTime);
 	void Draw(float deltaTime, float totalTime);
 
 private:
-
 	// Should we use vsync to limit the frame rate?
 	bool vsync;
 
-	// Initialization helper methods - feel free to customize, combine, etc.
-	void LoadShaders();
+	void LoadShadersAndMaterials();
 	void LoadTextures();
 	void LoadLighting();
 	void CreateBasicGeometry();
-
-	// Note the usage of ComPtr below
-	//  - This is a smart pointer for objects that abide by the
-	//    Component Object Model, which DirectX objects do
-	//  - More info here: https://github.com/Microsoft/DirectXTK/wiki/ComPtr
 	
 	// Shaders and shader-related constructs
 	std::shared_ptr<SimplePixelShader> pixelShader;
diff --git a/Lights.h b/Lights.h
index 546f6f6..8762f66 100644
--- a/Lights.h
+++ b/Lights.h
@@ -2,9 +2,9 @@
 
 #include <DirectXMath.h>
 
-#define LIGHT_TYPE_DIRECTIONAL	0
-#define LIGHT_TYPE_POINT		1
-#define LIGHT_TYPE_SPOT			2
+constexpr auto LIGHT_TYPE_DIRECTIONAL	= 0;
+constexpr auto LIGHT_TYPE_POINT			= 1;
+constexpr auto LIGHT_TYPE_SPOT			= 2;
 
 struct Light
 {
@@ -16,4 +16,25 @@ struct Light
 	DirectX::XMFLOAT3	Color;
 	float				SpotFalloff;
 	DirectX::XMFLOAT3	Padding;
+
+	static Light Directional(DirectX::XMFLOAT3 _direction, DirectX::XMFLOAT3 _color, float _intensity)
+	{
+		Light light = {};
+		light.Type = LIGHT_TYPE_DIRECTIONAL;
+		light.Direction = _direction;
+		light.Color = _color;
+		light.Intensity = _intensity;
+		return light;
+	};
+
+	static Light Point(DirectX::XMFLOAT3 _position, DirectX::XMFLOAT3 _color, float _intensity, float _range)
+	{
+		Light light = {};
+		light.Type = LIGHT_TYPE_POINT;
+		light.Position = _position;
+		light.Color = _color;
+		light.Intensity = _intensity;
+		light.Range = _range;
+		return light;
+	};
 };
diff --git a/Material.cpp b/Material.cpp
index 25a2bfd..dc99ff6 100644
--- a/Material.cpp
+++ b/Material.cpp
@@ -12,6 +12,7 @@ Material::Material(
 	pixelShader = _pixelShader;
 	uvOffset = DirectX::XMFLOAT2(0, 0);
 	uvScale = DirectX::XMFLOAT2(1, 1);
+	emitAmount = 0;
 }
 
 Material::~Material()
@@ -34,6 +35,7 @@ void Material::Activate(Transform* _transform, std::shared_ptr<Camera> _camera,
 	pixelShader->SetFloat3("ambient", _ambient);
 	pixelShader->SetFloat("emitAmount", GetEmitAmount());
 	pixelShader->SetFloat3("tint", GetTint());
+	pixelShader->SetFloat("lightCount", (int)_lights.size());
 	pixelShader->SetData("lights", &_lights[0], sizeof(Light) * (int)_lights.size());
 	pixelShader->CopyAllBufferData();
 	pixelShader->SetShader();
@@ -129,6 +131,13 @@ void Material::SetPixelShader(std::shared_ptr<SimplePixelShader> _pixelShader)
 	pixelShader = _pixelShader;
 }
 
+void Material::LoadTexture(const wchar_t* _path, const char* _type, ID3D11Device* _device, ID3D11DeviceContext* _context)
+{
+	Microsoft::WRL::ComPtr<ID3D11ShaderResourceView> shaderResourceView;
+	DirectX::CreateWICTextureFromFile(_device, _context, DXCore::GetFullPathTo_Wide(_path).c_str(), 0, shaderResourceView.GetAddressOf());
+	PushTexture(_type, shaderResourceView);
+}
+
 void Material::PushSampler(std::string _name, Microsoft::WRL::ComPtr<ID3D11SamplerState> _sampler)
 {
 	samplers.insert({ _name, _sampler });
diff --git a/Material.h b/Material.h
index c3df313..cdbd90b 100644
--- a/Material.h
+++ b/Material.h
@@ -2,10 +2,17 @@
 
 #include <DirectXMath.h>
 #include <memory>
+#include "DXCore.h"
 #include "SimpleShader.h"
 #include "Transform.h"
 #include "Camera.h"
 #include "Lights.h"
+#include "WICTextureLoader.h"
+
+constexpr auto TEXTYPE_ALBEDO = "Albedo";
+constexpr auto TEXTYPE_NORMAL = "Normal";
+constexpr auto TEXTYPE_EMISSIVE = "Emissive";
+constexpr auto TEXTYPE_SPECULAR = "Specular";
 
 class Material
 {
@@ -39,6 +46,7 @@ public:
 	void									SetVertexShader(std::shared_ptr<SimpleVertexShader> _vertexShader);
 	void									SetPixelShader(std::shared_ptr<SimplePixelShader> _pixelShader);
 
+	void									LoadTexture(const wchar_t* _path, const char* _type, ID3D11Device* _device, ID3D11DeviceContext* _context);
 	void									PushSampler(std::string _name, Microsoft::WRL::ComPtr<ID3D11SamplerState> _sampler);
 	void									PushTexture(std::string _name, Microsoft::WRL::ComPtr<ID3D11ShaderResourceView> _texture);
 
diff --git a/SimplePixelShader.hlsl b/SimplePixelShader.hlsl
index 7fa6b0b..a7c90d2 100644
--- a/SimplePixelShader.hlsl
+++ b/SimplePixelShader.hlsl
@@ -2,19 +2,23 @@
 #include "Helpers.hlsli"
 #include "Lights.hlsli"
 
-// temporary
-#define LIGHT_COUNT 5
+#define MAX_LIGHTS 128
 
 cbuffer ExternalData : register(b0)
 {
 	float3 cameraPosition;
 	float roughness;
+
 	float2 offset;
 	float2 scale;
+
 	float3 ambient;
 	float emitAmount;
+
 	float3 tint;
-	Light lights[LIGHT_COUNT];
+	float lightCount;
+
+	Light lights[MAX_LIGHTS];
 }
 
 Texture2D Albedo : register(t0);
@@ -70,7 +74,7 @@ float4 main(VertexToPixel input) : SV_TARGET
 	float3 light = ambient * surface;
 
 	// loop through lights
-	for (int i = 0; i < LIGHT_COUNT; i++)
+	for (int i = 0; i < lightCount; i++)
 	{
 		switch (lights[i].Type)
 		{