diff --git a/external/DMath b/external/DMath
index b44a8d7273fcc7e9775733a014c5d944fd48167c..0d9c06d9e19a54a8747147a370d5e73dfe616220 160000
--- a/external/DMath
+++ b/external/DMath
@@ -1 +1 @@
-Subproject commit b44a8d7273fcc7e9775733a014c5d944fd48167c
+Subproject commit 0d9c06d9e19a54a8747147a370d5e73dfe616220
diff --git a/src/Engine/Components/Camera.cpp b/src/Engine/Components/Camera.cpp
index 5fe66c3ddf30721d9f04c078427070cc65371e50..04d7824fd50aa6d74a0b4e48f3f60e13d47e7db7 100644
--- a/src/Engine/Components/Camera.cpp
+++ b/src/Engine/Components/Camera.cpp
@@ -10,13 +10,13 @@ namespace Engine
 	{
 		Camera::Camera(SceneObject& owningObject) :
 			ParentType(owningObject),
-			position(),
+			positionOffset(),
 			fov(defaultFovY),
 			forward(Math::Vector3D::Back()),
 			up(Math::Vector3D::Up()),
 			zNear(defaultZNear),
 			zFar(defaultZFar),
-			activeProjectionMode(ProjectionMode::Perspective),
+			projectionMode(ProjectionMode::Perspective),
 			orthographicWidth(defaultOrtographicWidth)
 		{
 		}
@@ -27,7 +27,7 @@ namespace Engine
 
 		void Camera::LookAt(const Math::Vector3D& newTarget)
 		{
-			forward = (newTarget - position).GetNormalized();
+			forward = (newTarget - positionOffset).GetNormalized();
 		}
 
 		Renderer::CameraInfo Camera::GetCameraInfo() const
@@ -39,10 +39,12 @@ namespace Engine
 			cameraInfo.zNear = zNear;
 			cameraInfo.zFar = zFar;
 
-			if (activeProjectionMode == ProjectionMode::Perspective)
+			if (projectionMode == ProjectionMode::Perspective)
 				cameraInfo.projectMode = Renderer::CameraInfo::ProjectMode::Perspective;
+			else if (projectionMode == ProjectionMode::Orthgraphic)
+				cameraInfo.projectMode = Renderer::CameraInfo::ProjectMode::Orthographic;
 
-			cameraInfo.transform = Math::LinTran3D::LookAtRH(position, position + forward, up);
+			cameraInfo.transform = Math::LinTran3D::LookAt_RH(positionOffset, positionOffset + forward, up);
 
 			return cameraInfo;
 		}
diff --git a/src/Engine/Components/Camera.hpp b/src/Engine/Components/Camera.hpp
index b462fbb05cb00d6c001510e27ebcc98eb204c9e5..0226c36cac8c60ce34a4953ad1b1bd0ad53c6686 100644
--- a/src/Engine/Components/Camera.hpp
+++ b/src/Engine/Components/Camera.hpp
@@ -30,7 +30,7 @@ namespace Engine
 			explicit Camera(SceneObject& owningObject);
 			~Camera();
 
-			Math::Vector3D position;
+			Math::Vector3D positionOffset;
 			Math::Vector3D forward;
 			Math::Vector3D up;
 
@@ -38,7 +38,7 @@ namespace Engine
 			float orthographicWidth;
 			float zNear;
 			float zFar;
-			ProjectionMode activeProjectionMode;
+			ProjectionMode projectionMode;
 
 			void LookAt(const Math::Vector3D& newTarget);
 
diff --git a/src/Engine/Components/MeshRenderer.cpp b/src/Engine/Components/MeshRenderer.cpp
index e0d9a299f7e2fd7450b335df02f3e3460617c856..f1136dc0c7ef2c918d9e05cb693c3f1b1eeacce7 100644
--- a/src/Engine/Components/MeshRenderer.cpp
+++ b/src/Engine/Components/MeshRenderer.cpp
@@ -56,7 +56,8 @@ namespace Engine
 
 		Math::Matrix4x4 MeshRenderer::GetModel(Space space) const
 		{
-			return Math::LinTran3D::AsMat4(GetModel_Reduced(space));
+			const auto& model = GetModel_Reduced(space);
+			return Math::LinTran3D::AsMat4(model);
 		}
 	}
 }
