diff --git a/.gitignore b/.gitignore
index 1110510c..5d998cfd 100644
--- a/.gitignore
+++ b/.gitignore
@@ -362,3 +362,5 @@ MigrationBackup/
 *.csproj
 
 *.filters
+
+Assets/Editor/Layouts/UserLayout.ini
diff --git a/Assets/Cube.003.shmesh.shmeta b/Assets/Cube.003.shmesh.shmeta
new file mode 100644
index 00000000..d41be546
--- /dev/null
+++ b/Assets/Cube.003.shmesh.shmeta
@@ -0,0 +1,3 @@
+Name: Cube.003
+ID: 110152941
+Type: 
diff --git a/Assets/Cube.012.shmesh.shmeta b/Assets/Cube.012.shmesh.shmeta
new file mode 100644
index 00000000..d5cd1090
--- /dev/null
+++ b/Assets/Cube.012.shmesh.shmeta
@@ -0,0 +1,3 @@
+Name: Cube.012
+ID: 107348815
+Type: 
diff --git a/Assets/Editor/Layouts/Default.ini b/Assets/Editor/Layouts/Default.ini
new file mode 100644
index 00000000..4ddc46c2
--- /dev/null
+++ b/Assets/Editor/Layouts/Default.ini
@@ -0,0 +1,48 @@
+[Window][MainStatusBar]
+Pos=0,1060
+Size=1920,20
+Collapsed=0
+
+[Window][SHEditorMenuBar]
+Pos=0,24
+Size=1920,1036
+Collapsed=0
+
+[Window][Hierarchy Panel]
+Pos=0,120
+Size=225,940
+Collapsed=0
+DockId=0x00000004,0
+
+[Window][Debug##Default]
+Pos=60,60
+Size=400,400
+Collapsed=0
+
+[Window][Inspector]
+Pos=1686,24
+Size=234,1036
+Collapsed=0
+DockId=0x00000006,0
+
+[Window][Profiler]
+Pos=0,24
+Size=225,94
+Collapsed=0
+DockId=0x00000003,0
+
+[Window][Viewport]
+Pos=227,24
+Size=1457,1036
+Collapsed=0
+DockId=0x00000002,0
+
+[Docking][Data]
+DockSpace       ID=0xC5C9B8AB Window=0xBE4044E9 Pos=8,55 Size=1920,1036 Split=X
+  DockNode      ID=0x00000005 Parent=0xC5C9B8AB SizeRef=1684,1036 Split=X
+    DockNode    ID=0x00000001 Parent=0x00000005 SizeRef=225,1036 Split=Y Selected=0x1E6EB881
+      DockNode  ID=0x00000003 Parent=0x00000001 SizeRef=225,94 Selected=0x1E6EB881
+      DockNode  ID=0x00000004 Parent=0x00000001 SizeRef=225,940 Selected=0xE096E5AE
+    DockNode    ID=0x00000002 Parent=0x00000005 SizeRef=1293,1036 CentralNode=1 Selected=0x13926F0B
+  DockNode      ID=0x00000006 Parent=0xC5C9B8AB SizeRef=234,1036 Selected=0xE7039252
+
diff --git a/Assets/RaccoonPreTexturedVer1_Base9.shtex.shmeta b/Assets/RaccoonPreTexturedVer1_Base9.shtex.shmeta
new file mode 100644
index 00000000..f8c267d9
--- /dev/null
+++ b/Assets/RaccoonPreTexturedVer1_Base9.shtex.shmeta
@@ -0,0 +1,3 @@
+Name: RaccoonPreTexturedVer1_Base9
+ID: 91918845
+Type: 
diff --git a/SHADE_Application/src/Application/SBApplication.cpp b/SHADE_Application/src/Application/SBApplication.cpp
index 202a3852..2d21be3f 100644
--- a/SHADE_Application/src/Application/SBApplication.cpp
+++ b/SHADE_Application/src/Application/SBApplication.cpp
@@ -104,10 +104,10 @@ namespace Sandbox
 
     //TODO: REMOVE AFTER PRESENTATION
     //SHAssetManager::LoadDataTemp("../../Assets/racoon.gltf");
-    SHAssetManager::LoadDataTemp("../../Assets/Cube.012.shmesh");
+    //SHAssetManager::LoadDataTemp("../../Assets/Cube.012.shmesh");
     //SHAssetManager::LoadDataTemp("../../Assets/RaccoonBag_Color_Ver4.dds");
     //SHAssetManager::LoadDataTemp("../../Assets/RaccoonPreTexturedVer1_Base9.dds");
-    SHAssetManager::LoadDataTemp("../../Assets/RaccoonPreTexturedVer1_Base9.shtex");
+    //SHAssetManager::LoadDataTemp("../../Assets/RaccoonPreTexturedVer1_Base9.shtex");
     //TODO: REMOVE AFTER PRESENTATION
 
 
@@ -125,19 +125,26 @@ namespace Sandbox
     SHSceneManager::InitSceneManager<SBTestScene>("TestScene");
     
     SHFrameRateController::UpdateFRC();
+
+    SHAssetManager::Load();
   }
 
   void SBApplication::Update(void)
   {
     SHGraphicsSystem* graphicsSystem = SHADE::SHSystemManager::GetSystem<SHGraphicsSystem>();
+    SHEditor* editor = SHADE::SHSystemManager::GetSystem<SHEditor>();
     //TODO: Change true to window is open
     while (!window.WindowShouldClose())
     {
       SHFrameRateController::UpdateFRC();
       SHInputManager::UpdateInput(SHFrameRateController::GetRawDeltaTime());
       SHSceneManager::UpdateSceneManager();
-      SHSceneManager::SceneUpdate(0.016f); 
-      SHSystemManager::RunRoutines(false, 0.016f);
+#ifdef SHEDITOR
+      if(editor->editorState == SHEditor::State::PLAY)
+        SHSceneManager::SceneUpdate(0.016f);
+#endif
+      SHSystemManager::RunRoutines(editor->editorState != SHEditor::State::PLAY, 0.016f);
+      editor->PollPicking();
     }
 
     // Finish all graphics jobs first
@@ -154,6 +161,7 @@ namespace Sandbox
 
     SHSceneManager::Exit();
     SHSystemManager::Exit();
+    SHAssetManager::Unload();
   }
 }
 
diff --git a/SHADE_Engine/src/Assets/Asset Types/SHTextureAsset.h b/SHADE_Engine/src/Assets/Asset Types/SHTextureAsset.h
index 07cebea9..d24b6c02 100644
--- a/SHADE_Engine/src/Assets/Asset Types/SHTextureAsset.h	
+++ b/SHADE_Engine/src/Assets/Asset Types/SHTextureAsset.h	
@@ -9,6 +9,7 @@ namespace SHADE
 	{
 		bool compiled;
 
+		std::string name;
 		uint32_t numBytes;
 		uint32_t width;
 		uint32_t height;
diff --git a/SHADE_Engine/src/Assets/Libraries/SHMeshCompiler.cpp b/SHADE_Engine/src/Assets/Libraries/SHMeshCompiler.cpp
index 12b2517e..8026f0e1 100644
--- a/SHADE_Engine/src/Assets/Libraries/SHMeshCompiler.cpp
+++ b/SHADE_Engine/src/Assets/Libraries/SHMeshCompiler.cpp
@@ -16,7 +16,7 @@
 
 #include <fstream>
 
-void SHADE::SHMeshCompiler::CompileMeshBinary(SHMeshAsset const& asset, AssetPath path) noexcept
+std::string SHADE::SHMeshCompiler::CompileMeshBinary(SHMeshAsset const& asset, AssetPath path) noexcept
 {
 	std::string newPath{ path.string() };
 	newPath = newPath.substr(0, newPath.find_last_of('/') + 1);
@@ -67,4 +67,6 @@ void SHADE::SHMeshCompiler::CompileMeshBinary(SHMeshAsset const& asset, AssetPat
 	);
 
 	file.close();
+
+	return newPath;
 }
diff --git a/SHADE_Engine/src/Assets/Libraries/SHMeshCompiler.h b/SHADE_Engine/src/Assets/Libraries/SHMeshCompiler.h
index 6da00525..a8ce67be 100644
--- a/SHADE_Engine/src/Assets/Libraries/SHMeshCompiler.h
+++ b/SHADE_Engine/src/Assets/Libraries/SHMeshCompiler.h
@@ -21,6 +21,6 @@ namespace SHADE
 	{
 	private:
 	public:
-		static void CompileMeshBinary(SHMeshAsset const& asset, AssetPath path) noexcept;
+		static std::string CompileMeshBinary(SHMeshAsset const& asset, AssetPath path) noexcept;
 	};
 }
\ No newline at end of file
diff --git a/SHADE_Engine/src/Assets/Libraries/SHMeshLoader.cpp b/SHADE_Engine/src/Assets/Libraries/SHMeshLoader.cpp
index 3a5fb9ec..4bfa2d9b 100644
--- a/SHADE_Engine/src/Assets/Libraries/SHMeshLoader.cpp
+++ b/SHADE_Engine/src/Assets/Libraries/SHMeshLoader.cpp
@@ -142,8 +142,7 @@ namespace SHADE
       SHLOG_ERROR("Unable to open SHMesh File: {}", path.string());
     }
 
-    std::string name{ path.filename().string() };
-    name = name.substr(0, name.find_last_of('.'));
+    const std::string name{ path.stem().string() };
 
     file.seekg(0);
 
diff --git a/SHADE_Engine/src/Assets/Libraries/SHMeshLoader.h b/SHADE_Engine/src/Assets/Libraries/SHMeshLoader.h
index 3e430aca..a27d63ea 100644
--- a/SHADE_Engine/src/Assets/Libraries/SHMeshLoader.h
+++ b/SHADE_Engine/src/Assets/Libraries/SHMeshLoader.h
@@ -29,8 +29,8 @@ namespace SHADE
 
 		static void LoadExternal(std::vector<SHMeshAsset>& meshes, AssetPath path) noexcept;
 
-		static void LoadSHMesh(SHMeshAsset& meshes, AssetPath path) noexcept;
 	public:
 		static void LoadMesh(std::vector<SHMeshAsset>& meshes, AssetPath path) noexcept;
+		static void LoadSHMesh(SHMeshAsset& meshes, AssetPath path) noexcept;
 	};
 }
\ No newline at end of file
diff --git a/SHADE_Engine/src/Assets/Libraries/SHTextureCompiler.cpp b/SHADE_Engine/src/Assets/Libraries/SHTextureCompiler.cpp
index 62af4da6..49de6b5c 100644
--- a/SHADE_Engine/src/Assets/Libraries/SHTextureCompiler.cpp
+++ b/SHADE_Engine/src/Assets/Libraries/SHTextureCompiler.cpp
@@ -17,7 +17,7 @@
 
 namespace SHADE
 {
-	void SHTextureCompiler::CompileTextureBinary(SHTextureAsset const& asset, AssetPath path)
+	std::string SHTextureCompiler::CompileTextureBinary(SHTextureAsset const& asset, AssetPath path)
 	{
 		std::string newPath{ path.string() };
 		newPath = newPath.substr(0, newPath.find_last_of('.'));
@@ -69,5 +69,7 @@ namespace SHADE
 		);
 
 		file.close();
+
+		return newPath;
 	}
 }
diff --git a/SHADE_Engine/src/Assets/Libraries/SHTextureCompiler.h b/SHADE_Engine/src/Assets/Libraries/SHTextureCompiler.h
index d8685795..52980084 100644
--- a/SHADE_Engine/src/Assets/Libraries/SHTextureCompiler.h
+++ b/SHADE_Engine/src/Assets/Libraries/SHTextureCompiler.h
@@ -19,6 +19,6 @@ namespace SHADE
 {
 	struct SHTextureCompiler
 	{
-		static void CompileTextureBinary(SHTextureAsset const& asset, AssetPath path);
+		static std::string CompileTextureBinary(SHTextureAsset const& asset, AssetPath path);
 	};
 }
\ No newline at end of file
diff --git a/SHADE_Engine/src/Assets/Libraries/SHTextureLoader.cpp b/SHADE_Engine/src/Assets/Libraries/SHTextureLoader.cpp
index 47501d42..5147562a 100644
--- a/SHADE_Engine/src/Assets/Libraries/SHTextureLoader.cpp
+++ b/SHADE_Engine/src/Assets/Libraries/SHTextureLoader.cpp
@@ -93,6 +93,7 @@ namespace SHADE
 		std::memcpy(pixel, file.GetImageData()->m_mem, totalBytes);
 		//pixel = std::move(reinterpret_cast<SHTexture::PixelChannel const*>(file.GetDDSData()));
 
+		asset.name = path.stem().string();
 		asset.compiled = false;
 		asset.numBytes = static_cast<uint32_t>(totalBytes);
 		asset.width = file.GetWidth();
diff --git a/SHADE_Engine/src/Assets/Libraries/SHTextureLoader.h b/SHADE_Engine/src/Assets/Libraries/SHTextureLoader.h
index e84fe5cf..eb61ea91 100644
--- a/SHADE_Engine/src/Assets/Libraries/SHTextureLoader.h
+++ b/SHADE_Engine/src/Assets/Libraries/SHTextureLoader.h
@@ -26,8 +26,8 @@ namespace SHADE
 
 
 		static void LoadTinyDDS(AssetPath path, SHTextureAsset& asset) noexcept;
-		static void LoadSHTexture(AssetPath path, SHTextureAsset& asset) noexcept;
 	public:
 		static void LoadImageAsset(AssetPath paths, SHTextureAsset& image);
+		static void LoadSHTexture(AssetPath path, SHTextureAsset& asset) noexcept;
 	};
 }
diff --git a/SHADE_Engine/src/Assets/SHAssetMacros.h b/SHADE_Engine/src/Assets/SHAssetMacros.h
index 8c462af7..61c5879d 100644
--- a/SHADE_Engine/src/Assets/SHAssetMacros.h
+++ b/SHADE_Engine/src/Assets/SHAssetMacros.h
@@ -40,7 +40,7 @@ typedef FMOD::Sound*					SHSound;
 #define ASSET_META_VER "1.0"
 
 // Asset type enum
-enum class AssetType : uint8_t
+enum class AssetType : AssetTypeMeta
 {
 	INVALID = 0,
 	AUDIO = 1,
@@ -57,7 +57,12 @@ enum class AssetType : uint8_t
 };
 
 //Directory
-#define ASSET_ROOT "./Assets/"
+#ifdef _PUBLISH
+#define ASSET_ROOT "Assets"
+#else
+#define ASSET_ROOT "../../Assets"
+#endif
+
 
 // ASSET EXTENSIONS
 #define META_EXTENSION ".shmeta"
diff --git a/SHADE_Engine/src/Assets/SHAssetManager.cpp b/SHADE_Engine/src/Assets/SHAssetManager.cpp
index 430b8c79..aa9772dd 100644
--- a/SHADE_Engine/src/Assets/SHAssetManager.cpp
+++ b/SHADE_Engine/src/Assets/SHAssetManager.cpp
@@ -255,6 +255,26 @@ namespace SHADE
 		return result;
 	}
 
+	SHMeshAsset const* SHAssetManager::GetMesh(AssetID id) noexcept
+	{
+		if (meshCollection.find(id) == meshCollection.end())
+		{
+			return nullptr;
+		}
+
+		return &meshCollection[id];
+	}
+
+	SHTextureAsset const* SHAssetManager::GetTexture(AssetID id) noexcept
+	{
+		if (textureCollection.find(id) == textureCollection.end())
+		{
+			return nullptr;
+		}
+
+		return &textureCollection[id];
+	}
+
 	/****************************************************************************
 	 * \param   Path for meta data file
 	 * \param   Path for asset file
@@ -307,12 +327,22 @@ namespace SHADE
 
 		for (auto const& mesh : meshes)
 		{
-			meshCollection.emplace(GenerateAssetID(AssetType::MESH), mesh);
+			auto id{ GenerateAssetID(AssetType::MESH) };
+			meshCollection.emplace(id, mesh);
 
+			AssetPath path;
 			if (!mesh.compiled)
 			{
-				SHMeshCompiler::CompileMeshBinary(mesh, asset.path);
+				path = SHMeshCompiler::CompileMeshBinary(mesh, asset.path);
 			}
+			
+			assetCollection.emplace_back(
+				mesh.header.meshName,
+				id,
+				AssetType::MESH,
+				path,
+				0
+			);
 		}
 	}
 
@@ -322,11 +352,20 @@ namespace SHADE
 
 		SHTextureLoader::LoadImageAsset(asset.path, image);
 
-		textureCollection.emplace(GenerateAssetID(AssetType::DDS), image);
-
 		if (!image.compiled)
 		{
-			SHTextureCompiler::CompileTextureBinary(image, asset.path);
+			auto id{ GenerateAssetID(AssetType::TEXTURE) };
+			textureCollection.emplace(id, image);
+
+			auto path{ SHTextureCompiler::CompileTextureBinary(image, asset.path) };
+
+			assetCollection.emplace_back(
+				image.name,
+				id,
+				AssetType::TEXTURE,
+				path,
+				0
+			);
 		}
 	}
 
@@ -344,8 +383,24 @@ namespace SHADE
 	****************************************************************************/
 	void SHAssetManager::LoadAllData() noexcept
 	{
+		//TODO Remove when on demand loading is done
 		for (auto const& asset : assetCollection)
 		{
+			switch (asset.type)
+			{
+			case AssetType::MESH:
+				meshCollection.emplace(asset.id, SHMeshAsset());
+				SHMeshLoader::LoadSHMesh(meshCollection[asset.id], asset.path);
+				break;
+
+			case AssetType::TEXTURE:
+				textureCollection.emplace(asset.id, SHTextureAsset());
+				SHTextureLoader::LoadSHTexture(asset.path, textureCollection[asset.id]);
+				break;
+
+			default:
+				void;
+			}
 		}
 	}
 
@@ -362,40 +417,51 @@ namespace SHADE
 		std::vector<AssetPath> metaFiles;
 		std::vector<AssetPath> AssetFiles;
 
-		//TODO: Write new function for file manager to loop through all files
-		SHFileSystem::StartupFillDirectories(ASSET_ROOT);
-		FolderPointer rootFolder = SHFileSystem::GetRoot();
-
-		for (auto const& meta : metaFiles)
+		for (auto const dir : std::filesystem::recursive_directory_iterator(ASSET_ROOT))
 		{
-			for (std::vector<AssetPath>::const_iterator it{ AssetFiles.cbegin() };
-				it != AssetFiles.cend();
-				++it)
+			if (dir.path().extension().string() == META_EXTENSION)
 			{
-				// Asset exists for meta file
-				std::string fileExtCheck{ it->filename().string() };
-				fileExtCheck += META_EXTENSION;
-				if (meta.filename().string() == fileExtCheck)
-				{
-					RegisterAsset(meta, *it);
-					AssetFiles.erase(it);
-					break;
-				}
+				auto meta{ SHAssetMetaHandler::RetrieveMetaData(dir.path()) };
+
+				assetCollection.push_back(meta);
+				assetRegistry.emplace(meta.id, meta);
 			}
 		}
 
+		//TODO: Write new function for file manager to loop through all files
+		//SHFileSystem::StartupFillDirectories(ASSET_ROOT);
+		//FolderPointer rootFolder = SHFileSystem::GetRoot();
+
+		//for (auto const& meta : metaFiles)
+		//{
+		//	for (std::vector<AssetPath>::const_iterator it{ AssetFiles.cbegin() };
+		//		it != AssetFiles.cend();
+		//		++it)
+		//	{
+		//		// Asset exists for meta file
+		//		std::string fileExtCheck{ it->filename().string() };
+		//		fileExtCheck += META_EXTENSION;
+		//		if (meta.filename().string() == fileExtCheck)
+		//		{
+		//			RegisterAsset(meta, *it);
+		//			AssetFiles.erase(it);
+		//			break;
+		//		}
+		//	}
+		//}
+
 		//TODO: Handle if meta does not match all assets (if meta exist and asset doesnt, vice versa)
-		for (auto const& file : AssetFiles)
-		{
-			if (IsRecognised(file.extension().string().c_str()))
-			{
-				SHAssetMetaHandler::WriteMetaData(RegisterAssetNew(file));
-			}
-			else
-			{
-				std::cout << "Unsupported File Format: " << file.filename() << "\n";
-			}
-		}
+		//for (auto const& file : AssetFiles)
+		//{
+		//	if (IsRecognised(file.extension().string().c_str()))
+		//	{
+		//		SHAssetMetaHandler::WriteMetaData(RegisterAssetNew(file));
+		//	}
+		//	else
+		//	{
+		//		std::cout << "Unsupported File Format: " << file.filename() << "\n";
+		//	}
+		//}
 	}
 
 	AssetID SHAssetManager::RetrieveAsset(char const* path) noexcept
diff --git a/SHADE_Engine/src/Assets/SHAssetManager.h b/SHADE_Engine/src/Assets/SHAssetManager.h
index 7064d63d..50549e01 100644
--- a/SHADE_Engine/src/Assets/SHAssetManager.h
+++ b/SHADE_Engine/src/Assets/SHAssetManager.h
@@ -75,6 +75,8 @@ namespace SHADE
 		static std::vector<SHMeshAsset> GetAllMeshes() noexcept;
 		static std::vector<SHTextureAsset> GetAllTextures() noexcept;
 
