feat(render): add shadow pass for entity models

This commit is contained in:
2026-07-25 11:57:00 +08:00
parent 5951a5e81c
commit 2e3b4f4f0f
6 changed files with 56 additions and 24 deletions

View File

@@ -13,10 +13,13 @@ public:
void render_model(const std::string& name, const glm::vec3& pos,
Camera& camera);
void shadow_pass(const std::string& name, const glm::vec3& pos,
const glm::mat4& light_matrix, Camera& camera);
private:
Renderer& m_renderer;
void render_node(const ModelNode& node, const glm::mat4& parent,
const glm::mat4& view, const Shader& shader);
void render_mesh(const Mesh& mesh);
const glm::mat4& view, const Shader& shader, bool shadow);
void render_mesh(const Mesh& mesh, bool shadow);
};
} // namespace Cubed

View File

@@ -82,10 +82,8 @@ public:
bool handle_event(const Event& e);
void render_model(const std::string& name, const glm::vec3& pos,
Camera& camera);
ModelManager& model_manager();
ModelRender& model_renderer();
private:
TextureManager& m_texture_manager;

View File

@@ -133,6 +133,7 @@ private:
void render_underwater(ClientWorld& world);
void render_outline(ClientWorld& world);
void render_entity(ClientWorld& world);
void shadow_entity(ClientWorld& world, const glm::mat4& light_matrix);
void render_player(ClientWorld& world);
void render_normal_block(const glm::mat4& model_mat,

View File

@@ -13,27 +13,43 @@ void ModelRender::render_model(const std::string& name, const glm::vec3& pos,
glm::mat4 transform = glm::translate(glm::mat4(1.0f), pos);
auto& shader = m_renderer.get_shader("model_shader");
glm::mat4 view = camera.get_camera_lookat();
shader.use();
shader.set_loc("proj_matrix", m_renderer.p_mat());
render_node(root, transform, view, shader);
render_node(root, transform, view, shader, false);
}
void ModelRender::shadow_pass(const std::string& name, const glm::vec3& pos,
const glm::mat4& light_matrix, Camera& camera) {
auto& model_manager = m_renderer.model_manager();
auto& root = model_manager.get_model(name);
glm::mat4 transform = glm::translate(glm::mat4(1.0f), pos);
auto& shader = m_renderer.get_shader("depth_model");
glm::mat4 view = camera.get_camera_lookat();
shader.set_loc("lightSpaceMatrix", light_matrix);
render_node(root, transform, view, shader, true);
}
void ModelRender::render_node(const ModelNode& node, const glm::mat4& parent,
const glm::mat4& view, const Shader& shader) {
const glm::mat4& view, const Shader& shader,
bool shadow) {
glm::mat4 transform = parent * node.transform;
if (shadow) {
shader.set_loc("modelMatrix", transform);
} else {
shader.set_loc("mv_matrix", view * transform);
}
shader.set_loc("mv_matrix", view * transform);
for (auto& mesh : node.meshes) {
render_mesh(mesh);
render_mesh(mesh, shadow);
}
for (auto& child : node.children) {
render_node(child, transform, view, shader);
render_node(child, transform, view, shader, shadow);
}
}
void ModelRender::render_mesh(const Mesh& mesh) {
void ModelRender::render_mesh(const Mesh& mesh, bool) {
mesh.vao->bind();
if (mesh.texture) {
mesh.texture->bind(0);

View File

@@ -250,12 +250,6 @@ void Renderer::render_dev_panel(DevPanel& dev_panel) {
glEnable(GL_DEPTH_TEST);
}
void Renderer::render_model(const std::string& name, const glm::vec3& pos,
Camera& camera) {
glEnable(GL_DEPTH_TEST);
m_model_renderer.render_model(name, pos, camera);
}
bool Renderer::handle_event(const Event& e) {
return std::visit(Overloaded{[](const MouseMoveEvent&) { return false; },
[](const MouseButtonEvent&) { return false; },
@@ -348,4 +342,5 @@ float Renderer::frame_width() const { return m_frame_width; }
const glm::mat4& Renderer::p_mat() const { return m_world_proj_matrix; }
const std::vector<VertexArray>& Renderer::vao() const { return m_vao; }
ModelManager& Renderer::model_manager() { return m_model_manager; }
ModelRender& Renderer::model_renderer() { return m_model_renderer; }
} // namespace Cubed

View File

@@ -45,6 +45,9 @@ void WorldRenderer::render(ClientWorld& world) {
day_night_calculation(world);
render_sky(world);
if (m_shader_on) {
shadow_map_generate(world);
}
render_world(world);
render_outline(world);
render_entity(world);
@@ -229,10 +232,6 @@ void WorldRenderer::render_world(ClientWorld& world) {
glm::mat4 norm_mat = glm::transpose(glm::inverse(mv_mat));
if (m_shader_on) {
shadow_map_generate(world);
}
m_world_fbo->bind();
glCullFace(GL_BACK);
@@ -293,12 +292,29 @@ void WorldRenderer::render_outline(ClientWorld& world) {
}
void WorldRenderer::render_entity(ClientWorld& world) {
glEnable(GL_DEPTH_TEST);
auto& registry = world.get_registry();
auto view = registry.view<Transform, Model>();
auto& shader = m_renderer.get_shader("model_shader");
shader.use();
for (auto entity : view) {
auto [transform, model] = view.get<Transform, Model>(entity);
m_renderer.render_model(model.name, transform.pos,
world.world_scene().camera());
m_renderer.model_renderer().render_model(model.name, transform.pos,
world.world_scene().camera());
}
}
void WorldRenderer::shadow_entity(ClientWorld& world,
const glm::mat4& light_matrix) {
auto& registry = world.get_registry();
auto view = registry.view<Transform, Model>();
auto& shader = m_renderer.get_shader("depth_model");
shader.use();
for (auto entity : view) {
auto [transform, model] = view.get<Transform, Model>(entity);
m_renderer.model_renderer().shadow_pass(model.name, transform.pos,
light_matrix,
world.world_scene().camera());
}
}
@@ -404,6 +420,9 @@ void WorldRenderer::shadow_map_generate(ClientWorld& world) {
snapshot->normal_discard_vertices_count);
}
}
shadow_entity(world, light_space_matrix);
// player
auto& player_shadow = m_renderer.get_shader("depth_model");
m_player_renderer.shadow_render(player_shadow, light_space_matrix, world);