diff --git a/Data/Shaders/Mesh/Mesh.frag b/Data/Shaders/Mesh/Mesh.frag
index 5d327cb4ef00f661f7c24d2b945d9b1392a566a3..183e6756889380be8279b06cbc625a9951444024 100644
--- a/Data/Shaders/Mesh/Mesh.frag
+++ b/Data/Shaders/Mesh/Mesh.frag
@@ -1,4 +1,4 @@
-#version 330 core
+#version 420 core
 
 in FragData
 {
diff --git a/Data/Shaders/Mesh/Mesh.vert b/Data/Shaders/Mesh/Mesh.vert
index 64d8749c47a9219c0a14b8038dda210ded65dd2c..aaee841d9a07f7a41d4136f63d21965d6de7b4ee 100644
--- a/Data/Shaders/Mesh/Mesh.vert
+++ b/Data/Shaders/Mesh/Mesh.vert
@@ -1,11 +1,15 @@
-#version 330 core
+#version 420 core
 
 layout(location = 0) in vec3 position;
 layout(location = 1) in vec2 texCoord;
 layout(location = 2) in vec3 normal;
 
+layout(std140, binding = 0) uniform CameraData
+{
+	mat4 viewProjection;
+} cameraData;
+
 uniform mat4 model;
-uniform mat4 viewProjection;
 
 out FragData
 {
@@ -16,7 +20,7 @@ out FragData
 
 void main()
 {
-	gl_Position = viewProjection * model * vec4(position, 1.0);
+	gl_Position = cameraData.viewProjection * model * vec4(position, 1.0);
 	
 	fragData.wsPosition = vec4(model * vec4(position, 1.0)).xyz;
 	fragData.wsNormal = vec4(model * vec4(normal, 0.0)).xyz;
diff --git a/external/DMath b/external/DMath
index d93a427928ba7957e5e162dd8567f22bc803ff57..b44a8d7273fcc7e9775733a014c5d944fd48167c 160000
--- a/external/DMath
+++ b/external/DMath
@@ -1 +1 @@
-Subproject commit d93a427928ba7957e5e162dd8567f22bc803ff57
+Subproject commit b44a8d7273fcc7e9775733a014c5d944fd48167c
diff --git a/src/Engine/Components/CircleCollider.cpp b/src/Engine/Components/CircleCollider.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..ec4a4e64b95bd8f7741febc8e0066a45effd1bac
--- /dev/null
+++ b/src/Engine/Components/CircleCollider.cpp
@@ -0,0 +1,23 @@
+#include "CircleCollider.hpp"
+
+namespace Engine
+{
+	namespace Components
+	{
+		CircleCollider::CircleCollider(SceneObject& owningObject) :
+			ParentType(owningObject),
+			positionOffset(),
+			radius(1)
+		{
+		}
+
+		CircleCollider::~CircleCollider()
+		{
+
+		}
+		Math::Matrix<4, 3, float> CircleCollider::GetModel_Reduced(Space space) const
+		{
+			return Math::Matrix<4, 3, float>();
+		}
+	}
+}
\ No newline at end of file
diff --git a/src/Engine/Components/CircleCollider.hpp b/src/Engine/Components/CircleCollider.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..d2aa45e3088c4c6047f87b51b73341ccce835561
--- /dev/null
+++ b/src/Engine/Components/CircleCollider.hpp
@@ -0,0 +1,26 @@
+#pragma once
+
+#include "Components.hpp"
+#include "../Enum.hpp"
+
+#include "DMath/Vector/Vector.hpp"
+
+namespace Engine
+{
+	namespace Components
+	{
+		class CircleCollider : ComponentBase
+		{
+		public:
+			using ParentType = ComponentBase;
+
+			explicit CircleCollider(SceneObject& owningObject);
+			~CircleCollider();
+
+			Math::Matrix<4, 3, float> GetModel_Reduced(Space space) const;
+
+			Math::Vector<3, float> positionOffset;
+			float radius;
+		};
+	}
+}
\ No newline at end of file
diff --git a/src/Engine/Components/MeshRenderer.cpp b/src/Engine/Components/MeshRenderer.cpp
index 7f3f3d564b6ed4481d85e9d4ca8672935a0a7d58..f7ea7da42fd785daab7624cc6b5cc56b09187edb 100644
--- a/src/Engine/Components/MeshRenderer.cpp
+++ b/src/Engine/Components/MeshRenderer.cpp
@@ -18,7 +18,7 @@ namespace Engine
 		MeshRenderer::MeshRenderer(SceneObject& owningSceneObject) :
 			ParentType(owningSceneObject),
 			mesh(Asset::Mesh::None),
-			position{ 0, 0, 0 },
+			positionOffset{ 0, 0, 0 },
 			scale{ 1, 1, 1 },
 			rotation()
 		{
@@ -42,16 +42,21 @@ namespace Engine
 			mesh = newMesh;
 		}
 
-		Math::Matrix4x4 MeshRenderer::GetModel(Space space) const
+		Math::Matrix<4, 3> MeshRenderer::GetModel_Reduced(Space space) const
 		{
 			using namespace Math::LinTran3D;
-			auto localModel = Multiply(Scale_Reduced(scale), Rotate_Reduced(rotation));
-			AddTranslation(localModel, position);
+			Math::Matrix<4, 3> localModel = Multiply(Scale_Reduced(scale), Rotate_Reduced(rotation));
+			AddTranslation(localModel, positionOffset);
 
 			if (space == Space::Local)
-				return AsMat4(localModel);
+				return localModel;
 			else
-				return AsMat4(Multiply(GetSceneObject().transform.GetModel_Reduced(Space::World), localModel));
+				Multiply(GetSceneObject().transform.GetModel_Reduced(Space::World), localModel);
+		}
+
+		Math::Matrix4x4 MeshRenderer::GetModel(Space space) const
+		{
+			return Math::LinTran3D::AsMat4(GetModel_Reduced(space));
 		}
 	}
 }
diff --git a/src/Engine/Components/MeshRenderer.hpp b/src/Engine/Components/MeshRenderer.hpp
index 3842cb089d8d44eb646a2a9bf0fa957d017de551..18841df923246c7e83b1db353504cce7f771d74b 100644
--- a/src/Engine/Components/MeshRenderer.hpp
+++ b/src/Engine/Components/MeshRenderer.hpp
@@ -26,9 +26,10 @@ namespace Engine
 			std::underlying_type_t<Asset::Mesh> GetMeshID() const;
 			void SetMesh(Asset::Mesh newMesh);
 
+			[[nodiscard]] Math::Matrix<4, 3> GetModel_Reduced(Space space) const;
 			Math::Matrix4x4 GetModel(Space space) const;
 
-			Math::Vector3D position;
+			Math::Vector3D positionOffset;
 			Math::UnitQuaternion<> rotation;
 			Math::Vector3D scale;
 
diff --git a/src/Engine/Components/PointLight.cpp b/src/Engine/Components/PointLight.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..6dc43ae22ee0e3d2d6df77bace5bdd31944d0d90
--- /dev/null
+++ b/src/Engine/Components/PointLight.cpp
@@ -0,0 +1,33 @@
+#include "PointLight.hpp"
+
+#include "../SceneObject.hpp"
+
+#include "DMath/LinearTransform3D.hpp"
+
+namespace Engine
+{
+	namespace Components
+	{
+		PointLight::PointLight(SceneObject& owningObject) :
+			ParentType(owningObject),
+			positionOffset(),
+			intensity(1)
+		{
+		}
+
+		PointLight::~PointLight()
+		{
+		}
+
+		Math::Matrix<4, 3> PointLight::GetModel_Reduced(Space space) const
+		{
+			using namespace Math::LinTran3D;
+			auto localModel = Translate_Reduced(positionOffset);
+			
+			if (space == Space::Local)
+				return localModel;
+			else
+				Multiply(GetSceneObject().transform.GetModel_Reduced(Space::World), localModel);
+		}
+	}
+}
\ No newline at end of file
diff --git a/src/Engine/Components/PointLight.hpp b/src/Engine/Components/PointLight.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..9507c4efb148712d6eefb279597f6c96117d1bcf
--- /dev/null
+++ b/src/Engine/Components/PointLight.hpp
@@ -0,0 +1,28 @@
+#pragma once
+
+#include "Components.hpp"
+#include "../Enum.hpp"
+
+#include "DMath/Vector/Vector.hpp"
+#include "DMath/Matrix/Matrix.hpp"
+
+
+namespace Engine
+{
+	namespace Components
+	{
+		class PointLight : public ComponentBase
+		{
+		public:
+			using ParentType = ComponentBase;
+
+			explicit PointLight(SceneObject& owningObject);
+			~PointLight();
+
+			float intensity;
+			Math::Vector3D positionOffset;
+
+			[[nodiscard]] Math::Matrix<4, 3> GetModel_Reduced(Space space) const;
+		};
+	}
+}
\ No newline at end of file
diff --git a/src/Engine/Components/ScriptBase.cpp b/src/Engine/Components/ScriptBase.cpp
index 48d095664da412fb36335b1d92eae3ceef8fc61d..caefdc9e36b57f449823ce040aa2d24bd7e5788f 100644
--- a/src/Engine/Components/ScriptBase.cpp
+++ b/src/Engine/Components/ScriptBase.cpp
@@ -15,7 +15,7 @@ namespace Engine
 
 		}
 