+		static SHMeshAsset const* GetMesh(AssetID id) noexcept;
+		static SHTextureAsset const* GetTexture(AssetID id) noexcept;
 	private:
 		/****************************************************************************
 		 * \brief   Load resource data into memory
diff --git a/SHADE_Engine/src/Assets/SHAssetMetaHandler.cpp b/SHADE_Engine/src/Assets/SHAssetMetaHandler.cpp
index 6554a3e4..442c3d96 100644
--- a/SHADE_Engine/src/Assets/SHAssetMetaHandler.cpp
+++ b/SHADE_Engine/src/Assets/SHAssetMetaHandler.cpp
@@ -72,6 +72,13 @@ namespace SHADE
 		std::string line;
 		SHAsset meta;
 
+		// Get resource name
+		GetFieldValue(metaFile, line);
+		std::stringstream nameStream{ line };
+		AssetName name;
+		nameStream >> name;
+		meta.name = name;
+
 		// Get resource id
 		GetFieldValue(metaFile, line);
 		std::stringstream idStream{ line };
@@ -88,6 +95,8 @@ namespace SHADE
 
 		metaFile.close();
 
+		meta.path = path.parent_path().string() + "/" + path.stem().string();
+
 		return meta;
 	}
 
@@ -103,7 +112,7 @@ namespace SHADE
 		std::string path{ meta.path.string() };
 		path.append(META_EXTENSION);
 
-		std::ofstream metaFile{ path, std::ios_base::out };
+		std::ofstream metaFile{ path, std::ios_base::out | std::ios_base::trunc };
 
 		if (!metaFile.is_open())
 		{
@@ -113,17 +122,17 @@ namespace SHADE
 
 		metaFile << "Name: " << meta.name << "\n";
 		metaFile << "ID: " << meta.id << "\n";
-		metaFile << "Type: " << static_cast<int>(meta.type) << std::endl;
+		metaFile << "Type: " << static_cast<AssetTypeMeta>(meta.type) << std::endl;
 
-		//TODO Add in information that is specific to types like mesh
-		switch(meta.type)
-		{
-		case AssetType::MESH:
-			break;
+		////TODO Add in information that is specific to types like mesh
+		//switch(meta.type)
+		//{
+		//case AssetType::MESH:
+		//	break;
 
-		default:
-			break;
-		}
+		//default:
+		//	break;
+		//}
 
 		metaFile.close();
 	}
diff --git a/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.cpp b/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.cpp
index 0f25175f..42c9da66 100644
--- a/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.cpp
+++ b/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.cpp
@@ -66,8 +66,8 @@ namespace SHADE
           editor->selectedEntities.clear();
       }
       ImGui::SeparatorEx(ImGuiSeparatorFlags_Horizontal);
-      ImGui::End();
     }
+    ImGui::End();
   }
 
   void SHHierarchyPanel::Exit()
@@ -75,6 +75,11 @@ namespace SHADE
     SHEditorWindow::Exit();
   }
 
+  void SHHierarchyPanel::SetScrollTo(EntityID eid)
+  {
+    scrollTo = eid;
+  }
+
   //#==============================================================#
   //||                  Private Member Functions                  ||
   //#==============================================================#
@@ -82,7 +87,20 @@ namespace SHADE
   {
     if (ImGui::BeginMenuBar())
     {
-      if (ImGui::SmallButton(ICON_MD_ADD))
+      
+      ImGui::SetCursorPosX(ImGui::GetContentRegionAvail().x - 35.0f);
+      if(ImGui::SmallButton(ICON_MD_DESELECT))
+      {
+        auto editor = SHSystemManager::GetSystem<SHEditor>();
+        editor->selectedEntities.clear();
+      }
+      if (ImGui::IsItemHovered())
+      {
+        ImGui::BeginTooltip();
+        ImGui::Text("Clear Selections");
+        ImGui::EndTooltip();
+      }
+      if (ImGui::SmallButton(ICON_MD_ADD_CIRCLE))
       {
         SHEntityManager::CreateEntity();
       }
@@ -103,6 +121,13 @@ namespace SHADE
     //Get node data (Children, eid, selected)
     auto& children = currentNode->GetChildren();
     EntityID eid = currentNode->GetEntityID();
+
+    if(scrollTo != MAX_EID && eid == scrollTo)
+    {
+      ImGui::SetScrollHereY();
+      scrollTo = MAX_EID;
+    }
+
     auto editor = SHSystemManager::GetSystem<SHEditor>();
 
     const bool isSelected = (std::ranges::find(editor->selectedEntities, eid) != editor->selectedEntities.end());
@@ -157,7 +182,7 @@ namespace SHADE
       }
       ImGui::EndPopup();
     }
-
+    
     //Handle node selection
     if (ImGui::IsItemHovered())
     {
diff --git a/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.h b/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.h
index 78e445fd..88983ca9 100644
--- a/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.h
+++ b/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.h
@@ -23,11 +23,13 @@ namespace SHADE
     void Init() override;
     void Update() override;
     void Exit() override;
+    void SetScrollTo(EntityID eid);
   private:
     void DrawMenuBar() const noexcept;
     ImRect RecursivelyDrawEntityNode(SHSceneNode*);
     void CreateChildEntity(EntityID parentEID) const noexcept;
     std::string filter;
     bool isAnyNodeSelected = false;
+    EntityID scrollTo = MAX_EID;
   };//class SHHierarchyPanel
 }//namespace SHADE
diff --git a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp
index 77ec5b03..47fec730 100644
--- a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp
+++ b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp
@@ -46,8 +46,8 @@ namespace SHADE
   {
     if (!component)
       return;
-    auto componentType = rttr::type::get<T>();
-    CheckBox("##IsActive", [component]() {return component->isActive; }, [component](bool const& active) {component->isActive = active; });
+    const auto componentType = rttr::type::get(*component);
+    SHEditorWidgets::CheckBox("##IsActive", [component]() {return component->isActive; }, [component](bool const& active) {component->isActive = active; });
     ImGui::SameLine();
     if (ImGui::CollapsingHeader(componentType.get_name().data()))
     {
@@ -207,8 +207,10 @@ namespace SHADE
       auto& colliders = component->GetColliders();
       int const size = static_cast<int>(colliders.size());
       ImGui::BeginChild("Colliders", {0.0f,  colliders.empty() ? 1.0f : 250.0f}, true);
+      std::optional<int> colliderToDelete{std::nullopt};
       for (int i{}; i < size; ++i)
       {
+        ImGui::PushID(i);
         SHCollider& collider = component->GetCollider(i);
         auto cursorPos = ImGui::GetCursorPos();
 
@@ -235,9 +237,14 @@ namespace SHADE
         }
         if(ImGui::Button(std::format("{} Remove Collider #{}", ICON_MD_REMOVE, i).data()))
         {
-          component->RemoveCollider(i);
+          colliderToDelete = i;
         }
         SHEditorWidgets::EndPanel();
+        ImGui::PopID();
+      }
+      if(colliderToDelete.has_value())
+      {
+        component->RemoveCollider(colliderToDelete.value());
       }
       ImGui::EndChild();
 
diff --git a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp
index a9b1c724..da09f345 100644
--- a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp
+++ b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp
@@ -99,8 +99,8 @@ namespace SHADE
         }
 
       }
-      ImGui::End();
     }
+    ImGui::End();
   }
 
   void SHEditorInspector::Exit()
diff --git a/SHADE_Engine/src/Editor/EditorWindow/MenuBar/SHEditorMenuBar.cpp b/SHADE_Engine/src/Editor/EditorWindow/MenuBar/SHEditorMenuBar.cpp
index a49af994..3cb6561d 100644
--- a/SHADE_Engine/src/Editor/EditorWindow/MenuBar/SHEditorMenuBar.cpp
+++ b/SHADE_Engine/src/Editor/EditorWindow/MenuBar/SHEditorMenuBar.cpp
@@ -36,6 +36,11 @@ namespace SHADE
   void SHEditorMenuBar::Init()
   {
     SHEditorWindow::Init();
+    constexpr std::string_view path = "../../Assets/Editor/Layouts";
+    for(auto const& entry : std::filesystem::directory_iterator(path))
+    {
+      layoutPaths.push_back(entry.path());
+    }
   }
 
   void SHEditorMenuBar::Update()
@@ -87,20 +92,6 @@ namespace SHADE
           ImGui::EndDisabled();
           ImGui::EndMenu();
         }
-        if(ImGui::BeginMenu("Theme"))
-        {
-          auto styles = rttr::type::get<SHEditor::Style>().get_enumeration();
-          auto values = styles.get_values();
-          for (auto style : values)
-          {
-            if(ImGui::Selectable(style.to_string().c_str()))
-            {
-              if(auto editor = SHSystemManager::GetSystem<SHEditor>())
-                editor->SetStyle(style.convert<SHEditor::Style>());
-            }
-          }
-          ImGui::EndMenu();
-        }
         if (ImGui::BeginMenu("Scripts"))
         {
           if (ImGui::Selectable("Generate Visual Studio Project"))
@@ -120,18 +111,79 @@ namespace SHADE
           }
           ImGui::EndMenu();
         }
+
+        if (ImGui::BeginMenu("Window"))
+        {
+          for (const auto& window : SHEditorWindowManager::editorWindows | std::views::values)
+          {
+            if (window.get() != this)
+              ImGui::Checkbox(window->windowName.data(), &window->isOpen);
+          }
+          ImGui::EndMenu();
+        }
+        if (ImGui::BeginMenu("Theme"))
+        {
+          const auto styles = rttr::type::get<SHEditor::Style>().get_enumeration();
+          auto values = styles.get_values();
+          for (auto style : values)
+          {
+            if (ImGui::Selectable(style.to_string().c_str()))
+            {
+              if (auto editor = SHSystemManager::GetSystem<SHEditor>())
+                editor->SetStyle(style.convert<SHEditor::Style>());
+            }
+          }
+          ImGui::EndMenu();
+        }
+        if(ImGui::BeginMenu("Layout"))
+        {
+          for(auto const& entry : layoutPaths)
+          {
+            if(ImGui::Selectable(entry.stem().string().c_str()))
+            {
+              ImGui::LoadIniSettingsFromDisk(entry.string().c_str());
+            }
+          }
+          ImGui::EndMenu();
+        }
         ImGui::EndMainMenuBar();
       }
 
-      const ImGuiID dockspace_id = ImGui::GetID("DockSpace");
-      ImGui::DockSpace(dockspace_id, ImVec2(0.0f, 0.0f), dockspaceFlags);
+      const ImGuiID dockspaceId = ImGui::GetID("DockSpace");
+      ImGui::DockSpace(dockspaceId, ImVec2(0.0f, 0.0f), dockspaceFlags);
       ImGui::End();
     }
   }
 
   void SHEditorMenuBar::DrawSecondaryBar() const noexcept
   {
-
+    ImGuiViewport* viewport = ImGui::GetMainViewport();
+    if(ImGui::BeginViewportSideBar("##SecondaryMenuBar", viewport, ImGuiDir_Up, ImGui::GetFrameHeight(), ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoNav | ImGuiWindowFlags_MenuBar))
+    {
+      ImGui::BeginMenuBar();
+      ImGui::SetCursorPosX(ImGui::GetContentRegionAvail().x * 0.5f - 80.f);
+      const auto editor = SHSystemManager::GetSystem<SHEditor>();
+      ImGui::BeginDisabled(editor->editorState == SHEditor::State::PLAY);
+      if(ImGui::SmallButton(ICON_MD_PLAY_ARROW))
+      {
+        editor->editorState = SHEditor::State::PLAY;
+      }
+      ImGui::EndDisabled();
+      ImGui::BeginDisabled(editor->editorState == SHEditor::State::PAUSE);
+      if(ImGui::SmallButton(ICON_MD_PAUSE))
+      {
+        editor->editorState = SHEditor::State::PAUSE;
+      }
+      ImGui::EndDisabled();
+      ImGui::BeginDisabled(editor->editorState == SHEditor::State::STOP);
+      if(ImGui::SmallButton(ICON_MD_STOP))
+      {
+        editor->editorState = SHEditor::State::STOP;
+      }
+      ImGui::EndDisabled();
+      ImGui::EndMenuBar();
+    }
+    ImGui::End();
   }
 
   void SHEditorMenuBar::DrawStatusBar() const noexcept
@@ -142,8 +194,8 @@ namespace SHADE
     if (ImGui::BeginViewportSideBar("MainStatusBar", ImGui::GetMainViewport(), ImGuiDir_Down, menuBarHeight, editorMenuBarFlags))
     {
       ImGui::Text("Entity count: ");
-      ImGui::End();
     }
+    ImGui::End();
     ImGui::PopStyleVar(3);
 
   }
diff --git a/SHADE_Engine/src/Editor/EditorWindow/MenuBar/SHEditorMenuBar.h b/SHADE_Engine/src/Editor/EditorWindow/MenuBar/SHEditorMenuBar.h
index 616ba43e..7cbcd696 100644
--- a/SHADE_Engine/src/Editor/EditorWindow/MenuBar/SHEditorMenuBar.h
+++ b/SHADE_Engine/src/Editor/EditorWindow/MenuBar/SHEditorMenuBar.h
@@ -18,5 +18,6 @@ namespace SHADE
     void DrawSecondaryBar() const noexcept;
     void DrawStatusBar() const noexcept;
     float menuBarHeight = 20.0f;
+    std::vector<std::filesystem::path> layoutPaths;
   };//class SHEditorMenuBar
 }//namespace SHADE
\ No newline at end of file
diff --git a/SHADE_Engine/src/Editor/EditorWindow/Profiling/SHEditorProfiler.cpp b/SHADE_Engine/src/Editor/EditorWindow/Profiling/SHEditorProfiler.cpp
index 4b36fe5d..ef2ff8c0 100644
--- a/SHADE_Engine/src/Editor/EditorWindow/Profiling/SHEditorProfiler.cpp
+++ b/SHADE_Engine/src/Editor/EditorWindow/Profiling/SHEditorProfiler.cpp
@@ -37,8 +37,8 @@ namespace SHADE
     if(Begin())
     {
       ImGui::PlotLines("DT", frames.data(), static_cast<int>(frames.size()), 0, nullptr, 0.0f, 16.0f);
-      ImGui::End();
     }
+    ImGui::End();
   }
 
   void SHEditorProfiler::Exit()
diff --git a/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindow.cpp b/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindow.cpp
index 2e2c820c..edbe0faa 100644
--- a/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindow.cpp
+++ b/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindow.cpp
@@ -19,7 +19,7 @@ namespace SHADE
 //||                  Public Member Functions                   ||
 //#==============================================================#
   SHEditorWindow::SHEditorWindow(std::string_view const& name, ImGuiWindowFlags const& inFlags)
-    : isOpen(true), windowName(name), windowFlags(inFlags), io(ImGui::GetIO())
+    : windowName(name), windowFlags(inFlags), io(ImGui::GetIO())
   {
   }
 
@@ -40,7 +40,30 @@ namespace SHADE
   //#==============================================================#
   bool SHEditorWindow::Begin()
   {
-    return ImGui::Begin(windowName.data(), &isOpen, windowFlags);
+    bool result = ImGui::Begin(windowName.data(), &isOpen, windowFlags);
+
+    auto wndSize = ImGui::GetWindowSize();
+    if(windowSize.x != wndSize.x || windowSize.y != wndSize.y)
+    {
+      windowSize = {wndSize.x, wndSize.y};
+      OnResize();
+    }
+    auto wndPos = ImGui::GetWindowPos();
+    if(windowPos.x != wndPos.x || windowPos.y != wndPos.y)
+    {
+      windowPos = {wndPos.x, wndPos.y};
+      OnPosChange();
+    }
+    isWindowHovered = ImGui::IsWindowHovered();
+    return result;
+  }
+
+  void SHEditorWindow::OnResize()
+  {
+  }
+
+  void SHEditorWindow::OnPosChange()
+  {
   }
 }//namespace SHADE
 
diff --git a/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindow.h b/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindow.h
index 244ef677..f46cd880 100644
--- a/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindow.h
+++ b/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindow.h
@@ -5,6 +5,8 @@
 //#==============================================================#
 #include <string>
 
+#include "Math/Vector/SHVec2.h"
+
 //#==============================================================#
 //||                    Forward Declarations                    ||
 //#==============================================================#
@@ -21,11 +23,18 @@ namespace SHADE
     virtual void Init();
     virtual void Update();
     virtual void Exit();
-    bool isOpen = false;
+    bool isOpen;
+    bool isWindowHovered;
     std::string_view windowName;
   protected:
     virtual bool Begin();
+    virtual void OnResize();
+    virtual void OnPosChange();
+
     ImGuiWindowFlags windowFlags = 0;
     ImGuiIO& io;
+    SHVec2 windowSize;
+    SHVec2 windowPos;
+    SHVec2 viewportMousePos;
   };//class SHEditorWindow
 }//namespace SHADE
diff --git a/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindowIncludes.h b/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindowIncludes.h
index d1ebfbf4..f0267b06 100644
--- a/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindowIncludes.h
+++ b/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindowIncludes.h
@@ -2,4 +2,5 @@
 #include "MenuBar/SHEditorMenuBar.h"          //Menu Bar
 #include "HierarchyPanel/SHHierarchyPanel.h"  //Hierarchy Panel
 #include "Inspector/SHEditorInspector.h"      //Inspector
-#include "Profiling/SHEditorProfiler.h"       //Profiler
\ No newline at end of file
+#include "Profiling/SHEditorProfiler.h"       //Profiler
+#include "ViewportWindow/SHEditorViewport.h"  //Editor Viewport
\ No newline at end of file
diff --git a/SHADE_Engine/src/Editor/EditorWindow/ViewportWindow/SHEditorViewport.cpp b/SHADE_Engine/src/Editor/EditorWindow/ViewportWindow/SHEditorViewport.cpp
new file mode 100644
index 00000000..420443ae
--- /dev/null
+++ b/SHADE_Engine/src/Editor/EditorWindow/ViewportWindow/SHEditorViewport.cpp
@@ -0,0 +1,84 @@
+#include "SHpch.h"
+#include "SHEditorViewport.h"
+
+#include "ECS_Base/Managers/SHSystemManager.h"
+#include "Editor/SHEditor.hpp"
+#include "Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.h"
+#include "Graphics/MiddleEnd/Interface/SHGraphicsSystem.h"
+#include "Graphics/Descriptors/SHVkDescriptorSetGroup.h"
+#include "Graphics/MiddleEnd/Interface/SHMousePickSystem.h"
+
+namespace SHADE
+{
+  SHEditorViewport::SHEditorViewport()
+    :SHEditorWindow("Viewport", ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoScrollbar)
+  {
+  }
+
+  void SHEditorViewport::Init()
+  {
+    SHEditorWindow::Init();
+
+  }
+
+  void SHEditorViewport::Update()
+  {
+    SHEditorWindow::Update();
+    if(Begin())
+    {
+      DrawMenuBar();
+      auto gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>();
+      auto const& descriptorSet = gfxSystem->GetPostOffscreenRenderSystem()->GetDescriptorSetGroup()->GetVkHandle()[0];
+      auto mousePos = ImGui::GetMousePos();
+      auto cursorPos = ImGui::GetCursorScreenPos();
+      viewportMousePos = {mousePos.x - cursorPos.x, mousePos.y - cursorPos.y};
+      gfxSystem->GetMousePickSystem ()->SetViewportMousePos (viewportMousePos);
+      //if (ImGui::IsMouseReleased(ImGuiMouseButton_Left))
+      //{
+      //  auto eid = gfxSystem->GetMousePickSystem ()->GetPickedEntity();
+      //  if(eid != MAX_EID)
+      //  {
+      //    auto editor = SHSystemManager::GetSystem<SHEditor>();
+      //    editor->selectedEntities.clear();
+      //    editor->selectedEntities.push_back(eid);
+      //    if (const auto hierarchyPanel = SHEditorWindowManager::GetEditorWindow<SHHierarchyPanel>())
+      //    {
+      //      hierarchyPanel->SetScrollTo(eid);
+      //    }
+      //  }
+      //}
+
+      ImGui::Image((ImTextureID)descriptorSet, ImGui::GetWindowSize());
+    }
+    ImGui::End();
+  }
+
+  void SHEditorViewport::Exit()
+  {
+    SHEditorWindow::Exit();
+  }
+
+  void SHEditorViewport::OnResize()
+  {
+    SHEditorWindow::OnResize();
+    //Get graphics system to resize swapchain image
+    auto gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>();
+
+    //auto pos = ImGui::GetCursorPos();
+    //windowCursorPos = {}
+    gfxSystem->PrepareResize(static_cast<uint32_t>(windowSize.x), static_cast<uint32_t>(windowSize.y));
+  }
+
+  void SHEditorViewport::OnPosChange()
+  {
+    SHEditorWindow::OnPosChange();
+  }
+
+  void SHEditorViewport::DrawMenuBar() const noexcept
+  {
+    if(ImGui::BeginMenuBar())
+    {
+      ImGui::EndMenuBar();
+    }
+  }
+}//namespace SHADE
diff --git a/SHADE_Engine/src/Editor/EditorWindow/ViewportWindow/SHEditorViewport.h b/SHADE_Engine/src/Editor/EditorWindow/ViewportWindow/SHEditorViewport.h
new file mode 100644
index 00000000..5f4a5919
--- /dev/null
+++ b/SHADE_Engine/src/Editor/EditorWindow/ViewportWindow/SHEditorViewport.h
@@ -0,0 +1,29 @@
+#pragma once
+//#==============================================================#
+//||                      Library Includes                      ||
+//#==============================================================#
+#include <imgui.h>
+
+//#==============================================================#
+//||                       SHADE Includes                       ||
+//#==============================================================#
+#include "imgui_internal.h"
+#include "ECS_Base/SHECSMacros.h"
+#include "Editor/EditorWindow/SHEditorWindow.h"
+
+namespace SHADE
+{
+    class SHEditorViewport final : public SHEditorWindow
+  {
+  public:
+    SHEditorViewport();
+    void Init() override;
+    void Update() override;
+    void Exit() override;
+  protected:
+    void OnResize() override;
+    void OnPosChange() override;
+  private:
+    void DrawMenuBar() const noexcept;
+  };//class SHEditorViewport
+}//namespace SHADE
diff --git a/SHADE_Engine/src/Editor/SHEditor.cpp b/SHADE_Engine/src/Editor/SHEditor.cpp
index d9fc8373..6b3c3a93 100644
--- a/SHADE_Engine/src/Editor/SHEditor.cpp
+++ b/SHADE_Engine/src/Editor/SHEditor.cpp
@@ -43,6 +43,8 @@
 #include <backends/imgui_impl_sdl.h>
 #include <backends/imgui_impl_vulkan.h>
 
+#include "Graphics/MiddleEnd/Interface/SHMousePickSystem.h"
+
 RTTR_REGISTRATION
 {
   using namespace SHADE;
@@ -73,6 +75,7 @@ namespace SHADE
   //#==============================================================#
   void SHEditor::Init()
   {
+
     IMGUI_CHECKVERSION();
     if(auto context = ImGui::CreateContext())
     {
@@ -82,11 +85,21 @@ namespace SHADE
       }
     }
 
-    ImGuiIO& io = ImGui::GetIO(); (void)io;
+    //Add editor windows
+    SHEditorWindowManager::CreateEditorWindow<SHEditorMenuBar>();
+    SHEditorWindowManager::CreateEditorWindow<SHEditorViewport>();
+    SHEditorWindowManager::CreateEditorWindow<SHHierarchyPanel>();
+    SHEditorWindowManager::CreateEditorWindow<SHEditorInspector>();
+    SHEditorWindowManager::CreateEditorWindow<SHEditorProfiler>();
 
-    io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;     // Enable Keyboard Controls
-    io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; //Enable for Multi-Viewports
-    io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; //Enable docking
+    io = &ImGui::GetIO();
+
+    io->ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;     // Enable Keyboard Controls
+    io->ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; //Enable for Multi-Viewports
+    io->ConfigFlags |= ImGuiConfigFlags_DockingEnable; //Enable docking
+    io->IniFilename = "../../Assets/Editor/Layouts/UserLayout.ini";
+
+    InitLayout();
 
     InitFonts();
 
@@ -98,11 +111,11 @@ namespace SHADE
 
     SetStyle(Style::SHADE);
     
-    //Add editor windows
-    SHEditorWindowManager::CreateEditorWindow<SHEditorMenuBar>();
-    SHEditorWindowManager::CreateEditorWindow<SHHierarchyPanel>();
-    SHEditorWindowManager::CreateEditorWindow<SHEditorInspector>();
-    SHEditorWindowManager::CreateEditorWindow<SHEditorProfiler>();
+
+    for (const auto& window : SHEditorWindowManager::editorWindows | std::views::values)
+    {
+      window->Init();
+    }
 
     SHLOG_INFO("Successfully initialised SHADE Engine Editor")
   }
@@ -116,7 +129,7 @@ namespace SHADE
       if(window->isOpen)
         window->Update();
     }
-
+    
     if(ImGui::IsKeyDown(ImGuiKey_LeftShift) && ImGui::IsKeyDown(ImGuiKey_LeftCtrl) && ImGui::IsKeyReleased(ImGuiKey_Z))
     {
       SHCommandManager::RedoCommand();
@@ -125,36 +138,46 @@ namespace SHADE
     {
       SHCommandManager::UndoCommand();
     }
-
-
+    
     Render();
   }
 
   void SHEditor::Render()
   {
     ImGui::Render();
-    ImGuiIO& io = ImGui::GetIO();
-    if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
+    if (io->ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
     {
       ImGui::UpdatePlatformWindows();
       ImGui::RenderPlatformWindowsDefault();
     }
   }
 
+  void SHEditor::InitLayout() noexcept
+  {
+    if(!std::filesystem::exists(io->IniFilename))
+    {
+      std::filesystem::copy_file("../../Assets/Editor/Layouts/Default.ini", io->IniFilename);
+    }
+    //eventually load preferred layout here
+  }
+
   void SHEditor::InitFonts() noexcept
   {
-    ImGuiIO& io = ImGui::GetIO();
-    ImFont* mainFont = io.Fonts->AddFontFromFileTTF("../../Assets/Editor/Fonts/Segoe UI.ttf", 20.f);//TODO: Change to config based assets path
+    ImFont* mainFont = io->Fonts->AddFontFromFileTTF("../../Assets/Editor/Fonts/Segoe UI.ttf", 20.f);//TODO: Change to config based assets path
 
-    static const ImWchar icon_ranges[] = { ICON_MIN_MD, ICON_MAX_16_MD, 0 };
+    constexpr ImWchar icon_ranges[] = { ICON_MIN_MD, ICON_MAX_16_MD, 0 };
     ImFontConfig icons_config{}; icons_config.MergeMode = true; icons_config.GlyphOffset.y = 5.f;
-    ImFont* UIFont = io.Fonts->AddFontFromFileTTF("../../Assets/Editor/Fonts/MaterialIcons-Regular.ttf", 20.f, &icons_config, icon_ranges); //TODO: Change to config based assets path
+    ImFont* UIFont = io->Fonts->AddFontFromFileTTF("../../Assets/Editor/Fonts/MaterialIcons-Regular.ttf", 20.f, &icons_config, icon_ranges); //TODO: Change to config based assets path
 
-    io.Fonts->Build();
+    io->Fonts->Build();
   }
 
   void SHEditor::Exit()
   {
+    for (const auto& window : SHEditorWindowManager::editorWindows | std::views::values)
+    {
+      window->Init();
+    }
     ImGui_ImplVulkan_Shutdown();
     ImGui_ImplSDL2_Shutdown();
     ImGui::DestroyContext();
@@ -167,86 +190,86 @@ namespace SHADE
     default: 
     case Style::SHADE:
       {
-      ImGuiStyle& imStyle = ImGui::GetStyle();
-      ImVec4* colors = imStyle.Colors;
-      colors[ImGuiCol_Text] = ImVec4(0.706f, 0.729f, 0.757f, 1.00f);
-      colors[ImGuiCol_TextDisabled] = ImVec4(0.50f, 0.50f, 0.50f, 1.00f);
-      colors[ImGuiCol_WindowBg] = ImVec4(0.172f, 0.184f, 0.203f, 1.f);
-      colors[ImGuiCol_ChildBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f);
-      colors[ImGuiCol_PopupBg] = ImVec4(0.19f, 0.19f, 0.19f, 0.92f);
-      colors[ImGuiCol_Border] = ImVec4(0.19f, 0.19f, 0.19f, 0.29f);
-      colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.24f);
-      colors[ImGuiCol_FrameBg] = ImVec4(0.05f, 0.05f, 0.05f, 0.54f);
-      colors[ImGuiCol_FrameBgHovered] = ImVec4(0.19f, 0.19f, 0.19f, 0.54f);
-      colors[ImGuiCol_FrameBgActive] = ImVec4(0.20f, 0.22f, 0.23f, 1.00f);
-      colors[ImGuiCol_TitleBg] = colors[ImGuiCol_WindowBg];
-      colors[ImGuiCol_TitleBgActive] = colors[ImGuiCol_WindowBg];
-      colors[ImGuiCol_TitleBgCollapsed] = colors[ImGuiCol_WindowBg];
-      colors[ImGuiCol_MenuBarBg] = ImVec4(0.129f, 0.141f, 0.157f, 1.f);
-      colors[ImGuiCol_ScrollbarBg] = colors[ImGuiCol_WindowBg];
-      colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.34f, 0.34f, 0.34f, 0.54f);
-      colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.40f, 0.40f, 0.40f, 0.54f);
-      colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.56f, 0.56f, 0.56f, 0.54f);
-      colors[ImGuiCol_CheckMark] = ImVec4(0.627f, 0.239f, 0.761f, 1.00f);
-      colors[ImGuiCol_SliderGrab] = ImVec4(0.34f, 0.34f, 0.34f, 0.54f);
-      colors[ImGuiCol_SliderGrabActive] = ImVec4(0.56f, 0.56f, 0.56f, 0.54f);
-      colors[ImGuiCol_Button] = ImVec4(0.05f, 0.05f, 0.05f, 0.54f);
-      colors[ImGuiCol_ButtonHovered] = ImVec4(0.15f, 0.15f, 0.15f, 0.54f);
-      colors[ImGuiCol_ButtonActive] = ImVec4(0.20f, 0.22f, 0.23f, 1.00f);
-      colors[ImGuiCol_Header] = ImVec4(0.00f, 0.00f, 0.00f, 0.52f);
-      colors[ImGuiCol_HeaderHovered] = ImVec4(0.00f, 0.00f, 0.00f, 0.36f);
-      colors[ImGuiCol_HeaderActive] = ImVec4(0.20f, 0.22f, 0.23f, 0.33f);
-      colors[ImGuiCol_Separator] = colors[ImGuiCol_MenuBarBg];
-      colors[ImGuiCol_SeparatorHovered] = ImVec4(0.44f, 0.44f, 0.44f, 0.29f);
-      colors[ImGuiCol_SeparatorActive] = ImVec4(0.40f, 0.44f, 0.47f, 1.00f);
-      colors[ImGuiCol_ResizeGrip] = ImVec4(0.28f, 0.28f, 0.28f, 0.29f);
-      colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.44f, 0.44f, 0.44f, 0.29f);
-      colors[ImGuiCol_ResizeGripActive] = ImVec4(0.40f, 0.44f, 0.47f, 1.00f);
-      colors[ImGuiCol_Tab] = colors[ImGuiCol_WindowBg];
-      colors[ImGuiCol_TabHovered] = ImVec4(0.14f, 0.14f, 0.14f, 1.00f);
-      colors[ImGuiCol_TabActive] = ImVec4(0.14f, 0.14f, 0.14f, 0.8f);
-      colors[ImGuiCol_TabUnfocused] = colors[ImGuiCol_WindowBg];
-      colors[ImGuiCol_TabUnfocusedActive] = colors[ImGuiCol_WindowBg];
-      colors[ImGuiCol_DockingPreview] = ImVec4(0.627f, 0.239f, 0.761f, 1.00f);
-      colors[ImGuiCol_DockingEmptyBg] = ImVec4(0.855f, 0.6f, 0.941f, 1.00f);
-      colors[ImGuiCol_PlotLines] = ImVec4(1.00f, 0.00f, 0.00f, 1.00f);
-      colors[ImGuiCol_PlotLinesHovered] = ImVec4(1.00f, 0.00f, 0.00f, 1.00f);
-      colors[ImGuiCol_PlotHistogram] = ImVec4(1.00f, 0.00f, 0.00f, 1.00f);
-      colors[ImGuiCol_PlotHistogramHovered] = ImVec4(1.00f, 0.00f, 0.00f, 1.00f);
-      colors[ImGuiCol_TableHeaderBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.52f);
-      colors[ImGuiCol_TableBorderStrong] = ImVec4(0.00f, 0.00f, 0.00f, 0.52f);
-      colors[ImGuiCol_TableBorderLight] = ImVec4(0.28f, 0.28f, 0.28f, 0.29f);
-      colors[ImGuiCol_TableRowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f);
-      colors[ImGuiCol_TableRowBgAlt] = ImVec4(1.00f, 1.00f, 1.00f, 0.06f);
-      colors[ImGuiCol_TextSelectedBg] = ImVec4(0.20f, 0.22f, 0.23f, 1.00f);
-      colors[ImGuiCol_DragDropTarget] = ImVec4(0.33f, 0.67f, 0.86f, 1.00f);
-      colors[ImGuiCol_NavHighlight] = ImVec4(0.73f, 0.73f, 0.73f, 0.7f);
+      ImGuiStyle& imStyle                    = ImGui::GetStyle();
+      ImVec4* colors                         = imStyle.Colors;
+      colors[ImGuiCol_Text]                  = ImVec4(0.706f, 0.729f, 0.757f, 1.00f);
+      colors[ImGuiCol_TextDisabled]          = ImVec4(0.50f, 0.50f, 0.50f, 1.00f);
+      colors[ImGuiCol_WindowBg]              = ImVec4(0.172f, 0.184f, 0.203f, 1.f);
+      colors[ImGuiCol_ChildBg]               = ImVec4(0.00f, 0.00f, 0.00f, 0.00f);
+      colors[ImGuiCol_PopupBg]               = ImVec4(0.19f, 0.19f, 0.19f, 0.92f);
+      colors[ImGuiCol_Border]                = ImVec4(0.19f, 0.19f, 0.19f, 0.29f);
+      colors[ImGuiCol_BorderShadow]          = ImVec4(0.00f, 0.00f, 0.00f, 0.24f);
+      colors[ImGuiCol_FrameBg]               = ImVec4(0.05f, 0.05f, 0.05f, 0.54f);
+      colors[ImGuiCol_FrameBgHovered]        = ImVec4(0.19f, 0.19f, 0.19f, 0.54f);
+      colors[ImGuiCol_FrameBgActive]         = ImVec4(0.20f, 0.22f, 0.23f, 1.00f);
+      colors[ImGuiCol_TitleBg]               = colors[ImGuiCol_WindowBg];
+      colors[ImGuiCol_TitleBgActive]         = colors[ImGuiCol_WindowBg];
+      colors[ImGuiCol_TitleBgCollapsed]      = colors[ImGuiCol_WindowBg];
+      colors[ImGuiCol_MenuBarBg]             = ImVec4(0.129f, 0.141f, 0.157f, 1.f);
+      colors[ImGuiCol_ScrollbarBg]           = colors[ImGuiCol_WindowBg];
+      colors[ImGuiCol_ScrollbarGrab]         = ImVec4(0.34f, 0.34f, 0.34f, 0.54f);
+      colors[ImGuiCol_ScrollbarGrabHovered]  = ImVec4(0.40f, 0.40f, 0.40f, 0.54f);
+      colors[ImGuiCol_ScrollbarGrabActive]   = ImVec4(0.56f, 0.56f, 0.56f, 0.54f);
+      colors[ImGuiCol_CheckMark]             = ImVec4(0.627f, 0.239f, 0.761f, 1.00f);
+      colors[ImGuiCol_SliderGrab]            = ImVec4(0.34f, 0.34f, 0.34f, 0.54f);
+      colors[ImGuiCol_SliderGrabActive]      = ImVec4(0.56f, 0.56f, 0.56f, 0.54f);
+      colors[ImGuiCol_Button]                = ImVec4(0.05f, 0.05f, 0.05f, 0.54f);
+      colors[ImGuiCol_ButtonHovered]         = ImVec4(0.15f, 0.15f, 0.15f, 0.54f);
+      colors[ImGuiCol_ButtonActive]          = ImVec4(0.20f, 0.22f, 0.23f, 1.00f);
+      colors[ImGuiCol_Header]                = ImVec4(0.00f, 0.00f, 0.00f, 0.52f);
+      colors[ImGuiCol_HeaderHovered]         = ImVec4(0.00f, 0.00f, 0.00f, 0.36f);
+      colors[ImGuiCol_HeaderActive]          = ImVec4(0.20f, 0.22f, 0.23f, 0.33f);
+      colors[ImGuiCol_Separator]             = colors[ImGuiCol_MenuBarBg];
+      colors[ImGuiCol_SeparatorHovered]      = ImVec4(0.44f, 0.44f, 0.44f, 0.29f);
+      colors[ImGuiCol_SeparatorActive]       = ImVec4(0.40f, 0.44f, 0.47f, 1.00f);
+      colors[ImGuiCol_ResizeGrip]            = ImVec4(0.28f, 0.28f, 0.28f, 0.29f);
+      colors[ImGuiCol_ResizeGripHovered]     = ImVec4(0.44f, 0.44f, 0.44f, 0.29f);
+      colors[ImGuiCol_ResizeGripActive]      = ImVec4(0.40f, 0.44f, 0.47f, 1.00f);
+      colors[ImGuiCol_Tab]                   = colors[ImGuiCol_WindowBg];
+      colors[ImGuiCol_TabHovered]            = ImVec4(0.14f, 0.14f, 0.14f, 1.00f);
+      colors[ImGuiCol_TabActive]             = ImVec4(0.14f, 0.14f, 0.14f, 0.8f);
+      colors[ImGuiCol_TabUnfocused]          = colors[ImGuiCol_WindowBg];
+      colors[ImGuiCol_TabUnfocusedActive]    = colors[ImGuiCol_WindowBg];
+      colors[ImGuiCol_DockingPreview]        = ImVec4(0.627f, 0.239f, 0.761f, 1.00f);
+      colors[ImGuiCol_DockingEmptyBg]        = ImVec4(0.855f, 0.6f, 0.941f, 1.00f);
+      colors[ImGuiCol_PlotLines]             = ImVec4(1.00f, 0.00f, 0.00f, 1.00f);
+      colors[ImGuiCol_PlotLinesHovered]      = ImVec4(1.00f, 0.00f, 0.00f, 1.00f);
+      colors[ImGuiCol_PlotHistogram]         = ImVec4(1.00f, 0.00f, 0.00f, 1.00f);
+      colors[ImGuiCol_PlotHistogramHovered]  = ImVec4(1.00f, 0.00f, 0.00f, 1.00f);
+      colors[ImGuiCol_TableHeaderBg]         = ImVec4(0.00f, 0.00f, 0.00f, 0.52f);
+      colors[ImGuiCol_TableBorderStrong]     = ImVec4(0.00f, 0.00f, 0.00f, 0.52f);
+      colors[ImGuiCol_TableBorderLight]      = ImVec4(0.28f, 0.28f, 0.28f, 0.29f);
+      colors[ImGuiCol_TableRowBg]            = ImVec4(0.00f, 0.00f, 0.00f, 0.00f);
+      colors[ImGuiCol_TableRowBgAlt]         = ImVec4(1.00f, 1.00f, 1.00f, 0.06f);
+      colors[ImGuiCol_TextSelectedBg]        = ImVec4(0.20f, 0.22f, 0.23f, 1.00f);
+      colors[ImGuiCol_DragDropTarget]        = ImVec4(0.33f, 0.67f, 0.86f, 1.00f);
+      colors[ImGuiCol_NavHighlight]          = ImVec4(0.73f, 0.73f, 0.73f, 0.7f);
       colors[ImGuiCol_NavWindowingHighlight] = ImVec4(0.141f, 0.141f, 0.141f, 0.70f);
-      colors[ImGuiCol_NavWindowingDimBg] = colors[ImGuiCol_NavHighlight];
-      colors[ImGuiCol_ModalWindowDimBg] = ImVec4(0.2f, 0.2f, 0.2f, 0.65f);
+      colors[ImGuiCol_NavWindowingDimBg]     = colors[ImGuiCol_NavHighlight];
+      colors[ImGuiCol_ModalWindowDimBg]      = ImVec4(0.2f, 0.2f, 0.2f, 0.65f);
 
-      imStyle.WindowPadding = ImVec2(8.00f, 8.00f);
-      imStyle.FramePadding = ImVec2(5.00f, 2.00f);
-      imStyle.CellPadding = ImVec2(6.00f, 8.00f);
-      imStyle.ItemSpacing = ImVec2(6.00f, 6.00f);
-      imStyle.ItemInnerSpacing = ImVec2(6.00f, 6.00f);
-      imStyle.TouchExtraPadding = ImVec2(0.00f, 0.00f);
-      imStyle.IndentSpacing = 25;
-      imStyle.ScrollbarSize = 15;
-      imStyle.GrabMinSize = 10;
-      imStyle.WindowBorderSize = 0.6f;
-      imStyle.ChildBorderSize = 1;
-      imStyle.PopupBorderSize = 1;
-      imStyle.FrameBorderSize = 1;
-      imStyle.TabBorderSize = 1;
-      imStyle.WindowRounding = 7;
-      imStyle.ChildRounding = 4;
-      imStyle.FrameRounding = 3;
-      imStyle.PopupRounding = 4;
-      imStyle.ScrollbarRounding = 9;
-      imStyle.GrabRounding = 3;
-      imStyle.LogSliderDeadzone = 4;
-      imStyle.TabRounding = 4;
+      imStyle.WindowPadding            = ImVec2(8.00f, 8.00f);
+      imStyle.FramePadding             = ImVec2(5.00f, 2.00f);
+      imStyle.CellPadding              = ImVec2(6.00f, 8.00f);
+      imStyle.ItemSpacing              = ImVec2(6.00f, 6.00f);
+      imStyle.ItemInnerSpacing         = ImVec2(6.00f, 6.00f);
+      imStyle.TouchExtraPadding        = ImVec2(0.00f, 0.00f);
+      imStyle.IndentSpacing            = 25;
+      imStyle.ScrollbarSize            = 15;
+      imStyle.GrabMinSize              = 10;
+      imStyle.WindowBorderSize         = 0.6f;
+      imStyle.ChildBorderSize          = 1;
+      imStyle.PopupBorderSize          = 1;
+      imStyle.FrameBorderSize          = 1;
+      imStyle.TabBorderSize            = 1;
+      imStyle.WindowRounding           = 7;
+      imStyle.ChildRounding            = 4;
+      imStyle.FrameRounding            = 3;
+      imStyle.PopupRounding            = 4;
+      imStyle.ScrollbarRounding        = 9;
+      imStyle.GrabRounding             = 3;
+      imStyle.LogSliderDeadzone        = 4;
+      imStyle.TabRounding              = 4;
       imStyle.WindowMenuButtonPosition = ImGuiDir_None;
       }
       break;
@@ -281,10 +304,11 @@ namespace SHADE
     imguiCommandPool = gfxSystem->GetDevice()->CreateCommandPool(SH_QUEUE_FAMILY_ARRAY_INDEX::GRAPHICS, SH_CMD_POOL_RESET::POOL_BASED, true);
     imguiCommandBuffer = imguiCommandPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY);
 
-    auto const& renderers = gfxSystem->GetDefaultViewport()->GetRenderers();
+    //auto const& renderers = gfxSystem->GetDefaultViewport()->GetRenderers();
+    auto const& renderers = gfxSystem->GetEditorViewport()->GetRenderers();
 
     SHASSERT(!renderers.empty(), "No Renderers available")
-    auto renderGraph = renderers[0]->GetRenderGraph();
+    auto renderGraph = renderers[SHGraphicsConstants::RenderGraphIndices::EDITOR]->GetRenderGraph();
     auto renderPass = renderGraph->GetNode("ImGui Node")->GetRenderpass();
 
     if(ImGui_ImplVulkan_Init(&initInfo, renderPass->GetVkRenderpass()) == false)
@@ -309,6 +333,29 @@ namespace SHADE
       });
   }
 
+  void SHEditor::PollPicking()
+  {
+    if (auto gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>())
+    {
+      auto viewportWindow = SHEditorWindowManager::GetEditorWindow<SHEditorViewport>();
+      if (viewportWindow->isWindowHovered && ImGui::IsMouseReleased(ImGuiMouseButton_Left))
+      {
+        EntityID pickedEID = gfxSystem->GetMousePickSystem()->GetPickedEntity();
+        if(pickedEID == MAX_EID)
+          return;
+        if (!ImGui::IsKeyDown(ImGuiKey_LeftCtrl))
+        {
+          if (const auto hierarchyPanel = SHEditorWindowManager::GetEditorWindow<SHHierarchyPanel>())
+          {
+            hierarchyPanel->SetScrollTo(pickedEID);
+          }
+          selectedEntities.clear();
+        }
+        selectedEntities.push_back(pickedEID);
+      }
+    }
+  }
+
   void SHEditor::NewFrame()
   {
     SDL_Event event;
diff --git a/SHADE_Engine/src/Editor/SHEditor.hpp b/SHADE_Engine/src/Editor/SHEditor.hpp
index d579a9b5..baa6324e 100644
--- a/SHADE_Engine/src/Editor/SHEditor.hpp
+++ b/SHADE_Engine/src/Editor/SHEditor.hpp
@@ -90,11 +90,11 @@ namespace SHADE
       return reinterpret_cast<T*>(editorWindows[GetEditorWindowID<T>()].get());
     }
 
+    static EditorWindowMap editorWindows;
   private:
     // Number of windows; used for Editor Window ID Generation
     static EditorWindowID windowCount;
     // Map of Editor Windows
-    static EditorWindowMap editorWindows;
     friend class SHEditor;
   };
 
@@ -110,10 +110,17 @@ namespace SHADE
     class SH_API EditorRoutine final : public SHSystemRoutine
     {
     public:
-        EditorRoutine() = default;
+        EditorRoutine():SHSystemRoutine("Editor routine", true) {};
         void Execute(double dt) noexcept override final;
     };
 
+    enum class State : uint8_t
+    {
+      PLAY,
+      PAUSE,
+      STOP
+    };
+
     /**
      * @brief Style options
      *
@@ -162,9 +169,13 @@ namespace SHADE
 
     void SetSDLWindow(SDL_Window* inSDLWindow){sdlWindow = inSDLWindow;};
 
+    void PollPicking();
+
     // List of selected entities
     std::vector<EntityID> selectedEntities;
 
+    State editorState = State::STOP;
+
   private:
     /**
      * @brief Start new frame for editor
@@ -177,7 +188,7 @@ namespace SHADE
      */
     void Render();
 
