mirror of
https://github.com/zhenyan121/Cubed.git
synced 2026-08-08 17:57:02 +08:00
feat(render): add shadow pass for entity models
This commit is contained in:
@@ -13,10 +13,13 @@ public:
|
|||||||
void render_model(const std::string& name, const glm::vec3& pos,
|
void render_model(const std::string& name, const glm::vec3& pos,
|
||||||
Camera& camera);
|
Camera& camera);
|
||||||
|
|
||||||
|
void shadow_pass(const std::string& name, const glm::vec3& pos,
|
||||||
|
const glm::mat4& light_matrix, Camera& camera);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Renderer& m_renderer;
|
Renderer& m_renderer;
|
||||||
void render_node(const ModelNode& node, const glm::mat4& parent,
|
void 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);
|
||||||
void render_mesh(const Mesh& mesh);
|
void render_mesh(const Mesh& mesh, bool shadow);
|
||||||
};
|
};
|
||||||
} // namespace Cubed
|
} // namespace Cubed
|
||||||
@@ -82,10 +82,8 @@ public:
|
|||||||
|
|
||||||
bool handle_event(const Event& e);
|
bool handle_event(const Event& e);
|
||||||
|
|
||||||
void render_model(const std::string& name, const glm::vec3& pos,
|
|
||||||
Camera& camera);
|
|
||||||
|
|
||||||
ModelManager& model_manager();
|
ModelManager& model_manager();
|
||||||
|
ModelRender& model_renderer();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TextureManager& m_texture_manager;
|
TextureManager& m_texture_manager;
|
||||||
|
|||||||
@@ -133,6 +133,7 @@ private:
|
|||||||
void render_underwater(ClientWorld& world);
|
void render_underwater(ClientWorld& world);
|
||||||
void render_outline(ClientWorld& world);
|
void render_outline(ClientWorld& world);
|
||||||
void render_entity(ClientWorld& world);
|
void render_entity(ClientWorld& world);
|
||||||
|
void shadow_entity(ClientWorld& world, const glm::mat4& light_matrix);
|
||||||
void render_player(ClientWorld& world);
|
void render_player(ClientWorld& world);
|
||||||
|
|
||||||
void render_normal_block(const glm::mat4& model_mat,
|
void render_normal_block(const glm::mat4& model_mat,
|
||||||
|
|||||||
@@ -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);
|
glm::mat4 transform = glm::translate(glm::mat4(1.0f), pos);
|
||||||
auto& shader = m_renderer.get_shader("model_shader");
|
auto& shader = m_renderer.get_shader("model_shader");
|
||||||
glm::mat4 view = camera.get_camera_lookat();
|
glm::mat4 view = camera.get_camera_lookat();
|
||||||
shader.use();
|
|
||||||
shader.set_loc("proj_matrix", m_renderer.p_mat());
|
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,
|
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;
|
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) {
|
for (auto& mesh : node.meshes) {
|
||||||
render_mesh(mesh);
|
render_mesh(mesh, shadow);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& child : node.children) {
|
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();
|
mesh.vao->bind();
|
||||||
if (mesh.texture) {
|
if (mesh.texture) {
|
||||||
mesh.texture->bind(0);
|
mesh.texture->bind(0);
|
||||||
|
|||||||
@@ -250,12 +250,6 @@ void Renderer::render_dev_panel(DevPanel& dev_panel) {
|
|||||||
glEnable(GL_DEPTH_TEST);
|
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) {
|
bool Renderer::handle_event(const Event& e) {
|
||||||
return std::visit(Overloaded{[](const MouseMoveEvent&) { return false; },
|
return std::visit(Overloaded{[](const MouseMoveEvent&) { return false; },
|
||||||
[](const MouseButtonEvent&) { 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 glm::mat4& Renderer::p_mat() const { return m_world_proj_matrix; }
|
||||||
const std::vector<VertexArray>& Renderer::vao() const { return m_vao; }
|
const std::vector<VertexArray>& Renderer::vao() const { return m_vao; }
|
||||||
ModelManager& Renderer::model_manager() { return m_model_manager; }
|
ModelManager& Renderer::model_manager() { return m_model_manager; }
|
||||||
|
ModelRender& Renderer::model_renderer() { return m_model_renderer; }
|
||||||
} // namespace Cubed
|
} // namespace Cubed
|
||||||
@@ -45,6 +45,9 @@ void WorldRenderer::render(ClientWorld& world) {
|
|||||||
day_night_calculation(world);
|
day_night_calculation(world);
|
||||||
|
|
||||||
render_sky(world);
|
render_sky(world);
|
||||||
|
if (m_shader_on) {
|
||||||
|
shadow_map_generate(world);
|
||||||
|
}
|
||||||
render_world(world);
|
render_world(world);
|
||||||
render_outline(world);
|
render_outline(world);
|
||||||
render_entity(world);
|
render_entity(world);
|
||||||
@@ -229,10 +232,6 @@ void WorldRenderer::render_world(ClientWorld& world) {
|
|||||||
|
|
||||||
glm::mat4 norm_mat = glm::transpose(glm::inverse(mv_mat));
|
glm::mat4 norm_mat = glm::transpose(glm::inverse(mv_mat));
|
||||||
|
|
||||||
if (m_shader_on) {
|
|
||||||
shadow_map_generate(world);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_world_fbo->bind();
|
m_world_fbo->bind();
|
||||||
|
|
||||||
glCullFace(GL_BACK);
|
glCullFace(GL_BACK);
|
||||||
@@ -293,11 +292,28 @@ void WorldRenderer::render_outline(ClientWorld& world) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void WorldRenderer::render_entity(ClientWorld& world) {
|
void WorldRenderer::render_entity(ClientWorld& world) {
|
||||||
|
glEnable(GL_DEPTH_TEST);
|
||||||
auto& registry = world.get_registry();
|
auto& registry = world.get_registry();
|
||||||
auto view = registry.view<Transform, Model>();
|
auto view = registry.view<Transform, Model>();
|
||||||
|
auto& shader = m_renderer.get_shader("model_shader");
|
||||||
|
shader.use();
|
||||||
for (auto entity : view) {
|
for (auto entity : view) {
|
||||||
auto [transform, model] = view.get<Transform, Model>(entity);
|
auto [transform, model] = view.get<Transform, Model>(entity);
|
||||||
m_renderer.render_model(model.name, transform.pos,
|
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());
|
world.world_scene().camera());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -404,6 +420,9 @@ void WorldRenderer::shadow_map_generate(ClientWorld& world) {
|
|||||||
snapshot->normal_discard_vertices_count);
|
snapshot->normal_discard_vertices_count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
shadow_entity(world, light_space_matrix);
|
||||||
|
|
||||||
// player
|
// player
|
||||||
auto& player_shadow = m_renderer.get_shader("depth_model");
|
auto& player_shadow = m_renderer.get_shader("depth_model");
|
||||||
m_player_renderer.shadow_render(player_shadow, light_space_matrix, world);
|
m_player_renderer.shadow_render(player_shadow, light_space_matrix, world);
|
||||||
|
|||||||
Reference in New Issue
Block a user