From 31bf337f6ffdadcb6ea73ec4293c5499109d97c2 Mon Sep 17 00:00:00 2001 From: zhenyan121 <3367366583@qq.com> Date: Wed, 17 Jun 2026 15:23:38 +0800 Subject: [PATCH] perf(shadow): increase depth map resolution and refine PCF sampling --- assets/shaders/block_f_shader.glsl | 34 ++++++++++++++++++++++++------ include/Cubed/renderer.hpp | 3 +-- src/renderer.cpp | 19 ++++++++++------- 3 files changed, 40 insertions(+), 16 deletions(-) diff --git a/assets/shaders/block_f_shader.glsl b/assets/shaders/block_f_shader.glsl index c93651e..6af8dd8 100644 --- a/assets/shaders/block_f_shader.glsl +++ b/assets/shaders/block_f_shader.glsl @@ -37,16 +37,20 @@ float ShadowCalculation(vec4 fragPosLightSpace, vec3 norm, vec3 lightDir) } float currentDepth = projCoords.z; vec2 texelSize = 1.0 / vec2(textureSize(shadowMap, 0)); - float bias = 0.0002; - bias += max(0.005 * texelSize.x * (1.0 - dot(norm, lightDir)), 0.0); - - float angle = random(gl_FragCoord.xyy) * 6.2831853; // 2*PI + float shadow = 0.0; + float bias = + max( + 0.0003, + 0.001 * (1.0 - dot(norm, lightDir)) + ); + vec3 seed = vert_pos * 37.0 + sin(vert_pos * 91.7) * 13.0; + float angle = random(seed) * 6.2831853;; // 2*PI float s = sin(angle), c = cos(angle); mat2 rot = mat2(c, -s, s, c); - float radius = 1.5; + float radius = 0.7; - float shadow = 0.0; + const int samples = 8; for (int i = 0; i < samples; ++i) { vec2 offset = rot * poissonDisk[i] * radius * texelSize; @@ -54,7 +58,25 @@ float ShadowCalculation(vec4 fragPosLightSpace, vec3 norm, vec3 lightDir) shadow += (currentDepth - bias > pcfDepth ? 1.0 : 0.0); } shadow /= float(samples); + + /* + for (int x = -1; x <= 1; ++x) { + for (int y = -1; y <= 1; ++y) { + vec2 offset = vec2(x, y) * texelSize; + float pcfDepth = texture(shadowMap, projCoords.xy + offset).r; + shadow += (currentDepth - bias > pcfDepth ? 1.0 : 0.0); + } + } + shadow /= 9.0; + */ + // pcf off + //float pcfDepth = + //texture(shadowMap, projCoords.xy).r; + //shadow = + // currentDepth - bias > pcfDepth + // ? 1.0 + // : 0.0; return shadow; } diff --git a/include/Cubed/renderer.hpp b/include/Cubed/renderer.hpp index f3453fa..11343d8 100644 --- a/include/Cubed/renderer.hpp +++ b/include/Cubed/renderer.hpp @@ -39,8 +39,7 @@ private: static constexpr float NEAR_PLANE = 0.1f; static constexpr float SUN_SIZE = 50.0f; static constexpr float MOON_SIZE = 50.0f; - static constexpr float DEPTH_MAP_WIDTH = 2048.0f; - static constexpr float DEPTH_MAP_HEIGHT = 2048.0f; + static constexpr float DEPTH_MAP_SIZE = 4096.0f; float m_ambient_strength = 0.1f; const Camera& m_camera; diff --git a/src/renderer.cpp b/src/renderer.cpp index 8d55b78..0f9edb6 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp @@ -470,8 +470,8 @@ void Renderer::updata_framebuffer(int width, int height) { glGenTextures(1, &m_depth_map_texture); glBindTexture(GL_TEXTURE_2D, m_depth_map_texture); - glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, DEPTH_MAP_WIDTH, - DEPTH_MAP_HEIGHT, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL); + glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, DEPTH_MAP_SIZE, + DEPTH_MAP_SIZE, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); @@ -506,7 +506,7 @@ void Renderer::render_world() { glm::vec3 cam_pos = m_camera.get_camera_pos(); glm::vec3 cam_fwd = m_camera.get_camera_front(); - float half_extent = 256.0f; + float half_extent = 128.0f; glm::vec3 center = cam_pos + cam_fwd * (half_extent * 0.5f); @@ -515,24 +515,27 @@ void Renderer::render_world() { fabs(sundir.y) > 0.99f ? glm::vec3(0, 0, 1) : glm::vec3(0, 1, 0); glm::mat4 light_basis = glm::lookAt(glm::vec3(0.0f), sundir, up); - float texels_per_unit = DEPTH_MAP_WIDTH / (half_extent * 2.0f); + float texels_per_unit = DEPTH_MAP_SIZE / (half_extent * 2.0f); glm::vec3 ls_center = glm::vec3(light_basis * glm::vec4(center, 1.0f)); ls_center.x = std::round(ls_center.x * texels_per_unit) / texels_per_unit; ls_center.y = std::round(ls_center.y * texels_per_unit) / texels_per_unit; glm::vec3 snapped_center = glm::vec3(glm::inverse(light_basis) * glm::vec4(ls_center, 1.0f)); - float distance = 128.0f; + float distance = half_extent * 1.5f; + float near_plane = 1.0f; + float far_plane = distance + half_extent * 2.0f; glm::vec3 light_pos = snapped_center - sundir * distance; glm::mat4 light_view = glm::lookAt(light_pos, snapped_center, up); - glm::mat4 light_projection = glm::ortho( - -half_extent, half_extent, -half_extent, half_extent, 1.0f, 500.0f); + glm::mat4 light_projection = + glm::ortho(-half_extent, half_extent, -half_extent, half_extent, + near_plane, far_plane); glm::mat4 light_space_matrix = light_projection * light_view; glUniformMatrix4fv(depth_shader.loc("lightSpaceMatrix"), 1, GL_FALSE, glm::value_ptr(light_space_matrix)); - glViewport(0, 0, DEPTH_MAP_WIDTH, DEPTH_MAP_WIDTH); + glViewport(0, 0, DEPTH_MAP_SIZE, DEPTH_MAP_SIZE); glCullFace(GL_FRONT); glBindFramebuffer(GL_FRAMEBUFFER, m_depth_map_fbo);