-    
+    void InitLayout() noexcept;
 
     void InitFonts() noexcept;
 
@@ -186,6 +197,8 @@ namespace SHADE
     // Handle to command buffer used for ImGui Vulkan Backend
     Handle<SHVkCommandBuffer> imguiCommandBuffer;
 
-    SDL_Window* sdlWindow;
+    SDL_Window* sdlWindow {nullptr};
+
+    ImGuiIO* io{nullptr};
   };//class SHEditor
 }//namespace SHADE
diff --git a/SHADE_Engine/src/Graphics/Debugging/SHVulkanDebugUtil.cpp b/SHADE_Engine/src/Graphics/Debugging/SHVulkanDebugUtil.cpp
index c8a1fe1a..fd39da24 100644
--- a/SHADE_Engine/src/Graphics/Debugging/SHVulkanDebugUtil.cpp
+++ b/SHADE_Engine/src/Graphics/Debugging/SHVulkanDebugUtil.cpp
@@ -99,7 +99,7 @@ namespace SHADE
 
   void SHVulkanDebugUtil::ReportVkSuccess(std::string_view message) noexcept
   {
-    SHLOGV_INFO(message);
+    //SHLOGV_INFO(message);
   }
 
   /***************************************************************************/
diff --git a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.cpp b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.cpp
index e842df47..ea859718 100644
--- a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.cpp
+++ b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetGroup.cpp
@@ -172,7 +172,7 @@ namespace SHADE
       // write sampler and image view
       auto& [view, sampler, layout] = imageViewsAndSamplers[i];
       writeInfo.descImageInfos[i].imageView = view->GetImageView();
