diff --git a/extern/typed-geometry b/extern/typed-geometry
index 284afd6d95f579066d800345648367e7d986d8cf..6dd433f303977ebd6c92759041590d41288b25a1 160000
--- a/extern/typed-geometry
+++ b/extern/typed-geometry
@@ -1 +1 @@
-Subproject commit 284afd6d95f579066d800345648367e7d986d8cf
+Subproject commit 6dd433f303977ebd6c92759041590d41288b25a1
diff --git a/tests/feature/objects/frustum.cc b/tests/feature/objects/frustum.cc
new file mode 100644
index 0000000000000000000000000000000000000000..5a732529030fe5127b0ab68e61e83114841ff01e
--- /dev/null
+++ b/tests/feature/objects/frustum.cc
@@ -0,0 +1,27 @@
+#include "test.hh"
+
+TG_FUZZ_TEST(Frustum, BasicFuzzer)
+{
+    auto const bb = tg::aabb3(-10, 10);
+
+    auto const eye = uniform(rng, bb);
+    auto const target = uniform(rng, bb);
+
+    auto const view = tg::look_at_opengl(eye, target, tg::dir3::pos_y);
+    auto const proj = tg::perspective_opengl(uniform(rng, 30_deg, 80_deg), uniform(rng, 0.5f, 2.0f), uniform(rng, 0.1f, 1.f), uniform(rng, 100.f, 500.f));
+
+    auto const view_proj = proj * view;
+    auto const inv_view_proj = inverse(view_proj);
+
+    auto const frustum = tg::frustum3::from_view_proj(view_proj);
+
+    for (auto p : frustum.vertices)
+        CHECK(contains(frustum, p, 0.01f));
+
+    for (auto i = 0; i < 10; ++i)
+    {
+        auto const p = inv_view_proj * uniform(rng, tg::aabb3::minus_one_to_one);
+
+        CHECK(contains(frustum, p, 0.01f));
+    }
+}