-		void ScriptBase::Start() {}
+		void ScriptBase::SceneStart() {}
 
 		void ScriptBase::Tick() {}
 
diff --git a/src/Engine/Components/ScriptBase.hpp b/src/Engine/Components/ScriptBase.hpp
index 22ab30357b67c983f88db2d60b2ba743eb718b61..a2adcd13ccf2a0ebd234a648f137cb01b9f46ed5 100644
--- a/src/Engine/Components/ScriptBase.hpp
+++ b/src/Engine/Components/ScriptBase.hpp
@@ -25,7 +25,7 @@ namespace Engine
 			const SceneObject& GetSceneObject() const;
 
 		protected:
-			virtual void Start() = 0;
+			virtual void SceneStart() = 0;
 			
 			virtual void Tick() = 0;
 
diff --git a/src/Engine/Engine.cpp b/src/Engine/Engine.cpp
index 59eafd049953ad7862d7121fb978157a1a2249d4..aab234d04038394fed9d9dcc97a80919a3c11a6e 100644
--- a/src/Engine/Engine.cpp
+++ b/src/Engine/Engine.cpp
@@ -36,9 +36,9 @@ public:
 protected:
 	
 
-	void Start() override
+	void SceneStart() override
 	{
-		ParentType::Start();
+		ParentType::SceneStart();
 	}
 
 	void Tick() override