-      writeInfo.descImageInfos[i].sampler = sampler->GetVkSampler();
+      writeInfo.descImageInfos[i].sampler = sampler ? sampler->GetVkSampler() : nullptr;
       writeInfo.descImageInfos[i].imageLayout = layout;
     }
   }
diff --git a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetLayout.cpp b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetLayout.cpp
index 002aa29d..0943c489 100644
--- a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetLayout.cpp
+++ b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetLayout.cpp
@@ -1,16 +1,18 @@
 #include "SHPch.h"
 #include "SHVkDescriptorSetLayout.h"
 #include "Graphics/Devices/SHVkLogicalDevice.h"
+#include "Graphics/Images/SHVkSampler.h"
 
 namespace SHADE
 {
     /*---------------------------------------------------------------------------------*/
     /* Constructor/Destructor                                                          */
     /*---------------------------------------------------------------------------------*/
-    SHVkDescriptorSetLayout::SHVkDescriptorSetLayout(Handle<SHVkLogicalDevice> device, SetIndex set, const std::vector<Binding>& bindings)
+    SHVkDescriptorSetLayout::SHVkDescriptorSetLayout(Handle<SHVkLogicalDevice> device, SetIndex set, const std::vector<Binding>& bindings, bool genImmutableSamplers/* = false*/)
     : device     { device }
     , layoutDesc { bindings }
     , setIndex {set}
+    , immutableSampler{}
     {
         // Check if auto-binding point calculation configuration is valid
         bool autoCalc = false;
@@ -26,6 +28,25 @@ namespace SHADE
             }
         }
 
+        vk::Sampler tempVkSampler = nullptr;
+        if (genImmutableSamplers)
+        {
+          // Create sampler
+          immutableSampler = device->CreateSampler(
+            {
+              .minFilter = vk::Filter::eLinear,
+              .magFilter = vk::Filter::eLinear,
+              .addressMode = vk::SamplerAddressMode::eRepeat,
+              .mipmapMode = vk::SamplerMipmapMode::eLinear,
+              .minLod = -1000,
+              .maxLod = 1000
+            }
+          );
+
+          tempVkSampler = immutableSampler->GetVkSampler();
+        }
+
+
         // Fill up VK bindings with auto calculated bind points if needed
         std::vector<vk::DescriptorSetLayoutBinding> layoutBindings;
         layoutBindings.reserve(bindings.size());
@@ -39,7 +60,7 @@ namespace SHADE
                 .descriptorType     = binding.Type,
                 .descriptorCount    = binding.DescriptorCount,
                 .stageFlags         = binding.Stage,
-                .pImmutableSamplers = nullptr // We will create our own samplers
+                .pImmutableSamplers = genImmutableSamplers ? &tempVkSampler : nullptr,
             };
             layoutBindings.emplace_back(VK_BINDING);
 
@@ -75,7 +96,8 @@ namespace SHADE
       : device {rhs.device}
       , setLayout {rhs.setLayout}
       , layoutDesc{std::move (rhs.layoutDesc)}
-      , setIndex {rhs.setIndex}
+      , setIndex{ rhs.setIndex }
+      , immutableSampler{ rhs.immutableSampler }
     {
       rhs.setLayout = VK_NULL_HANDLE;
     }
@@ -106,6 +128,7 @@ namespace SHADE
       setLayout = rhs.setLayout;
       layoutDesc = std::move(rhs.layoutDesc);
       setIndex = rhs.setIndex;
+      immutableSampler = rhs.immutableSampler;
 
       rhs.setLayout = VK_NULL_HANDLE;
 
diff --git a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetLayout.h b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetLayout.h
index 9b436026..4fffbc96 100644
--- a/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetLayout.h
+++ b/SHADE_Engine/src/Graphics/Descriptors/SHVkDescriptorSetLayout.h
@@ -10,6 +10,7 @@ namespace SHADE
     /* Forward Declarations                                                            */
     /*---------------------------------------------------------------------------------*/
     class SHVkLogicalDevice;
+    class SHVkSampler;
 
     /*---------------------------------------------------------------------------------*/
     /* Type Definitions                                                                */
@@ -74,7 +75,7 @@ namespace SHADE
         /// </summary>
         /// <param name="device"></param>
         /// <param name="bindings"></param>
-        SHVkDescriptorSetLayout(Handle<SHVkLogicalDevice> device, SetIndex setIndex, const std::vector<Binding>& bindings);
+        SHVkDescriptorSetLayout(Handle<SHVkLogicalDevice> device, SetIndex setIndex, const std::vector<Binding>& bindings, bool genImmutableSamplers = false);
         SHVkDescriptorSetLayout(const SHVkDescriptorSetLayout&) = delete;
         SHVkDescriptorSetLayout(SHVkDescriptorSetLayout&& rhs) noexcept;
         /// <summary>
@@ -107,5 +108,6 @@ namespace SHADE
         vk::DescriptorSetLayout   setLayout;
         std::vector<Binding>      layoutDesc; // Stores description of the layout
         SetIndex                  setIndex;   // Index of the set
+        Handle<SHVkSampler>       immutableSampler;
     };
 }
\ No newline at end of file
diff --git a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.cpp b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.cpp
index 4f4f94a4..7c7acfc5 100644
--- a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.cpp
+++ b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.cpp
@@ -550,10 +550,9 @@ namespace SHADE
 
   }
 
-  Handle<SHVkDescriptorSetLayout> SHVkLogicalDevice::CreateDescriptorSetLayout(SetIndex setIndex, std::vector<SHVkDescriptorSetLayout::Binding> const& bindings) noexcept
+  Handle<SHVkDescriptorSetLayout> SHVkLogicalDevice::CreateDescriptorSetLayout(SetIndex setIndex, std::vector<SHVkDescriptorSetLayout::Binding> const& bindings, bool genImmutableSamplers/* = false*/) noexcept
   {
-    return SHVkInstance::GetResourceManager().Create <SHVkDescriptorSetLayout>(GetHandle(), setIndex,  bindings);
-
+    return SHVkInstance::GetResourceManager().Create <SHVkDescriptorSetLayout>(GetHandle(), setIndex,  bindings, genImmutableSamplers);
   }
 
   Handle<SHVkDescriptorPool> SHVkLogicalDevice::CreateDescriptorPools(const SHVkDescriptorPool::Config& config /*= {}*/) noexcept
diff --git a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.h b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.h
index 5c400e02..6f7048b8 100644
--- a/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.h
+++ b/SHADE_Engine/src/Graphics/Devices/SHVkLogicalDevice.h
@@ -186,7 +186,7 @@ namespace SHADE
     Handle<SHVkRenderpass>          CreateRenderpass          (std::span<vk::AttachmentDescription> const vkDescriptions, std::vector<SHVkSubpassParams> const& subpasses) noexcept;
     Handle<SHVkRenderpass>          CreateRenderpass          (std::span<vk::AttachmentDescription> const vkDescriptions, std::span<vk::SubpassDescription> const spDescs, std::span<vk::SubpassDependency> const spDeps) noexcept;
     Handle<SHVkFramebuffer>         CreateFramebuffer         (Handle<SHVkRenderpass> const& renderpassHdl, std::vector<Handle<SHVkImageView>> const& attachments, uint32_t inWidth, uint32_t inHeight) noexcept;
-    Handle<SHVkDescriptorSetLayout> CreateDescriptorSetLayout (SetIndex setIndex, std::vector<SHVkDescriptorSetLayout::Binding> const& bindings) noexcept;
+    Handle<SHVkDescriptorSetLayout> CreateDescriptorSetLayout (SetIndex setIndex, std::vector<SHVkDescriptorSetLayout::Binding> const& bindings, bool genImmutableSamplers = false) noexcept;
     Handle<SHVkDescriptorPool>      CreateDescriptorPools     (const SHVkDescriptorPool::Config& config = {}) noexcept;
     Handle<SHVkDescriptorSetGroup>  CreateDescriptorSetGroup(Handle<SHVkDescriptorPool> pool,
       std::vector<Handle<SHVkDescriptorSetLayout>> const& layouts,
diff --git a/SHADE_Engine/src/Graphics/Images/SHVkSampler.cpp b/SHADE_Engine/src/Graphics/Images/SHVkSampler.cpp
index f12b834d..4300f2bd 100644
--- a/SHADE_Engine/src/Graphics/Images/SHVkSampler.cpp
+++ b/SHADE_Engine/src/Graphics/Images/SHVkSampler.cpp
@@ -24,14 +24,15 @@ namespace SHADE
   {
     const vk::SamplerCreateInfo SAMPLER_CREATE_INFO
     {
-      .magFilter    = params.magFilter,
-      .minFilter    = params.minFilter,
-      .mipmapMode   = params.mipmapMode,
-      .addressModeU = params.addressMode,
-      .addressModeV = params.addressMode,
-      .addressModeW = params.addressMode,
-      .minLod       = params.minLod,
-      .maxLod       = params.maxLod
+      .magFilter     = params.magFilter,
+      .minFilter     = params.minFilter,
+      .mipmapMode    = params.mipmapMode,
+      .addressModeU  = params.addressMode,
+      .addressModeV  = params.addressMode,
+      .addressModeW  = params.addressMode,
+      .maxAnisotropy = 1.0f,
+      .minLod        = params.minLod,
+      .maxLod        = params.maxLod,
     };
 
     // Create the sampler
@@ -39,7 +40,8 @@ namespace SHADE
   }
 
   SHVkSampler::SHVkSampler(SHVkSampler&& rhs) noexcept
-  : vkSampler { rhs.vkSampler }
+    : vkSampler{ rhs.vkSampler }
+    , device{ rhs.device }
   {
     rhs.vkSampler = nullptr;    
   }
@@ -56,6 +58,7 @@ namespace SHADE
   SHADE::SHVkSampler& SHVkSampler::operator=(SHVkSampler&& rhs) noexcept
   {
     vkSampler = rhs.vkSampler;
+    device = rhs.device;
     rhs.vkSampler = nullptr;
     return *this;
   }
diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsConstants.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsConstants.h
index ac2f1f8c..67cbc001 100644
--- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsConstants.h
+++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsConstants.h
@@ -25,6 +25,12 @@ namespace SHADE
   struct SHGraphicsConstants
   {
   public:
+    struct RenderGraphIndices
+    {
+      static constexpr uint32_t WORLD  = 0;
+      static constexpr uint32_t EDITOR = 0;
+    };
+
     struct DescriptorSetIndex
     {
       /***************************************************************************/
diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp
index 09f1c93e..143f3bf5 100644
--- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp
+++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.cpp
@@ -36,11 +36,9 @@ of DigiPen Institute of Technology is prohibited.
 
 namespace SHADE
 {
+#pragma region INIT_EXIT
 
-  /*---------------------------------------------------------------------------------*/
-  /* Constructor/Destructors                                                         */
-  /*---------------------------------------------------------------------------------*/
-  void SHGraphicsSystem::Init(void)
+  void SHGraphicsSystem::InitBoilerplate(void) noexcept
   {
     /*-----------------------------------------------------------------------*/
     /* BACKEND BOILERPLATE                                                   */
@@ -51,7 +49,7 @@ namespace SHADE
     // Get Physical Device and Construct Logical Device
     physicalDevice = SHVkInstance::CreatePhysicalDevice(SH_PHYSICAL_DEVICE_TYPE::BEST);
     device = SHVkInstance::CreateLogicalDevice({ SHQueueParams(SH_Q_FAM::GRAPHICS, SH_QUEUE_SELECT::DEDICATED), SHQueueParams(SH_Q_FAM::TRANSFER, SH_QUEUE_SELECT::DEDICATED) }, physicalDevice);
-      
+
     // Construct surface
     surface = device->CreateSurface(window->GetHWND());
 
@@ -71,7 +69,15 @@ namespace SHADE
         if (width == 0 || height == 0)
           return;
 
-        renderContext.SetIsResized(true);
+#ifdef SHEDITOR
+
+        //PrepareResize(1, 1, SHVec2(0, 0));
+
+#else
+
+        PrepareResize(resizeWidth, resizeHeight, SHVec2(0, 0));
+
+#endif
       });
 
     window->RegisterWindowCloseCallback([&](void)
@@ -106,11 +112,12 @@ namespace SHADE
     graphicsCmdPool = device->CreateCommandPool(SH_QUEUE_FAMILY_ARRAY_INDEX::GRAPHICS, SH_CMD_POOL_RESET::POOL_BASED, true);
     transferCmdBuffer = graphicsCmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY);
     graphicsTexCmdBuffer = graphicsCmdPool->RequestCommandBuffer(SH_CMD_BUFFER_TYPE::PRIMARY);
+  }
 
-
-
+  void SHGraphicsSystem::InitSceneRenderGraph(void) noexcept
+  {
     /*-----------------------------------------------------------------------*/
-    /* MIDDLE END SETUP                                                      
+    /* MIDDLE END SETUP
        - Viewports
        - Renderer
        - Render graph in renderers
@@ -118,8 +125,8 @@ namespace SHADE
        - Default vertex input state
        - Global data
     /*-----------------------------------------------------------------------*/
+    auto windowDims = window->GetWindowSize();
 
-    SHGraphicsGlobalData::Init(device);
 
     // Set Up Cameras
     screenCamera = resourceManager.Create<SHCamera>();
@@ -131,12 +138,12 @@ namespace SHADE
     worldCamera->SetPerspective(90.0f, static_cast<float>(windowDims.first), static_cast<float>(windowDims.second), 0.0f, 100.0f);
 
     // Create Default Viewport
-    defaultViewport = AddViewport(vk::Viewport(0.0f, 0.0f, static_cast<float>(window->GetWindowSize().first), static_cast<float>(window->GetWindowSize().second), 0.0f, 1.0f));
-    
+    worldViewport = AddViewport(vk::Viewport(0.0f, 0.0f, static_cast<float>(window->GetWindowSize().first), static_cast<float>(window->GetWindowSize().second), 0.0f, 1.0f));
+
     // Get render graph from default viewport world renderer
     worldRenderGraph = resourceManager.Create<SHRenderGraph>();
-    
-    std::vector<Handle<SHVkCommandPool>> renderContextCmdPools{swapchain->GetNumImages()};
+
+    std::vector<Handle<SHVkCommandPool>> renderContextCmdPools{ swapchain->GetNumImages() };
     for (uint32_t i = 0; i < renderContextCmdPools.size(); ++i)
     {
       renderContextCmdPools[i] = renderContext.GetFrameData(i).cmdPoolHdls[0];
@@ -144,44 +151,27 @@ namespace SHADE
 
     // Initialize world render graph
     worldRenderGraph->Init(device, swapchain);
-    worldRenderGraph->AddResource("Present", SH_ATT_DESC_TYPE::COLOR_PRESENT, windowDims.first, windowDims.second);
-    worldRenderGraph->AddResource("Depth Buffer", SH_ATT_DESC_TYPE::DEPTH_STENCIL, windowDims.first, windowDims.second, vk::Format::eD32SfloatS8Uint);
-    worldRenderGraph->AddResource("Entity ID", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eR32Uint, 1, vk::ImageUsageFlagBits::eTransferSrc);
+    worldRenderGraph->AddResource("Scene", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT }, windowDims.first, windowDims.second);
+    worldRenderGraph->AddResource("Depth Buffer", { SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL }, windowDims.first, windowDims.second, vk::Format::eD32SfloatS8Uint);
+    worldRenderGraph->AddResource("Entity ID", { SH_ATT_DESC_TYPE_FLAGS::COLOR }, windowDims.first, windowDims.second, vk::Format::eR32Uint, 1, vk::ImageUsageFlagBits::eTransferSrc);
 
-    //worldRenderGraph->AddResource("Position", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eR16G16B16A16Sfloat);
-    //worldRenderGraph->AddResource("Normals", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eR16G16B16A16Sfloat);
-    //worldRenderGraph->AddResource("Composite", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eR16G16B16A16Sfloat);
-    //worldRenderGraph->AddResource("Scene", SH_ATT_DESC_TYPE::COLOR, windowDims.first, windowDims.second, vk::Format::eB8G8R8A8Unorm);
-    auto node = worldRenderGraph->AddNode("G-Buffer", { "Entity ID", "Depth Buffer", "Present"}, {}); // no predecessors
+    auto node = worldRenderGraph->AddNode("G-Buffer", { "Entity ID", "Depth Buffer", "Scene"}, {}); // no predecessors
 
      //First subpass to write to G-Buffer
     auto gBufferWriteSubpass = node->AddSubpass("G-Buffer Write");
-    gBufferWriteSubpass->AddColorOutput("Present");
+    gBufferWriteSubpass->AddColorOutput("Scene");
     gBufferWriteSubpass->AddColorOutput("Entity ID");
-    gBufferWriteSubpass->AddDepthOutput ("Depth Buffer", SH_ATT_DESC_TYPE::DEPTH_STENCIL);
+    gBufferWriteSubpass->AddDepthOutput("Depth Buffer", SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL);
 
+    // We do this to just transition our scene layout to shader read
+    auto sceneLayoutTransitionSubpass = node->AddSubpass("Scene Layout Transition");
+    sceneLayoutTransitionSubpass->AddInput("Scene");
 
-    // TODO: Use macro to add this node when SH_EDITOR is enabled
-    auto imguiNode = worldRenderGraph->AddNode("ImGui Node", { "Present" }, {"G-Buffer"});
-    auto imguiSubpass = imguiNode->AddSubpass("ImGui Draw");
-    imguiSubpass->AddColorOutput("Present");
-
+    // Generate world render graph
     worldRenderGraph->Generate();
 
-    // Create Semaphore
-    for (auto& semaHandle : graphSemaphores)
-    {
-      semaHandle = device->CreateSemaphore();
-    }
-
-    // Create Debug Renderers
-    /*debugScreenRenderer = defaultViewport->AddRenderer(resourceManager, worldRenderGraph);
-    debugScreenRenderer->SetCamera(screenCamera);
-    debugWorldRenderer = defaultViewport->AddRenderer(resourceManager, worldRenderGraph);
-    debugWorldRenderer->SetCamera(worldCamera);*/
-
     // Add world renderer to default viewport
-    worldRenderer = defaultViewport->AddRenderer(resourceManager, swapchain->GetNumImages(), renderContextCmdPools, descPool, SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS], worldRenderGraph);
+    worldRenderer = worldViewport->AddRenderer(resourceManager, swapchain->GetNumImages(), renderContextCmdPools, descPool, SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS], worldRenderGraph);
     worldRenderer->SetCamera(worldCamera);
 
 
@@ -198,17 +188,97 @@ namespace SHADE
     cubeFS->Reflect();
 
     defaultMaterial = AddMaterial(cubeVS, cubeFS, gBufferWriteSubpass);
+  }
+
+  void SHGraphicsSystem::InitMiddleEnd(void) noexcept
+  {
+    SHGraphicsGlobalData::Init(device);
+
+    InitSceneRenderGraph();
+
+#ifdef SHEDITOR
+    InitEditorRenderGraph();
+#endif
+
+    // Create Semaphore
+    for (auto& semaHandle : graphSemaphores)
+    {
+      semaHandle = device->CreateSemaphore();
+    }
+  }
+
+  void SHGraphicsSystem::InitSubsystems(void) noexcept
+  {
 
     mousePickSystem = resourceManager.Create<SHMousePickSystem>();
 
     std::vector<Handle<SHVkCommandPool>> cmdPools;
     cmdPools.reserve(swapchain->GetNumImages());
     for (uint32_t i = 0; i < swapchain->GetNumImages(); ++i)
-    	cmdPools.push_back(renderContext.GetFrameData(i).cmdPoolHdls[0]);
+      cmdPools.push_back(renderContext.GetFrameData(i).cmdPoolHdls[0]);
 
     mousePickSystem->Init(device, cmdPools, worldRenderGraph->GetRenderGraphResource("Entity ID"));
+
+    // Register the post offscreen render to the system
+    postOffscreenRender = resourceManager.Create<SHPostOffscreenRenderSystem>();
+    postOffscreenRender->Init(device, worldRenderGraph->GetRenderGraphResource("Scene"), descPool);
   }
 