diff --git a/src/Engine/Components/PointLight.cpp b/src/Engine/Components/PointLight.cpp
index 809e3cd7e010d9dd6278a87aa551552ffc1de81c..da60b31cee0e16233114b3750e3192c103c83527 100644
--- a/src/Engine/Components/PointLight.cpp
+++ b/src/Engine/Components/PointLight.cpp
@@ -29,5 +29,11 @@ namespace Engine
 			else
 				return Multiply(GetSceneObject().transform.GetModel_Reduced(Space::World), localModel);
 		}
+
+		Math::Matrix4x4 PointLight::GetModel(Space space) const
+		{
+			using namespace Math::LinTran3D;
+			return AsMat4(GetModel_Reduced(space));
+		}
 	}
 }
\ No newline at end of file
diff --git a/src/Engine/Components/PointLight.hpp b/src/Engine/Components/PointLight.hpp
index 9507c4efb148712d6eefb279597f6c96117d1bcf..5bbe42cb94dba2c489a667fcb7484c2054f5f8f8 100644
--- a/src/Engine/Components/PointLight.hpp
+++ b/src/Engine/Components/PointLight.hpp
@@ -23,6 +23,7 @@ namespace Engine
 			Math::Vector3D positionOffset;
 
 			[[nodiscard]] Math::Matrix<4, 3> GetModel_Reduced(Space space) const;
+			[[nodiscard]] Math::Matrix4x4 GetModel(Space space) const;
 		};
 	}
 }
\ No newline at end of file
diff --git a/src/Engine/Components/SpriteRenderer.cpp b/src/Engine/Components/SpriteRenderer.cpp
index 139895d184295471b7b28d2284eaf7c31e77587f..f46ff15a45cecdebebee85b660f7ccf5277d4d24 100644
--- a/src/Engine/Components/SpriteRenderer.cpp
+++ b/src/Engine/Components/SpriteRenderer.cpp
@@ -15,7 +15,7 @@ namespace Engine
 		SpriteRenderer::SpriteRenderer(SceneObject& owningObject) :
 			ParentType(owningObject),
 			sprite(Asset::Sprite::None),
-			position{ 0, 0 },
+			positionOffset{ 0, 0 },
 			rotation(0),
 			scale{ 1, 1 }
 		{
@@ -39,33 +39,26 @@ namespace Engine
 
 		Math::Matrix<3, 2> SpriteRenderer::GetModel2D_Reduced(Space space) const
 		{
-			const auto& scaleModel = Math::LinTran2D::Scale_Reduced(scale);
-			const auto& rotateModel = Math::LinTran2D::Rotate_Reduced(rotation);
-			auto localModel = Math::LinTran2D::Multiply(scaleModel, rotateModel);
-			Math::LinTran2D::AddTranslation(localModel, position);
+			using namespace Math::LinTran2D;
+
+			const auto& scaleModel = Scale_Reduced(scale);
+			const auto& rotateModel = Rotate_Reduced(rotation);
+			auto localModel = Multiply(scaleModel, rotateModel);
+			AddTranslation(localModel, positionOffset);
 
 			if (space == Space::Local)
 				return localModel;
 			else
 			{
 				auto parentModel = GetSceneObject().transform.GetModel2D_Reduced(space);
-				return Math::LinTran2D::Multiply(parentModel, localModel);
+				return Multiply(parentModel, localModel);
 			}
 		}
 
 		Math::Matrix4x4 SpriteRenderer::GetModel(Space space) const
 		{
 			const auto& model = GetModel2D_Reduced(space);
-			auto newMatrix = Math::Matrix4x4::Identity();
-			for (size_t x = 0; x < model.GetWidth() - 1; x++)
-			{
-				for (size_t y = 0; y < model.GetHeight(); y++)
-					newMatrix[x][y] = model[x][y];
-			}
-
-			for (size_t y = 0; y < model.GetHeight(); y++)
-				newMatrix[3][y] = model[2][y];
-			return newMatrix;
+			return Math::LinTran2D::AsMat4(model);
 		}
 	}
 }