@@ -48,32 +48,6 @@ protected:
 	}
 };
 
-class ScriptTest2 : public Engine::Components::ScriptBase
-{
-	using ParentType = Engine::Components::ScriptBase;
-
-public:
-	explicit ScriptTest2(Engine::SceneObject& owningObject) :
-			ParentType(owningObject)
-	{
-
-	}
-
-protected:
-
-
-	void Start() override
-	{
-		ParentType::Start();
-	}
-
-	void Tick() override
-	{
-		ParentType::Tick();
-		std::cout << "We ticked222222!" << std::endl;
-	}
-};
-
 std::vector<std::unique_ptr<Engine::Scene>> Engine::Core::scenes;
 
 void Engine::Core::Run()
@@ -103,7 +77,7 @@ void Engine::Core::Run()
 
 	auto& mesh2 = sceneObject1.AddComponent<Components::MeshRenderer>().first.get();
 	mesh2.SetMesh(Asset::Mesh::Cube);
-	mesh2.position.x = 2.5f;
+	mesh2.positionOffset.x = 2.5f;
 
 	auto& objCamera = scene1.NewSceneObject();
 	auto& camera = objCamera.AddComponent<Components::Camera>().first.get();
@@ -111,18 +85,16 @@ void Engine::Core::Run()
 	camera.position.z = 5.f;
 
 	auto& obj3 = scene1.NewSceneObject();
-	ScriptTest& scriptTest = obj3.AddComponent<ScriptTest>();
-	ScriptTest2& scriptTest2 = obj3.AddComponent<ScriptTest2>();
+	//ScriptTest& scriptTest = obj3.AddComponent<ScriptTest>();
 
 
 	Renderer::RenderGraph graph;
 	Renderer::RenderGraphTransform graphTransform;
 
 
