diff --git a/include/vkcv/Logger.hpp b/include/vkcv/Logger.hpp
index d484711f642506926b1281a830fb2c9caf8240a2..fb1185eb1d32b19bc972ce0ecf69746f2ae89669 100644
--- a/include/vkcv/Logger.hpp
+++ b/include/vkcv/Logger.hpp
@@ -5,6 +5,7 @@
 namespace vkcv {
 	
 	enum class LogLevel {
+		RAW_INFO,
 		INFO,
 		WARNING,
 		ERROR
@@ -12,6 +13,7 @@ namespace vkcv {
 	
 	constexpr auto getLogOutput(LogLevel level) {
 		switch (level) {
+			case LogLevel::RAW_INFO:
 			case LogLevel::INFO:
 				return stdout;
 			default:
@@ -21,6 +23,7 @@ namespace vkcv {
 	
 	constexpr const char* getLogName(LogLevel level) {
 		switch (level) {
+			case LogLevel::RAW_INFO:
 			case LogLevel::INFO:
 				return "INFO";
 			case LogLevel::WARNING:
@@ -41,24 +44,33 @@ namespace vkcv {
 #define __PRETTY_FUNCTION__ __FUNCSIG__
 #endif
 
-#define vkcv_log(level, ...) {      \
-  char output_message [             \
-    VKCV_DEBUG_MESSAGE_LEN          \
-  ];                                \
-  snprintf(                         \
-    output_message,                 \
-    VKCV_DEBUG_MESSAGE_LEN,         \
-    __VA_ARGS__                     \
-  );                                \
-  fprintf(                          \
-    getLogOutput(level),            \
-    "[%s]: %s [%s, line %d: %s]\n", \
-  	vkcv::getLogName(level),        \
-    output_message,                 \
-    __FILE__,                       \
-    __LINE__,                       \
-    __PRETTY_FUNCTION__             \
-  );                                \
+#define vkcv_log(level, ...) {        \
+  char output_message [               \
+    VKCV_DEBUG_MESSAGE_LEN            \
+  ];                                  \
+  snprintf(                           \
+    output_message,                   \
+    VKCV_DEBUG_MESSAGE_LEN,           \
+    __VA_ARGS__                       \
+  );                                  \
+  if (level != LogLevel::RAW_INFO) {  \
+    fprintf(                          \
+      getLogOutput(level),            \
+      "[%s]: %s [%s, line %d: %s]\n", \
+      vkcv::getLogName(level),        \
+      output_message,                 \
+      __FILE__,                       \
+      __LINE__,                       \
+      __PRETTY_FUNCTION__             \
+    );                                \
+  } else {                            \
+    fprintf(                          \
+      getLogOutput(level),            \
+      "[%s]: %s\n",                   \
+      vkcv::getLogName(level),        \
+      output_message                  \
+    );                                \
+  }                                   \
 }
 
 #else
diff --git a/modules/scene/include/vkcv/scene/Mesh.hpp b/modules/scene/include/vkcv/scene/Mesh.hpp
index 96d719b66c5fa21b1441ea5c4ac9499956f204b0..f725a681a7eaf01d53b4db035c4dccfc9fffaec1 100644
--- a/modules/scene/include/vkcv/scene/Mesh.hpp
+++ b/modules/scene/include/vkcv/scene/Mesh.hpp
@@ -27,6 +27,9 @@ namespace vkcv::scene {
 		void recordDrawcalls(const glm::mat4& viewProjection,
 							 std::vector<glm::mat4>& matrices,
 							 std::vector<DrawcallInfo>& drawcalls);
+		
+		[[nodiscard]]
+		size_t getDrawcallCount() const;
 	
 	public:
 		~Mesh();
diff --git a/modules/scene/include/vkcv/scene/Node.hpp b/modules/scene/include/vkcv/scene/Node.hpp
index 58cef8f3622a721bda66286dcfa7b7ac65bcbd13..2c12e25ad70d85921525f842f669ba5da44d6d92 100644
--- a/modules/scene/include/vkcv/scene/Node.hpp
+++ b/modules/scene/include/vkcv/scene/Node.hpp
@@ -26,6 +26,9 @@ namespace vkcv::scene {
 		void recordDrawcalls(const glm::mat4& viewProjection,
 							 std::vector<glm::mat4>& matrices,
 							 std::vector<DrawcallInfo>& drawcalls);
+		
+		[[nodiscard]]
+		size_t getDrawcallCount() const;
 	
 	public:
 		~Node();
diff --git a/modules/scene/src/vkcv/scene/Mesh.cpp b/modules/scene/src/vkcv/scene/Mesh.cpp
index 12402f10701f6ef1f7ad66ef7972c93672f231d2..c4943646ed66769972b9dd392a789f5f47e02709 100644
--- a/modules/scene/src/vkcv/scene/Mesh.cpp
+++ b/modules/scene/src/vkcv/scene/Mesh.cpp
@@ -79,10 +79,21 @@ namespace vkcv::scene {
 		return *this;
 	}
 	
-	static glm::vec3 projectPoint(const glm::mat4& transform, const glm::vec3& point) {
+	static glm::vec3 projectPoint(const glm::mat4& transform, const glm::vec3& point, bool& negative_w) {
 		const glm::vec4 position = transform * glm::vec4(point, 1.0f);
 		const float perspective = std::abs(position[3]);
 		
+		/*
+		 * We divide by the absolute of the 4th coorditnate because
+		 * clipping is weird and points have to move to the other
+		 * side of the camera.
+		 *
+		 * We also need to collect if the 4th coordinate was negative
+		 * to know if all corners are behind the camera. So these can
+		 * be culled as well
+		 */
+		negative_w = (position[3] < 0.0f);
+		
 		return glm::vec3(
 				position[0] / perspective,
 				position[1] / perspective,
@@ -109,16 +120,19 @@ namespace vkcv::scene {
 			const Bounds& bounds = part.getBounds();
 			const auto corners = bounds.getCorners();
 			
-			auto projected = projectPoint(transform, corners[0]);
+			bool negative_w;
+			auto projected = projectPoint(transform, corners[0], negative_w);
 			
 			Bounds aabb (projected, projected);
 			
 			for (size_t j = 1; j < corners.size(); j++) {
-				projected = projectPoint(transform, corners[j]);
+				bool flag_w;
+				projected = projectPoint(transform, corners[j], flag_w);
 				aabb.extend(projected);
+				negative_w &= flag_w;
 			}
 			
-			if (!checkFrustum(aabb)) {
+			if ((negative_w) || (!checkFrustum(aabb))) {
 				continue;
 			}
 			
@@ -126,5 +140,9 @@ namespace vkcv::scene {
 			drawcalls.push_back(m_drawcalls[i]);
 		}
 	}
+	
+	size_t Mesh::getDrawcallCount() const {
+		return m_drawcalls.size();
+	}
 
 }
diff --git a/modules/scene/src/vkcv/scene/Node.cpp b/modules/scene/src/vkcv/scene/Node.cpp
index 9e7347036cec6a81797c33458bd7def645a8a3cd..82f4191e0f07b39be319c4984db93273419440ee 100644
--- a/modules/scene/src/vkcv/scene/Node.cpp
+++ b/modules/scene/src/vkcv/scene/Node.cpp
@@ -66,5 +66,19 @@ namespace vkcv::scene {
 			node.recordDrawcalls(viewProjection, matrices, drawcalls);
 		}
 	}
+	
+	size_t Node::getDrawcallCount() const {
+		size_t count = 0;
+		
+		for (auto& mesh : m_meshes) {
+			count += mesh.getDrawcallCount();
+		}
+		
+		for (auto& node : m_nodes) {
+			count += node.getDrawcallCount();
+		}
+		
+		return count;
+	}
 
 }
diff --git a/modules/scene/src/vkcv/scene/Scene.cpp b/modules/scene/src/vkcv/scene/Scene.cpp
index aa8c83b4a5f9f280c81c4e78f01f5f3d52615c5d..da0f7fb69a501d9ed448677fe0ab00652b7fa7be 100644
--- a/modules/scene/src/vkcv/scene/Scene.cpp
+++ b/modules/scene/src/vkcv/scene/Scene.cpp
@@ -73,13 +73,17 @@ namespace vkcv::scene {
 								const std::vector<ImageHandle>  &renderTargets) {
 		std::vector<glm::mat4> matrices;
 		std::vector<DrawcallInfo> drawcalls;
+		size_t count = 0;
 		
 		const glm::mat4 viewProjection = camera.getMVP();
 		
 		for (auto& node : m_nodes) {
+			count += node.getDrawcallCount();
 			node.recordDrawcalls(viewProjection, matrices, drawcalls);
 		}
 		
+		vkcv_log(LogLevel::RAW_INFO, "Frustum culling: %lu / %lu", drawcalls.size(), count);
+		
 		PushConstantData pushConstantData (matrices.data(), sizeof(glm::mat4));
 		
 		m_core->recordDrawcallsToCmdStream(