diff --git a/modules/camera/include/vkcv/camera/Camera.hpp b/modules/camera/include/vkcv/camera/Camera.hpp
index 7e177b9a2fbde0890e0c8ea6a1d9a19d6e277c7c..a798daa1f886e9257634883e9fdc1a031600e497 100644
--- a/modules/camera/include/vkcv/camera/Camera.hpp
+++ b/modules/camera/include/vkcv/camera/Camera.hpp
@@ -11,9 +11,6 @@ namespace vkcv {
 		glm::mat4 m_view;
 		glm::mat4 m_projection;
 
-		int m_width;
-		int m_height;
-
 		float m_near;
 		float m_far;
 		float m_fov;
diff --git a/modules/camera/include/vkcv/camera/CameraManager.hpp b/modules/camera/include/vkcv/camera/CameraManager.hpp
index 9511b752e972afb1e10f41a118433a4e8933fd65..f69ea121fee52f5f09df941fc325b07647f27c9e 100644
--- a/modules/camera/include/vkcv/camera/CameraManager.hpp
+++ b/modules/camera/include/vkcv/camera/CameraManager.hpp
@@ -16,9 +16,9 @@ namespace vkcv{
 
         Window &m_window;
         Camera m_camera;
+        TrackballCamera m_trackball;    // TODO: maybe there is a better way for switching between cameras?
         float m_width;
         float m_height;
-//        std::shared_ptr<vkcv::TrackballCamera> m_trackball;
 
         bool m_roationActive = false;
         double m_lastX ;
@@ -33,6 +33,8 @@ namespace vkcv{
     public:
         CameraManager(Window &window, float width, float height, glm::vec3 up = glm::vec3(0.0f,-1.0f,0.0f), glm::vec3 position = glm::vec3(0.0f,0.0f,0.0f));
 
-        Camera &getCamera();
+        Camera& getCamera();
+
+        TrackballCamera& getTrackballCamera();
     };
 }
diff --git a/modules/camera/include/vkcv/camera/TrackballCamera.hpp b/modules/camera/include/vkcv/camera/TrackballCamera.hpp
index c9e269e9f7ad708c68158d5b358efbf37c5bb7a9..21243532cbc2f146b91269ba140abee3593110b8 100644
--- a/modules/camera/include/vkcv/camera/TrackballCamera.hpp
+++ b/modules/camera/include/vkcv/camera/TrackballCamera.hpp
@@ -5,45 +5,31 @@
 namespace vkcv {
 
     class TrackballCamera : public vkcv::Camera {
-    public:
+    protected:
+        glm::vec3 m_center;
+        float m_radius;
 
-        TrackballCamera( int width, int height, glm::mat4 projection);
+    public:
 
-        TrackballCamera(int width, int height);
+        TrackballCamera();
 
         ~TrackballCamera();
 
-        float getSensitivity() const;
-
-        void setSensitivity(float sensitivity);
-
-        float getStepSize() const;
-
-        void setStepSize(float stepSize);
-
-        float getTheta() const;
-
-        void setTheta(float theta);
-
-        float getPhi() const;
-
-        void setPhi(float phi);
-
-        float getRadius() const;
+        float getRadius();
 
         void setRadius(float radius);
 
-        const glm::vec3& getCenter() const;
+        glm::vec3& getCenter();
 
         void setCenter(const glm::vec3 &center);
 
-    private:
-        float m_sensitivity;
-        float m_stepSize, m_theta, m_phi, m_radius;
-        glm::vec3 m_center;
+        void setPitch(float pitch);
+
+        void setYaw(float yaw);
+
+        glm::mat4 updateView(double deltaTime);
 
-        float m_oldX;
-        float m_oldY;
+        void updatePosition(double deltaTime);
     };
 
 }
\ No newline at end of file
diff --git a/modules/camera/src/vkcv/camera/CameraManager.cpp b/modules/camera/src/vkcv/camera/CameraManager.cpp
index 18f499a2b34b64c1442c5d9e267d6476b8d69199..c3d52c3e5bf8f2a3114f74317af027a97b4f3247 100644
--- a/modules/camera/src/vkcv/camera/CameraManager.cpp
+++ b/modules/camera/src/vkcv/camera/CameraManager.cpp
@@ -9,6 +9,9 @@ namespace vkcv{
         m_camera.setUp(up);
         m_camera.setPosition(position);
         m_camera.setPerspective( glm::radians(60.0f), m_width / m_height, 0.1f, 10.f);
+        m_trackball.setUp(up);
+        m_trackball.setPosition(position);
+        m_trackball.setPerspective( glm::radians(60.0f), m_width / m_height, 0.1f, 10.f);
         m_lastX = width/2.0;
         m_lastY = height/2.0;
         bindCamera();
@@ -47,10 +50,12 @@ namespace vkcv{
         yoffset *= sensitivity;
 
         m_camera.panView( xoffset , yoffset );
+        m_trackball.panView( xoffset , yoffset );
     }
 
     void CameraManager::scrollCallback(double offsetX, double offsetY) {
         m_camera.changeFov(offsetY);
+        m_trackball.changeFov(offsetY);
     }
 
     void CameraManager::keyCallback(int key, int scancode, int action, int mods) {
@@ -75,8 +80,13 @@ namespace vkcv{
                 break;
         }
     }
-    Camera &CameraManager::getCamera(){
+    Camera& CameraManager::getCamera(){
         return m_camera;
     }
 
+    TrackballCamera& CameraManager::getTrackballCamera() {
+        return m_trackball;
+    }
+
+
 }
\ No newline at end of file
diff --git a/modules/camera/src/vkcv/camera/TrackballCamera.cpp b/modules/camera/src/vkcv/camera/TrackballCamera.cpp
index 3bbb8611dd234499fb9ba08ba87009c8c76660f6..c808611ebe1bf7d21144c81fd8cbfd7c3c525712 100644
--- a/modules/camera/src/vkcv/camera/TrackballCamera.cpp
+++ b/modules/camera/src/vkcv/camera/TrackballCamera.cpp
@@ -1,146 +1,66 @@
 #include "vkcv/camera/TrackballCamera.hpp"
 
-namespace vkcv{
+namespace vkcv {
 
-    TrackballCamera::TrackballCamera( int width, int height, glm::mat4 projection)
-    {
-        setPosition( glm::vec3(0.0f, 0.0f, 5.0) );
-        m_center = glm::vec3( 0.0f, 0.0f, 0.0f);
-        m_up = glm::vec3(0.0f, 1.0f, 0.0f);
+    TrackballCamera::TrackballCamera() {
+        m_pitch = 90.0f;
+        m_yaw = 0.0f;
+        m_radius = 1.5f;
 
-        m_width = width;
-        m_height = height;
-
-        m_sensitivity = 0.010f;
-        m_stepSize = 0.1f;
-        m_theta = glm::pi<float>() / 2.0f;
-        m_phi = 0.f;
-        m_radius = 1.5;
-
-        m_view = glm::lookAt( m_center + getPosition(), m_center, m_up);
-
-        m_oldX = width/2.f;
-        m_oldY = height/2.f;
-
-        setProjection(projection);
+        m_center = glm::vec3(0.0f,0.0f,0.0f);
     }
 
+    TrackballCamera::~TrackballCamera() = default;
 
-    TrackballCamera::TrackballCamera(int width, int height)
-    {
-        setPosition(    glm::vec3(0.0f, 0.0f, 5.0));
-        m_center = glm::vec3( 0.0f, 0.0f, 0.0f);
-        m_up = glm::vec3(0.0f, 1.0f, 0.0f);
-
-        m_width = width;
-        m_height = height;
-
-        m_sensitivity = 0.010f;
-        m_stepSize = 0.1f;
-        m_theta = glm::pi<float>() / 2.0f;
-        m_phi = 0.f;
-        m_radius = 1.5;
-
-        m_view = glm::lookAt( m_center + getPosition(), m_center, m_up);
-
-        m_oldX = width/2.f;
-        m_oldY = height/2.f;
-
-        m_fov = glm::radians(60.f);
-        m_ratio = m_width / (float) m_height;
-        m_near = 0.001f;
-        m_far = 10.f;
-        glm::mat4 projection = glm::perspective(m_fov, m_ratio, m_near, m_far);
-
-        setProjection(projection);
-    }
-
-    TrackballCamera::~TrackballCamera()
-    {
+    float TrackballCamera::getRadius() {
+        return m_radius;
     }
 
-	// TODO: Can be done as events... (mouseMove, mouseDown, mouseUp)
-    /*void TrackballCamera::update( GLFWwindow* window) {
-
-        double x, y;
-
-        glfwGetCursorPos( window, &x, &y);
-        if (glfwGetMouseButton( window, GLFW_MOUSE_BUTTON_LEFT) == GLFW_PRESS)
-        {
-            float changeX = ((float) x - m_oldX) * m_sensitivity;
-            float changeY = ((float) y - m_oldY) * m_sensitivity;
-
-            m_theta -= changeY;
-            if (m_theta < 0.01f) m_theta = 0.01f;
-            else if (m_theta > glm::pi<float>() - 0.01f) m_theta = glm::pi<float>() - 0.01f;
-
-            m_phi -= changeX;
-            if (m_phi < 0) m_phi += 2*glm::pi<float>();
-            else if (m_phi > 2*glm::pi<float>()) m_phi -= 2*glm::pi<float>();
+    void TrackballCamera::setRadius(float radius) {
+        if (m_radius < 0.1f) {
+            m_radius = 0.1f;
         }
-
-        m_oldX = (float) x;
-        m_oldY = (float) y;
-
-        if (glfwGetKey( window, GLFW_KEY_UP) == GLFW_PRESS)
-            m_radius -= m_stepSize;
-        if (glfwGetKey( window, GLFW_KEY_DOWN) == GLFW_PRESS)
-            m_radius += m_stepSize;
-        if (m_radius < 0.1f) m_radius = 0.1f;
-
-        m_position.x = m_center.x + m_radius * sin(m_theta) * sin(m_phi);
-        m_position.y = m_center.y + m_radius * cos(m_theta);
-        m_position.z = m_center.z + m_radius * sin(m_theta) * cos(m_phi);
-
-        m_view = glm::lookAt( m_position, m_center, m_up);
-
-    }*/
-
-    float TrackballCamera::getSensitivity() const {
-        return m_sensitivity;
-    }
-
-    void TrackballCamera::setSensitivity(float sensitivity) {
-        m_sensitivity = sensitivity;
-    }
-
-    float TrackballCamera::getStepSize() const {
-        return m_stepSize;
-    }
-
-    void TrackballCamera::setStepSize(float stepSize) {
-        m_stepSize = stepSize;
-    }
-
-    float TrackballCamera::getTheta() const {
-        return m_theta;
+        m_radius = radius;
     }
 
-    void TrackballCamera::setTheta(float theta) {
-        m_theta = theta;
+    glm::vec3& TrackballCamera::getCenter() {
+        return m_center;
     }
 
-    float TrackballCamera::getPhi() const {
-        return m_phi;
+    void TrackballCamera::setCenter(const glm::vec3 &center) {
+        m_center = center;
     }
 
-    void TrackballCamera::setPhi(float phi) {
-        m_phi = phi;
+    void TrackballCamera::setPitch(float pitch) {
+        if (pitch > 89.0f) {
+            pitch = 89.0f;
+        }
+        if (pitch < -89.0f) {
+            pitch = -89.0f;
+        }
+        m_pitch = pitch;
     }
 
-    float TrackballCamera::getRadius() const {
-        return m_radius;
+    void TrackballCamera::setYaw(float yaw) {
+        if (m_yaw < 0.0f) {
+            m_yaw += 360.0f;
+        }
+        else if (m_yaw > 360.0f) {
+            m_yaw -= 360.0f;
+        }
+        m_yaw = yaw;
     }
 
-    void TrackballCamera::setRadius(float radius) {
-        m_radius = radius;
+    glm::mat4 TrackballCamera::updateView(double deltaTime)  {
+        updatePosition(deltaTime);
+        return m_view = glm::lookAt(m_position, m_center, m_up);
     }
 
-    const glm::vec3& TrackballCamera::getCenter() const {
-        return m_center;
+    // TODO: deal with gimbal lock problem, e.g. using quaternions, angleaxis etc.
+    void TrackballCamera::updatePosition(double deltaTime) {
+        m_position.x = m_center.x + m_radius * sin(glm::radians(m_pitch)) * sin(glm::radians(m_yaw));
+        m_position.y = m_center.y + m_radius * cos(glm::radians(m_pitch));
+        m_position.z = m_center.z + m_radius * sin(glm::radians(m_pitch)) * cos(glm::radians(m_yaw));
     }
 
-    void TrackballCamera::setCenter(const glm::vec3 &center) {
-        m_center = center;
-    }
 }
\ No newline at end of file
diff --git a/projects/first_triangle/src/main.cpp b/projects/first_triangle/src/main.cpp
index 275c87cf67f059c5896272639363733634e26ca2..83df215a729d18ac5dcc40653fc4816bc570a283 100644
--- a/projects/first_triangle/src/main.cpp
+++ b/projects/first_triangle/src/main.cpp
@@ -17,6 +17,8 @@ int main(int argc, const char** argv) {
     );
 
     vkcv::CameraManager cameraManager(window, windowWidth, windowHeight);
+    cameraManager.getTrackballCamera().setPosition(glm::vec3(0.0f,0.0f,-0.5f));
+    cameraManager.getTrackballCamera().setCenter(glm::vec3(0.0f,0.0f,-1.0f));
 
     window.initEvents();
 
@@ -137,8 +139,8 @@ int main(int argc, const char** argv) {
         auto end = std::chrono::system_clock::now();
         auto deltatime = end - start;
         start = end;
-        cameraManager.getCamera().updateView(std::chrono::duration<double>(deltatime).count());
-		const glm::mat4 mvp = cameraManager.getCamera().getProjection() * cameraManager.getCamera().getView();
+        cameraManager.getTrackballCamera().updateView(std::chrono::duration<double>(deltatime).count());
+		const glm::mat4 mvp = cameraManager.getTrackballCamera().getProjection() * cameraManager.getTrackballCamera().getView();
 
 	    core.renderTriangle(trianglePass, trianglePipeline, windowWidth, windowHeight, sizeof(mvp), &mvp);
 	    core.endFrame();