diff --git a/applications/gui2/src/modules/camera.cpp b/applications/gui2/src/modules/camera.cpp
index 363639d538d2660f26d87ef64fa6040574890918..1ed0d23a56990ef64a38008e6cfe9c005ff84807 100644
--- a/applications/gui2/src/modules/camera.cpp
+++ b/applications/gui2/src/modules/camera.cpp
@@ -416,10 +416,10 @@ bool Camera::hasFrame() {
 	return false;
 }
 
-void Camera::drawOverlay(NVGcontext *ctx) {
+void Camera::drawOverlay(NVGcontext *ctx, const nanogui::Vector2f &s, const nanogui::Vector2f &is, const Eigen::Vector2f &offset) {
 	auto ptr = std::atomic_load(&latest_);
 	// TODO: Need all the source framesets here or all data dumped in by renderer
-	overlay_->draw(ctx, *ptr, ptr->frames[frame_idx].cast<ftl::rgbd::Frame>(), view->size().cast<float>());
+	overlay_->draw(ctx, *ptr, ptr->frames[frame_idx].cast<ftl::rgbd::Frame>(), s, is, offset);  // , view->size().cast<float>()
 }
 
 void Camera::sendPose(const Eigen::Matrix4d &pose) {
diff --git a/applications/gui2/src/modules/camera.hpp b/applications/gui2/src/modules/camera.hpp
index 5ad2c355780747a19965b1116245324f0319db4a..c22675f7e38b86976264b4d1940602f8952a74cb 100644
--- a/applications/gui2/src/modules/camera.hpp
+++ b/applications/gui2/src/modules/camera.hpp
@@ -49,12 +49,13 @@ public:
 	inline bool isLive() const { return live_; }
 	inline bool isTouchable() const { return touch_; }
 	inline bool isMovable() const { return movable_; }
+	inline bool isVR() const { return vr_; }
 
 	ftl::render::Colouriser* colouriser() { return colouriser_.get(); };
 	ftl::overlay::Overlay* overlay() { return overlay_.get(); }
 	ftl::audio::StereoMixerF<100> *mixer();
 
-	void drawOverlay(NVGcontext *ctx);
+	void drawOverlay(NVGcontext *ctx, const nanogui::Vector2f &size, const nanogui::Vector2f &is, const Eigen::Vector2f &offset);
 
 	std::string getActiveSourceURI();
 
diff --git a/applications/gui2/src/views/camera.cpp b/applications/gui2/src/views/camera.cpp
index 2794a96ec9797bf5a3e158e692e27f5394c04b4a..b70f82da0d767d0006fca1e3230446a355bc853a 100644
--- a/applications/gui2/src/views/camera.cpp
+++ b/applications/gui2/src/views/camera.cpp
@@ -377,6 +377,8 @@ CameraView::CameraView(ftl::gui2::Screen* parent, ftl::gui2::Camera* ctrl) :
 	imview_ = new ftl::gui2::FTLImageView(this);
 	panel_ = new ftl::gui2::MediaPanel(screen(), ctrl, this);
 
+	imview_->setFlipped(ctrl->isVR());
+
 	auto *mod = ctrl_->screen->getModule<ftl::gui2::Statistics>();
 	if (ctrl_->isMovable()) {
 		imview_->setCursor(nanogui::Cursor::Hand);
@@ -504,6 +506,8 @@ bool CameraView::mouseButtonEvent(const Eigen::Vector2i &p, int button, bool dow
 }
 
 void CameraView::draw(NVGcontext*ctx) {
+	using namespace nanogui;
+
 	if (ctrl_->hasFrame()) {
 		try {
 			// TODO: Select shader to flip if VR capability found...
@@ -518,7 +522,8 @@ void CameraView::draw(NVGcontext*ctx) {
 	}
 	View::draw(ctx);
 
-	ctrl_->drawOverlay(ctx);
+	auto osize = imview_->scaledImageSizeF();
+	ctrl_->drawOverlay(ctx, screen()->size().cast<float>(), osize, imview_->offset());
 
 	auto mouse = screen()->mousePos();
 	auto pos = imview_->imageCoordinateAt((mouse - mPos).cast<float>());
diff --git a/applications/gui2/src/widgets/imageview.cpp b/applications/gui2/src/widgets/imageview.cpp
index 178ce2f3e09f26ebefc3b71d7bf411cd51554d27..3562577975d3d882b3599e6efbbc693811bb5c8f 100644
--- a/applications/gui2/src/widgets/imageview.cpp
+++ b/applications/gui2/src/widgets/imageview.cpp
@@ -49,13 +49,14 @@ namespace {
 		R"(#version 330
 		uniform vec2 scaleFactor;
 		uniform vec2 position;
+		uniform float flip_y;
 		in vec2 vertex;
 		out vec2 uv;
 		void main() {
 			uv = vertex;
 			vec2 scaledVertex = (vertex * scaleFactor) + position;
 			gl_Position  = vec4(2.0*scaledVertex.x - 1.0,
-								1.0 - 2.0*scaledVertex.y,
+								flip_y*(1.0 - 2.0*scaledVertex.y),
 								0.0, 1.0);
 
 		})";
@@ -322,6 +323,7 @@ void ftl::gui2::ImageView::draw(NVGcontext* ctx) {
 		glActiveTexture(GL_TEXTURE0);
 		glBindTexture(GL_TEXTURE_2D, mImageID);
 		mShader.setUniform("image", 0);
+		mShader.setUniform("flip_y", (flipped_) ? -1.0f : 1.0f);
 		mShader.setUniform("scaleFactor", scaleFactor);
 		mShader.setUniform("position", imagePosition);
 		mShader.drawIndexed(GL_TRIANGLES, 0, 2);
diff --git a/applications/gui2/src/widgets/imageview.hpp b/applications/gui2/src/widgets/imageview.hpp
index f7541c5d78f548056fff51bfbd4acbde874b033b..740152cdf15183a2aed2440c53ea52edb1059fa3 100644
--- a/applications/gui2/src/widgets/imageview.hpp
+++ b/applications/gui2/src/widgets/imageview.hpp
@@ -55,6 +55,8 @@ public:
 	float scale() const { return mScale; }
 	void setScale(float scale) { mScale = scale > 0.01f ? scale : 0.01f; }
 
+	inline void setFlipped(bool flipped) { flipped_ = flipped; }
+
 	bool fixedOffset() const { return mFixedOffset; }
 	void setFixedOffset(bool fixedOffset) { mFixedOffset = fixedOffset; }
 	bool fixedScale() const { return mFixedScale; }
@@ -166,6 +168,7 @@ protected:
 	nanogui::Vector2f mOffset;
 	bool mFixedScale;
 	bool mFixedOffset;
+	bool flipped_ = false;
 
 	// Fine-tuning parameters.
 	float mZoomSensitivity = 1.1f;
diff --git a/components/renderers/cpp/include/ftl/render/overlay.hpp b/components/renderers/cpp/include/ftl/render/overlay.hpp
index fd17ff83322336717bc5983193f209f657c3e315..945af363f73a525676e6664efbb9b02a072d6fb5 100644
--- a/components/renderers/cpp/include/ftl/render/overlay.hpp
+++ b/components/renderers/cpp/include/ftl/render/overlay.hpp
@@ -26,7 +26,7 @@ class Overlay : public ftl::Configurable {
 
 	//void apply(ftl::rgbd::FrameSet &fs, cv::Mat &out, ftl::rgbd::FrameState &state);
 
-	void draw(NVGcontext *, ftl::data::FrameSet &fs, ftl::rgbd::Frame &frame, const Eigen::Vector2f &);
+	void draw(NVGcontext *, ftl::data::FrameSet &fs, ftl::rgbd::Frame &frame, const Eigen::Vector2f &, const Eigen::Vector2f &, const Eigen::Vector2f &offset);
 
 	private:
 	nanogui::GLShader oShader;
diff --git a/components/renderers/cpp/src/overlay.cpp b/components/renderers/cpp/src/overlay.cpp
index 60633884450c19d9a424346b82ffc5bcf3825d9b..864fbddeff4b2b2fc6dcaf40b87294d32464e494 100644
--- a/components/renderers/cpp/src/overlay.cpp
+++ b/components/renderers/cpp/src/overlay.cpp
@@ -22,6 +22,8 @@ namespace {
 		uniform float height;
 		uniform float far;
 		uniform float near;
+		//uniform float offset_x;
+		//uniform float offset_y;
 		uniform mat4 pose;
 		uniform vec3 scale;
 
@@ -33,8 +35,8 @@ namespace {
 			//	(vert.z-near) / (far-near) * 2.0 - 1.0, 1.0);
 
 			vec4 pos = vec4(
-				vert.x*focal / (width/2.0),
-				-vert.y*focal / (height/2.0),
+				(vert.x*focal) / (width/2.0),
+				(-vert.y*focal) / (height/2.0),
 				-vert.z * ((far+near) / (far-near)) + (2.0 * near * far / (far-near)),
 				//((vert.z - near) / (far - near) * 2.0 - 1.0) * vert.z,
 				vert.z
@@ -242,12 +244,12 @@ void Overlay::_drawAxis(const Eigen::Matrix4d &pose, const Eigen::Vector3f &scal
 				(const void *)(loffset * sizeof(uint32_t)));
 }
 
-void Overlay::draw(NVGcontext *ctx, ftl::data::FrameSet &fs, ftl::rgbd::Frame &frame, const Eigen::Vector2f &screenSize) {
+void Overlay::draw(NVGcontext *ctx, ftl::data::FrameSet &fs, ftl::rgbd::Frame &frame, const Eigen::Vector2f &screenSize, const Eigen::Vector2f &imageSize, const Eigen::Vector2f &offset) {
 	if (!value("enabled", false)) return;
 
 	double zfar = 8.0f;
 	auto intrin = frame.getLeft();
-	intrin = intrin.scaled(screenSize[0], screenSize[1]);
+	intrin = intrin.scaled(imageSize[0], imageSize[1]);
 
 	if (!init_) {
 		oShader.init("OverlayShader", overlayVertexShader, overlayFragmentShader);
@@ -279,10 +281,12 @@ void Overlay::draw(NVGcontext *ctx, ftl::data::FrameSet &fs, ftl::rgbd::Frame &f
 	glEnable(GL_LINE_SMOOTH);
 
 	oShader.setUniform("focal", intrin.fx);
-	oShader.setUniform("width", float(intrin.width));
-	oShader.setUniform("height", float(intrin.height));
+	oShader.setUniform("width", screenSize[0]);
+	oShader.setUniform("height", screenSize[1]);
 	oShader.setUniform("far", zfar);
 	oShader.setUniform("near", 0.1f);  // TODO: but make sure CUDA depth is also normalised like this
+	//oShader.setUniform("offset_x", offset[0]);
+	//oShader.setUniform("offset_y", offset[1]);
 
 	/*oShader.setUniform("blockColour", Eigen::Vector4f(1.0f,1.0f,0.0f,0.5f));
 	oShader.uploadAttrib("vertex", sizeof(tris), 3, sizeof(float), GL_FLOAT, false, tris);
diff --git a/components/streams/src/renderers/openvr_render.cpp b/components/streams/src/renderers/openvr_render.cpp
index e5ac8c0f84b920650db1b702b2769d8bea9e031b..386c8b6aa580fbc746f14b757b1d3ec7c9b23607 100644
--- a/components/streams/src/renderers/openvr_render.cpp
+++ b/components/streams/src/renderers/openvr_render.cpp
@@ -68,6 +68,7 @@ OpenVRRender::OpenVRRender(ftl::render::Source *host, ftl::stream::Feed *feed)
 	rotmat_.setIdentity();
 	initial_pose_.setIdentity();
 
+	host_->value("reset_pose", false);
 	host_->on("reset_pose", [this]() {
 		pose_calibrated_.clear();
 	});
@@ -314,7 +315,22 @@ bool OpenVRRender::retrieve(ftl::data::Frame &frame_out) {
 			auto viewPose = t.matrix() * rotmat_;
 
 			if (!pose_calibrated_.test_and_set()) {
-				initial_pose_ = viewPose.inverse();
+				if (pose_calibration_start_ == -1) pose_calibration_start_ = ftl::timer::get_time();
+
+				std::string headset_origin = host_->value("headset_origin", std::string(""));
+				Eigen::Matrix4d horigin;
+				horigin.setIdentity();
+
+				if (headset_origin.size() > 0) {
+					ftl::operators::Poser::get(headset_origin, horigin);
+				}
+				initial_pose_ = horigin*viewPose.inverse();
+
+				if (host_->value("reset_pose", false) && ftl::timer::get_time() < pose_calibration_start_ + host_->value("calibration_time",10000)) {
+					pose_calibrated_.clear();
+				} else {
+					pose_calibration_start_ = -1;
+				}
 			}
 
 			rgbdframe.setPose() = initial_pose_*viewPose;
diff --git a/components/streams/src/renderers/openvr_render.hpp b/components/streams/src/renderers/openvr_render.hpp
index 9accd58a436a04cca87c959e117b423af853b6c7..3907b9c3eab2adb692be82ca3935f75ac5b9b96b 100644
--- a/components/streams/src/renderers/openvr_render.hpp
+++ b/components/streams/src/renderers/openvr_render.hpp
@@ -44,6 +44,7 @@ class OpenVRRender : public ftl::render::BaseSourceImpl {
 	ftl::operators::Graph *post_pipe_;
 
 	std::atomic_flag pose_calibrated_;
+	int64_t pose_calibration_start_=-1;
 
 	float baseline_;
 	Eigen::Matrix4d initial_pose_;