+#ifdef SHEDITOR
+  void SHGraphicsSystem::InitEditorRenderGraph(void) noexcept
+  {
+    auto windowDims = window->GetWindowSize();
+
+    // Create Default Viewport
+    editorViewport = AddViewport(vk::Viewport(0.0f, 0.0f, static_cast<float>(windowDims.first), static_cast<float>(windowDims.second), 0.0f, 1.0f));
+
+    // Get render graph from viewport editor renderer
+    editorRenderGraph = resourceManager.Create<SHRenderGraph>();
+
+    std::vector<Handle<SHVkCommandPool>> renderContextCmdPools{ swapchain->GetNumImages() };
+    for (uint32_t i = 0; i < renderContextCmdPools.size(); ++i)
+      renderContextCmdPools[i] = renderContext.GetFrameData(i).cmdPoolHdls[0];
+
+    editorRenderGraph->Init(device, swapchain);
+    editorRenderGraph->AddResource("Present", { SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT }, windowDims.first, windowDims.second);
+
+
+    auto imguiNode = editorRenderGraph->AddNode("ImGui Node", { "Present"}, {});
+    auto imguiSubpass = imguiNode->AddSubpass("ImGui Draw");
+    imguiSubpass->AddColorOutput("Present");
+
+    // Generate world render graph
+    editorRenderGraph->Generate();
+
+    // Add world renderer to default viewport
+    editorRenderer = editorViewport->AddRenderer(resourceManager, swapchain->GetNumImages(), renderContextCmdPools, descPool, SHGraphicsGlobalData::GetDescSetLayouts()[SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS], editorRenderGraph);
+    editorRenderer->SetCamera(worldCamera);
+  }
+#endif
+
+  /*---------------------------------------------------------------------------------*/
+  /* Constructor/Destructors                                                         */
+  /*---------------------------------------------------------------------------------*/
+  void SHGraphicsSystem::Init(void)
+  {
+    InitBoilerplate();
+    InitMiddleEnd();
+    InitSubsystems();
+
+
+  }
+
+  void SHGraphicsSystem::Exit(void)
+  {
+  }
+
+#pragma endregion INIT_EXIT
+
+#pragma region LIFECYCLE
+
+  /*---------------------------------------------------------------------------------*/
+  /* Lifecycle Functions                                                             */
+  /*---------------------------------------------------------------------------------*/
   /***************************************************************************/
   /*!
   
@@ -227,12 +297,6 @@ namespace SHADE
     if (window->IsMinimized() || renderContext.GetWindowIsDead())
       return;
 
-    if (renderContext.GetResized())
-    {
-      return;
-    }
-
-
     // Frame data for the current frame
     auto const& frameData = renderContext.GetCurrentFrameData();
     uint32_t frameIndex = renderContext.GetCurrentFrame();
@@ -328,14 +392,7 @@ namespace SHADE
       }
     }
   }
-
-  void SHGraphicsSystem::Exit(void)
-  {
-  }
-
-  /*---------------------------------------------------------------------------------*/
-  /* Lifecycle Functions                                                             */
-  /*---------------------------------------------------------------------------------*/
+  
   /***************************************************************************/
   /*!
 
@@ -400,12 +457,6 @@ namespace SHADE
     if (window->IsMinimized() || renderContext.GetWindowIsDead())
       return;
 
-    if (renderContext.GetResized())
-    {
-      return;
-    }
-
-
     const uint32_t CURR_FRAME_IDX = renderContext.GetCurrentFrame();
     auto& currFrameData = renderContext.GetCurrentFrameData();
 
@@ -417,9 +468,7 @@ namespace SHADE
       // If swapchain is incompatible/outdated
       if (result == vk::Result::eErrorOutOfDateKHR || result == vk::Result::eSuboptimalKHR)
       {
-
         HandleResize();
-
       }
     }
 
@@ -427,6 +476,10 @@ namespace SHADE
     renderContext.AdvanceFrame();
   }
 
+#pragma endregion LIFECYCLE
+
+#pragma region ADD_REMOVE_BUILD
+
   Handle<SHViewport> SHGraphicsSystem::AddViewport(const vk::Viewport& viewport)
   {
     // Create the viewport
@@ -537,41 +590,14 @@ namespace SHADE
       );
   }
 
-  void SHGraphicsSystem::HandleResize(void) noexcept
-  {
-    if (window->IsMinimized() || renderContext.GetWindowIsDead())
-      return;
-
-    auto windowDims = window->GetWindowSize();
-
-    // Resize the swapchain
-    swapchain->Resize(surface, windowDims.first, windowDims.second);
-
-    renderContext.HandleResize();
-
-    worldRenderGraph->HandleResize(windowDims.first, windowDims.second);
-
-    defaultViewport->SetWidth(static_cast<float>(windowDims.first));
-    defaultViewport->SetHeight(static_cast<float>(windowDims.second));
-
-    worldCamera->SetPerspective(90.0f, static_cast<float>(windowDims.first), static_cast<float>(windowDims.second), 0.0f, 100.0f);
-  }
-  
-  void SHGraphicsSystem::AwaitGraphicsExecution()
-  {
-    device->WaitIdle();
-  }
-
-  void SHGraphicsSystem::SetWindow(SHWindow* wind) noexcept
-  {
-    window = wind;
-  }
+#pragma endregion ADD_REMOVE
 
+#pragma region ROUTINES
   /*-----------------------------------------------------------------------------------*/
   /* System Routine Functions - BeginRoutine                                           */
   /*-----------------------------------------------------------------------------------*/
   SHGraphicsSystem::BeginRoutine::BeginRoutine()
-  : SHSystemRoutine("Graphics System Frame Set Up", false)
+  : SHSystemRoutine("Graphics System Frame Set Up", true)
   {}
 
   void SHGraphicsSystem::BeginRoutine::Execute(double) noexcept
@@ -583,7 +609,7 @@ namespace SHADE
   /* System Routine Functions - RenderRoutine                                          */
   /*-----------------------------------------------------------------------------------*/
   SHGraphicsSystem::RenderRoutine::RenderRoutine()
-  : SHSystemRoutine("Graphics System Render", false)
+  : SHSystemRoutine("Graphics System Render", true)
   {}
 
   void SHGraphicsSystem::RenderRoutine::Execute(double dt) noexcept
@@ -595,7 +621,7 @@ namespace SHADE
   /* System Routine Functions - EndRoutine                                             */
   /*-----------------------------------------------------------------------------------*/
   SHGraphicsSystem::EndRoutine::EndRoutine()
-  : SHSystemRoutine("Graphics System Frame Clean Up", false)
+  : SHSystemRoutine("Graphics System Frame Clean Up", true)
   {}
 
   void SHGraphicsSystem::EndRoutine::Execute(double) noexcept
@@ -607,7 +633,7 @@ namespace SHADE
   /* System Routine Functions - BatcherDispatcherRoutine                               */
   /*-----------------------------------------------------------------------------------*/
   SHGraphicsSystem::BatcherDispatcherRoutine::BatcherDispatcherRoutine()
-  : SHSystemRoutine("Graphics System Batcher Dispatcher", false)
+  : SHSystemRoutine("Graphics System Batcher Dispatcher", true)
   {}
 
   void SHGraphicsSystem::BatcherDispatcherRoutine::Execute(double) noexcept
@@ -638,5 +664,62 @@ namespace SHADE
       renderable.ResetChangedFlag();
     }
   }
+#pragma endregion ROUTINES
 
+#pragma region MISC
+
+  void SHGraphicsSystem::PrepareResize(uint32_t newWidth, uint32_t newHeight) noexcept
+  {
+    resizeWidth = newWidth;
+    resizeHeight = newHeight;
+
+    renderContext.SetIsResized(true);
+  }
+
+  void SHGraphicsSystem::HandleResize(void) noexcept
+  {
+    device->WaitIdle();
+
+    if (window->IsMinimized() || renderContext.GetWindowIsDead())
+      return;
+
+    graphSemaphores[0].Free();
+    graphSemaphores[1].Free();
+
+    auto windowDims = window->GetWindowSize();
+
+    // Resize the swapchain
+    swapchain->Resize(surface, windowDims.first, windowDims.second);
+
+    renderContext.HandleResize();
+
+    worldRenderGraph->HandleResize(resizeWidth, resizeHeight);
+    editorRenderGraph->HandleResize(windowDims.first, windowDims.second);
+
+    mousePickSystem->HandleResize();
+    postOffscreenRender->HandleResize();
+
+    worldViewport->SetWidth(static_cast<float>(resizeWidth));
+    worldViewport->SetHeight(static_cast<float>(resizeHeight));
+
+    worldCamera->SetPerspective(90.0f, static_cast<float>(resizeWidth), static_cast<float>(resizeHeight), 0.0f, 100.0f);
+
+    for (auto& semaHandle : graphSemaphores)
+      semaHandle = device->CreateSemaphore();
+
+
+  }
+  
+  void SHGraphicsSystem::AwaitGraphicsExecution()
+  {
+    device->WaitIdle();
+  }
+
+  void SHGraphicsSystem::SetWindow(SHWindow* wind) noexcept
+  {
+    window = wind;
+  }
+
+
+#pragma endregion MISC
 }
diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h
index 3160cd57..7d0fa3ab 100644
--- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h
+++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHGraphicsSystem.h
@@ -31,6 +31,7 @@ of DigiPen Institute of Technology is prohibited.
 #include "Graphics/MiddleEnd/Materials/SHMaterialInstanceCache.h"
 #include "../Textures/SHTextureLibrary.h"
 #include "../Textures/SHVkSamplerCache.h"