-	scene1.ScriptStart();
+	scene1.Scripts_SceneStart();
 	while (Application::Core::UpdateEvents(), Application::IsRunning())
 	{
-
 		// Handles origin movement for camera
 		const float speed = 2.5f;
 		auto cross = Math::Vector3D::Cross(camera.forward, camera.up);
@@ -140,6 +112,11 @@ void Engine::Core::Run()
 			camera.position += Math::Vector3D::Down() * speed * scene1.GetTimeData().GetDeltaTime();
 		camera.LookAt({ 0, 0, 0 });
 
+		if (Input::Raw::GetEventType(Input::Raw::Button::C) == Input::EventType::Pressed)
+		{
+			scene1.Clear();
+		}
+
 
 		scene1.ScriptTick();
 
diff --git a/src/Engine/Renderer/OpenGL.cpp b/src/Engine/Renderer/OpenGL.cpp
index 0c9f6aa7b79a23089e9bc8b01f4478c8e9d6db72..be81be082b886b0e926a6efe7198ad0c1cea5a32 100644
--- a/src/Engine/Renderer/OpenGL.cpp
+++ b/src/Engine/Renderer/OpenGL.cpp
@@ -19,6 +19,12 @@ namespace Engine
 	{
 		namespace OpenGL
 		{
+#ifdef NDEBUG
+			constexpr bool enableDebug = false;
+#else
+			constexpr bool enableDebug = true;
+#endif
+
 			struct VertexBufferObject;
 			using VBO = VertexBufferObject;
 
@@ -26,6 +32,7 @@ namespace Engine
 			using IBO = ImageBufferObject;
 
 			struct Data;
+			struct CameraDataUBO;
 
 			void UpdateVBODatabase(Data& data, const std::vector<MeshID>& loadQueue);
 			std::optional<VBO> VBOFromPath(const std::string& path);
@@ -42,6 +49,11 @@ namespace Engine
 	}
 }
 
+struct Engine::Renderer::OpenGL::CameraDataUBO
+{
+	Math::Matrix<4, 4, float> viewProjection;
+};
+
 struct Engine::Renderer::OpenGL::VertexBufferObject
 {
 	enum class Attribute
@@ -76,16 +88,17 @@ struct Engine::Renderer::OpenGL::Data
 
 	std::unordered_map<SpriteID, IBO> iboDatabase;
 
+	GLuint cameraDataUBO;
+	GLuint samplerObject;
+
 	GLuint spriteProgram;
 	GLint spriteModelUniform;
-	GLint spriteViewUniform;
 	GLint spriteSamplerUniform;
 
 	GLuint meshProgram;
 	GLint meshModelUniform;
-	GLint meshViewUniform;
 
-	GLuint samplerObject;
+	
 };
 
 Engine::Renderer::OpenGL::Data& Engine::Renderer::OpenGL::GetData() { return std::any_cast<Data&>(Core::GetAPIData()); }
@@ -173,10 +186,6 @@ void Engine::Renderer::OpenGL::LoadSpriteShader(Data& data)
 	for (unsigned int i = 0; i < 2; i++)
 		glAttachShader(data.spriteProgram, shaders[i]);
 
-	glBindAttribLocation(data.spriteProgram, 0, "position");
-	glBindAttribLocation(data.spriteProgram, 1, "texCoord");
-	glBindAttribLocation(data.spriteProgram, 2, "normal");
-
 	glLinkProgram(data.spriteProgram);
 	CheckShaderError(data.spriteProgram, GL_LINK_STATUS, true, "Error linking shader program");
 
@@ -188,7 +197,6 @@ void Engine::Renderer::OpenGL::LoadSpriteShader(Data& data)
 
 	// Grab uniforms
 	data.spriteModelUniform = glGetUniformLocation(data.spriteProgram, "model");
-	data.spriteViewUniform = glGetUniformLocation(data.spriteProgram, "viewProjection");
 
 	data.spriteSamplerUniform = glGetUniformLocation(data.spriteProgram, "sampler");
 }
