mirror of
https://github.com/zhenyan121/Cubed.git
synced 2026-08-09 02:07:04 +08:00
perf(render): batch model rendering with instancing
Replaces per-entity draw calls with instanced rendering for both main and shadow passes. Each model's node hierarchy is flattened once and instance matrices are updated per frame, reducing draw calls and CPU overhead.
This commit is contained in:
13
assets/shaders/depth_model_instance_vert.glsl
Normal file
13
assets/shaders/depth_model_instance_vert.glsl
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
#version 460
|
||||||
|
|
||||||
|
layout (location = 0) in vec3 pos;
|
||||||
|
layout (location = 1) in vec2 texCoord;
|
||||||
|
layout (location = 3) in mat4 modelMatrix;
|
||||||
|
uniform mat4 lightSpaceMatrix;
|
||||||
|
|
||||||
|
out vec2 tc;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
tc = texCoord;
|
||||||
|
gl_Position = lightSpaceMatrix * modelMatrix * vec4(pos, 1.0);
|
||||||
|
}
|
||||||
14
assets/shaders/depth_model_vert copy.glsl
Normal file
14
assets/shaders/depth_model_vert copy.glsl
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
#version 460
|
||||||
|
|
||||||
|
layout (location = 0) in vec3 pos;
|
||||||
|
layout (location = 1) in vec2 texCoord;
|
||||||
|
|
||||||
|
uniform mat4 lightSpaceMatrix;
|
||||||
|
uniform mat4 modelMatrix;
|
||||||
|
|
||||||
|
out vec2 tc;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
tc = texCoord;
|
||||||
|
gl_Position = lightSpaceMatrix * modelMatrix * vec4(pos, 1.0);
|
||||||
|
}
|
||||||
26
assets/shaders/model_instance_vert.glsl
Normal file
26
assets/shaders/model_instance_vert.glsl
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
#version 460
|
||||||
|
|
||||||
|
layout (location = 0) in vec3 pos;
|
||||||
|
layout (location = 1) in vec2 texCoord;
|
||||||
|
layout (location = 2) in vec3 aNormal;
|
||||||
|
layout (location = 3) in mat4 modelMatrix;
|
||||||
|
uniform mat4 view_matrix;
|
||||||
|
uniform mat4 proj_matrix;
|
||||||
|
uniform mat4 lightSpaceMatrix;
|
||||||
|
out vec4 FragPosLightSpace;
|
||||||
|
out vec3 normal;
|
||||||
|
out vec2 tc;
|
||||||
|
out vec3 vert_pos;
|
||||||
|
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec4 worldPos = modelMatrix * vec4(pos, 1.0);
|
||||||
|
FragPosLightSpace = lightSpaceMatrix * worldPos;
|
||||||
|
mat4 mv_matrix= view_matrix * modelMatrix;
|
||||||
|
mat4 norm_matrix = transpose(inverse(mv_matrix));
|
||||||
|
vec4 viewPos = mv_matrix * vec4(pos, 1.0);
|
||||||
|
tc = texCoord;
|
||||||
|
vert_pos = pos;
|
||||||
|
normal = normalize(mat3(norm_matrix) * aNormal);
|
||||||
|
gl_Position = proj_matrix * viewPos;
|
||||||
|
}
|
||||||
@@ -3,28 +3,50 @@
|
|||||||
#include "Cubed/gameplay/ecs/animation.hpp"
|
#include "Cubed/gameplay/ecs/animation.hpp"
|
||||||
#include "Cubed/gameplay/model.hpp"
|
#include "Cubed/gameplay/model.hpp"
|
||||||
#include "Cubed/render/model_node.hpp"
|
#include "Cubed/render/model_node.hpp"
|
||||||
#include "Cubed/shader.hpp"
|
|
||||||
|
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
|
#include <span>
|
||||||
namespace Cubed {
|
namespace Cubed {
|
||||||
class Renderer;
|
class Renderer;
|
||||||
class Camera;
|
class Camera;
|
||||||
class ModelRender {
|
class ModelRender {
|
||||||
public:
|
public:
|
||||||
ModelRender(Renderer& renderer);
|
struct InstanceData {
|
||||||
void render_model(ModelID id, const glm::vec3& pos, float yaw,
|
glm::vec3 pos{0.0f};
|
||||||
Camera& camera, const WalkPose& pose);
|
float yaw = 0.0f;
|
||||||
|
WalkPose pose;
|
||||||
|
};
|
||||||
|
|
||||||
void shadow_pass(ModelID id, const glm::vec3& pos, float yaw,
|
struct DrawEntry {
|
||||||
Camera& camera, const WalkPose& pose);
|
const Mesh* mesh = nullptr;
|
||||||
|
size_t node_slot = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ModelBatch {
|
||||||
|
size_t node_count = 0;
|
||||||
|
size_t capacity = 0;
|
||||||
|
std::vector<DrawEntry> entries;
|
||||||
|
std::vector<glm::mat4> instance_matrices;
|
||||||
|
std::unique_ptr<VertexBuffer> instance_vbo;
|
||||||
|
};
|
||||||
|
|
||||||
|
ModelRender(Renderer& renderer);
|
||||||
|
|
||||||
|
void render_instance(ModelID id, std::span<const InstanceData> instances,
|
||||||
|
const Camera& camera, bool shadow);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Renderer& m_renderer;
|
Renderer& m_renderer;
|
||||||
void render_node(const ModelNode& node, const glm::mat4& parent,
|
|
||||||
const glm::mat4& view, const Shader& shader, bool shadow,
|
std::unordered_map<ModelID, ModelBatch> m_batches;
|
||||||
const WalkPose& pose, const ModelAnimConfig& cfg);
|
|
||||||
|
size_t collect_matrices(const ModelNode& node, const glm::mat4& parent,
|
||||||
|
const WalkPose& pose, const ModelAnimConfig& cfg,
|
||||||
|
std::vector<glm::mat4>& out, size_t slot);
|
||||||
glm::mat4 pose_node(const ModelNode& node, const ModelAnimConfig& cfg,
|
glm::mat4 pose_node(const ModelNode& node, const ModelAnimConfig& cfg,
|
||||||
const WalkPose& pose);
|
const WalkPose& pose);
|
||||||
void render_mesh(const Mesh& mesh, bool shadow);
|
|
||||||
|
ModelBatch& get_batch(ModelID id, const ModelNode& root);
|
||||||
|
size_t flatten_nodes(const ModelNode& node, size_t slot, ModelBatch& batch);
|
||||||
};
|
};
|
||||||
} // namespace Cubed
|
} // namespace Cubed
|
||||||
@@ -19,6 +19,7 @@ public:
|
|||||||
|
|
||||||
void attribute(GLuint index, GLint size, GLenum type, GLsizei stride,
|
void attribute(GLuint index, GLint size, GLenum type, GLsizei stride,
|
||||||
const void* ptr, bool normalized = false) const;
|
const void* ptr, bool normalized = false) const;
|
||||||
|
void divisor(GLuint index, GLuint divisor = 1);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
GLuint m_vao = 0;
|
GLuint m_vao = 0;
|
||||||
|
|||||||
@@ -26,6 +26,8 @@ public:
|
|||||||
GLuint id() const;
|
GLuint id() const;
|
||||||
void buffer_data(const void* data, GLsizeiptr size,
|
void buffer_data(const void* data, GLsizeiptr size,
|
||||||
BufferUsage usage = BufferUsage::STATIC_DRAW) const;
|
BufferUsage usage = BufferUsage::STATIC_DRAW) const;
|
||||||
|
void buffer_sub_data(const void* data, GLsizeiptr size,
|
||||||
|
GLintptr offset) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
GLuint m_vbo = 0;
|
GLuint m_vbo = 0;
|
||||||
|
|||||||
@@ -18,77 +18,112 @@ float swing_angle(const WalkPose& pose, float speed, float amp_deg) {
|
|||||||
|
|
||||||
ModelRender::ModelRender(Renderer& renderer) : m_renderer(renderer) {}
|
ModelRender::ModelRender(Renderer& renderer) : m_renderer(renderer) {}
|
||||||
|
|
||||||
void ModelRender::render_model(ModelID id, const glm::vec3& pos, float yaw,
|
void ModelRender::render_instance(ModelID id,
|
||||||
Camera& camera, const WalkPose& pose) {
|
std::span<const InstanceData> instances,
|
||||||
|
const Camera& camera, bool shadow) {
|
||||||
|
if (instances.empty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
auto& root = ModelManager::model(id).node;
|
auto& root = ModelManager::model(id).node;
|
||||||
glm::vec3 bob_pos = pos;
|
auto& batch = get_batch(id, root);
|
||||||
if (pose.gait != Gait::STOP &&
|
const size_t PER_INSTANCE_SIZE = batch.node_count * sizeof(glm::mat4);
|
||||||
|
if (instances.size() > batch.capacity) {
|
||||||
|
batch.capacity = instances.size() * 2;
|
||||||
|
batch.instance_matrices.resize(batch.capacity * batch.node_count);
|
||||||
|
batch.instance_vbo = std::make_unique<VertexBuffer>();
|
||||||
|
batch.instance_vbo->buffer_data(batch.instance_matrices.data(),
|
||||||
|
batch.instance_matrices.size() *
|
||||||
|
sizeof(glm::mat4),
|
||||||
|
BufferUsage::DYNAMIC_DRAW);
|
||||||
|
for (const auto& entry : batch.entries) {
|
||||||
|
for (int col = 0; col < 4; ++col) {
|
||||||
|
entry.mesh->vao->attribute(
|
||||||
|
3 + col, 4, GL_FLOAT, PER_INSTANCE_SIZE,
|
||||||
|
(void*)(entry.node_slot * sizeof(glm::mat4) +
|
||||||
|
col * sizeof(glm::vec4)));
|
||||||
|
entry.mesh->vao->divisor(3 + col);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < instances.size(); ++i) {
|
||||||
|
glm::vec3 bob_pos = instances[i].pos;
|
||||||
|
if (instances[i].pose.gait != Gait::STOP &&
|
||||||
root.anim.has_role(NodeAnimRule::Role::LEG)) {
|
root.anim.has_role(NodeAnimRule::Role::LEG)) {
|
||||||
bob_pos.y += std::abs(glm::sin(pose.walk_time * root.anim.walk_speed)) *
|
float speed = instances[i].pose.gait == Gait::RUN
|
||||||
|
? root.anim.run_speed
|
||||||
|
: root.anim.walk_speed;
|
||||||
|
bob_pos.y +=
|
||||||
|
std::abs(glm::sin(instances[i].pose.walk_time * speed)) *
|
||||||
root.anim.body_bob;
|
root.anim.body_bob;
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::mat4 transform = glm::translate(glm::mat4(1.0f), bob_pos) *
|
glm::mat4 transform =
|
||||||
glm::rotate(glm::mat4(1.0f), yaw, {0, 1, 0});
|
glm::translate(glm::mat4(1.0f), bob_pos) *
|
||||||
auto& shader = m_renderer.get_shader("model_shader");
|
glm::rotate(glm::mat4(1.0f), instances[i].yaw, {0, 1, 0});
|
||||||
|
collect_matrices(root, transform, instances[i].pose, root.anim,
|
||||||
|
batch.instance_matrices, i * batch.node_count);
|
||||||
|
}
|
||||||
|
|
||||||
|
batch.instance_vbo->buffer_sub_data(
|
||||||
|
batch.instance_matrices.data(),
|
||||||
|
instances.size() * batch.node_count * sizeof(glm::mat4), 0);
|
||||||
|
|
||||||
|
auto& shader = shadow ? m_renderer.get_shader("depth_model_instance")
|
||||||
|
: m_renderer.get_shader("model_instance");
|
||||||
glm::mat4 view = camera.get_camera_lookat();
|
glm::mat4 view = camera.get_camera_lookat();
|
||||||
shader.set_loc("proj_matrix", m_renderer.p_mat());
|
shader.set_loc("proj_matrix", m_renderer.p_mat());
|
||||||
render_node(root, transform, view, shader, false, pose, root.anim);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ModelRender::shadow_pass(ModelID id, const glm::vec3& pos, float yaw,
|
|
||||||
Camera& camera, const WalkPose& pose) {
|
|
||||||
auto& root = ModelManager::model(id).node;
|
|
||||||
glm::vec3 bob_pos = pos;
|
|
||||||
if (pose.gait != Gait::STOP &&
|
|
||||||
root.anim.has_role(NodeAnimRule::Role::LEG)) {
|
|
||||||
bob_pos.y += std::abs(glm::sin(pose.walk_time * root.anim.walk_speed)) *
|
|
||||||
root.anim.body_bob;
|
|
||||||
}
|
|
||||||
|
|
||||||
glm::mat4 transform = glm::translate(glm::mat4(1.0f), bob_pos) *
|
|
||||||
glm::rotate(glm::mat4(1.0f), yaw, {0, 1, 0});
|
|
||||||
|
|
||||||
auto& shader = m_renderer.get_shader("depth_model");
|
|
||||||
glm::mat4 view = camera.get_camera_lookat();
|
|
||||||
|
|
||||||
render_node(root, transform, view, shader, true, pose, root.anim);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ModelRender::render_node(const ModelNode& node, const glm::mat4& parent,
|
|
||||||
const glm::mat4& view, const Shader& shader,
|
|
||||||
bool shadow, const WalkPose& pose,
|
|
||||||
const ModelAnimConfig& cfg) {
|
|
||||||
|
|
||||||
glm::mat4 transform = parent * pose_node(node, cfg, pose);
|
|
||||||
if (shadow) {
|
if (shadow) {
|
||||||
shader.set_loc("modelMatrix", transform);
|
|
||||||
} else {
|
} else {
|
||||||
glm::mat4 mv_matrix = view * transform;
|
shader.set_loc("view_matrix", view);
|
||||||
shader.set_loc("modelMatrix", transform);
|
|
||||||
shader.set_loc("mv_matrix", mv_matrix);
|
|
||||||
shader.set_loc("norm_matrix", glm::transpose(glm::inverse(mv_matrix)));
|
|
||||||
}
|
}
|
||||||
|
for (const auto& entry : batch.entries) {
|
||||||
for (auto& mesh : node.meshes) {
|
if (entry.mesh->texture) {
|
||||||
render_mesh(mesh, shadow);
|
entry.mesh->texture->bind(1);
|
||||||
}
|
}
|
||||||
|
entry.mesh->vao->bind();
|
||||||
for (auto& child : node.children) {
|
glDrawElementsInstanced(GL_TRIANGLES, entry.mesh->indices.size(),
|
||||||
render_node(child, transform, view, shader, shadow, pose, cfg);
|
GL_UNSIGNED_INT, 0, instances.size());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModelRender::render_mesh(const Mesh& mesh, bool) {
|
size_t ModelRender::collect_matrices(const ModelNode& node,
|
||||||
mesh.vao->bind();
|
const glm::mat4& parent,
|
||||||
if (mesh.texture) {
|
const WalkPose& pose,
|
||||||
mesh.texture->bind(1);
|
const ModelAnimConfig& cfg,
|
||||||
} else {
|
std::vector<glm::mat4>& out, size_t slot) {
|
||||||
Logger::error("Model Texture Not Find");
|
glm::mat4 transform = parent * pose_node(node, cfg, pose);
|
||||||
|
out[slot] = transform;
|
||||||
|
size_t next = slot + 1;
|
||||||
|
for (const auto& clild : node.children) {
|
||||||
|
next = collect_matrices(clild, transform, pose, cfg, out, next);
|
||||||
|
}
|
||||||
|
return next;
|
||||||
|
}
|
||||||
|
|
||||||
|
ModelRender::ModelBatch& ModelRender::get_batch(ModelID id,
|
||||||
|
const ModelNode& root) {
|
||||||
|
auto it = m_batches.find(id);
|
||||||
|
if (it != m_batches.end()) {
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
ModelBatch batch;
|
||||||
|
batch.node_count = flatten_nodes(root, 0, batch);
|
||||||
|
return m_batches.try_emplace(id, std::move(batch)).first->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t ModelRender::flatten_nodes(const ModelNode& node, size_t slot,
|
||||||
|
ModelBatch& batch) {
|
||||||
|
size_t node_slot = slot++;
|
||||||
|
for (const auto& mesh : node.meshes) {
|
||||||
|
batch.entries.emplace_back(&mesh, node_slot);
|
||||||
}
|
}
|
||||||
|
|
||||||
glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(mesh.indices.size()),
|
for (const auto& child : node.children) {
|
||||||
GL_UNSIGNED_INT, 0);
|
slot = flatten_nodes(child, slot, batch);
|
||||||
|
}
|
||||||
|
|
||||||
|
return slot;
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::mat4 ModelRender::pose_node(const ModelNode& node,
|
glm::mat4 ModelRender::pose_node(const ModelNode& node,
|
||||||
|
|||||||
@@ -35,6 +35,11 @@ void ShaderManager::init() {
|
|||||||
"shaders/rect_f_shader.glsl");
|
"shaders/rect_f_shader.glsl");
|
||||||
register_shader("model_shader", "shaders/model_vert.glsl",
|
register_shader("model_shader", "shaders/model_vert.glsl",
|
||||||
"shaders/model_frag.glsl");
|
"shaders/model_frag.glsl");
|
||||||
|
register_shader("model_instance", "shaders/model_instance_vert.glsl",
|
||||||
|
"shaders/model_frag.glsl");
|
||||||
|
register_shader("depth_model_instance",
|
||||||
|
"shaders/depth_model_instance_vert.glsl",
|
||||||
|
"shaders/depth_model_frag.glsl");
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShaderManager::register_shader(const std::string& name,
|
void ShaderManager::register_shader(const std::string& name,
|
||||||
|
|||||||
@@ -35,5 +35,8 @@ void VertexArray::attribute(GLuint index, GLint size, GLenum type,
|
|||||||
stride, ptr);
|
stride, ptr);
|
||||||
glEnableVertexAttribArray(index);
|
glEnableVertexAttribArray(index);
|
||||||
}
|
}
|
||||||
|
void VertexArray::divisor(GLuint index, GLuint divisor) {
|
||||||
|
bind();
|
||||||
|
glVertexAttribDivisor(index, divisor);
|
||||||
|
}
|
||||||
} // namespace Cubed
|
} // namespace Cubed
|
||||||
@@ -48,5 +48,10 @@ void VertexBuffer::buffer_data(const void* data, GLsizeiptr size,
|
|||||||
|
|
||||||
glBufferData(target, size, data, std::to_underlying(usage));
|
glBufferData(target, size, data, std::to_underlying(usage));
|
||||||
}
|
}
|
||||||
|
void VertexBuffer::buffer_sub_data(const void* data, GLsizeiptr size,
|
||||||
|
GLintptr offset) const {
|
||||||
|
bind();
|
||||||
|
glBufferSubData(get_buffer_target(), offset, size, data);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Cubed
|
} // namespace Cubed
|
||||||
@@ -11,7 +11,37 @@
|
|||||||
#include "Cubed/tools/math_tools.hpp"
|
#include "Cubed/tools/math_tools.hpp"
|
||||||
|
|
||||||
#include <SDL3/SDL_timer.h>
|
#include <SDL3/SDL_timer.h>
|
||||||
|
#include <unordered_map>
|
||||||
namespace Cubed {
|
namespace Cubed {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
std::unordered_map<ModelID, std::vector<ModelRender::InstanceData>>
|
||||||
|
get_instances_data_map(ClientWorld& world) {
|
||||||
|
std::unordered_map<ModelID, std::vector<ModelRender::InstanceData>>
|
||||||
|
instances_data_map;
|
||||||
|
auto& registry = world.entity_manager().get_registry();
|
||||||
|
auto view = registry.view<BaseClientCreature, RenderTransform>();
|
||||||
|
for (auto entity : view) {
|
||||||
|
auto& creature = view.get<BaseClientCreature>(entity);
|
||||||
|
auto pos = creature.transform.position.value;
|
||||||
|
if (!world.is_render(pos)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
auto& t = view.get<RenderTransform>(entity);
|
||||||
|
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));
|
||||||
|
// m_renderer.model_renderer().shadow_pass(
|
||||||
|
// creature.model, t.position.value, yaw,
|
||||||
|
// world.world_scene().camera(), creature.pose);
|
||||||
|
}
|
||||||
|
return instances_data_map;
|
||||||
|
};
|
||||||
|
} // namespace
|
||||||
|
|
||||||
WorldRenderer::WorldRenderer(Renderer& renderer)
|
WorldRenderer::WorldRenderer(Renderer& renderer)
|
||||||
: m_renderer(renderer), m_player_renderer(renderer),
|
: m_renderer(renderer), m_player_renderer(renderer),
|
||||||
m_texture_manager(renderer.texture_mamger()) {}
|
m_texture_manager(renderer.texture_mamger()) {}
|
||||||
@@ -292,26 +322,24 @@ void WorldRenderer::render_outline(ClientWorld& world) {
|
|||||||
|
|
||||||
void WorldRenderer::shadow_entity(ClientWorld& world,
|
void WorldRenderer::shadow_entity(ClientWorld& world,
|
||||||
const glm::mat4& light_matrix) {
|
const glm::mat4& light_matrix) {
|
||||||
|
glEnable(GL_DEPTH_TEST);
|
||||||
|
{
|
||||||
|
auto& shader = m_renderer.get_shader("depth_model_instance");
|
||||||
|
shader.use();
|
||||||
|
shader.set_loc("lightSpaceMatrix", light_matrix);
|
||||||
|
auto instances_data_map = get_instances_data_map(world);
|
||||||
|
for (auto& [id, data] : instances_data_map) {
|
||||||
|
m_renderer.model_renderer().render_instance(
|
||||||
|
id, data, world.world_scene().camera(), true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
auto& shader = m_renderer.get_shader("depth_model");
|
auto& shader = m_renderer.get_shader("depth_model");
|
||||||
shader.use();
|
shader.use();
|
||||||
shader.set_loc("lightSpaceMatrix", light_matrix);
|
shader.set_loc("lightSpaceMatrix", light_matrix);
|
||||||
glEnable(GL_DEPTH_TEST);
|
|
||||||
auto& registry = world.entity_manager().get_registry();
|
|
||||||
auto view = registry.view<BaseClientCreature, RenderTransform>();
|
|
||||||
for (auto entity : view) {
|
|
||||||
auto& creature = view.get<BaseClientCreature>(entity);
|
|
||||||
auto pos = creature.transform.position.value;
|
|
||||||
if (!world.is_render(pos)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
auto& t = view.get<RenderTransform>(entity);
|
|
||||||
float yaw = std::atan2(t.direction.value.x, t.direction.value.z);
|
|
||||||
|
|
||||||
m_renderer.model_renderer().shadow_pass(
|
|
||||||
creature.model, t.position.value, yaw, world.world_scene().camera(),
|
|
||||||
creature.pose);
|
|
||||||
}
|
|
||||||
m_player_renderer.render(shader, world, true);
|
m_player_renderer.render(shader, world, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldRenderer::shadow_map_generate(ClientWorld& world) {
|
void WorldRenderer::shadow_map_generate(ClientWorld& world) {
|
||||||
@@ -700,46 +728,57 @@ void WorldRenderer::render_transparent_block(const glm::mat4& mv_mat,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void WorldRenderer::render_entity(ClientWorld& world) {
|
void WorldRenderer::render_entity(ClientWorld& world) {
|
||||||
auto& shader = m_renderer.get_shader("model_shader");
|
|
||||||
shader.use();
|
|
||||||
glm::vec3 light_dir_view =
|
|
||||||
glm::normalize(glm::mat3(view_matrix) * m_parallel_light.lightdir);
|
|
||||||
|
|
||||||
shader.set_loc("lightSpaceMatrix", m_parallel_light.light_space_matrix);
|
|
||||||
shader.set_loc("ambientStrength", m_ambient_strength);
|
|
||||||
shader.set_loc("sunlightColor", m_parallel_light.directional_light_color);
|
|
||||||
shader.set_loc("ambientColor", m_parallel_light.finnal_ambient_color);
|
|
||||||
shader.set_loc("sunlightDir", light_dir_view);
|
|
||||||
shader.set_loc("shadowMode", m_shadow_mode);
|
|
||||||
shader.set_loc("shader_on", m_shader_on);
|
|
||||||
shader.set_loc("lightSizeUV", static_cast<float>(m_light_size_uv));
|
|
||||||
shader.set_loc("minRadius", m_min_radius);
|
|
||||||
shader.set_loc("maxRadius", m_max_radius);
|
|
||||||
shader.set_loc("samples", m_samples);
|
|
||||||
|
|
||||||
// shader.set_loc("renderDistance", m_world.rendering_distance());
|
// shader.set_loc("renderDistance", m_world.rendering_distance());
|
||||||
// shader.set_loc("skyColor", m_sky_uniform.sky_top);
|
// shader.set_loc("skyColor", m_sky_uniform.sky_top);
|
||||||
|
glEnable(GL_DEPTH_TEST);
|
||||||
|
{
|
||||||
|
auto& model = m_renderer.get_shader("model_instance");
|
||||||
|
model.use();
|
||||||
|
glm::vec3 light_dir_view =
|
||||||
|
glm::normalize(glm::mat3(view_matrix) * m_parallel_light.lightdir);
|
||||||
|
|
||||||
|
model.set_loc("lightSpaceMatrix", m_parallel_light.light_space_matrix);
|
||||||
|
model.set_loc("ambientStrength", m_ambient_strength);
|
||||||
|
model.set_loc("sunlightColor",
|
||||||
|
m_parallel_light.directional_light_color);
|
||||||
|
model.set_loc("ambientColor", m_parallel_light.finnal_ambient_color);
|
||||||
|
model.set_loc("sunlightDir", light_dir_view);
|
||||||
|
model.set_loc("shadowMode", m_shadow_mode);
|
||||||
|
model.set_loc("shader_on", m_shader_on);
|
||||||
|
model.set_loc("lightSizeUV", static_cast<float>(m_light_size_uv));
|
||||||
|
model.set_loc("minRadius", m_min_radius);
|
||||||
|
model.set_loc("maxRadius", m_max_radius);
|
||||||
|
model.set_loc("samples", m_samples);
|
||||||
m_depth_map_texture->bind(0);
|
m_depth_map_texture->bind(0);
|
||||||
|
|
||||||
glEnable(GL_DEPTH_TEST);
|
auto instances_data_map = get_instances_data_map(world);
|
||||||
|
for (auto& [id, data] : instances_data_map) {
|
||||||
auto& registry = world.entity_manager().get_registry();
|
m_renderer.model_renderer().render_instance(
|
||||||
auto view = registry.view<BaseClientCreature, RenderTransform>();
|
id, data, world.world_scene().camera(), false);
|
||||||
for (auto entity : view) {
|
|
||||||
auto& creature = view.get<BaseClientCreature>(entity);
|
|
||||||
auto pos = creature.transform.position.value;
|
|
||||||
if (!world.is_render(pos)) {
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
auto& t = view.get<RenderTransform>(entity);
|
|
||||||
float yaw = std::atan2(t.direction.value.x, t.direction.value.z);
|
|
||||||
m_renderer.model_renderer().render_model(
|
|
||||||
creature.model, t.position.value, yaw, world.world_scene().camera(),
|
|
||||||
creature.pose);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_player_renderer.render(shader, world, false);
|
{
|
||||||
|
auto& model = m_renderer.get_shader("model_shader");
|
||||||
|
model.use();
|
||||||
|
glm::vec3 light_dir_view =
|
||||||
|
glm::normalize(glm::mat3(view_matrix) * m_parallel_light.lightdir);
|
||||||
|
|
||||||
|
model.set_loc("lightSpaceMatrix", m_parallel_light.light_space_matrix);
|
||||||
|
model.set_loc("ambientStrength", m_ambient_strength);
|
||||||
|
model.set_loc("sunlightColor",
|
||||||
|
m_parallel_light.directional_light_color);
|
||||||
|
model.set_loc("ambientColor", m_parallel_light.finnal_ambient_color);
|
||||||
|
model.set_loc("sunlightDir", light_dir_view);
|
||||||
|
model.set_loc("shadowMode", m_shadow_mode);
|
||||||
|
model.set_loc("shader_on", m_shader_on);
|
||||||
|
model.set_loc("lightSizeUV", static_cast<float>(m_light_size_uv));
|
||||||
|
model.set_loc("minRadius", m_min_radius);
|
||||||
|
model.set_loc("maxRadius", m_max_radius);
|
||||||
|
model.set_loc("samples", m_samples);
|
||||||
|
m_player_renderer.render(model, world, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec3 WorldRenderer::quantize_sun_direction(const glm::vec3& lightdir,
|
glm::vec3 WorldRenderer::quantize_sun_direction(const glm::vec3& lightdir,
|
||||||
|
|||||||
Reference in New Issue
Block a user