diff --git a/components/streams/src/renderers/screen_render.cpp b/components/streams/src/renderers/screen_render.cpp
index 9a1728c139621868912bb233f8073e5d8007382f..bc78d4216292d2aa024e813e5a9620a8dfd5fb85 100644
--- a/components/streams/src/renderers/screen_render.cpp
+++ b/components/streams/src/renderers/screen_render.cpp
@@ -31,6 +31,17 @@ ScreenRender::ScreenRender(ftl::render::Source *host, ftl::stream::Feed *feed)
 	);
 
 	intrinsics_ = ftl::create<ftl::Configurable>(host_, "intrinsics");
+	refresh_calibration_ = false;
+
+	intrinsics_->on("focal", [this](const ftl::config::Event &e) {
+		refresh_calibration_ = true;
+	});
+	intrinsics_->on("width", [this](const ftl::config::Event &e) {
+		refresh_calibration_ = true;
+	});
+	intrinsics_->on("height", [this](const ftl::config::Event &e) {
+		refresh_calibration_ = true;
+	});
 
 	filter_ = nullptr;
 	std::string source = host_->value("source", std::string(""));
@@ -78,7 +89,8 @@ bool ScreenRender::retrieve(ftl::data::Frame &frame_out) {
 	if (sets.size() > 0) {
 		ftl::rgbd::Frame &rgbdframe = frame_out.cast<ftl::rgbd::Frame>();
 
-		if (!frame_out.has(Channel::Calibration)) {
+		if (!frame_out.has(Channel::Calibration) || refresh_calibration_) {
+			refresh_calibration_ = false;
 			rgbdframe.setLeft() = ftl::rgbd::Camera::from(intrinsics_);
 
 			if (!frame_out.has(Channel::Capabilities)) {
diff --git a/components/streams/src/renderers/screen_render.hpp b/components/streams/src/renderers/screen_render.hpp
index 084b096fe5875c2a297b7a0458ad19e5fc0c9f53..4de8e9609f54847dd9c41285f1e3dc12b7f2a355 100644
--- a/components/streams/src/renderers/screen_render.hpp
+++ b/components/streams/src/renderers/screen_render.hpp
@@ -34,6 +34,7 @@ class ScreenRender : public ftl::render::BaseSourceImpl {
 	ftl::Configurable *intrinsics_;
 	uint32_t my_id_;
 	ftl::operators::Graph *post_pipe_;
+	bool refresh_calibration_;
 };
 
 }