diff --git a/applications/gui/src/camera.cpp b/applications/gui/src/camera.cpp
index 8fdad63282a9a9f54020cb0268e366794104bf83..9390df759d793e20f20efd897970fa05388bd637 100644
--- a/applications/gui/src/camera.cpp
+++ b/applications/gui/src/camera.cpp
@@ -263,6 +263,8 @@ const GLTexture &ftl::gui::Camera::captureFrame() {
 
 		if (screen_->hasVR()) {
 			#ifdef HAVE_OPENVR
+			src_->setChannel(ftl::rgbd::kChanRight);
+
 			vr::VRCompositor()->WaitGetPoses(rTrackedDevicePose_, vr::k_unMaxTrackedDeviceCount, NULL, 0 );
 
 			if ( rTrackedDevicePose_[vr::k_unTrackedDeviceIndex_Hmd].bPoseIsValid )
@@ -290,6 +292,9 @@ const GLTexture &ftl::gui::Camera::captureFrame() {
 		src_->grab();
 		src_->getFrames(rgb, depth);
 
+		cv::flip(rgb,rgb,0);
+		cv::flip(depth,depth,0);
+
 		// When switching from right to depth, client may still receive
 		// right images from previous batch (depth.channels() == 1 check)
 		if (channel_ == ftl::rgbd::kChanDeviation &&
@@ -335,6 +340,13 @@ const GLTexture &ftl::gui::Camera::captureFrame() {
 				if (rgb.rows == 0) { break; }
 				//imageSize = Vector2f(rgb.cols,rgb.rows);
 				texture_.update(rgb);
+
+				#ifdef HAVE_OPENVR
+				if (screen_->hasVR() && depth.channels() >= 3) {
+					LOG(INFO) << "DRAW RIGHT";
+					textureRight_.update(depth);
+				}
+				#endif
 		}
 	}
 
diff --git a/applications/gui/src/camera.hpp b/applications/gui/src/camera.hpp
index 162bad2f0e73879e31efacaa1d20f66c35184b15..cdd243ab3cb35e1cad7fddf9dfa9b3eae339c774 100644
--- a/applications/gui/src/camera.hpp
+++ b/applications/gui/src/camera.hpp
@@ -44,6 +44,7 @@ class Camera {
 
 	const GLTexture &captureFrame();
 	const GLTexture &getLeft() const { return texture_; }
+	const GLTexture &getRight() const { return textureRight_; }
 
 	nlohmann::json getMetaData();
 
@@ -54,6 +55,7 @@ class Camera {
 	ftl::rgbd::Source *src_;
 	GLTexture thumb_;
 	GLTexture texture_;
+	GLTexture textureRight_;
 	ftl::gui::PoseWindow *posewin_;
 	nlohmann::json meta_;
 	Eigen::Vector4d neye_;
diff --git a/applications/gui/src/screen.cpp b/applications/gui/src/screen.cpp
index e944c76b1c5f9eed7200b370097d883675e5085a..4d53fbb9307fae77dcaa21b4efc94e3508056cad 100644
--- a/applications/gui/src/screen.cpp
+++ b/applications/gui/src/screen.cpp
@@ -359,10 +359,10 @@ void ftl::gui::Screen::draw(NVGcontext *ctx) {
 
 		mImageID = camera_->captureFrame().texture();
 		leftEye_ = mImageID;
-		rightEye_ = mImageID;
+		rightEye_ = camera_->getRight().texture();
 
 		#ifdef HAVE_OPENVR
-		if (hasVR() && (mImageID < std::numeric_limits<unsigned int>::max() && imageSize[0] > 0) && camera_->getLeft().isValid()) {
+		if (hasVR() && imageSize[0] > 0 && camera_->getLeft().isValid() && camera_->getRight().isValid()) {
 			vr::Texture_t leftEyeTexture = {(void*)(uintptr_t)leftEye_, vr::TextureType_OpenGL, vr::ColorSpace_Gamma };
 			vr::VRCompositor()->Submit(vr::Eye_Left, &leftEyeTexture );
 			vr::Texture_t rightEyeTexture = {(void*)(uintptr_t)rightEye_, vr::TextureType_OpenGL, vr::ColorSpace_Gamma };
diff --git a/applications/reconstruct/src/splat_render.cpp b/applications/reconstruct/src/splat_render.cpp
index 92d70a1c50d06e985fcb0faa1ef8f0bd5b961f86..61a8fcb7cdff2cd71c556883625c71f2065179cb 100644
--- a/applications/reconstruct/src/splat_render.cpp
+++ b/applications/reconstruct/src/splat_render.cpp
@@ -83,7 +83,12 @@ void Splatter::render(ftl::rgbd::Source *src, cudaStream_t stream) {
 		} else if (src->getChannel() == ftl::rgbd::kChanRight) {
 			// Adjust pose to right eye position
 			Eigen::Affine3f transform(Eigen::Translation3f(camera.baseline,0.0f,0.0f));
-			Eigen::Matrix4f matrix =  src->getPose().cast<float>() * transform.matrix();
+			Eigen::Matrix4f tmat = transform.matrix();
+			Eigen::Matrix4f rmat = src->getPose().cast<float>();
+			rmat(3,0) = 0.0f;
+			rmat(3,1) = 0.0f;
+			rmat(3,2) = 0.0f;
+			Eigen::Matrix4f matrix =  (rmat * transform.matrix()) + src->getPose().cast<float>();
 			params.m_viewMatrix = MatrixConversion::toCUDA(matrix.inverse());
 			params.m_viewMatrixInverse = MatrixConversion::toCUDA(matrix);