diff --git a/applications/reconstruct/src/main.cpp b/applications/reconstruct/src/main.cpp
index 55c6e6d1c92f60512817d4ac349b37cad9f6bd30..8202aff31a10a164edb330173634016e296ed508 100644
--- a/applications/reconstruct/src/main.cpp
+++ b/applications/reconstruct/src/main.cpp
@@ -246,7 +246,7 @@ static void run(ftl::Configurable *root) {
 
 	bool busy = false;
 
-	auto *smooth = ftl::config::create<ftl::filters::DepthSmoother>(root, "filters");
+	auto *smooth = ftl::config::create<ftl::filters::MLSSmoother>(root, "filters");
 
 	group->setLatency(4);
 	group->setName("ReconGroup");
diff --git a/components/filters/src/smoothing.cpp b/components/filters/src/smoothing.cpp
index ce0e03db369e436b89d47f42c19a0c43fa1b0bb8..517179976fc5e5a3db73e769f5ad8e0cdb796241 100644
--- a/components/filters/src/smoothing.cpp
+++ b/components/filters/src/smoothing.cpp
@@ -1,6 +1,8 @@
 #include <ftl/filters/smoothing.hpp>
 #include "smoothing_cuda.hpp"
 
+#include <ftl/cuda/normals.hpp>
+
 using ftl::filters::DepthSmoother;
 using ftl::filters::MLSSmoother;
 using ftl::codecs::Channel;
@@ -66,9 +68,15 @@ MLSSmoother::~MLSSmoother() {
 }
 
 void MLSSmoother::smooth(ftl::rgbd::Frame &f, ftl::rgbd::Source *s) {
+	bool do_smooth = value("mls_smooth", false);
+	if (!do_smooth) return;
+
 	if (!f.hasChannel(Channel::Normals)) {
-		LOG(ERROR) << "Missing normals for MLS smooth";
-		return;
+		ftl::cuda::normals(
+			f.createTexture<float4>(Channel::Normals, ftl::rgbd::Format<float4>(f.get<cv::cuda::GpuMat>(Channel::Depth).size())),
+			f.createTexture<float>(Channel::Depth),
+			s->parameters(), 0
+		);
 	}
 
 	float thresh = value("mls_threshold", 0.04f);
@@ -81,6 +89,6 @@ void MLSSmoother::smooth(ftl::rgbd::Frame &f, ftl::rgbd::Source *s) {
 		0
 	);
 
-
+	f.swapChannels(Channel::Depth, Channel::Depth2);
 }