From 9745ccc7d670bdc8c060e8c24fed17feb7bad00d Mon Sep 17 00:00:00 2001 From: zhenyan121 <3367366583@qq.com> Date: Thu, 6 Aug 2026 20:40:01 +0800 Subject: [PATCH] perf(render): frustum cull entities before instance building Add frustum culling to entity instance data collection using AABB vs camera frustum planes. Pass renderer into get_instances_data_map to compute MVP and extract planes. Also add "Rendered Entities" debug counter for visibility. --- src/debug_collector.cpp | 3 +++ src/render/world_renderer.cpp | 27 ++++++++++++++++++++++++--- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/src/debug_collector.cpp b/src/debug_collector.cpp index b5ad9f9..985711c 100644 --- a/src/debug_collector.cpp +++ b/src/debug_collector.cpp @@ -68,6 +68,9 @@ void DebugCollector::init(int, int) { // rendered_chunk add_label("Rendered Chunk: 0", "rendered_chunk"); + // rendered_entities + add_label("Rendered Entities: 0", "rendered_entities"); + // rss add_label("RSS: 0mb", "rss"); diff --git a/src/render/world_renderer.cpp b/src/render/world_renderer.cpp index e62df6f..d439fb4 100644 --- a/src/render/world_renderer.cpp +++ b/src/render/world_renderer.cpp @@ -4,6 +4,7 @@ #include "Cubed/debug_collector.hpp" #include "Cubed/gameplay/client_world.hpp" #include "Cubed/gameplay/ecs/client_entity.hpp" +#include "Cubed/gameplay/hitbox_manager.hpp" #include "Cubed/render/renderer.hpp" #include "Cubed/render/renderer_constants.hpp" #include "Cubed/scene/world_scene.hpp" @@ -15,28 +16,48 @@ namespace Cubed { namespace { -WorldRenderer::InstanceDataMap get_instances_data_map(ClientWorld& world) { +WorldRenderer::InstanceDataMap get_instances_data_map(ClientWorld& world, + Renderer& renderer) { + + glm::mat4 mvp_mat = + renderer.p_mat() * world.world_scene().camera().get_camera_lookat(); + + auto& m_planes = world.planes(); + + Math::extract_frustum_planes(mvp_mat, m_planes); + size_t cnt = 0; std::unordered_map> instances_data_map; auto& registry = world.entity_manager().get_registry(); - auto view = registry.view(); + auto view = + registry.view(); for (auto entity : view) { auto& creature = view.get(entity); auto pos = creature.transform.position.value; if (!world.is_render(pos)) { continue; } + auto& info = view.get(entity); auto& t = view.get(entity); + auto aabb = HitboxManager::hitbox(info.name); + aabb.box.center += t.position.value; + if (!Math::is_aabb_in_frustum(aabb.box.center, aabb.box.half + 1.0f, + m_planes)) { + continue; + } + float yaw = std::atan2(t.direction.value.x, t.direction.value.z); ModelRender::InstanceData data; data.pos = t.position.value; data.yaw = yaw; data.pose = creature.pose; instances_data_map[creature.model].emplace_back(std::move(data)); + ++cnt; // m_renderer.model_renderer().shadow_pass( // creature.model, t.position.value, yaw, // world.world_scene().camera(), creature.pose); } + d_rep("rendered_entities", "Rendered Entities: {}", cnt); return instances_data_map; }; @@ -131,7 +152,7 @@ void WorldRenderer::day_night_calculation(ClientWorld& world) { } WorldRenderer::InstanceDataMap WorldRenderer::entity_build(ClientWorld& world) { - auto instances_data_map = get_instances_data_map(world); + auto instances_data_map = get_instances_data_map(world, m_renderer); for (auto& [id, data] : instances_data_map) { m_renderer.model_renderer().build_vertices(id, data); }