diff --git a/assets/shaders/block_f_shader.glsl b/assets/shaders/block_f_shader.glsl index 6af8dd8..9e0d681 100644 --- a/assets/shaders/block_f_shader.glsl +++ b/assets/shaders/block_f_shader.glsl @@ -12,6 +12,8 @@ layout (binding = 1) uniform sampler2DArray samp; uniform float ambientStrength; uniform vec3 sunlightColor; uniform vec3 sunlightDir; +uniform bool shader_on; +uniform int shadowMode; const vec2 poissonDisk[8] = vec2[]( vec2( 0.1440, 0.7659), vec2(-0.5761, 0.4479), @@ -43,50 +45,67 @@ float ShadowCalculation(vec4 fragPosLightSpace, vec3 norm, vec3 lightDir) 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 = 0.7; + if (shadowMode == 0) { + 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); - - const int samples = 8; - for (int i = 0; i < samples; ++i) { - vec2 offset = rot * poissonDisk[i] * radius * texelSize; - float pcfDepth = texture(shadowMap, projCoords.xy + offset).r; - 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 radius = 0.7; + + + const int samples = 8; + for (int i = 0; i < samples; ++i) { + vec2 offset = rot * poissonDisk[i] * radius * 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 /= float(samples); + } else if (shadowMode == 1) { + 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; + } else if (shadowMode == 2) { + // pcf off + float pcfDepth = + texture(shadowMap, projCoords.xy).r; - //shadow = - // currentDepth - bias > pcfDepth - // ? 1.0 - // : 0.0; + shadow = + currentDepth - bias > pcfDepth + ? 1.0 + : 0.0; + } else { + float pcfDepth = + texture(shadowMap, projCoords.xy).r; + + shadow = + currentDepth - bias > pcfDepth + ? 1.0 + : 0.0; + } + + return shadow; } void main(void) { vec4 objectColor = texture(samp, vec3(tc, tex_layer)); - + if (objectColor.a < 0.8) { discard; } + if (!shader_on) { + color = objectColor; + return; + } + vec3 lightDir = normalize(-sunlightDir); diff --git a/assets/shaders/depth_fragment_shader.glsl b/assets/shaders/depth_fragment_shader.glsl index 2c249e5..9976e10 100644 --- a/assets/shaders/depth_fragment_shader.glsl +++ b/assets/shaders/depth_fragment_shader.glsl @@ -4,9 +4,13 @@ in vec2 tc; flat in int tex_layer; layout (binding = 1) uniform sampler2DArray samp; +uniform bool is_discard_tranparent; + void main() { - vec4 texColor = texture(samp, vec3(tc, tex_layer)); - if (texColor.a < 0.8) - discard; + if (is_discard_tranparent) { + vec4 texColor = texture(samp, vec3(tc, tex_layer)); + if (texColor.a < 0.8) + discard; + } //gl_FragDepth = gl_FragCoord.z; } \ No newline at end of file diff --git a/include/Cubed/dev_panel.hpp b/include/Cubed/dev_panel.hpp index 17917b1..4b47e56 100644 --- a/include/Cubed/dev_panel.hpp +++ b/include/Cubed/dev_panel.hpp @@ -56,6 +56,7 @@ private: void show_world_tab_item(); void show_player_tab_item(); void show_items_tab_item(); + void show_shader_tab_item(); void update_config_view(); void update_player_profile(); diff --git a/include/Cubed/renderer.hpp b/include/Cubed/renderer.hpp index 11343d8..b7c0f67 100644 --- a/include/Cubed/renderer.hpp +++ b/include/Cubed/renderer.hpp @@ -30,6 +30,11 @@ public: void updata_framebuffer(int width, int height); float& ambient_strength(); + bool& discard_transparent(); + bool& shader_on(); + int& shadow_mode(); + int& light_cull_face(); + private: static constexpr glm::vec3 SUNLIGHT_COLOR{1.0f, 1.0f, 1.0f}; static constexpr glm::vec3 SUN_COLOR{1.00f, 0.95f, 0.80f}; @@ -47,6 +52,10 @@ private: const TextureManager& m_texture_manager; World& m_world; + bool m_discard_tranparent = true; + bool m_shader_on = true; + int m_shadow_mode = 0; + int m_light_cull_face = 0; float m_aspect = 0.0f; float m_fov = DEFAULT_FOV; diff --git a/src/dev_panel.cpp b/src/dev_panel.cpp index 4bec87c..dc248a5 100644 --- a/src/dev_panel.cpp +++ b/src/dev_panel.cpp @@ -84,6 +84,7 @@ void DevPanel::render() { show_world_tab_item(); show_player_tab_item(); show_items_tab_item(); + show_shader_tab_item(); show_about_table_bar(); ImGui::EndTabBar(); @@ -107,6 +108,7 @@ void DevPanel::show_about_table_bar() { ImGui::Text("FreeType"); ImGui::Text("toml++"); ImGui::Text("Dear ImGui"); + ImGui::Text("Tbb"); ImGui::Separator(); ImGui::Text("Special Thanks"); ImGui::Text("TANGERIME"); @@ -361,10 +363,7 @@ void DevPanel::show_settings_tab_item() { static_cast(m_config.mouse_sensitivity)); m_player->hot_reload(); } - if (ImGui::SliderFloat("AmbientStrength", - &m_app.renderer().ambient_strength(), 0.0f, - 0.35f)) - ; + if (ImGui::SliderInt("Distance", &m_config.rendering_distance, 2, 128)) { Config::get().set("world.rendering_distance", @@ -610,6 +609,27 @@ void DevPanel::show_items_tab_item() { } } +void DevPanel::show_shader_tab_item() { + + static const char* shader_mode[] = {"Rotated Poisson Disk PCF", + "3x3 Square Grid PCF", "PCF off"}; + static const char* cull_face_mode[] = {"Front", "Back"}; + if (ImGui::BeginTabItem("shader")) { + ImGui::Checkbox("Shader", &m_app.renderer().shader_on()); + if (ImGui::SliderFloat("AmbientStrength", + &m_app.renderer().ambient_strength(), 0.0f, + 0.35f)) + ; + ImGui::Checkbox("Discard Transparent", + &m_app.renderer().discard_transparent()); + ImGui::Combo("ShaderMode", &m_app.renderer().shadow_mode(), shader_mode, + IM_ARRAYSIZE(shader_mode)); + ImGui::Combo("LightCullFaceMode", &m_app.renderer().light_cull_face(), + cull_face_mode, IM_ARRAYSIZE(cull_face_mode)); + ImGui::EndTabItem(); + } +} + void DevPanel::update_config_view() { auto config = Config::get(); m_config.fov = diff --git a/src/renderer.cpp b/src/renderer.cpp index 0f9edb6..809b58c 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp @@ -501,81 +501,96 @@ void Renderer::updata_framebuffer(int width, int height) { void Renderer::render_world() { // shader map - const auto& depth_shader = get_shader("depth_shader"); - depth_shader.use(); - - glm::vec3 cam_pos = m_camera.get_camera_pos(); - glm::vec3 cam_fwd = m_camera.get_camera_front(); - float half_extent = 128.0f; - - glm::vec3 center = cam_pos + cam_fwd * (half_extent * 0.5f); - - glm::vec3 sundir = glm::normalize(m_world.sunlight_dir()); - glm::vec3 up = - 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_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 = 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, - 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_SIZE, DEPTH_MAP_SIZE); - glCullFace(GL_FRONT); - - glBindFramebuffer(GL_FRAMEBUFFER, m_depth_map_fbo); - glClear(GL_DEPTH_BUFFER_BIT); - + glm::mat4 light_space_matrix; auto& m_render_snapshots = m_world.render_snapshots(); auto& camera_pos = m_camera.get_camera_pos(); - glActiveTexture(GL_TEXTURE1); - glEnable(GL_DEPTH_TEST); - for (const auto& snapshot : m_render_snapshots) { - glBindTexture(GL_TEXTURE_2D_ARRAY, - m_texture_manager.get_texture_array()); - glBindVertexArray(snapshot.normal_vao); + if (m_shader_on) { + const auto& depth_shader = get_shader("depth_shader"); + depth_shader.use(); - glDrawArrays(GL_TRIANGLES, 0, snapshot.normal_vertices_count); - } + glm::vec3 cam_pos = m_camera.get_camera_pos(); + glm::vec3 cam_fwd = m_camera.get_camera_front(); + float half_extent = 128.0f; - // cross_plane and discard + glm::vec3 center = cam_pos + cam_fwd * (half_extent * 0.5f); - for (const auto& snapshot : m_render_snapshots) { + glm::vec3 sundir = glm::normalize(m_world.sunlight_dir()); + glm::vec3 up = + fabs(sundir.y) > 0.99f ? glm::vec3(0, 0, 1) : glm::vec3(0, 1, 0); - glm::vec2 camera_pos_xz{camera_pos.x, camera_pos.z}; - if (snapshot.cross_vertices_count != 0) { - glm::vec2 center_xz{snapshot.center.x, snapshot.center.z}; - float dist2d = glm::distance(camera_pos_xz, center_xz); - if (dist2d <= CROSS_PLANE_DISTANCE * 16) { - glBindTexture(GL_TEXTURE_2D_ARRAY, - m_texture_manager.get_texture_array()); - glBindVertexArray(snapshot.cross_vao); + glm::mat4 light_basis = glm::lookAt(glm::vec3(0.0f), sundir, up); + 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)); - glDrawArrays(GL_TRIANGLES, 0, snapshot.cross_vertices_count); - } + 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, + near_plane, far_plane); + + light_space_matrix = light_projection * light_view; + glUniformMatrix4fv(depth_shader.loc("lightSpaceMatrix"), 1, GL_FALSE, + glm::value_ptr(light_space_matrix)); + glUniform1i(depth_shader.loc("is_discard_tranparent"), + m_discard_tranparent); + glViewport(0, 0, DEPTH_MAP_SIZE, DEPTH_MAP_SIZE); + if (m_light_cull_face == 0) { + glCullFace(GL_FRONT); + } else if (m_light_cull_face == 1) { + glCullFace(GL_BACK); + } else { + Logger::warn("Light Cull Face {} Over The Max Selection", + m_light_cull_face); + glCullFace(GL_BACK); } - if (snapshot.normal_discard_vertices_count != 0) { + + glBindFramebuffer(GL_FRAMEBUFFER, m_depth_map_fbo); + glClear(GL_DEPTH_BUFFER_BIT); + + glActiveTexture(GL_TEXTURE1); + glEnable(GL_DEPTH_TEST); + for (const auto& snapshot : m_render_snapshots) { glBindTexture(GL_TEXTURE_2D_ARRAY, m_texture_manager.get_texture_array()); - glBindVertexArray(snapshot.normal_discard_vao); + glBindVertexArray(snapshot.normal_vao); - glDrawArrays(GL_TRIANGLES, 0, - snapshot.normal_discard_vertices_count); + glDrawArrays(GL_TRIANGLES, 0, snapshot.normal_vertices_count); + } + + // cross_plane and discard + + for (const auto& snapshot : m_render_snapshots) { + + glm::vec2 camera_pos_xz{camera_pos.x, camera_pos.z}; + if (snapshot.cross_vertices_count != 0) { + glm::vec2 center_xz{snapshot.center.x, snapshot.center.z}; + float dist2d = glm::distance(camera_pos_xz, center_xz); + if (dist2d <= CROSS_PLANE_DISTANCE * 16) { + glBindTexture(GL_TEXTURE_2D_ARRAY, + m_texture_manager.get_texture_array()); + glBindVertexArray(snapshot.cross_vao); + + glDrawArrays(GL_TRIANGLES, 0, + snapshot.cross_vertices_count); + } + } + if (snapshot.normal_discard_vertices_count != 0) { + glBindTexture(GL_TEXTURE_2D_ARRAY, + m_texture_manager.get_texture_array()); + glBindVertexArray(snapshot.normal_discard_vao); + + glDrawArrays(GL_TRIANGLES, 0, + snapshot.normal_discard_vertices_count); + } } } @@ -611,7 +626,8 @@ void Renderer::render_world() { glm::value_ptr(SUNLIGHT_COLOR)); glUniform3fv(normal_block_shader.loc("sunlightDir"), 1, glm::value_ptr(light_dir_view)); - + glUniform1i(normal_block_shader.loc("shadowMode"), m_shadow_mode); + glUniform1i(normal_block_shader.loc("shader_on"), m_shader_on); m_mvp_mat = m_p_mat * m_mv_mat; auto& m_planes = m_world.planes(); @@ -742,5 +758,8 @@ void Renderer::render_dev_panel() { } float& Renderer::ambient_strength() { return m_ambient_strength; } - +bool& Renderer::discard_transparent() { return m_discard_tranparent; } +bool& Renderer::shader_on() { return m_shader_on; } +int& Renderer::shadow_mode() { return m_shadow_mode; } +int& Renderer::light_cull_face() { return m_light_cull_face; } } // namespace Cubed \ No newline at end of file