+#include "Graphics/MiddleEnd/Interface/SHPostOffscreenRenderSystem.h"
 
 namespace SHADE
 {
@@ -66,6 +67,16 @@ namespace SHADE
   /***********************************************************************************/
   class SH_API SHGraphicsSystem : public SHSystem
   {
+  private:
+    void InitBoilerplate       (void) noexcept;
+    void InitSceneRenderGraph  (void) noexcept;
+    void InitMiddleEnd         (void) noexcept;
+    void InitSubsystems        (void) noexcept;
+
+#ifdef SHEDITOR
+    void InitEditorRenderGraph (void) noexcept;
+#endif
+
   public:
     class SH_API BeginRoutine final : public SHSystemRoutine
     {
@@ -251,6 +262,7 @@ namespace SHADE
     /***************************************************************************/
     void BuildTextures();
 
+    void PrepareResize(uint32_t newWidth, uint32_t newHeight) noexcept;
     void HandleResize(void) noexcept;
     void AwaitGraphicsExecution();
 
@@ -262,20 +274,25 @@ namespace SHADE
     /*-----------------------------------------------------------------------------*/
     /* Getters (Temporary)                                                         */
     /*-----------------------------------------------------------------------------*/
-    Handle<SHVkLogicalDevice> GetDevice() const { return device; }
-    Handle<SHVkSwapchain> GetSwapchain() const { return swapchain; }
-    Handle<SHVkSurface> GetSurface() const { return surface; }
-    Handle<SHVkPhysicalDevice> GetPhysicalDevice() const { return physicalDevice; }
-    Handle<SHVkQueue> GetQueue() const { return graphicsQueue; }
-    Handle<SHVkDescriptorPool> GetDescriptorPool() const { return descPool; }
-    Handle<SHViewport> GetDefaultViewport() const {return defaultViewport;}
-    Handle<SHMousePickSystem> GetMousePickSystem(void) const noexcept {return mousePickSystem;};
+    Handle<SHVkLogicalDevice>           GetDevice() const { return device; }
+    Handle<SHVkSwapchain>               GetSwapchain() const { return swapchain; }
+    Handle<SHVkSurface>                 GetSurface() const { return surface; }
+    Handle<SHVkPhysicalDevice>          GetPhysicalDevice() const { return physicalDevice; }
+    Handle<SHVkQueue>                   GetQueue() const { return graphicsQueue; }
+    Handle<SHVkDescriptorPool>          GetDescriptorPool() const { return descPool; }
+    Handle<SHViewport>                  GetDefaultViewport() const {return worldViewport;}
+#ifdef SHEDITOR
+    Handle<SHViewport>                  GetEditorViewport () const {return editorViewport;};
+#endif
+    Handle<SHMousePickSystem>           GetMousePickSystem(void) const noexcept {return mousePickSystem;};
+    Handle<SHPostOffscreenRenderSystem> GetPostOffscreenRenderSystem(void) const noexcept {return postOffscreenRender;};
     //SHRenderGraph const& GetRenderGraph(void) const noexcept;
 
     //Handle<SHVkRenderpass> GetRenderPass() const { return renderPass; }
 
 
   private:
+
     /*-----------------------------------------------------------------------------*/
     /* Data Members                                                                */
     /*-----------------------------------------------------------------------------*/
@@ -296,13 +313,19 @@ namespace SHADE
     SHWindow*                                                 window = nullptr;
 
     // Middle End Resources
-	  ResourceManager                                           resourceManager;
+    ResourceManager                                           resourceManager;
     SHMeshLibrary                                             meshLibrary;
     SHTextureLibrary                                          texLibrary;
     SHSamplerCache                                            samplerCache;
     SHMaterialInstanceCache                                   materialInstanceCache;
     // Viewports 
-    Handle<SHViewport>                                        defaultViewport;    // Whole screen
+#ifdef SHEDITOR
+    Handle<SHViewport>                                        editorViewport;
+    Handle<SHRenderer>                                        editorRenderer;
+    Handle<SHRenderGraph>                                     editorRenderGraph;
+#endif
+
+    Handle<SHViewport>                                        worldViewport;    // Whole screen
     std::vector<Handle<SHViewport>>                           viewports;          // Additional viewports
 
     // Debug Renderers
@@ -327,5 +350,9 @@ namespace SHADE
 
     // Sub systems
     Handle<SHMousePickSystem>                                 mousePickSystem;
+    Handle<SHPostOffscreenRenderSystem>                       postOffscreenRender;
+
+    uint32_t                                                  resizeWidth;
+    uint32_t                                                  resizeHeight;
   };
 }
\ No newline at end of file
diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMousePickSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMousePickSystem.cpp
index ee8665d5..57a08d47 100644
--- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMousePickSystem.cpp
+++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMousePickSystem.cpp
@@ -6,12 +6,15 @@
 #include "Graphics/Synchronization/SHVkFence.h"
 #include "Graphics/Buffers/SHVkBuffer.h"
 #include "Graphics/SHVkUtil.h"
+#include "Graphics/MiddleEnd/Interface/SHViewport.h"
 
 namespace SHADE
 {
-  void SHMousePickSystem::Init(Handle<SHVkLogicalDevice> logicalDevice, std::span<Handle<SHVkCommandPool>> cmdPools, Handle<SHRenderGraphResource> eidAttachment) noexcept
+  void SHMousePickSystem::Init(Handle<SHVkLogicalDevice> device, std::span<Handle<SHVkCommandPool>> cmdPools, Handle<SHRenderGraphResource> eidAttachment) noexcept
   {
-    pickedEID = 0;
+    logicalDevice = device;
+
+    pickedEID = MAX_EID;
 
     // Create command buffers
     for (auto& pool : cmdPools)
@@ -22,19 +25,13 @@ namespace SHADE
     // assign the attachment
     entityIDAttachment = eidAttachment;
     
-    // Create the fence
-    afterCopyFence = logicalDevice->CreateFence();
-
-    uint32_t bufferSize = entityIDAttachment->GetWidth() * eidAttachment->GetHeight() * SHVkUtil::GetBytesPerPixelFromFormat(entityIDAttachment->GetResourceFormat());
-
-    // Create the buffer
-    imageDataDstBuffer = logicalDevice->CreateBuffer(bufferSize, nullptr, bufferSize, vk::BufferUsageFlagBits::eTransferDst, VMA_MEMORY_USAGE_AUTO, VMA_ALLOCATION_CREATE_MAPPED_BIT |  VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT);
+    HandleResize();
   }
 
   void SHMousePickSystem::Run(Handle<SHVkQueue> queue, uint32_t frameIndex) noexcept
   {
     // if input detected
-    if (SHInputManager::GetKey(SHInputManager::SH_KEYCODE::LEFT_CTRL) && SHInputManager::GetKeyUp(SHInputManager::SH_KEYCODE::LMB))
+    if (SHInputManager::GetKeyUp(SHInputManager::SH_KEYCODE::LMB))
     {
       afterCopyFence->Reset();
 
@@ -56,13 +53,36 @@ namespace SHADE
       // wait for the copy to be done
       afterCopyFence->Wait(true, std::numeric_limits<uint64_t>::max());
 
-      int mouseX = 0, mouseY = 0;
-      SHInputManager::GetMouseWindowPosition(&mouseX, &mouseY);
+      pickedEID = imageDataDstBuffer->GetDataFromMappedPointer<uint32_t>(static_cast<uint32_t>(viewportMousePos.y) * entityIDAttachment->GetWidth() + static_cast<uint32_t>(viewportMousePos.x));
 
-      pickedEID = imageDataDstBuffer->GetDataFromMappedPointer<uint32_t>(mouseY * entityIDAttachment->GetWidth() + mouseX);
     }
   }
 
+  void SHMousePickSystem::HandleResize(void) noexcept
+  {
+    if (afterCopyFence)
+    {
+      afterCopyFence->Reset();
+      afterCopyFence.Free();
+    }
+
+    if (imageDataDstBuffer)
+      imageDataDstBuffer.Free();
+
+    // Create the fence
+    afterCopyFence = logicalDevice->CreateFence();
+
+    uint32_t bufferSize = entityIDAttachment->GetWidth() * entityIDAttachment->GetHeight() * SHVkUtil::GetBytesPerPixelFromFormat(entityIDAttachment->GetResourceFormat());
+
+    // Create the buffer
+    imageDataDstBuffer = logicalDevice->CreateBuffer(bufferSize, nullptr, bufferSize, vk::BufferUsageFlagBits::eTransferDst, VMA_MEMORY_USAGE_AUTO, VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT);
+  }
+
+  void SHMousePickSystem::SetViewportMousePos(SHVec2 vpMousePos) noexcept
+  {
+    viewportMousePos = vpMousePos;
+  }
+
   EntityID SHMousePickSystem::GetPickedEntity(void) const noexcept
   {
     return pickedEID;
diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMousePickSystem.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMousePickSystem.h
index 080a192c..85e86969 100644
--- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMousePickSystem.h
+++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHMousePickSystem.h
@@ -13,10 +13,13 @@ namespace SHADE
   class SHVkFence;
   class SHVkQueue;
   class SHVkBuffer;
+  class SHViewport;
 
   class SHMousePickSystem
   {
   private:
+    Handle<SHVkLogicalDevice>     logicalDevice;
+
     //! Handle to the render graph resource that will contain the entity IDs
     Handle<SHRenderGraphResource> entityIDAttachment; 
 
@@ -31,16 +34,23 @@ namespace SHADE
 
     //! eid picked from screen
     EntityID pickedEID;
+
+    //! mouse position relative to the viewport window displaying the world
+    SHVec2 viewportMousePos;
+
   public:
     /*-----------------------------------------------------------------------*/
     /* PUBLIC MEMBER FUNCTIONS                                              */
     /*-----------------------------------------------------------------------*/
-    void Init(Handle<SHVkLogicalDevice> logicalDevice, std::span<Handle<SHVkCommandPool>> cmdPools, Handle<SHRenderGraphResource> eidAttachment) noexcept;
+    void Init(Handle<SHVkLogicalDevice> device, std::span<Handle<SHVkCommandPool>> cmdPools, Handle<SHRenderGraphResource> eidAttachment) noexcept;
     void Run (Handle<SHVkQueue> queue, uint32_t frameIndex) noexcept; 
+    void HandleResize (void) noexcept;
 
     /*-----------------------------------------------------------------------*/
     /* SETTERS AND GETTERS                                                   */
     /*-----------------------------------------------------------------------*/
+    void SetViewportMousePos (SHVec2 vpMousePos) noexcept;
+
     EntityID GetPickedEntity (void) const noexcept;
 
   };
diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHPostOffscreenRenderSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHPostOffscreenRenderSystem.cpp
new file mode 100644
index 00000000..8b41a979
--- /dev/null
+++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHPostOffscreenRenderSystem.cpp
@@ -0,0 +1,84 @@
+#include "SHpch.h"
+#include "SHPostOffscreenRenderSystem.h"
+#include "Graphics/Descriptors/SHVkDescriptorSetLayout.h"
+#include "Graphics/Descriptors/SHVkDescriptorSetGroup.h"
+#include "Graphics/Descriptors/SHVkDescriptorPool.h"
+#include "Graphics/Devices/SHVkLogicalDevice.h"
+#include "Graphics/Images/SHVkSampler.h"
+#include "Graphics/RenderGraph/SHRenderGraphResource.h"
+
+namespace SHADE
+{
+  /***************************************************************************/
+  /*!
+  
+    \brief
+      This function basically creates the entities required for offscreen
+      rendering. It takes in a render graph resource. Side note: it creates
+      a descriptor set layout that is similar to the one created in imgui. This
+      is so that the descriptor set passed to imGui won't be invalid.
+    
+    \param logicalDevice
+      For vulkan object creation
+
+    \param renderGraphResource
+      The resource in which has been 
+
+    \param descriptorPool
+   
+    \return 
+  
+  */
+  /***************************************************************************/
+  void SHPostOffscreenRenderSystem::Init(Handle<SHVkLogicalDevice> logicalDevice, Handle<SHRenderGraphResource> renderGraphResource, Handle<SHVkDescriptorPool> descriptorPool) noexcept
+  {
+    offscreenRender = renderGraphResource;
+
+    // Create sampler
+    offscreenRenderSampler = logicalDevice->CreateSampler(
+      {
+        .minFilter = vk::Filter::eLinear,
+        .magFilter = vk::Filter::eLinear,
+        .addressMode = vk::SamplerAddressMode::eRepeat,
+        .mipmapMode = vk::SamplerMipmapMode::eLinear,
+        .minLod = -1000,
+        .maxLod = 1000
+      }
+    );
+
+    // Create descriptor set layout binding
+    SHVkDescriptorSetLayout::Binding imageBinding
+    {
+      .Type = vk::DescriptorType::eCombinedImageSampler,
+      .Stage = vk::ShaderStageFlagBits::eFragment,
+      .BindPoint = 0,
+      .DescriptorCount = 1,
+    };
+
+    // Create descriptor set layout
+    offscreenRenderDescSetLayout = logicalDevice->CreateDescriptorSetLayout(0, { imageBinding }, false);
+
+    // Create descriptor set
+    offscreenRenderDescSet = descriptorPool->Allocate({ offscreenRenderDescSetLayout }, { 1 });
+    
+    HandleResize();
+  }
+
+  void SHPostOffscreenRenderSystem::HandleResize(void) noexcept
+  {
+    std::vector combinedImageSampler
+    {
+      std::make_tuple(offscreenRender->GetImageView(), offscreenRenderSampler, vk::ImageLayout::eShaderReadOnlyOptimal),
+    };
+
+    // Register the image view and sampler with the descriptor set. Now whenever rendering to the offscreen image is done, the descriptor set will see the change
+    offscreenRenderDescSet->ModifyWriteDescImage(0, 0, combinedImageSampler);
+    offscreenRenderDescSet->UpdateDescriptorSetImages(0, 0);
+  }
+
+  Handle<SHVkDescriptorSetGroup> SHPostOffscreenRenderSystem::GetDescriptorSetGroup(void) const noexcept
+  {
+    return offscreenRenderDescSet;
+  }
+
+}
\ No newline at end of file
diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHPostOffscreenRenderSystem.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHPostOffscreenRenderSystem.h
new file mode 100644
index 00000000..d3360b87
--- /dev/null
+++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHPostOffscreenRenderSystem.h
@@ -0,0 +1,31 @@
+#pragma once
+
+#include "Resource/Handle.h"
+
+namespace SHADE
+{
+  class SHVkLogicalDevice;
+  class SHVkDescriptorSetLayout;
+  class SHVkDescriptorSetGroup;
+  class SHVkDescriptorPool;
+  class SHVkSampler;
+  class SHRenderGraphResource;
+
+  class SHPostOffscreenRenderSystem
+  {
+  private:
+    Handle<SHRenderGraphResource>   offscreenRender;
+    
+    Handle<SHVkDescriptorSetLayout> offscreenRenderDescSetLayout;
+    Handle<SHVkDescriptorSetGroup>  offscreenRenderDescSet;
+    Handle<SHVkSampler>             offscreenRenderSampler;
+
+  public:
+    void Init (Handle<SHVkLogicalDevice> logicalDevice, Handle<SHRenderGraphResource> renderGraphResource, Handle<SHVkDescriptorPool> descriptorPool) noexcept;
+    //void Run ()
+
+    void HandleResize (void) noexcept;
+
+    Handle<SHVkDescriptorSetGroup> GetDescriptorSetGroup (void) const noexcept;
+  };
+}
diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.cpp
index 14af56ee..425e9c81 100644
--- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.cpp
+++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHRenderer.cpp
@@ -75,12 +75,15 @@ namespace SHADE
 
   void SHRenderer::UpdateDataAndBind(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept
   {
-    cpuCameraData.viewProjectionMatrix = camera->GetViewProjectionMatrix();
-    cameraBuffer->WriteToMemory(&cpuCameraData, sizeof(SHShaderCameraData), 0, cameraDataAlignedSize * frameIndex);
+    if (camera)
+    {
+      cpuCameraData.viewProjectionMatrix = camera->GetViewProjectionMatrix();
+      cameraBuffer->WriteToMemory(&cpuCameraData, sizeof(SHShaderCameraData), 0, cameraDataAlignedSize * frameIndex);
 
-      std::array<uint32_t, 1> dynamicOffsets{ frameIndex * cameraDataAlignedSize };
+        std::array<uint32_t, 1> dynamicOffsets{ frameIndex * cameraDataAlignedSize };
 
-    cmdBuffer->BindDescriptorSet(cameraDescriptorSet, vk::PipelineBindPoint::eGraphics, SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS, std::span{ dynamicOffsets.data(), 1 });
+      cmdBuffer->BindDescriptorSet(cameraDescriptorSet, vk::PipelineBindPoint::eGraphics, SHGraphicsConstants::DescriptorSetIndex::HIGH_FREQUENCY_GLOBALS, std::span{ dynamicOffsets.data(), 1 });
+    }
   }
 
   void SHRenderer::UpdateCameraDataToBuffer(void) noexcept
diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.cpp
index dc534a49..f47920e0 100644
--- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.cpp
+++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.cpp
@@ -85,4 +85,14 @@ namespace SHADE
 
   }
 
+  void SHViewport::SetX(float x) noexcept
+  {
+		viewport.x = x;
+  }
+
+  void SHViewport::SetY(float y) noexcept
+  {
+    viewport.y = y;
+  }
+
 }
diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.h b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.h
index 221dbe7e..04b39f00 100644
--- a/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.h
+++ b/SHADE_Engine/src/Graphics/MiddleEnd/Interface/SHViewport.h
@@ -67,6 +67,8 @@ namespace SHADE
 		/*-----------------------------------------------------------------------------*/
 		void SetWidth(float w) noexcept;
 		void SetHeight (float h) noexcept;
+		void SetX (float x) noexcept;
+		void SetY (float y) noexcept;
 
 		/*-----------------------------------------------------------------------------*/
 		/* Getters                                                                     */
diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/PerFrame/SHRenderContext.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/PerFrame/SHRenderContext.cpp
index 0ac7013a..8041adfd 100644
--- a/SHADE_Engine/src/Graphics/MiddleEnd/PerFrame/SHRenderContext.cpp
+++ b/SHADE_Engine/src/Graphics/MiddleEnd/PerFrame/SHRenderContext.cpp
@@ -52,7 +52,6 @@ namespace SHADE
       {
         frameData[i].cmdPoolHdls.push_back(logicalDeviceHdl->CreateCommandPool(params.cmdPoolQueueFamilyType, params.cmdPoolResetMode, params.cmdBufferTransient));
       }
-
     }
 
     // Initialize all the info.
diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHAttachmentDescInitParams.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHAttachmentDescInitParams.cpp
new file mode 100644
index 00000000..6e01269e
--- /dev/null
+++ b/SHADE_Engine/src/Graphics/RenderGraph/SHAttachmentDescInitParams.cpp
@@ -0,0 +1,7 @@
+#include "SHpch.h"
+#include "SHAttachmentDescInitParams.h"
+
+namespace SHADE
+{
+
+}
diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHAttachmentDescInitParams.h b/SHADE_Engine/src/Graphics/RenderGraph/SHAttachmentDescInitParams.h
new file mode 100644
index 00000000..20e924cb
--- /dev/null
+++ b/SHADE_Engine/src/Graphics/RenderGraph/SHAttachmentDescInitParams.h
@@ -0,0 +1,14 @@
+#pragma once
+
+#include "Resource/Handle.h"
+
+namespace SHADE
+{
+  class SHRenderGraphResource;
+
+  struct SHAttachmentDescInitParams
+  {
+    Handle<SHRenderGraphResource> resourceHdl;
+    bool dontClearOnLoad{false};
+  };
+}
diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHAttachmentDescriptionType.h b/SHADE_Engine/src/Graphics/RenderGraph/SHAttachmentDescriptionType.h
index dc21fa37..241292d4 100644
--- a/SHADE_Engine/src/Graphics/RenderGraph/SHAttachmentDescriptionType.h
+++ b/SHADE_Engine/src/Graphics/RenderGraph/SHAttachmentDescriptionType.h
@@ -3,12 +3,13 @@
 namespace SHADE
 {
   // Used for attachment description creation for renderpass node
-  enum class SH_ATT_DESC_TYPE
+  enum class SH_ATT_DESC_TYPE_FLAGS
   {
-    COLOR,
-    COLOR_PRESENT,
-    DEPTH,
-    STENCIL,
-    DEPTH_STENCIL,
+    COLOR = 0x01,
+    COLOR_PRESENT = 0x02,
+    DEPTH = 0x04,
+    STENCIL = 0x08,
+    DEPTH_STENCIL = 0x10,
+    INPUT = 0x20
   };
 }
diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp
index 1861f6d2..98cb6709 100644
--- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp
+++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.cpp
@@ -8,10 +8,17 @@
 #include "Graphics/Framebuffer/SHVkFramebuffer.h"
 #include "Graphics/Buffers/SHVkBuffer.h"
 #include "Tools/SHLogger.h"
+#include "SHAttachmentDescInitParams.h"
 
 namespace SHADE
 {
-  
+
+  SHRenderGraph::ResourceInstruction::ResourceInstruction(char const* resourceName, bool dontClearOnLoad /*= false*/) noexcept
+    : resourceName{ resourceName }
+    , dontClearOnLoad{ dontClearOnLoad }
+  {
+
+  }
 
   /***************************************************************************/
   /*!
@@ -40,7 +47,7 @@ namespace SHADE
 
   */
   /***************************************************************************/
-  void SHRenderGraph::AddResource(std::string resourceName, SH_ATT_DESC_TYPE type, uint32_t w /*= static_cast<uint32_t>(-1)*/, uint32_t h /*= static_cast<uint32_t>(-1)*/, vk::Format format/* = vk::Format::eB8G8R8A8Unorm*/, uint8_t levels /*= 1*/, vk::ImageUsageFlagBits usageFlags/* = {}*/, vk::ImageCreateFlagBits createFlags /*= {}*/)
+  void SHRenderGraph::AddResource(std::string resourceName, std::initializer_list<SH_ATT_DESC_TYPE_FLAGS> typeFlags, uint32_t w /*= static_cast<uint32_t>(-1)*/, uint32_t h /*= static_cast<uint32_t>(-1)*/, vk::Format format/* = vk::Format::eB8G8R8A8Unorm*/, uint8_t levels /*= 1*/, vk::ImageUsageFlagBits usageFlags/* = {}*/, vk::ImageCreateFlagBits createFlags /*= {}*/)
   {
     // If we set to 
     if (w == static_cast<uint32_t>(-1) && h == static_cast<uint32_t>(-1))
@@ -50,7 +57,7 @@ namespace SHADE
       format = swapchainHdl->GetSurfaceFormatKHR().format;
     }
 
-    graphResources.try_emplace(resourceName, resourceManager.Create<SHRenderGraphResource>(logicalDeviceHdl, swapchainHdl, resourceName, type, format, w, h, levels, usageFlags, createFlags));
+    graphResources.try_emplace(resourceName, resourceManager->Create<SHRenderGraphResource>(logicalDeviceHdl, swapchainHdl, resourceName, typeFlags, format, w, h, levels, usageFlags, createFlags));
   }
 
   /***************************************************************************/
@@ -82,7 +89,7 @@ namespace SHADE
       {
         for (auto& color : subpass->colorReferences)
         {
-          if (i == nodes.size() - 1 && node->attResources[color.attachment]->resourceType == SH_ATT_DESC_TYPE::COLOR_PRESENT)
+          if (i == nodes.size() - 1 && (node->attResources[color.attachment]->resourceTypeFlags & static_cast<uint32_t>(SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT)))
             resourceAttLayouts[color.attachment] = vk::ImageLayout::ePresentSrcKHR;
           else
             resourceAttLayouts[color.attachment] = color.layout;
@@ -95,11 +102,11 @@ namespace SHADE
           resourceAttLayouts[input.attachment] = input.layout;
       }
 
-      for (uint32_t i = 0; i < node->attachmentDescriptions.size(); ++i)
+      for (uint32_t j = 0; j < node->attachmentDescriptions.size(); ++j)
       {
-        auto& att = node->attachmentDescriptions[i];
+        auto& att = node->attachmentDescriptions[j];
         att.initialLayout = vk::ImageLayout::eUndefined;
-        att.finalLayout = resourceAttLayouts[i];
+        att.finalLayout = resourceAttLayouts[j];
       }
       ++i;
     }
@@ -210,10 +217,18 @@ namespace SHADE
         for (auto& inputAtt : subpass->inputReferences)
         {
           auto resource = node->attResources[inputAtt.attachment];
-          if (resource->resourceType == SH_ATT_DESC_TYPE::COLOR || resource->resourceType == SH_ATT_DESC_TYPE::COLOR_PRESENT)
-            colorRead |= (1 << i);
-          else if (resource->resourceType == SH_ATT_DESC_TYPE::DEPTH_STENCIL)
-            depthRead |= (1 << i);
+          if (resource->resourceTypeFlags & static_cast<uint32_t>(SH_ATT_DESC_TYPE_FLAGS::INPUT))
+          {
+              if (resource->resourceTypeFlags & static_cast<uint32_t>(SH_ATT_DESC_TYPE_FLAGS::COLOR) ||
+                  resource->resourceTypeFlags & static_cast<uint32_t>(SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT))
+              colorRead |= (1 << i);
+            else if (resource->resourceTypeFlags & static_cast<uint32_t>(SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL))
+              depthRead |= (1 << i);
+          }
+          else
+          {
+            SHLOG_ERROR("While configuring subpass, an input reference was detected but the resource to be used is not marked as SH_ATT_DESC_TYPE_FLAGS::INPUT. ");
+          }
         }
 
         ++i;
@@ -350,10 +365,9 @@ namespace SHADE
     , swapchainHdl{ }
     , nodes{}
     , graphResources{}
-    , resourceManager{}
-
+    , resourceManager{nullptr}
   {
-
+    resourceManager = std::make_shared<ResourceManager>();
   }
 
   SHRenderGraph::SHRenderGraph(SHRenderGraph&& rhs) noexcept
@@ -400,7 +414,7 @@ namespace SHADE
 
   */
   /***************************************************************************/
-  Handle<SHRenderGraphNode> SHRenderGraph::AddNode(std::string nodeName, std::initializer_list<std::string> resourceNames, std::initializer_list<std::string> predecessorNodes) noexcept
+  SHADE::Handle<SHADE::SHRenderGraphNode> SHRenderGraph::AddNode(std::string nodeName, std::initializer_list<ResourceInstruction> resourceInstruction, std::initializer_list<std::string> predecessorNodes) noexcept
   {
     if (nodeIndexing.contains(nodeName))
     {
@@ -408,12 +422,19 @@ namespace SHADE
       return {};
     }
 
-    std::vector<Handle<SHRenderGraphResource>> resources;
-    for (auto const& name : resourceNames)
+    std::vector<SHAttachmentDescInitParams> descInitParams;
+    for (auto const& instruction : resourceInstruction)
     {
       // If the resource that the new node is requesting for exists, allow the graph to reference it
-      if (graphResources.contains(name))
-        resources.push_back(graphResources.at(name));
+      if (graphResources.contains(instruction.resourceName))
+      {
+        descInitParams.push_back(
+          {
+            .resourceHdl = graphResources.at(instruction.resourceName),
+            .dontClearOnLoad = false, 
+          }
+        );
+      }
       else
       {
         SHLOG_ERROR("Resource doesn't exist in graph yet. Cannot create new node.");
@@ -435,7 +456,7 @@ namespace SHADE
       }
     }
 
-    nodes.emplace_back(resourceManager.Create<SHRenderGraphNode>(resourceManager, logicalDeviceHdl, swapchainHdl, std::move(resources), std::move(predecessors), &graphResources));
+    nodes.emplace_back(resourceManager->Create<SHRenderGraphNode>(resourceManager, logicalDeviceHdl, swapchainHdl, std::move(descInitParams), std::move(predecessors), &graphResources));
     nodeIndexing.emplace(nodeName, static_cast<uint32_t>(nodes.size()) - 1u);
     return nodes.at(nodeIndexing[nodeName]);
   }
diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h
index cfc29bc2..952c6d8f 100644
--- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h
+++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraph.h
@@ -16,6 +16,7 @@
 
 #include <string>
 #include <map>
+#include <memory>
 
 namespace SHADE
 {
@@ -33,7 +34,17 @@ namespace SHADE
 
   class SH_API SHRenderGraph
   {
+  public:
+    struct ResourceInstruction
+    {
+      std::string resourceName;
+      bool dontClearOnLoad;
+
+      ResourceInstruction (char const* resourceName, bool dontClearOnLoad = false) noexcept;
+    };
+
   private:
+
     /*-----------------------------------------------------------------------*/
     /* PRIVATE MEMBER FUNCTIONS                                              */
     /*-----------------------------------------------------------------------*/
@@ -60,7 +71,7 @@ namespace SHADE
     std::unordered_map<std::string, Handle<SHRenderGraphResource>> graphResources;
 
     //! Resource library for graph handles
-    ResourceManager resourceManager;
+    std::shared_ptr<ResourceManager> resourceManager;
 
   public:
     /*-----------------------------------------------------------------------*/
@@ -74,13 +85,14 @@ namespace SHADE
     /*-----------------------------------------------------------------------*/
     /* PUBLIC MEMBER FUNCTIONS                                               */
     /*-----------------------------------------------------------------------*/
-    void Init (Handle<SHVkLogicalDevice> const& logicalDevice, Handle<SHVkSwapchain> const& swapchain) noexcept;
-    void                      AddResource(std::string resourceName, SH_ATT_DESC_TYPE type, uint32_t w = static_cast<uint32_t>(-1), uint32_t h = static_cast<uint32_t>(-1), vk::Format format = vk::Format::eB8G8R8A8Unorm, uint8_t levels = 1, vk::ImageUsageFlagBits usageFlags = {}, vk::ImageCreateFlagBits createFlags = {});
-    Handle<SHRenderGraphNode> AddNode      (std::string nodeName, std::initializer_list<std::string> resourceNames, std::initializer_list<std::string> predecessorNodes) noexcept;
+    void                      Init (Handle<SHVkLogicalDevice> const& logicalDevice, Handle<SHVkSwapchain> const& swapchain) noexcept;
+    void                      AddResource(std::string resourceName, std::initializer_list<SH_ATT_DESC_TYPE_FLAGS> typeFlags, uint32_t w = static_cast<uint32_t>(-1), uint32_t h = static_cast<uint32_t>(-1), vk::Format format = vk::Format::eB8G8R8A8Unorm, uint8_t levels = 1, vk::ImageUsageFlagBits usageFlags = {}, vk::ImageCreateFlagBits createFlags = {});
+    Handle<SHRenderGraphNode> AddNode (std::string nodeName, std::initializer_list<ResourceInstruction> resourceInstruction, std::initializer_list<std::string> predecessorNodes) noexcept;
+    
     void                      Generate     (void) noexcept;
-    void Execute (uint32_t frameIndex, Handle<SHVkCommandBuffer> cmdBuffer, Handle<SHVkDescriptorPool> descPool) noexcept;
-    void FinaliseBatch(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool);
-    void HandleResize (uint32_t newWidth, uint32_t newHeight) noexcept;
+    void                      Execute (uint32_t frameIndex, Handle<SHVkCommandBuffer> cmdBuffer, Handle<SHVkDescriptorPool> descPool) noexcept;
+    void                      FinaliseBatch(uint32_t frameIndex, Handle<SHVkDescriptorPool> descPool);
+    void                      HandleResize (uint32_t newWidth, uint32_t newHeight) noexcept;
 
     /*-----------------------------------------------------------------------*/
     /* SETTERS AND GETTERS                                                   */
diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp
index ea09dd47..ec184386 100644
--- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp
+++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.cpp
@@ -42,7 +42,7 @@ namespace SHADE
 
       for (uint32_t j = 0; j < attResources.size(); ++j)
       {
-        uint32_t imageViewIndex = (attResources[j]->resourceType == SH_ATT_DESC_TYPE::COLOR_PRESENT) ? i : 0;
+        uint32_t imageViewIndex = (attResources[j]->resourceTypeFlags & static_cast<uint32_t>(SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT)) ? i : 0;
         imageViews[j] = attResources[j]->imageViews[imageViewIndex];
 
         // We want the minimum dimensions for the framebuffer because the image attachments referenced cannot have dimensions smaller than the framebuffer's
@@ -69,7 +69,7 @@ namespace SHADE
 
       for (uint32_t j = 0; j < attResources.size(); ++j)
       {
-        uint32_t imageViewIndex = (attResources[j]->resourceType == SH_ATT_DESC_TYPE::COLOR_PRESENT) ? i : 0;
+        uint32_t imageViewIndex = (attResources[j]->resourceTypeFlags & static_cast<uint32_t>(SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT)) ? i : 0;
         imageViews[j] = attResources[j]->imageViews[imageViewIndex];
 
         // We want the minimum dimensions for the framebuffer because the image attachments referenced cannot have dimensions smaller than the framebuffer's
@@ -104,14 +104,14 @@ namespace SHADE
 
   */
   /***************************************************************************/
-  SHRenderGraphNode::SHRenderGraphNode(ResourceManager& rm, Handle<SHVkLogicalDevice> const& logicalDevice, Handle<SHVkSwapchain> const& swapchain, std::vector<Handle<SHRenderGraphResource>> attRes, std::vector<Handle<SHRenderGraphNode>> predecessors, std::unordered_map<std::string, Handle<SHRenderGraphResource>> const* resources) noexcept
+  SHRenderGraphNode::SHRenderGraphNode(std::shared_ptr<ResourceManager> rm, Handle<SHVkLogicalDevice> const& logicalDevice, Handle<SHVkSwapchain> const& swapchain, std::vector<SHAttachmentDescInitParams> attDescInitParams, std::vector<Handle<SHRenderGraphNode>> predecessors, std::unordered_map<std::string, Handle<SHRenderGraphResource>> const* resources) noexcept
     : logicalDeviceHdl{ logicalDevice }
     , renderpass{}
     , framebuffers{}
     , prereqNodes{ std::move(predecessors) }
     , attachmentDescriptions{}
     , resourceAttachmentMapping{}
-    , attResources{ std::move(attRes) }
+    , attResources{ }
     , subpasses{}
     , executed{ false }
     , configured{ false }
@@ -121,6 +121,12 @@ namespace SHADE
     // pipeline library initialization
     pipelineLibrary.Init(logicalDeviceHdl);
 
+    // Store all the handles to resources
+    attResources.reserve (attDescInitParams.size());
+    for (auto& param : attDescInitParams)
+      attResources.push_back(param.resourceHdl);
+
+    // We have as many descriptions as we have resources
     attachmentDescriptions.resize(attResources.size());
 
     bool containsSwapchainImage = false;
@@ -140,7 +146,7 @@ namespace SHADE
 
       newDesc.format = attResources[i]->resourceFormat;
 
-      if (attResources[i]->resourceType == SH_ATT_DESC_TYPE::COLOR_PRESENT)
+      if (attResources[i]->resourceTypeFlags & static_cast<uint32_t>(SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT))
         containsSwapchainImage = true;
 
       resourceAttachmentMapping.try_emplace(attResources[i].GetId().Raw, i);
@@ -156,7 +162,7 @@ namespace SHADE
   }
 
   SHRenderGraphNode::SHRenderGraphNode(SHRenderGraphNode&& rhs) noexcept
-    : resourceManager{ rhs.resourceManager }
+    : resourceManager{ std::move (rhs.resourceManager) }
     , logicalDeviceHdl{ rhs.logicalDeviceHdl }
     , renderpass{ rhs.renderpass }
     , framebuffers{ std::move(rhs.framebuffers) }
@@ -171,6 +177,8 @@ namespace SHADE
     , ptrToResources{ rhs.ptrToResources }
     , pipelineLibrary{ std::move(rhs.pipelineLibrary) }
     , batcher{ std::move(rhs.batcher) }
+    , spDescs{ std::move(rhs.spDescs) }
+    , spDeps{ std::move(rhs.spDeps) }
 
   {
     rhs.renderpass = {};
@@ -181,7 +189,7 @@ namespace SHADE
     if (&rhs == this)
       return *this;
 
-    resourceManager = rhs.resourceManager;
+    resourceManager = std::move(rhs.resourceManager);
     logicalDeviceHdl = rhs.logicalDeviceHdl;
     renderpass = rhs.renderpass;
     framebuffers = std::move(rhs.framebuffers);
@@ -194,6 +202,9 @@ namespace SHADE
     ptrToResources = std::move(rhs.ptrToResources);
     pipelineLibrary = std::move(rhs.pipelineLibrary);
     batcher = std::move(rhs.batcher);
+    spDescs = std::move(rhs.spDescs);
+    spDeps = std::move(rhs.spDeps);
+
 
     rhs.renderpass = {};
 
@@ -224,10 +235,10 @@ namespace SHADE
     }
 
     // Add subpass to container and create mapping for it
-    subpasses.emplace_back(resourceManager.Create<SHSubpass>(resourceManager, GetHandle(), subpasses.size(), &resourceAttachmentMapping, ptrToResources));
+    subpasses.emplace_back(resourceManager->Create<SHSubpass>(GetHandle(), subpasses.size(), &resourceAttachmentMapping, ptrToResources));
     subpassIndexing.try_emplace(subpassName, static_cast<uint32_t>(subpasses.size()) - 1u);
     Handle<SHSubpass> subpass = subpasses.back();
-    subpass->Init(resourceManager);
+    subpass->Init(*resourceManager);
 
     // Register the SuperBatch
     batcher.RegisterSuperBatch(subpass->GetSuperBatch());
diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h
index 28527a92..77861108 100644
--- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h
+++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphNode.h
@@ -9,6 +9,7 @@
 #include "SH_API.h"
 #include "Graphics/MiddleEnd/Pipeline/SHPipelineLibrary.h"
 #include "Graphics/MiddleEnd/Batching/SHBatcher.h"
+#include "SHAttachmentDescInitParams.h"
 
 namespace SHADE
 {
@@ -25,7 +26,7 @@ namespace SHADE
     /*-----------------------------------------------------------------------*/
     /* PRIVATE MEMBER VARIABLES                                              */
     /*-----------------------------------------------------------------------*/
-    ResourceManager& resourceManager;
+    std::shared_ptr<ResourceManager> resourceManager;
 
     //! For Vulkan object creation
     Handle<SHVkLogicalDevice> logicalDeviceHdl;
@@ -87,7 +88,7 @@ namespace SHADE
     /*-----------------------------------------------------------------------*/
     /* CTORS AND DTORS                                                       */
     /*-----------------------------------------------------------------------*/
-    SHRenderGraphNode(ResourceManager& rm, Handle<SHVkLogicalDevice> const& logicalDevice, Handle<SHVkSwapchain> const& swapchain, std::vector<Handle<SHRenderGraphResource>> attRes, std::vector<Handle<SHRenderGraphNode>> predecessors, std::unordered_map<std::string, Handle<SHRenderGraphResource>> const* resources) noexcept;
+    SHRenderGraphNode(std::shared_ptr<ResourceManager> rm, Handle<SHVkLogicalDevice> const& logicalDevice, Handle<SHVkSwapchain> const& swapchain, std::vector<SHAttachmentDescInitParams> attDescInitParams, std::vector<Handle<SHRenderGraphNode>> predecessors, std::unordered_map<std::string, Handle<SHRenderGraphResource>> const* resources) noexcept;
     SHRenderGraphNode(SHRenderGraphNode&& rhs) noexcept;
     SHRenderGraphNode& operator= (SHRenderGraphNode&& rhs) noexcept;
 
diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.cpp
index bcd1dc9f..adf3b6cd 100644
--- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.cpp
+++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.cpp
@@ -45,10 +45,10 @@ namespace SHADE
 
   */
   /***************************************************************************/
-  SHRenderGraphResource::SHRenderGraphResource(Handle<SHVkLogicalDevice> const& logicalDevice, Handle<SHVkSwapchain> const& swapchain, std::string const& name, SH_ATT_DESC_TYPE type, vk::Format format, uint32_t w, uint32_t h, uint8_t levels, vk::ImageUsageFlagBits usageFlags, vk::ImageCreateFlagBits createFlags) noexcept
+  SHRenderGraphResource::SHRenderGraphResource(Handle<SHVkLogicalDevice> const& logicalDevice, Handle<SHVkSwapchain> const& swapchain, std::string const& name, std::initializer_list<SH_ATT_DESC_TYPE_FLAGS> typeFlags, vk::Format format, uint32_t w, uint32_t h, uint8_t levels, vk::ImageUsageFlagBits usageFlags, vk::ImageCreateFlagBits createFlags) noexcept
     : logicalDevice {logicalDevice}
     , swapchain{ swapchain }
-    , resourceType{ type }
+    , resourceTypeFlags{ }
     , resourceFormat{ format }
     , images{}
     , imageViews{}
@@ -58,52 +58,10 @@ namespace SHADE
     , resourceName{ name }
   {
     // If the resource type is an arbitrary image and not swapchain image
-    if (resourceType != SH_ATT_DESC_TYPE::COLOR_PRESENT)
+    if (typeFlags.size() == 1 && *typeFlags.begin() == SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT)
     {
-      imageAspectFlags = vk::ImageAspectFlags{};
-      usage = usageFlags;
+      resourceTypeFlags |= static_cast<uint32_t>(SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT);
 
-      // Check the resource type and set image usage flags and image aspect flags accordingly
-      switch (resourceType)
-      {
-      case SH_ATT_DESC_TYPE::COLOR:
-        usage |= vk::ImageUsageFlagBits::eColorAttachment;
-        imageAspectFlags |= vk::ImageAspectFlagBits::eColor;
-        break;
-      case SH_ATT_DESC_TYPE::DEPTH:
-        usage |= vk::ImageUsageFlagBits::eDepthStencilAttachment;
-        imageAspectFlags |= vk::ImageAspectFlagBits::eDepth;
-        break;
-      case SH_ATT_DESC_TYPE::STENCIL:
-        usage |= vk::ImageUsageFlagBits::eDepthStencilAttachment;
-        imageAspectFlags |= vk::ImageAspectFlagBits::eStencil;
-        break;
-      case SH_ATT_DESC_TYPE::DEPTH_STENCIL:
-        usage |= vk::ImageUsageFlagBits::eDepthStencilAttachment;
-        imageAspectFlags |= vk::ImageAspectFlagBits::eStencil | vk::ImageAspectFlagBits::eDepth;
-        break;
-      }
-
-      // The resource is not a swapchain image, just use the first slot of the vector 
-      images.push_back(logicalDevice->CreateImage(width, height, mipLevels, resourceFormat, usage, createFlags));
-
-      // prepare image view details
-      SHImageViewDetails viewDetails
-      {
-        .viewType = vk::ImageViewType::e2D,
-        .format = images[0]->GetImageFormat(),
-        .imageAspectFlags = imageAspectFlags,
-        .baseMipLevel = 0,
-        .mipLevelCount = mipLevels,
-        .baseArrayLayer = 0,
-        .layerCount = 1,
-      };
-
-      // just 1 image view created
-      imageViews.push_back(images[0]->CreateImageView(logicalDevice, images[0], viewDetails));
-    }
-    else // if swapchain image resource
-    {
       // Prepare image view details
       SHImageViewDetails viewDetails
       {
@@ -126,6 +84,65 @@ namespace SHADE
         imageViews[i] = images[i]->CreateImageView(logicalDevice, images[i], viewDetails);
       }
     }
+    else // if swapchain image resource
+    {
+      imageAspectFlags = vk::ImageAspectFlags{};
+      usage = usageFlags;
+
+      for (auto& type : typeFlags)
+      {
+        // store the flags
+        resourceTypeFlags |= static_cast<uint32_t>(type);
+
+        // Check the resource type and set image usage flags and image aspect flags accordingly
+        switch (type)
+        {
+        case SH_ATT_DESC_TYPE_FLAGS::COLOR:
+          usage |= vk::ImageUsageFlagBits::eColorAttachment;
+          imageAspectFlags |= vk::ImageAspectFlagBits::eColor;
+          break;
+        case SH_ATT_DESC_TYPE_FLAGS::DEPTH:
+          usage |= vk::ImageUsageFlagBits::eDepthStencilAttachment;
+          imageAspectFlags |= vk::ImageAspectFlagBits::eDepth;
+          break;
+        case SH_ATT_DESC_TYPE_FLAGS::STENCIL:
+          usage |= vk::ImageUsageFlagBits::eDepthStencilAttachment;
+          imageAspectFlags |= vk::ImageAspectFlagBits::eStencil;
+          break;
+        case SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL:
+          usage |= vk::ImageUsageFlagBits::eDepthStencilAttachment;
+          imageAspectFlags |= vk::ImageAspectFlagBits::eStencil | vk::ImageAspectFlagBits::eDepth;
+          break;
+        case SH_ATT_DESC_TYPE_FLAGS::INPUT:
+          usage |= vk::ImageUsageFlagBits::eInputAttachment;
+          usage |= vk::ImageUsageFlagBits::eSampled;
+          break;
+        case SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT:
+          {
+            SHLOG_ERROR ("COLOR_PRESENT cannot be with other resource type flags. ");
+            return;
+          }
+        }
+      }
+
+      // The resource is not a swapchain image, just use the first slot of the vector 
+      images.push_back(logicalDevice->CreateImage(width, height, mipLevels, resourceFormat, usage, createFlags));
+
+      // prepare image view details
+      SHImageViewDetails viewDetails
+      {
+        .viewType = vk::ImageViewType::e2D,
+        .format = images[0]->GetImageFormat(),
+        .imageAspectFlags = imageAspectFlags,
+        .baseMipLevel = 0,
+        .mipLevelCount = mipLevels,
+        .baseArrayLayer = 0,
+        .layerCount = 1,
+      };
+
+      // just 1 image view created
+      imageViews.push_back(images[0]->CreateImageView(logicalDevice, images[0], viewDetails));
+    }
   }
 
   /***************************************************************************/
@@ -141,7 +158,7 @@ namespace SHADE
   /***************************************************************************/
   SHRenderGraphResource::SHRenderGraphResource(SHRenderGraphResource&& rhs) noexcept
     : resourceName{ std::move(rhs.resourceName) }
-    , resourceType{ std::move(rhs.resourceType) }
+    , resourceTypeFlags{ std::move(rhs.resourceTypeFlags) }
     , images{ std::move(rhs.images) }
     , imageViews{ std::move(rhs.imageViews) }
     , resourceFormat{ std::move(rhs.resourceFormat) }
@@ -149,6 +166,7 @@ namespace SHADE
     , height{ rhs.height }
     , mipLevels{ rhs.mipLevels }
     , imageAspectFlags{ rhs.imageAspectFlags }
+    , swapchain {rhs.swapchain}
   {
 
   }
@@ -172,7 +190,7 @@ namespace SHADE
       return *this;
 
     resourceName = std::move(rhs.resourceName);
-    resourceType = std::move(rhs.resourceType);
+    resourceTypeFlags = std::move(rhs.resourceTypeFlags);
     images = std::move(rhs.images);
     imageViews = std::move(rhs.imageViews);
     resourceFormat = std::move(rhs.resourceFormat);
@@ -180,6 +198,7 @@ namespace SHADE
     height = rhs.height;
     mipLevels = rhs.mipLevels;
     imageAspectFlags = rhs.imageAspectFlags;
+    swapchain = rhs.swapchain;
 
     return *this;
   }
@@ -202,7 +221,7 @@ namespace SHADE
     width = newWidth;
     height = newHeight;
 
-    if (resourceType != SH_ATT_DESC_TYPE::COLOR_PRESENT)
+    if ((resourceTypeFlags & static_cast<uint32_t>(SH_ATT_DESC_TYPE_FLAGS::COLOR_PRESENT)) == 0)
     {
       // prepare image view details
       SHImageViewDetails viewDetails
@@ -299,4 +318,9 @@ namespace SHADE
     return height;
   }
 
+  Handle<SHVkImageView> SHRenderGraphResource::GetImageView(uint32_t index /*= NON_SWAPCHAIN_RESOURCE_INDEX*/) const noexcept
+  {
+    return imageViews [index];
+  }
+
 }
\ No newline at end of file
diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.h b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.h
index 66f0677b..efaf9bf5 100644
--- a/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.h
+++ b/SHADE_Engine/src/Graphics/RenderGraph/SHRenderGraphResource.h
@@ -16,6 +16,8 @@ namespace SHADE
   class SHVkCommandBuffer;
   class SHVkBuffer;
 
+  static constexpr uint32_t NON_SWAPCHAIN_RESOURCE_INDEX = 0;
+
   class SH_API SHRenderGraphResource
   {
   private:
@@ -32,7 +34,7 @@ namespace SHADE
     std::string resourceName;
 
     //! Used for initializing image layouts
-    SH_ATT_DESC_TYPE resourceType;
+    SHRenderGraphResourceFlags resourceTypeFlags;
 
     //! The resource itself (this is a vector because if the resource happens
     //! to be a swapchain image, then we need however many frames in flight). 
@@ -67,7 +69,7 @@ namespace SHADE
     /*-----------------------------------------------------------------------*/
     /* CTORS AND DTORS                                                       */
     /*-----------------------------------------------------------------------*/
-    SHRenderGraphResource(Handle<SHVkLogicalDevice> const& logicalDevice, Handle<SHVkSwapchain> const& swapchain, std::string const& name, SH_ATT_DESC_TYPE type, vk::Format format, uint32_t w, uint32_t h, uint8_t levels, vk::ImageUsageFlagBits usageFlags, vk::ImageCreateFlagBits createFlags) noexcept;
+    SHRenderGraphResource(Handle<SHVkLogicalDevice> const& logicalDevice, Handle<SHVkSwapchain> const& swapchain, std::string const& name, std::initializer_list<SH_ATT_DESC_TYPE_FLAGS> typeFlags, vk::Format format, uint32_t w, uint32_t h, uint8_t levels, vk::ImageUsageFlagBits usageFlags, vk::ImageCreateFlagBits createFlags) noexcept;
     SHRenderGraphResource(SHRenderGraphResource&& rhs) noexcept;
     SHRenderGraphResource& operator=(SHRenderGraphResource&& rhs) noexcept;
     ~SHRenderGraphResource(void) noexcept;
@@ -82,9 +84,10 @@ namespace SHADE
     /*-----------------------------------------------------------------------*/
     /* SETTERS AND GETTERS                                                   */
     /*-----------------------------------------------------------------------*/
-    vk::Format GetResourceFormat (void) const noexcept;
-    uint32_t   GetWidth          (void) const noexcept;
-    uint32_t   GetHeight         (void) const noexcept;
+    vk::Format            GetResourceFormat (void) const noexcept;
+    uint32_t              GetWidth          (void) const noexcept;
+    uint32_t              GetHeight         (void) const noexcept;
+    Handle<SHVkImageView> GetImageView      (uint32_t index = NON_SWAPCHAIN_RESOURCE_INDEX) const noexcept;
 
     friend class SHRenderGraphNode;
     friend class SHRenderGraph;
diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp
index abd3a7be..ffbe4ff0 100644
--- a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp
+++ b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.cpp
@@ -23,7 +23,7 @@ namespace SHADE
 
   */
   /***************************************************************************/
-  SHSubpass::SHSubpass(ResourceManager& rm, Handle<SHRenderGraphNode> const& parent, uint32_t index, std::unordered_map<uint64_t, uint32_t> const* mapping, std::unordered_map<std::string, Handle<SHRenderGraphResource>> const* resources) noexcept
+  SHSubpass::SHSubpass(Handle<SHRenderGraphNode> const& parent, uint32_t index, std::unordered_map<uint64_t, uint32_t> const* mapping, std::unordered_map<std::string, Handle<SHRenderGraphResource>> const* resources) noexcept
     : resourceAttachmentMapping{ mapping }
     , ptrToResources{ resources }
     , parentNode{ parent }
@@ -55,6 +55,8 @@ namespace SHADE
     , inputReferences{ std::move(rhs.inputReferences) }
     , resourceAttachmentMapping{ rhs.resourceAttachmentMapping }
     , ptrToResources{ rhs.ptrToResources }
+    , descriptorSetLayout{ rhs.descriptorSetLayout }
+    , exteriorDrawCalls{ std::move (rhs.exteriorDrawCalls) }
   {
 
   }
@@ -83,6 +85,8 @@ namespace SHADE
     inputReferences = std::move(rhs.inputReferences);
     resourceAttachmentMapping = rhs.resourceAttachmentMapping;
     ptrToResources = rhs.ptrToResources;
+    descriptorSetLayout = rhs.descriptorSetLayout;
+    exteriorDrawCalls = std::move(rhs.exteriorDrawCalls);
 
     return *this;
   }
@@ -120,18 +124,18 @@ namespace SHADE
 
   */
   /***************************************************************************/
-  void SHSubpass::AddDepthOutput(std::string resourceToReference, SH_ATT_DESC_TYPE attachmentDescriptionType) noexcept
+  void SHSubpass::AddDepthOutput(std::string resourceToReference, SH_ATT_DESC_TYPE_FLAGS attachmentDescriptionType) noexcept
   {
     vk::ImageLayout imageLayout;
     switch (attachmentDescriptionType)
     {
-    case SH_ATT_DESC_TYPE::DEPTH:
+    case SH_ATT_DESC_TYPE_FLAGS::DEPTH:
       imageLayout = vk::ImageLayout::eDepthAttachmentOptimal;
       break;
-    case SH_ATT_DESC_TYPE::STENCIL:
+    case SH_ATT_DESC_TYPE_FLAGS::STENCIL:
       imageLayout = vk::ImageLayout::eStencilAttachmentOptimal;
       break;
-    case SH_ATT_DESC_TYPE::DEPTH_STENCIL:
+    case SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL:
       imageLayout = vk::ImageLayout::eDepthStencilAttachmentOptimal;
       break;
     default:
diff --git a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.h b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.h
index aba282b9..c567a897 100644
--- a/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.h
+++ b/SHADE_Engine/src/Graphics/RenderGraph/SHSubpass.h
@@ -62,7 +62,7 @@ namespace SHADE
     /*-----------------------------------------------------------------------*/
     /* CTORS AND DTORS                                                       */
     /*-----------------------------------------------------------------------*/
-    SHSubpass(ResourceManager& rm, Handle<SHRenderGraphNode> const& parent, uint32_t index, std::unordered_map<uint64_t, uint32_t> const* mapping, std::unordered_map<std::string, Handle<SHRenderGraphResource>> const* ptrToResources) noexcept;
+    SHSubpass(Handle<SHRenderGraphNode> const& parent, uint32_t index, std::unordered_map<uint64_t, uint32_t> const* mapping, std::unordered_map<std::string, Handle<SHRenderGraphResource>> const* ptrToResources) noexcept;
     SHSubpass(SHSubpass&& rhs) noexcept;
     SHSubpass& operator=(SHSubpass&& rhs) noexcept;
 
@@ -71,7 +71,7 @@ namespace SHADE
     /*-----------------------------------------------------------------------*/
     // Preparation functions
     void AddColorOutput(std::string resourceToReference) noexcept;
-    void AddDepthOutput(std::string resourceToReference, SH_ATT_DESC_TYPE attachmentDescriptionType = SH_ATT_DESC_TYPE::DEPTH_STENCIL) noexcept;
+    void AddDepthOutput(std::string resourceToReference, SH_ATT_DESC_TYPE_FLAGS attachmentDescriptionType = SH_ATT_DESC_TYPE_FLAGS::DEPTH_STENCIL) noexcept;
     void AddInput(std::string resourceToReference) noexcept;
 
     // Runtime functions
diff --git a/SHADE_Engine/src/Graphics/Renderpass/SHVkRenderpass.cpp b/SHADE_Engine/src/Graphics/Renderpass/SHVkRenderpass.cpp
index fee23f13..74128ec8 100644
--- a/SHADE_Engine/src/Graphics/Renderpass/SHVkRenderpass.cpp
+++ b/SHADE_Engine/src/Graphics/Renderpass/SHVkRenderpass.cpp
@@ -253,7 +253,8 @@ namespace SHADE
 
   SHVkRenderpass::~SHVkRenderpass(void) noexcept
   {
-    logicalDeviceHdl->GetVkLogicalDevice().destroyRenderPass(vkRenderpass, nullptr);
+    if (vkRenderpass)
+      logicalDeviceHdl->GetVkLogicalDevice().destroyRenderPass(vkRenderpass, nullptr);
   }
 
 
diff --git a/SHADE_Engine/src/Graphics/SHVulkanDefines.h b/SHADE_Engine/src/Graphics/SHVulkanDefines.h
index 1cbcae0f..a0a6d57c 100644
--- a/SHADE_Engine/src/Graphics/SHVulkanDefines.h
+++ b/SHADE_Engine/src/Graphics/SHVulkanDefines.h
@@ -12,6 +12,7 @@ namespace SHADE
   using BindingAndSetHash = uint64_t;
   using SetIndex = uint32_t;
   using SHSubPassIndex = uint32_t;
+  using SHRenderGraphResourceFlags = uint32_t;
 
 }
 
diff --git a/SHADE_Engine/src/Resource/SparseSet.h b/SHADE_Engine/src/Resource/SparseSet.h
index 8a3f9c6e..fb4a8311 100644
--- a/SHADE_Engine/src/Resource/SparseSet.h
+++ b/SHADE_Engine/src/Resource/SparseSet.h
@@ -59,9 +59,9 @@ namespace SHADE
         SparseSet();
         ~SparseSet() = default;
 
-        // Disallow moving or copying
-        SparseSet(const SparseSet&) = delete;
-        SparseSet(SparseSet&&) = delete;
+        //// Disallow moving or copying
+        //SparseSet(const SparseSet&) = delete;
+        //SparseSet(SparseSet&&) = delete;
 
         /*-----------------------------------------------------------------------------*/
         /* Usage Functions                                                             */
diff --git a/SHADE_Managed/src/Input/Input.cxx b/SHADE_Managed/src/Input/Input.cxx
new file mode 100644
index 00000000..0a386f3a
--- /dev/null
+++ b/SHADE_Managed/src/Input/Input.cxx
@@ -0,0 +1,102 @@
+/************************************************************************************//*!
+\file           Input.cxx
+\author         Tng Kah Wei, kahwei.tng, 390009620
+\par            email: kahwei.tng\@digipen.edu
+\date           Oct 16, 2022
+\brief          Contains the definition of the managed Input static class.
+
+                Note: This file is written in C++17/CLI.
+ 
+Copyright (C) 2022 DigiPen Institute of Technology.
+Reproduction or disclosure of this file or its contents without the prior written consent 
+of DigiPen Institute of Technology is prohibited.
+*//*************************************************************************************/
+#include "SHpch.h"
+#include "Input.hxx"
+#include "Utility/Convert.hxx"
+
+namespace SHADE
+{
+    /*---------------------------------------------------------------------------------*/
+    /* Properties                                                                      */
+    /*---------------------------------------------------------------------------------*/
+    Vector3 Input::MousePosition::get()
+    {
+        int x, y;
+        SHInputManager::GetMouseWindowPosition(&x, &y);
+        return Vector3(static_cast<float>(x), static_cast<float>(y), 0.0f);
+    }
+    int Input::MouseScrollDelta::get()
+    {
+        return SHInputManager::GetMouseWheelVerticalDelta();
+    }
+
+    /*---------------------------------------------------------------------------------*/
+    /* Usage Functions                                                                 */
+    /*---------------------------------------------------------------------------------*/
+    bool Input::GetKey(KeyCode key)
+    {
+        return SHInputManager::GetKey(static_cast<SHInputManager::SH_KEYCODE>(key));
+    }
+
+    bool Input::GetKeyDown(KeyCode key)
+    {
+        return SHInputManager::GetKeyDown(static_cast<SHInputManager::SH_KEYCODE>(key));
+    }
+
+    bool Input::GetKeyUp(KeyCode key)
+    {
+        return SHInputManager::GetKeyUp(static_cast<SHInputManager::SH_KEYCODE>(key));
+    }
+
+    bool Input::GetMouseButton(MouseCode mouseButton)
+    {
+        return SHInputManager::GetKey(static_cast<SHInputManager::SH_KEYCODE>(mouseButton));
+    }
+
+    bool Input::GetMouseButtonDown(MouseCode mouseButton)
+    {
+        return SHInputManager::GetKeyDown(static_cast<SHInputManager::SH_KEYCODE>(mouseButton));
+    }
+
+    bool Input::GetMouseButtonUp(MouseCode mouseButton)
+    {
+        return SHInputManager::GetKeyUp(static_cast<SHInputManager::SH_KEYCODE>(mouseButton));
+    }
+
+    /*---------------------------------------------------------------------------------*/
+    /* Cursor Functions                                                                */
+    /*---------------------------------------------------------------------------------*/
+    void Input::SetMousePosition(Vector2 pos)
+    {
+        SHInputManager::SetMouseWindowPosition
+        (
+            static_cast<int>(pos.x),
+            static_cast<int>(pos.y)
+        );
+    }
+
+    /*---------------------------------------------------------------------------------*/
+    /* Time Functions                                                                  */
+    /*---------------------------------------------------------------------------------*/
+    double Input::GetKeyHeldTime(KeyCode key)
+    {
+        return SHInputManager::GetKeyHeldTime(static_cast<SHInputManager::SH_KEYCODE>(key));
+    }
+
+    double Input::GetKeyReleasedTime(KeyCode key)
+    {
+        return SHInputManager::GetKeyReleasedTime(static_cast<SHInputManager::SH_KEYCODE>(key));
+    }
+
+    double Input::GetMouseHeldTime(MouseCode key)
+    {
+        return SHInputManager::GetKeyHeldTime(static_cast<SHInputManager::SH_KEYCODE>(key));
+    }
+
+    double Input::GetMouseReleasedTime(MouseCode key)
+    {
+        return SHInputManager::GetKeyReleasedTime(static_cast<SHInputManager::SH_KEYCODE>(key));
+    }
+
+}
\ No newline at end of file
diff --git a/SHADE_Managed/src/Input/Input.hxx b/SHADE_Managed/src/Input/Input.hxx
new file mode 100644
index 00000000..f281e4c8
--- /dev/null
+++ b/SHADE_Managed/src/Input/Input.hxx
@@ -0,0 +1,325 @@
+/************************************************************************************//*!
+\file           Input.hxx
+\author         Tng Kah Wei, kahwei.tng, 390009620
+\par            email: kahwei.tng\@digipen.edu
+\date           Oct 16, 2022
+\brief          Contains the definition of the managed Input static class.
+
+                Note: This file is written in C++17/CLI.
+ 
+Copyright (C) 2022 DigiPen Institute of Technology.
+Reproduction or disclosure of this file or its contents without the prior written consent 
+of DigiPen Institute of Technology is prohibited.
+*//*************************************************************************************/
+#pragma once
+
+#include "Input/SHInputManager.h"
+#include "Math/Vector2.hxx"
+#include "Math/Vector3.hxx"
+
+namespace SHADE
+{
+    /// <summary>
+    /// Static class responsible for providing access to Input-related functionality.
+    /// </summary>
+    public ref class Input abstract sealed
+    {
+      public:
+        /*-----------------------------------------------------------------------------*/
+        /* Type Definitions                                                            */
+        /*-----------------------------------------------------------------------------*/
+        /// <summary>
+        /// Represents the available supported keycodes that can be passed into the 
+        /// key-based Input functions.
+        /// </summary>
+        enum class KeyCode : int
+        {
+            Space           = static_cast<int>(SHInputManager::SH_KEYCODE::SPACE),
+            //Apostrophe		= static_cast<int>(SHInputManager::SH_KEYCODE::APOSTROPHE),
+            Comma           = static_cast<int>(SHInputManager::SH_KEYCODE::OEM_COMMA),
+            Minus           = static_cast<int>(SHInputManager::SH_KEYCODE::OEM_MINUS),
+            Period          = static_cast<int>(SHInputManager::SH_KEYCODE::OEM_PERIOD),
+            //Slash           = static_cast<int>(SHInputManager::SH_KEYCODE::SLASH),
+            Key0            = static_cast<int>(SHInputManager::SH_KEYCODE::NUMBER_0),
+            Key1            = static_cast<int>(SHInputManager::SH_KEYCODE::NUMBER_1),
+            Key2            = static_cast<int>(SHInputManager::SH_KEYCODE::NUMBER_2),
+            Key3            = static_cast<int>(SHInputManager::SH_KEYCODE::NUMBER_3),
+            Key4            = static_cast<int>(SHInputManager::SH_KEYCODE::NUMBER_4),
+            Key5            = static_cast<int>(SHInputManager::SH_KEYCODE::NUMBER_5),
+            Key6            = static_cast<int>(SHInputManager::SH_KEYCODE::NUMBER_6),
+            Key7            = static_cast<int>(SHInputManager::SH_KEYCODE::NUMBER_7),
+            Key8            = static_cast<int>(SHInputManager::SH_KEYCODE::NUMBER_8),
+            Key9            = static_cast<int>(SHInputManager::SH_KEYCODE::NUMBER_9),
+            
+            //Semicolon       = static_cast<int>(SHInputManager::SH_KEYCODE::SEMICOLON),
+            //Equal           = static_cast<int>(SHInputManager::SH_KEYCODE::EQUAL),
+            
+            A               = static_cast<int>(SHInputManager::SH_KEYCODE::A),
+            B               = static_cast<int>(SHInputManager::SH_KEYCODE::B),
+            C               = static_cast<int>(SHInputManager::SH_KEYCODE::C),
+            D               = static_cast<int>(SHInputManager::SH_KEYCODE::D),
+            E               = static_cast<int>(SHInputManager::SH_KEYCODE::E),
+            F               = static_cast<int>(SHInputManager::SH_KEYCODE::F),
+            G               = static_cast<int>(SHInputManager::SH_KEYCODE::G),
+            H               = static_cast<int>(SHInputManager::SH_KEYCODE::H),
+            I               = static_cast<int>(SHInputManager::SH_KEYCODE::I),
+            J               = static_cast<int>(SHInputManager::SH_KEYCODE::J),
+            K               = static_cast<int>(SHInputManager::SH_KEYCODE::K),
+            L               = static_cast<int>(SHInputManager::SH_KEYCODE::L),
+            M               = static_cast<int>(SHInputManager::SH_KEYCODE::M),
+            N               = static_cast<int>(SHInputManager::SH_KEYCODE::N),
+            O               = static_cast<int>(SHInputManager::SH_KEYCODE::O),
+            P               = static_cast<int>(SHInputManager::SH_KEYCODE::P),
+            Q               = static_cast<int>(SHInputManager::SH_KEYCODE::Q),
+            R               = static_cast<int>(SHInputManager::SH_KEYCODE::R),
+            S               = static_cast<int>(SHInputManager::SH_KEYCODE::S),
+            T               = static_cast<int>(SHInputManager::SH_KEYCODE::T),
+            U               = static_cast<int>(SHInputManager::SH_KEYCODE::U),
+            V               = static_cast<int>(SHInputManager::SH_KEYCODE::V),
+            W               = static_cast<int>(SHInputManager::SH_KEYCODE::W),
+            X               = static_cast<int>(SHInputManager::SH_KEYCODE::X),
+            Y               = static_cast<int>(SHInputManager::SH_KEYCODE::Y),
+            Z               = static_cast<int>(SHInputManager::SH_KEYCODE::Z),
+
+            //LeftBracket     = static_cast<int>(SHInputManager::SH_KEYCODE::LEFTBRACKET),
+            //BackSlash       = static_cast<int>(SHInputManager::SH_KEYCODE::BACKSLASH),
+            //RightBracket    = static_cast<int>(SHInputManager::SH_KEYCODE::RIGHTBRACKET),
+            //GraveAccent     = static_cast<int>(SHInputManager::SH_KEYCODE::GRAVEACCENT),
+
+            //WORLD1          = static_cast<int>(SHInputManager::SH_KEYCODE::WORLD1),
+            //WORLD2          = static_cast<int>(SHInputManager::SH_KEYCODE::WORLD2),
+
+            /* Function keys */
+            Escape			= static_cast<int>(SHInputManager::SH_KEYCODE::ESCAPE),
+            Enter			= static_cast<int>(SHInputManager::SH_KEYCODE::ENTER),	
+            Tab				= static_cast<int>(SHInputManager::SH_KEYCODE::TAB),			
+            Backspace		= static_cast<int>(SHInputManager::SH_KEYCODE::BACKSPACE),
+            Insert			= static_cast<int>(SHInputManager::SH_KEYCODE::INSERT),	
+            Delete			= static_cast<int>(SHInputManager::SH_KEYCODE::DEL),			
+            Right			= static_cast<int>(SHInputManager::SH_KEYCODE::RIGHT_ARROW),		
+            Left			= static_cast<int>(SHInputManager::SH_KEYCODE::LEFT_ARROW),		
+            Down			= static_cast<int>(SHInputManager::SH_KEYCODE::DOWN_ARROW),	
+            Up				= static_cast<int>(SHInputManager::SH_KEYCODE::UP_ARROW),	
+            PageUp			= static_cast<int>(SHInputManager::SH_KEYCODE::PAGE_UP),	
+            PageDown		= static_cast<int>(SHInputManager::SH_KEYCODE::PAGE_DOWN),	
+            Home			= static_cast<int>(SHInputManager::SH_KEYCODE::HOME),
+            End				= static_cast<int>(SHInputManager::SH_KEYCODE::END),
+            CapsLock		= static_cast<int>(SHInputManager::SH_KEYCODE::CAPS_LOCK),	
+            ScrollLock		= static_cast<int>(SHInputManager::SH_KEYCODE::SCROLL_LOCK),
+            NumLock			= static_cast<int>(SHInputManager::SH_KEYCODE::NUM_LOCK),		
+            PrintScreen		= static_cast<int>(SHInputManager::SH_KEYCODE::PRINT_SCREEN),	
+            Pause			= static_cast<int>(SHInputManager::SH_KEYCODE::PAUSE),		
+            F1				= static_cast<int>(SHInputManager::SH_KEYCODE::F1),			
+            F2				= static_cast<int>(SHInputManager::SH_KEYCODE::F2),			
+            F3				= static_cast<int>(SHInputManager::SH_KEYCODE::F3),			
+            F4				= static_cast<int>(SHInputManager::SH_KEYCODE::F4),			
+            F5				= static_cast<int>(SHInputManager::SH_KEYCODE::F5),			
+            F6				= static_cast<int>(SHInputManager::SH_KEYCODE::F6),			
+            F7				= static_cast<int>(SHInputManager::SH_KEYCODE::F7),			
+            F8				= static_cast<int>(SHInputManager::SH_KEYCODE::F8),			
+            F9				= static_cast<int>(SHInputManager::SH_KEYCODE::F9),			
+            F10				= static_cast<int>(SHInputManager::SH_KEYCODE::F10),		
+            F11				= static_cast<int>(SHInputManager::SH_KEYCODE::F11),		
+            F12				= static_cast<int>(SHInputManager::SH_KEYCODE::F12),		
+            F13				= static_cast<int>(SHInputManager::SH_KEYCODE::F13),		
+            F14				= static_cast<int>(SHInputManager::SH_KEYCODE::F14),		
+            F15				= static_cast<int>(SHInputManager::SH_KEYCODE::F15),		
+            F16				= static_cast<int>(SHInputManager::SH_KEYCODE::F16),		
+            F17				= static_cast<int>(SHInputManager::SH_KEYCODE::F17),		
+            F18				= static_cast<int>(SHInputManager::SH_KEYCODE::F18),		
+            F19				= static_cast<int>(SHInputManager::SH_KEYCODE::F19),		
+            F20				= static_cast<int>(SHInputManager::SH_KEYCODE::F20),		
+            F21				= static_cast<int>(SHInputManager::SH_KEYCODE::F21),		
+            F22				= static_cast<int>(SHInputManager::SH_KEYCODE::F22),		
+            F23				= static_cast<int>(SHInputManager::SH_KEYCODE::F23),		
+            F24				= static_cast<int>(SHInputManager::SH_KEYCODE::F24),		
+
+            /* Keypad */
+            KeyPad0	        = static_cast<int>(SHInputManager::SH_KEYCODE::NUMPAD_0),
+            KeyPad1	        = static_cast<int>(SHInputManager::SH_KEYCODE::NUMPAD_1),
+            KeyPad2	        = static_cast<int>(SHInputManager::SH_KEYCODE::NUMPAD_2),
+            KeyPad3	        = static_cast<int>(SHInputManager::SH_KEYCODE::NUMPAD_3),
+            KeyPad4	        = static_cast<int>(SHInputManager::SH_KEYCODE::NUMPAD_4),
+            KeyPad5	        = static_cast<int>(SHInputManager::SH_KEYCODE::NUMPAD_5),
+            KeyPad6	        = static_cast<int>(SHInputManager::SH_KEYCODE::NUMPAD_6),
+            KeyPad7	        = static_cast<int>(SHInputManager::SH_KEYCODE::NUMPAD_7),
+            KeyPad8	        = static_cast<int>(SHInputManager::SH_KEYCODE::NUMPAD_8),
+            KeyPad9	        = static_cast<int>(SHInputManager::SH_KEYCODE::NUMPAD_9),
+            //KeyPadDecimal   = static_cast<int>(SHInputManager::SH_KEYCODE::KPDECIMAL),
+            //KeyPadDivide    = static_cast<int>(SHInputManager::SH_KEYCODE::KPDIVIDE),
+            //KeyPadMultiply  = static_cast<int>(SHInputManager::SH_KEYCODE::KPMULTIPLY),
+            //KeyPadSubtract  = static_cast<int>(SHInputManager::SH_KEYCODE::KPSUBTRACT),
+            //KeyPadAdd       = static_cast<int>(SHInputManager::SH_KEYCODE::KPADD),
+            //KeyPadEnter     = static_cast<int>(SHInputManager::SH_KEYCODE::KPENTER),		
+            //KeyPadEqual     = static_cast<int>(SHInputManager::SH_KEYCODE::KEYPAD),	
+
+            Shift           = static_cast<int>(SHInputManager::SH_KEYCODE::SHIFT),
+            LeftControl     = static_cast<int>(SHInputManager::SH_KEYCODE::LEFT_CTRL),
+            LeftAlt         = static_cast<int>(SHInputManager::SH_KEYCODE::LEFT_ALT),
+            LeftSuper       = static_cast<int>(SHInputManager::SH_KEYCODE::LEFT_WINDOWS), 
+            RightShift      = static_cast<int>(SHInputManager::SH_KEYCODE::RIGHT_SHIFT),
+            RightControl    = static_cast<int>(SHInputManager::SH_KEYCODE::RIGHT_CTRL),
+            RightAlt        = static_cast<int>(SHInputManager::SH_KEYCODE::RIGHT_ALT),
+            RightSuper      = static_cast<int>(SHInputManager::SH_KEYCODE::RIGHT_WINDOWS),
+
+            /* Gamepad */
+            JoystickA             = static_cast<int>(SHInputManager::SH_KEYCODE::GAMEPAD_A),
+            JoystickB             = static_cast<int>(SHInputManager::SH_KEYCODE::GAMEPAD_B),
+            JoystickX             = static_cast<int>(SHInputManager::SH_KEYCODE::GAMEPAD_X),
+            JoystickY             = static_cast<int>(SHInputManager::SH_KEYCODE::GAMEPAD_Y),
+            JoystickLeftBumper    = static_cast<int>(SHInputManager::SH_KEYCODE::GAMEPAD_LEFTSHOULDER),
+            JoystickRightBumper   = static_cast<int>(SHInputManager::SH_KEYCODE::GAMEPAD_RIGHTSHOULDER),
+            JoystickLeftTrigger   = static_cast<int>(SHInputManager::SH_KEYCODE::GAMEPAD_LEFTTRIGGER),
+            JoystickRightTrigger  = static_cast<int>(SHInputManager::SH_KEYCODE::GAMEPAD_RIGHTTRIGGER),
+            JoystickDPadUp        = static_cast<int>(SHInputManager::SH_KEYCODE::GAMEPAD_DPAD_UP),
+            JoystickDPadDown      = static_cast<int>(SHInputManager::SH_KEYCODE::GAMEPAD_DPAD_DOWN),
+            JoystickDPadLeft      = static_cast<int>(SHInputManager::SH_KEYCODE::GAMEPAD_DPAD_LEFT),
+            JoystickDPadRight     = static_cast<int>(SHInputManager::SH_KEYCODE::GAMEPAD_DPAD_RIGHT),
+            JoystickMenu          = static_cast<int>(SHInputManager::SH_KEYCODE::GAMEPAD_MENU),
+            JoystickView          = static_cast<int>(SHInputManager::SH_KEYCODE::GAMEPAD_VIEW),
+            JoystickLeftStick     = static_cast<int>(SHInputManager::SH_KEYCODE::GAMEPAD_LEFT_THUMBSTICK_BUTTON),
+            JoystickRightStick    = static_cast<int>(SHInputManager::SH_KEYCODE::GAMEPAD_RIGHT_THUMBSTICK_BUTTON),
+
+            /* Unity Gamepad Mappings */
+            JoystickButton0       =  JoystickA,           
+            JoystickButton1       =  JoystickB,          
+            JoystickButton2       =  JoystickX,           
+            JoystickButton3       =  JoystickY,           
+            JoystickButton4       =  JoystickLeftBumper,  
+            JoystickButton5       =  JoystickRightBumper, 
+            JoystickButton6       =  JoystickView,        
+            JoystickButton7       =  JoystickMenu,        
+            JoystickButton8       =  JoystickLeftStick,   
+            JoystickButton9       =  JoystickRightStick  
+
+        };
+        /// <summary>
+        /// Represents the available supported mouse keycodes that can be passed into the 
+        /// mouse-button-based Input functions.
+        /// </summary>
+        enum class MouseCode : int
+        {
+            LeftButton	 = static_cast<int>(SHInputManager::SH_KEYCODE::LMB),
+            RightButton	 = static_cast<int>(SHInputManager::SH_KEYCODE::RMB),
+            MiddleButton = static_cast<int>(SHInputManager::SH_KEYCODE::MMB),
+            Button3	     = static_cast<int>(SHInputManager::SH_KEYCODE::XMB1),
+            Button4	     = static_cast<int>(SHInputManager::SH_KEYCODE::XMB2)
+        };
+
+        /*-----------------------------------------------------------------------------*/
+        /* Properites                                                                  */
+        /*-----------------------------------------------------------------------------*/
+        /// <summary>
+        /// Mouse position in screen coordinates relative to the top left of the window.
+        /// This value is a Vector3 for compatibility with functions that have Vector3 
+        /// arguments. The z component of the Vector3 is always 0
+        /// </summary>
+        static property Vector3 MousePosition
+        {
+            Vector3 get();
+        }
+        /// <summary>
+        /// Amnount of vertical mouse scroll in this frame.
+        /// </summary>
+        static property int MouseScrollDelta
+        {
+            int get();
+        }
+
+        /*-----------------------------------------------------------------------------*/
+        /* Usage Functions                                                             */
+        /*-----------------------------------------------------------------------------*/
+        /// <summary>
+        /// Checks if a specified key is being held down.
+        /// This will also be true if GetKeyDown() is true.
+        /// </summary>
+        /// <param name="key">KeyCode of the key to check.</param>
+        /// <returns>True while the user holds down the key specified.</returns>
+        static bool GetKey(KeyCode key);
+        /// <summary>
+        /// Checks if a specified key is pressed and was not pressed before.
+        /// </summary>
+        /// <param name="key">KeyCode of the key to check.</param>
+        /// <returns>
+        /// True during the frame the user starts pressing down the key specified.
+        /// </returns>
+        static bool GetKeyDown(KeyCode key);
+        /// <summary>
+        /// Checks if a specified key is no longer pressed pressed and was pressed
+        /// before.
+        /// </summary>
+        /// <param name="key">KeyCode of the key to check.</param>
+        /// <returns>
+        /// True during the frame the user releases the key identified by name.
+        /// </returns>
+        static bool GetKeyUp(KeyCode key);
+        /// <summary>
+        /// Checks if a specified mouse button is being held down.
+        /// This will also be true if GetMouseButtonDown() is true.
+        /// </summary>
+        /// <param name="mouseButton">MouseCode of the mouse button to check.</param>
+        /// <returns>True while the user holds down the mouse button specified.</returns>
+        static bool GetMouseButton(MouseCode mouseButton);
+        /// <summary>
+        /// Checks if a specified mouse button is pressed and was not pressed before.
+        /// </summary>
+        /// <param name="mouseButton">MouseCode of the mouse button to check.</param>
+        /// <returns>
+        /// True during the frame the user pressed the given mouse button.
+        /// </returns>
+        static bool GetMouseButtonDown(MouseCode mouseButton);
+        /// <summary>
+        /// Checks if a specified mouse button is no longer pressed and was pressed
+        /// before.
+        /// </summary>
+        /// <param name="mouseButton">MouseCode of the mouse button to check.</param>
+        /// <returns>
+        /// True during the frame the user releases the given mouse button.
+        /// </returns>
+        static bool GetMouseButtonUp(MouseCode mouseButton);
+        
+        /*-----------------------------------------------------------------------------*/
+        /* Cursor Functions                                                            */
+        /*-----------------------------------------------------------------------------*/
+        /// <summary>
+        /// Sets the position of the mouse cursor relative to the top left corner of the
+        /// window.
+        /// </summary>
+        /// <param name="pos">
+        /// Position of the mouse in window pixel coordinates to set.
+        /// </param>
+        static void SetMousePosition(Vector2 pos);
+
+        /*-----------------------------------------------------------------------------*/
+        /* Timing Functions                                                            */
+        /*-----------------------------------------------------------------------------*/
+        /// <summary>
+        /// Retrieves the duration that the specified key has been held or was last held
+        /// for.
+        /// </summary>
+        /// <param name="key">The key to check.</param>
+        /// <returns>Time in seconds that the key was held.</returns>
+        static double GetKeyHeldTime(KeyCode key);
+        /// <summary>
+        /// Retrieves the duration that the specified key has not been held or was last
+        /// not been held for.
+        /// </summary>
+        /// <param name="key">The key to check.</param>
+        /// <returns>Time in seconds that the key was held.</returns>
+        static double GetKeyReleasedTime(KeyCode key);
+        /// <summary>
+        /// Retrieves the duration that the specified key has been held or was last held
+        /// for.
+        /// </summary>
+        /// <param name="key">The key to check.</param>
+        /// <returns>Time in seconds that the key was held.</returns>
+        static double GetMouseHeldTime(MouseCode mouseButton);
+        /// <summary>
+        /// Retrieves the duration that the specified key has not been held or was last
+        /// not been held for.
+        /// </summary>
+        /// <param name="key">The key to check.</param>
+        /// <returns>Time in seconds that the key was held.</returns>
+        static double GetMouseReleasedTime(MouseCode mouseButton);
+    };
+}
\ No newline at end of file