diff --git a/src/Engine/Components/SpriteRenderer.hpp b/src/Engine/Components/SpriteRenderer.hpp
index 130f984ca322b202b8d7296f4e1555bac5933c8f..70994367f7f2f6dfea79ec033718cb5bae774190 100644
--- a/src/Engine/Components/SpriteRenderer.hpp
+++ b/src/Engine/Components/SpriteRenderer.hpp
@@ -27,7 +27,7 @@ namespace Engine
 			Math::Matrix<3, 2> GetModel2D_Reduced(Space space) const;
 			Math::Matrix4x4 GetModel(Space space) const;
 
-			Math::Vector2D position;
+			Math::Vector2D positionOffset;
 			float rotation;
 			Math::Vector2D scale;
 
diff --git a/src/Engine/Engine.cpp b/src/Engine/Engine.cpp
index f1c43217a399e1d45f04754a5f416ce025dc8b2c..ac5b7a5317e5c9fa81afb2073b6b312c81cdbd00 100644
--- a/src/Engine/Engine.cpp
+++ b/src/Engine/Engine.cpp
@@ -6,6 +6,7 @@
 #include "Renderer/Renderer.hpp"
 #include "Components/SpriteRenderer.hpp"
 #include "Components/MeshRenderer.hpp"
+#include "Components/PointLight.hpp"
 #include "Time/Time.hpp"
 #include "Input/InputRaw.hpp"
 #include "Scene.hpp"
@@ -34,8 +35,6 @@ public:
 	}
 
 protected:
-	
-
 	void SceneStart() override
 	{
 		ParentType::SceneStart();
@@ -69,7 +68,6 @@ void Engine::Core::Run()
 	Renderer::GetViewport(0).SetSceneRef(&scene1);
 
 
-
 	auto& sceneObject1 = scene1.NewSceneObject();
 	auto& sprite1 = sceneObject1.AddComponent<Components::MeshRenderer>().first.get();
 	sprite1.SetMesh(Asset::Mesh::Helmet);
@@ -80,11 +78,11 @@ void Engine::Core::Run()
 
 	auto& objCamera = scene1.NewSceneObject();
 	auto& camera = objCamera.AddComponent<Components::Camera>().first.get();
-
-	camera.position.z = 5.f;
+	camera.positionOffset.z = 5.f;
 
 	auto& obj3 = scene1.NewSceneObject();
-	//ScriptTest& scriptTest = obj3.AddComponent<ScriptTest>();
+	obj3.transform.localPosition = { 5.f, 5.f, 10.f };
+	Components::PointLight& light1 = obj3.AddComponent<Components::PointLight>().first.get();
 
 
 	Renderer::RenderGraph graph;
@@ -98,22 +96,19 @@ void Engine::Core::Run()
 		const float speed = 2.5f;
 		auto cross = Math::Vector3D::Cross(camera.forward, camera.up);
 		if (Input::Raw::GetValue(Input::Raw::Button::A))
-			camera.position -= cross * speed * scene1.GetTimeData().GetDeltaTime();
+			camera.positionOffset -= cross * speed * scene1.GetTimeData().GetDeltaTime();
 		if (Input::Raw::GetValue(Input::Raw::Button::D))
-			camera.position += cross * speed * scene1.GetTimeData().GetDeltaTime();
+			camera.positionOffset += cross * speed * scene1.GetTimeData().GetDeltaTime();
 		if (Input::Raw::GetValue(Input::Raw::Button::W))
-			camera.position += camera.forward *  speed * scene1.GetTimeData().GetDeltaTime();
+			camera.positionOffset += camera.forward *  speed * scene1.GetTimeData().GetDeltaTime();
 		if (Input::Raw::GetValue(Input::Raw::Button::S))
-			camera.position -= camera.forward * speed * scene1.GetTimeData().GetDeltaTime();
+			camera.positionOffset -= camera.forward * speed * scene1.GetTimeData().GetDeltaTime();
 		if (Input::Raw::GetValue(Input::Raw::Button::Space))
-			camera.position += Math::Vector3D::Up() * speed * scene1.GetTimeData().GetDeltaTime();
+			camera.positionOffset += Math::Vector3D::Up() * speed * scene1.GetTimeData().GetDeltaTime();
 		if (Input::Raw::GetValue(Input::Raw::Button::LeftCtrl))
-			camera.position += Math::Vector3D::Down() * speed * scene1.GetTimeData().GetDeltaTime();
+			camera.positionOffset += Math::Vector3D::Down() * speed * scene1.GetTimeData().GetDeltaTime();
 		camera.LookAt({ 0, 0, 0 });
 
-		if (Input::Raw::GetValue(Input::Raw::Button::K))
-			mesh2.positionOffset.y += 1.f * scene1.GetTimeData().GetDeltaTime();
-
 		if (Input::Raw::GetEventType(Input::Raw::Button::C) == Input::EventType::Pressed)
 		{
 			scene1.Clear();
@@ -123,18 +118,20 @@ void Engine::Core::Run()
 		scene1.ScriptTick();
 
 
-		RenderSystem::BuildRenderGraph(scene1, graph, graphTransform);
+		RenderSystem::BuildRenderGraph(scene1, graph);
+		Renderer::Core::PrepareRenderingEarly(graph);
 
 
+		RenderSystem::BuildRenderGraphTransform(scene1, graphTransform);
+		Renderer::Core::PrepareRenderingLate(graphTransform);
+
 
 		Renderer::Core::SetCameraInfo(camera.GetCameraInfo());
 
-		Renderer::Core::PrepareRenderingEarly(graph);
-
-		Renderer::Core::PrepareRenderingLate(graphTransform);
 
 		Renderer::Core::Draw();
 
+
 		Time::Core::TickEnd(scene1.GetTimeData());
 	}
 
diff --git a/src/Engine/Renderer/OpenGL.cpp b/src/Engine/Renderer/OpenGL.cpp
index be81be082b886b0e926a6efe7198ad0c1cea5a32..5cd066160f9b28561f7b12b5fa83a92abfbb02fa 100644
--- a/src/Engine/Renderer/OpenGL.cpp
+++ b/src/Engine/Renderer/OpenGL.cpp
@@ -33,6 +33,7 @@ namespace Engine
 
 			struct Data;
 			struct CameraDataUBO;
+			struct LightDataUBO;
 
 			void UpdateVBODatabase(Data& data, const std::vector<MeshID>& loadQueue);
 			std::optional<VBO> VBOFromPath(const std::string& path);
@@ -54,6 +55,12 @@ struct Engine::Renderer::OpenGL::CameraDataUBO
 	Math::Matrix<4, 4, float> viewProjection;
 };
 