@@ -205,10 +213,6 @@ void Engine::Renderer::OpenGL::LoadMeshShader(Engine::Renderer::OpenGL::Data &da
 	for (unsigned int i = 0; i < 2; i++)
 		glAttachShader(data.meshProgram, shader[i]);
 
-	glBindAttribLocation(data.meshProgram, 0, "position");
-	glBindAttribLocation(data.meshProgram, 1, "texCoord");
-	glBindAttribLocation(data.meshProgram, 2, "normal");
-
 	glLinkProgram(data.meshProgram);
 	CheckShaderError(data.meshProgram, GL_LINK_STATUS, true, "Error linking shader program");
 
@@ -220,7 +224,8 @@ void Engine::Renderer::OpenGL::LoadMeshShader(Engine::Renderer::OpenGL::Data &da
 
 	// Grab uniforms
 	data.meshModelUniform = glGetUniformLocation(data.meshProgram, "model");
-	data.meshViewUniform = glGetUniformLocation(data.meshProgram, "viewProjection");
+
+	glUniformBlockBinding(data.meshProgram, 0, 0);
 }
 
 void Engine::Renderer::OpenGL::Initialize(std::any& apiData, CreateInfo&& createInfo)
@@ -228,13 +233,16 @@ void Engine::Renderer::OpenGL::Initialize(std::any& apiData, CreateInfo&& create
 	auto glInitResult = glewInit();
 	assert(glInitResult == 0);
 
-
 	apiData = std::make_any<Data>();
 	Data& data = std::any_cast<Data&>(apiData);
 
 	data.glSwapBuffers = std::move(createInfo.glSwapBuffers);
 
-
+	// Make camera ubo
+	glGenBuffers(1, &data.cameraDataUBO);
+	glBindBuffer(GL_UNIFORM_BUFFER, data.cameraDataUBO);
+	glBufferData(GL_UNIFORM_BUFFER, sizeof(CameraDataUBO), nullptr, GL_DYNAMIC_DRAW);
+	glBindBufferRange(GL_UNIFORM_BUFFER, 0, data.cameraDataUBO, 0, sizeof(CameraDataUBO));
 
 	// Gen sampler
 	glGenSamplers(1, &data.samplerObject);
@@ -250,6 +258,8 @@ void Engine::Renderer::OpenGL::Initialize(std::any& apiData, CreateInfo&& create
 	else
 		assert(false);
 
+
+
 	glEnable(GL_DEPTH_TEST);
 
 	glEnable(GL_CULL_FACE);
@@ -257,6 +267,13 @@ void Engine::Renderer::OpenGL::Initialize(std::any& apiData, CreateInfo&& create
 
 	//LoadSpriteShader(data);
 	LoadMeshShader(data);
+
+	if constexpr (enableDebug)
+	{
+		auto errorEnum = glGetError();
+		if (errorEnum != 0)
+			std::cout << glewGetErrorString(errorEnum) << std::endl;
+	}
 }
 
 void Engine::Renderer::OpenGL::Terminate(std::any& apiData)
@@ -271,6 +288,7 @@ void Engine::Renderer::OpenGL::Terminate(std::any& apiData)
 		iboItem.second.DeallocateDeviceBuffers();
 
 	glDeleteProgram(data.spriteProgram);
+	glDeleteProgram(data.meshProgram);
 
 	//delete static_cast<Data*>(apiData);
 	//apiData = nullptr;
@@ -295,6 +313,12 @@ void Engine::Renderer::OpenGL::Draw()
 
 	auto& viewport = Renderer::GetViewport(0);
 
+
+	auto& cameraInfo = Renderer::Core::GetCameraInfo();
+	auto viewMatrix = cameraInfo.GetModel(viewport.GetDimensions().GetAspectRatio());
+	glNamedBufferSubData(data.cameraDataUBO, 0, sizeof(CameraDataUBO::viewProjection), viewMatrix.data.data());
+
+
 	const auto& renderGraph = Core::GetRenderGraph();
 	const auto& renderGraphTransform = Core::GetRenderGraphTransform();
 
@@ -302,6 +326,13 @@ void Engine::Renderer::OpenGL::Draw()
 	Draw_SpritePass(data, renderGraph.sprites, renderGraphTransform.sprites);
 	Draw_MeshPass(data, renderGraph.meshes, renderGraphTransform.meshes);
 
+	if constexpr (enableDebug)
+	{
+		auto errorEnum = glGetError();
+		if (errorEnum != 0)
+			std::cout << glewGetErrorString(errorEnum) << std::endl;
+	}
+
 	data.glSwapBuffers(viewport.GetSurfaceHandle());
 }
 
@@ -316,9 +347,6 @@ void Engine::Renderer::OpenGL::Draw_SpritePass(const Data& data,
 	{
 		glUseProgram(data.spriteProgram);
 
-		auto viewMat = Core::GetCameraInfo().GetModel(viewport.GetDimensions().GetAspectRatio());
-		glProgramUniformMatrix4fv(data.spriteProgram, data.spriteViewUniform, 1, GL_FALSE, viewMat.data.data());
-
 		glProgramUniform1ui(data.spriteProgram, data.spriteSamplerUniform, 0);
 		glBindSampler(0, data.samplerObject);
 
@@ -348,9 +376,6 @@ void Engine::Renderer::OpenGL::Draw_MeshPass(const Engine::Renderer::OpenGL::Dat
 	{
 		glUseProgram(data.meshProgram);
 
-		auto viewMat = Core::GetCameraInfo().GetModel(viewport.GetDimensions().GetAspectRatio());
-		glProgramUniformMatrix4fv(data.meshProgram, data.meshViewUniform, 1, GL_FALSE, viewMat.data.data());
-
 		for (size_t i = 0; i < meshes.size(); i++)
 		{
 			glProgramUniformMatrix4fv(data.meshProgram, data.meshModelUniform, 1, GL_FALSE, transforms[i].data.data());
diff --git a/src/Engine/Renderer/Renderer.cpp b/src/Engine/Renderer/Renderer.cpp
index 50fde5749281aa8601f0bb3dbadd040dfe8d5c9c..9aaa7d4d6956e23db9c6b47bf5948cda9015d1b8 100644
--- a/src/Engine/Renderer/Renderer.cpp
+++ b/src/Engine/Renderer/Renderer.cpp
@@ -245,9 +245,9 @@ Math::Matrix4x4 Engine::Renderer::CameraInfo::GetModel(float aspectRatio) const
 		switch (GetActiveAPI())
 		{
 			case API::OpenGL:
-				return Math::LinTran3D::PerspectiveRH_NO(fovY, aspectRatio, zNear, zFar) *  transform;
+				return Math::LinTran3D::Perspective<float>(Math::API3D::OpenGL, fovY, aspectRatio, zNear, zFar) *  transform;
 			case API::Vulkan:
-				return Math::LinTran3D::PerspectiveRH_ZO(fovY, aspectRatio, zNear, zFar) * transform;
+				return Math::LinTran3D::Perspective<float>(Math::API3D::Vulkan, fovY, aspectRatio, zNear, zFar) * transform;
 			default:
 				assert(false);
 				return {};
diff --git a/src/Engine/Scene.cpp b/src/Engine/Scene.cpp
index dc8516f3652919bd85dd340d5b6ac071095d9aa7..3c783dd0908f13523638cadf7c3597fdf02f3a06 100644
--- a/src/Engine/Scene.cpp
+++ b/src/Engine/Scene.cpp
@@ -42,15 +42,16 @@ namespace Engine
 
 	void Scene::Clear()
 	{
+		sceneObjects.clear();
 		components.clear();
 	}
 
-	void Scene::ScriptStart()
+	void Scene::Scripts_SceneStart()
 	{
 		for (auto& ptr : scriptComponents)
 		{
 			auto& ref = *ptr;
-			ref.Start();
+			ref.SceneStart();
 		}
 	}
 
diff --git a/src/Engine/Scene.hpp b/src/Engine/Scene.hpp
index db2520ca67f907ad26aed267e42e046b9ce11d9b..e534fcc8ff7fa01d558040068d5627a4fe1d21c1 100644
--- a/src/Engine/Scene.hpp
+++ b/src/Engine/Scene.hpp
@@ -72,7 +72,7 @@ namespace Engine
 
 
 		std::vector<Components::ScriptBase*> scriptComponents;
-		void ScriptStart();
+		void Scripts_SceneStart();
 		void ScriptTick();
 
 		Time::SceneData &GetTimeData();