+struct Engine::Renderer::OpenGL::LightDataUBO
+{
+	uint32_t pointLightCount;
+	std::array<Math::Vector4D, 10> pointLights;
+};
+
 struct Engine::Renderer::OpenGL::VertexBufferObject
 {
 	enum class Attribute
@@ -302,6 +309,7 @@ void Engine::Renderer::OpenGL::PrepareRenderingEarly(const std::vector<SpriteID>
 
 void Engine::Renderer::OpenGL::PrepareRenderingLate()
 {
+	// Update lights positions
 }
 
 void Engine::Renderer::OpenGL::Draw()
diff --git a/src/Engine/Renderer/Renderer.cpp b/src/Engine/Renderer/Renderer.cpp
index 9aaa7d4d6956e23db9c6b47bf5948cda9015d1b8..ce93f8ad7bfe8b279ec478e56cf1da838924755d 100644
--- a/src/Engine/Renderer/Renderer.cpp
+++ b/src/Engine/Renderer/Renderer.cpp
@@ -61,7 +61,13 @@ size_t Engine::Renderer::GetViewportCount() { return Core::data->viewports.size(
 
 Engine::Renderer::Viewport& Engine::Renderer::GetViewport(size_t index) { return *Core::data->viewports[index]; }
 
-Engine::Renderer::API Engine::Renderer::GetActiveAPI() { return Core::data->activeAPI; }
+Engine::Renderer::API Engine::Renderer::GetActiveAPI()
+{
+	if (Core::data)
+		return Core::data->activeAPI;
+	else
+		return API::None;
+}
 
 std::any& Engine::Renderer::Core::GetAPIData() { return data->apiData; }
 
@@ -187,6 +193,9 @@ bool Engine::Renderer::IsCompatible(const RenderGraph &renderGraph, const Render
 	if (renderGraph.meshes.size() != transforms.meshes.size())
 		return false;
 
+	if (renderGraph.pointLights.size() != transforms.pointLights.size())
+		return false;
+
 	return true;
 }
 
@@ -240,22 +249,39 @@ void Engine::Renderer::Core::UpdateAssetReferences(Data& data, const RenderGraph
 
 Math::Matrix4x4 Engine::Renderer::CameraInfo::GetModel(float aspectRatio) const
 {
+	using namespace Math::LinTran3D;
 	if (projectMode == ProjectMode::Perspective)
 	{
 		switch (GetActiveAPI())
 		{
 			case API::OpenGL:
-				return Math::LinTran3D::Perspective<float>(Math::API3D::OpenGL, fovY, aspectRatio, zNear, zFar) *  transform;
+				return Perspective<float>(Math::API3D::OpenGL, fovY, aspectRatio, zNear, zFar) * transform;
 			case API::Vulkan:
-				return Math::LinTran3D::Perspective<float>(Math::API3D::Vulkan, fovY, aspectRatio, zNear, zFar) * transform;
+				return Perspective<float>(Math::API3D::Vulkan, fovY, aspectRatio, zNear, zFar) * transform;
 			default:
 				assert(false);
 				return {};
 		}
 	}
-	else // Orthogonal
+	else if (projectMode == ProjectMode::Orthographic)
 	{
-		assert(false);
-		return {};
+		const float& right = orthoWidth / 2;
+		const float& left = -right;
+		const float& top = orthoWidth / aspectRatio / 2;
+		const float& bottom = -top;
+		switch (GetActiveAPI())
+		{
+			case API::OpenGL:
+				return Orthographic<float>(Math::API3D::OpenGL, left, right, bottom, top, zNear, zFar);
+			case API::Vulkan:
+				return Orthographic<float>(Math::API3D::Vulkan, left, right, bottom, top, zNear, zFar);
+			default:
+				assert(false);
+				return {};
+		}
 	}
+
+	// Function should NOT reach here.
+	assert(false);
+	return {};
 }
\ No newline at end of file
diff --git a/src/Engine/Systems/RenderSystem.cpp b/src/Engine/Systems/RenderSystem.cpp
index 037ad38832de4778e0160c89ad88fcd6d0dfaf27..d48089d869165c40b4273a201966f4d85cbc652d 100644
--- a/src/Engine/Systems/RenderSystem.cpp
+++ b/src/Engine/Systems/RenderSystem.cpp
@@ -2,43 +2,86 @@
 
 #include "../Renderer/Renderer.hpp"
 
+#include "../Components/SpriteRenderer.hpp"
+#include "../Components/MeshRenderer.hpp"
+#include "../Components/PointLight.hpp"
+
+#include "DMath/LinearTransform3D.hpp"
+
 namespace Engine
 {
-	void RenderSystem::BuildRenderGraph(const Scene& scene, Renderer::RenderGraph& graph, Renderer::RenderGraphTransform& transforms)
+	void RenderSystem::BuildRenderGraph(const Scene& scene, Renderer::RenderGraph& graph)
 	{
 		auto spriteComponentsPtr = scene.GetAllComponents<Components::SpriteRenderer>();
 		if (spriteComponentsPtr == nullptr)
-		{
 			graph.sprites.clear();
-			transforms.sprites.clear();
-		}
 		else
 		{
 			const auto& spriteComponents = *spriteComponentsPtr;
 			graph.sprites.resize(spriteComponents.size());
-			transforms.sprites.resize(spriteComponents.size());
 			for (size_t i = 0; i < spriteComponents.size(); i++)
-			{
 				graph.sprites[i] = static_cast<Renderer::SpriteID>(spriteComponents[i].GetSprite());
-				transforms.sprites[i] = spriteComponents[i].GetModel(Space::World);
-			}
 		}
 
 		auto meshComponentsPtr = scene.GetAllComponents<Components::MeshRenderer>();
 		if (meshComponentsPtr == nullptr)
-		{
 			graph.meshes.clear();
-			transforms.meshes.clear();
-		}
 		else
 		{
 			const auto& meshComponents = *meshComponentsPtr;
 			graph.meshes.resize(meshComponents.size());
-			transforms.meshes.resize(meshComponents.size());
 			for (size_t i = 0; i < meshComponents.size(); i++)
-			{
 				graph.meshes[i] = static_cast<Renderer::MeshID>(meshComponents[i].GetMesh());
+		}
+
+		auto pointLightComponentsPtr = scene.GetAllComponents<Components::PointLight>();
+		if (pointLightComponentsPtr == nullptr)
+			graph.pointLights.clear();
+		else
+		{
+			const auto& pointLightComponents = *pointLightComponentsPtr;
+			graph.pointLights.resize(pointLightComponents.size());
+			for (size_t i = 0; i < pointLightComponents.size(); i++)
+				graph.pointLights[i] = Renderer::PointLight{ pointLightComponents[i].intensity };
+		}
+	}
+
+	void RenderSystem::BuildRenderGraphTransform(const Scene& scene, Renderer::RenderGraphTransform& transforms)
+	{
+		auto spriteComponentsPtr = scene.GetAllComponents<Components::SpriteRenderer>();
+		if (spriteComponentsPtr == nullptr)
+			transforms.sprites.clear();
+		else
+		{
+			const auto& spriteComponents = *spriteComponentsPtr;
+			transforms.sprites.resize(spriteComponents.size());
+			for (size_t i = 0; i < spriteComponents.size(); i++)
+				transforms.sprites[i] = spriteComponents[i].GetModel(Space::World);
+		}
+
+		auto meshComponentsPtr = scene.GetAllComponents<Components::MeshRenderer>();
+		if (meshComponentsPtr == nullptr)
+			transforms.meshes.clear();
+		else
+		{
+			const auto& meshComponents = *meshComponentsPtr;
+			transforms.meshes.resize(meshComponents.size());
+			for (size_t i = 0; i < meshComponents.size(); i++)
 				transforms.meshes[i] = meshComponents[i].GetModel(Space::World);
+		}
+
+		auto pointLightComponentsPtr = scene.GetAllComponents<Components::PointLight>();
+		if (pointLightComponentsPtr == nullptr)
+			transforms.pointLights.clear();
+		else
+		{
+			const auto& pointLightComponents = *pointLightComponentsPtr;
+			transforms.pointLights.resize(pointLightComponents.size());
+			for (size_t i = 0; i < pointLightComponents.size(); i++)
+			{
+				const auto& model = pointLightComponents[i].GetModel_Reduced(Space::World);
+				const Math::Vector3D& position = Math::LinTran3D::GetTranslation(model);
+				transforms.pointLights[i] = position;
 			}
 		}
 	}
diff --git a/src/Engine/Systems/RenderSystem.hpp b/src/Engine/Systems/RenderSystem.hpp
index dd9a3002b61ccff49704489a0d2fc877034ea701..e80c7fc3c639684c7f83aaea608ec8d04c33518b 100644
--- a/src/Engine/Systems/RenderSystem.hpp
+++ b/src/Engine/Systems/RenderSystem.hpp
@@ -2,20 +2,42 @@
 
 #include "System.hpp"
 
-#include "../Components/MeshRenderer.hpp"
-#include "../Components/SpriteRenderer.hpp"
 #include "../Renderer/Typedefs.hpp"
 
 #include "../Scene.hpp"
 
+// Forward declarations
 namespace Engine
 {
-	using RenderSystem = System<Components::MeshRenderer, Components::SpriteRenderer>;
+	class Scene;
+
+	namespace Components
+	{
+		class MeshRenderer;
+		class SpriteRenderer;
+		class PointLight;
+	}
+}
+
+namespace Engine
+{
+	using RenderSystem = System
+	<
+		Components::MeshRenderer, 
+		Components::SpriteRenderer,
+		Components::PointLight
+	>;
 
 	template<>
-	class System<Components::MeshRenderer, Components::SpriteRenderer>
+	class System
+	<
+		Components::MeshRenderer, 
+		Components::SpriteRenderer,
+		Components::PointLight
+	>
 	{
 	public:
-		static void BuildRenderGraph(const Scene& scene, Renderer::RenderGraph& graph, Renderer::RenderGraphTransform& transforms);
+		static void BuildRenderGraph(const Scene& scene, Renderer::RenderGraph& graph);
+		static void BuildRenderGraphTransform(const Scene& scene, Renderer::RenderGraphTransform& transforms);
 	};
 }
\ No newline at end of file