From a9beb7aa8c9e81c57ff4c9753c846bf14c5a1620 Mon Sep 17 00:00:00 2001 From: reduz Date: Sun, 24 Jan 2021 16:00:20 -0300 Subject: [PATCH] Shadow map rendering optimization -All shadow rendering is done with raster now (no compute) -All shadow rendering is done by rendering directly to the shadow atlas -Improved how buffer clearing is done to optimize the above. -Ability to set shadows as 16 bits. --- drivers/vulkan/rendering_device_vulkan.cpp | 24 ++- editor/editor_node.cpp | 5 + editor/plugins/node_3d_editor_plugin.cpp | 2 + main/main.cpp | 21 --- scene/main/scene_tree.cpp | 20 ++ scene/main/viewport.cpp | 27 ++- scene/main/viewport.h | 4 + servers/rendering/renderer_rd/effects_rd.cpp | 35 ++-- servers/rendering/renderer_rd/effects_rd.h | 9 +- .../renderer_scene_render_forward.cpp | 109 ++++++----- .../renderer_scene_render_forward.h | 4 +- .../renderer_rd/renderer_scene_render_rd.cpp | 173 ++++++++---------- .../renderer_rd/renderer_scene_render_rd.h | 21 +-- .../renderer_rd/shaders/cube_to_dp.glsl | 45 +++-- servers/rendering/renderer_rd/shaders/gi.glsl | 3 +- .../renderer_rd/shaders/resolve.glsl | 7 +- .../renderer_rd/shaders/scene_forward.glsl | 2 +- .../shaders/scene_forward_inc.glsl | 60 +++--- servers/rendering/renderer_scene.h | 4 +- servers/rendering/renderer_scene_cull.h | 4 +- servers/rendering/renderer_scene_render.h | 4 +- servers/rendering/renderer_viewport.cpp | 5 +- servers/rendering/renderer_viewport.h | 3 +- servers/rendering/rendering_device.cpp | 1 + servers/rendering/rendering_device.h | 3 +- servers/rendering/rendering_server_default.h | 4 +- servers/rendering/rendering_server_wrap_mt.h | 4 +- servers/rendering_server.cpp | 15 +- servers/rendering_server.h | 4 +- 29 files changed, 330 insertions(+), 292 deletions(-) diff --git a/drivers/vulkan/rendering_device_vulkan.cpp b/drivers/vulkan/rendering_device_vulkan.cpp index 3dcdaef699b8..45987f4ee9fc 100644 --- a/drivers/vulkan/rendering_device_vulkan.cpp +++ b/drivers/vulkan/rendering_device_vulkan.cpp @@ -3104,6 +3104,7 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vectorsize.width; + render_pass_begin.renderArea.extent.height = framebuffer->size.height; + render_pass_begin.renderArea.offset.x = 0; + render_pass_begin.renderArea.offset.y = 0; Vector clear_values; clear_values.resize(framebuffer->texture_ids.size()); @@ -5879,11 +5887,11 @@ RenderingDevice::DrawListID RenderingDeviceVulkan::draw_list_begin(RID p_framebu viewport_offset = regioni.position; viewport_size = regioni.size; - if (p_initial_color_action == INITIAL_ACTION_CLEAR) { + if (p_initial_color_action == INITIAL_ACTION_CLEAR_REGION) { needs_clear_color = true; p_initial_color_action = INITIAL_ACTION_KEEP; } - if (p_initial_depth_action == INITIAL_ACTION_CLEAR) { + if (p_initial_depth_action == INITIAL_ACTION_CLEAR_REGION) { needs_clear_depth = true; p_initial_depth_action = INITIAL_ACTION_KEEP; } @@ -5969,11 +5977,11 @@ Error RenderingDeviceVulkan::draw_list_begin_split(RID p_framebuffer, uint32_t p viewport_offset = regioni.position; viewport_size = regioni.size; - if (p_initial_color_action == INITIAL_ACTION_CLEAR) { + if (p_initial_color_action == INITIAL_ACTION_CLEAR_REGION) { needs_clear_color = true; p_initial_color_action = INITIAL_ACTION_KEEP; } - if (p_initial_depth_action == INITIAL_ACTION_CLEAR) { + if (p_initial_depth_action == INITIAL_ACTION_CLEAR_REGION) { needs_clear_depth = true; p_initial_depth_action = INITIAL_ACTION_KEEP; } diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index daf7f1203320..0daaaf0e6206 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -498,6 +498,11 @@ void EditorNode::_notification(int p_what) { float sss_scale = GLOBAL_GET("rendering/quality/subsurface_scattering/subsurface_scattering_scale"); float sss_depth_scale = GLOBAL_GET("rendering/quality/subsurface_scattering/subsurface_scattering_depth_scale"); RS::get_singleton()->sub_surface_scattering_set_scale(sss_scale, sss_depth_scale); + + uint32_t directional_shadow_size = GLOBAL_GET("rendering/quality/directional_shadow/size"); + uint32_t directional_shadow_16_bits = GLOBAL_GET("rendering/quality/directional_shadow/16_bits"); + RS::get_singleton()->directional_shadow_atlas_set_size(directional_shadow_size, directional_shadow_16_bits); + RS::ShadowQuality shadows_quality = RS::ShadowQuality(int(GLOBAL_GET("rendering/quality/shadows/soft_shadow_quality"))); RS::get_singleton()->shadows_quality_set(shadows_quality); RS::ShadowQuality directional_shadow_quality = RS::ShadowQuality(int(GLOBAL_GET("rendering/quality/directional_shadow/soft_shadow_quality"))); diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp index 7717a9a27ebf..4fb001362092 100644 --- a/editor/plugins/node_3d_editor_plugin.cpp +++ b/editor/plugins/node_3d_editor_plugin.cpp @@ -2445,12 +2445,14 @@ void Node3DEditorViewport::_notification(int p_what) { //update shadow atlas if changed int shadowmap_size = ProjectSettings::get_singleton()->get("rendering/quality/shadow_atlas/size"); + bool shadowmap_16_bits = ProjectSettings::get_singleton()->get("rendering/quality/shadow_atlas/16_bits"); int atlas_q0 = ProjectSettings::get_singleton()->get("rendering/quality/shadow_atlas/quadrant_0_subdiv"); int atlas_q1 = ProjectSettings::get_singleton()->get("rendering/quality/shadow_atlas/quadrant_1_subdiv"); int atlas_q2 = ProjectSettings::get_singleton()->get("rendering/quality/shadow_atlas/quadrant_2_subdiv"); int atlas_q3 = ProjectSettings::get_singleton()->get("rendering/quality/shadow_atlas/quadrant_3_subdiv"); viewport->set_shadow_atlas_size(shadowmap_size); + viewport->set_shadow_atlas_16_bits(shadowmap_16_bits); viewport->set_shadow_atlas_quadrant_subdiv(0, Viewport::ShadowAtlasQuadrantSubdiv(atlas_q0)); viewport->set_shadow_atlas_quadrant_subdiv(1, Viewport::ShadowAtlasQuadrantSubdiv(atlas_q1)); viewport->set_shadow_atlas_quadrant_subdiv(2, Viewport::ShadowAtlasQuadrantSubdiv(atlas_q2)); diff --git a/main/main.cpp b/main/main.cpp index 943abbf9147d..f45482910038 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -2151,11 +2151,6 @@ bool Main::start() { } #endif - { - int directional_atlas_size = GLOBAL_GET("rendering/quality/directional_shadow/size"); - RenderingServer::get_singleton()->directional_shadow_atlas_set_size(directional_atlas_size); - } - if (!editor && !project_manager) { //standard helpers that can be changed from main config @@ -2199,22 +2194,6 @@ bool Main::start() { DisplayServer::get_singleton()->window_set_title(appname); #endif - int shadow_atlas_size = GLOBAL_GET("rendering/quality/shadow_atlas/size"); - int shadow_atlas_q0_subdiv = GLOBAL_GET("rendering/quality/shadow_atlas/quadrant_0_subdiv"); - int shadow_atlas_q1_subdiv = GLOBAL_GET("rendering/quality/shadow_atlas/quadrant_1_subdiv"); - int shadow_atlas_q2_subdiv = GLOBAL_GET("rendering/quality/shadow_atlas/quadrant_2_subdiv"); - int shadow_atlas_q3_subdiv = GLOBAL_GET("rendering/quality/shadow_atlas/quadrant_3_subdiv"); - - sml->get_root()->set_shadow_atlas_size(shadow_atlas_size); - sml->get_root()->set_shadow_atlas_quadrant_subdiv(0, Viewport::ShadowAtlasQuadrantSubdiv( - shadow_atlas_q0_subdiv)); - sml->get_root()->set_shadow_atlas_quadrant_subdiv(1, Viewport::ShadowAtlasQuadrantSubdiv( - shadow_atlas_q1_subdiv)); - sml->get_root()->set_shadow_atlas_quadrant_subdiv(2, Viewport::ShadowAtlasQuadrantSubdiv( - shadow_atlas_q2_subdiv)); - sml->get_root()->set_shadow_atlas_quadrant_subdiv(3, Viewport::ShadowAtlasQuadrantSubdiv( - shadow_atlas_q3_subdiv)); - bool snap_controls = GLOBAL_DEF("gui/common/snap_controls_to_pixels", true); sml->get_root()->set_snap_controls_to_pixels(snap_controls); diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp index f18ac3b801c4..1c9d81e87c76 100644 --- a/scene/main/scene_tree.cpp +++ b/scene/main/scene_tree.cpp @@ -1372,6 +1372,26 @@ SceneTree::SceneTree() { bool snap_2d_vertices = GLOBAL_DEF("rendering/quality/2d/snap_2d_vertices_to_pixel", false); root->set_snap_2d_vertices_to_pixel(snap_2d_vertices); + int shadowmap_size = GLOBAL_DEF("rendering/quality/shadow_atlas/size", 4096); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/shadow_atlas/size", PropertyInfo(Variant::INT, "rendering/quality/shadow_atlas/size", PROPERTY_HINT_RANGE, "256,16384")); + GLOBAL_DEF("rendering/quality/shadow_atlas/size.mobile", 2048); + bool shadowmap_16_bits = GLOBAL_DEF("rendering/quality/shadow_atlas/16_bits", true); + int atlas_q0 = GLOBAL_DEF("rendering/quality/shadow_atlas/quadrant_0_subdiv", 2); + int atlas_q1 = GLOBAL_DEF("rendering/quality/shadow_atlas/quadrant_1_subdiv", 2); + int atlas_q2 = GLOBAL_DEF("rendering/quality/shadow_atlas/quadrant_2_subdiv", 3); + int atlas_q3 = GLOBAL_DEF("rendering/quality/shadow_atlas/quadrant_3_subdiv", 4); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/shadow_atlas/quadrant_0_subdiv", PropertyInfo(Variant::INT, "rendering/quality/shadow_atlas/quadrant_0_subdiv", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows")); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/shadow_atlas/quadrant_1_subdiv", PropertyInfo(Variant::INT, "rendering/quality/shadow_atlas/quadrant_1_subdiv", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows")); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/shadow_atlas/quadrant_2_subdiv", PropertyInfo(Variant::INT, "rendering/quality/shadow_atlas/quadrant_2_subdiv", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows")); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/shadow_atlas/quadrant_3_subdiv", PropertyInfo(Variant::INT, "rendering/quality/shadow_atlas/quadrant_3_subdiv", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows")); + + root->set_shadow_atlas_size(shadowmap_size); + root->set_shadow_atlas_16_bits(shadowmap_16_bits); + root->set_shadow_atlas_quadrant_subdiv(0, Viewport::ShadowAtlasQuadrantSubdiv(atlas_q0)); + root->set_shadow_atlas_quadrant_subdiv(1, Viewport::ShadowAtlasQuadrantSubdiv(atlas_q1)); + root->set_shadow_atlas_quadrant_subdiv(2, Viewport::ShadowAtlasQuadrantSubdiv(atlas_q2)); + root->set_shadow_atlas_quadrant_subdiv(3, Viewport::ShadowAtlasQuadrantSubdiv(atlas_q3)); + Viewport::SDFOversize sdf_oversize = Viewport::SDFOversize(int(GLOBAL_DEF("rendering/quality/2d_sdf/oversize", 1))); root->set_sdf_oversize(sdf_oversize); Viewport::SDFScale sdf_scale = Viewport::SDFScale(int(GLOBAL_DEF("rendering/quality/2d_sdf/scale", 1))); diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index 31496366deb2..82053e1557dd 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -1416,18 +1416,26 @@ Ref Viewport::get_texture() const { } void Viewport::set_shadow_atlas_size(int p_size) { - if (shadow_atlas_size == p_size) { - return; - } - shadow_atlas_size = p_size; - RS::get_singleton()->viewport_set_shadow_atlas_size(viewport, p_size); + RS::get_singleton()->viewport_set_shadow_atlas_size(viewport, p_size, shadow_atlas_16_bits); } int Viewport::get_shadow_atlas_size() const { return shadow_atlas_size; } +void Viewport::set_shadow_atlas_16_bits(bool p_16_bits) { + if (shadow_atlas_16_bits == p_16_bits) { + return; + } + + shadow_atlas_16_bits = p_16_bits; + RS::get_singleton()->viewport_set_shadow_atlas_size(viewport, shadow_atlas_size, shadow_atlas_16_bits); +} + +bool Viewport::get_shadow_atlas_16_bits() const { + return shadow_atlas_16_bits; +} void Viewport::set_shadow_atlas_quadrant_subdiv(int p_quadrant, ShadowAtlasQuadrantSubdiv p_subdiv) { ERR_FAIL_INDEX(p_quadrant, 4); ERR_FAIL_INDEX(p_subdiv, SHADOW_ATLAS_QUADRANT_SUBDIV_MAX); @@ -3481,6 +3489,9 @@ void Viewport::_bind_methods() { ClassDB::bind_method(D_METHOD("set_shadow_atlas_size", "size"), &Viewport::set_shadow_atlas_size); ClassDB::bind_method(D_METHOD("get_shadow_atlas_size"), &Viewport::get_shadow_atlas_size); + ClassDB::bind_method(D_METHOD("set_shadow_atlas_16_bits", "enable"), &Viewport::set_shadow_atlas_16_bits); + ClassDB::bind_method(D_METHOD("get_shadow_atlas_16_bits"), &Viewport::get_shadow_atlas_16_bits); + ClassDB::bind_method(D_METHOD("set_snap_controls_to_pixels", "enabled"), &Viewport::set_snap_controls_to_pixels); ClassDB::bind_method(D_METHOD("is_snap_controls_to_pixels_enabled"), &Viewport::is_snap_controls_to_pixels_enabled); @@ -3548,6 +3559,7 @@ void Viewport::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "sdf_scale", PROPERTY_HINT_ENUM, "100%,50%,25%"), "set_sdf_scale", "get_sdf_scale"); ADD_GROUP("Shadow Atlas", "shadow_atlas_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "shadow_atlas_size"), "set_shadow_atlas_size", "get_shadow_atlas_size"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "shadow_atlas_16_bits"), "set_shadow_atlas_16_bits", "get_shadow_atlas_16_bits"); ADD_PROPERTYI(PropertyInfo(Variant::INT, "shadow_atlas_quad_0", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"), "set_shadow_atlas_quadrant_subdiv", "get_shadow_atlas_quadrant_subdiv", 0); ADD_PROPERTYI(PropertyInfo(Variant::INT, "shadow_atlas_quad_1", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"), "set_shadow_atlas_quadrant_subdiv", "get_shadow_atlas_quadrant_subdiv", 1); ADD_PROPERTYI(PropertyInfo(Variant::INT, "shadow_atlas_quad_2", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"), "set_shadow_atlas_quadrant_subdiv", "get_shadow_atlas_quadrant_subdiv", 2); @@ -3662,7 +3674,10 @@ Viewport::Viewport() { physics_has_last_mousepos = false; physics_last_mousepos = Vector2(Math_INF, Math_INF); - shadow_atlas_size = 0; + shadow_atlas_16_bits = true; + shadow_atlas_size = 2048; + set_shadow_atlas_size(shadow_atlas_size); + for (int i = 0; i < 4; i++) { shadow_atlas_quadrant_subdiv[i] = SHADOW_ATLAS_QUADRANT_SUBDIV_MAX; } diff --git a/scene/main/viewport.h b/scene/main/viewport.h index 7473b6937f4d..17d4835c6308 100644 --- a/scene/main/viewport.h +++ b/scene/main/viewport.h @@ -297,6 +297,7 @@ private: DebugDraw debug_draw; int shadow_atlas_size; + bool shadow_atlas_16_bits = true; ShadowAtlasQuadrantSubdiv shadow_atlas_quadrant_subdiv[4]; MSAA msaa; @@ -537,6 +538,9 @@ public: void set_shadow_atlas_size(int p_size); int get_shadow_atlas_size() const; + void set_shadow_atlas_16_bits(bool p_16_bits); + bool get_shadow_atlas_16_bits() const; + void set_shadow_atlas_quadrant_subdiv(int p_quadrant, ShadowAtlasQuadrantSubdiv p_subdiv); ShadowAtlasQuadrantSubdiv get_shadow_atlas_quadrant_subdiv(int p_quadrant) const; diff --git a/servers/rendering/renderer_rd/effects_rd.cpp b/servers/rendering/renderer_rd/effects_rd.cpp index 6e1d61ff94ab..27d6cb086d55 100644 --- a/servers/rendering/renderer_rd/effects_rd.cpp +++ b/servers/rendering/renderer_rd/effects_rd.cpp @@ -702,27 +702,24 @@ void EffectsRD::make_mipmap(RID p_source_rd_texture, RID p_dest_texture, const S RD::get_singleton()->compute_list_end(); } -void EffectsRD::copy_cubemap_to_dp(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, float p_z_near, float p_z_far, float p_bias, bool p_dp_flip) { +void EffectsRD::copy_cubemap_to_dp(RID p_source_rd_texture, RID p_dst_framebuffer, const Rect2 &p_rect, float p_z_near, float p_z_far, bool p_dp_flip) { CopyToDPPushConstant push_constant; - push_constant.screen_size[0] = p_rect.size.x; - push_constant.screen_size[1] = p_rect.size.y; - push_constant.dest_offset[0] = p_rect.position.x; - push_constant.dest_offset[1] = p_rect.position.y; - push_constant.bias = p_bias; + push_constant.screen_rect[0] = p_rect.position.x; + push_constant.screen_rect[1] = p_rect.position.y; + push_constant.screen_rect[2] = p_rect.size.width; + push_constant.screen_rect[3] = p_rect.size.height; push_constant.z_far = p_z_far; push_constant.z_near = p_z_near; push_constant.z_flip = p_dp_flip; - int32_t x_groups = (p_rect.size.width - 1) / 8 + 1; - int32_t y_groups = (p_rect.size.height - 1) / 8 + 1; + RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dst_framebuffer, RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ); + RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, cube_to_dp.pipeline.get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dst_framebuffer))); + RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_source_rd_texture), 0); + RD::get_singleton()->draw_list_bind_index_array(draw_list, index_array); - RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); - RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, cube_to_dp.pipeline); - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_rd_texture), 0); - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_dest_texture), 1); - RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(CopyToDPPushConstant)); - RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1); - RD::get_singleton()->compute_list_end(); + RD::get_singleton()->draw_list_set_push_constant(draw_list, &push_constant, sizeof(CopyToDPPushConstant)); + RD::get_singleton()->draw_list_draw(draw_list, true); + RD::get_singleton()->draw_list_end(); } void EffectsRD::tonemapper(RID p_source_color, RID p_dst_framebuffer, const TonemapSettings &p_settings) { @@ -1678,8 +1675,12 @@ EffectsRD::EffectsRD() { cube_to_dp.shader.initialize(copy_modes); cube_to_dp.shader_version = cube_to_dp.shader.version_create(); - - cube_to_dp.pipeline = RD::get_singleton()->compute_pipeline_create(cube_to_dp.shader.version_get_shader(cube_to_dp.shader_version, 0)); + RID shader = cube_to_dp.shader.version_get_shader(cube_to_dp.shader_version, 0); + RD::PipelineDepthStencilState dss; + dss.enable_depth_test = true; + dss.depth_compare_operator = RD::COMPARE_OP_ALWAYS; + dss.enable_depth_write = true; + cube_to_dp.pipeline.setup(shader, RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), dss, RD::PipelineColorBlendState(), 0); } { diff --git a/servers/rendering/renderer_rd/effects_rd.h b/servers/rendering/renderer_rd/effects_rd.h index e2cdd0c3d8f0..00309b4d0f2c 100644 --- a/servers/rendering/renderer_rd/effects_rd.h +++ b/servers/rendering/renderer_rd/effects_rd.h @@ -234,18 +234,17 @@ class EffectsRD { } luminance_reduce; struct CopyToDPPushConstant { - int32_t screen_size[2]; - int32_t dest_offset[2]; - float bias; float z_far; float z_near; uint32_t z_flip; + uint32_t pad; + float screen_rect[4]; }; struct CoptToDP { CubeToDpShaderRD shader; RID shader_version; - RID pipeline; + PipelineCacheRD pipeline; } cube_to_dp; struct BokehPushConstant { @@ -687,7 +686,7 @@ public: void cubemap_roughness(RID p_source_rd_texture, RID p_dest_framebuffer, uint32_t p_face_id, uint32_t p_sample_count, float p_roughness, float p_size); void make_mipmap(RID p_source_rd_texture, RID p_dest_texture, const Size2i &p_size); - void copy_cubemap_to_dp(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, float p_z_near, float p_z_far, float p_bias, bool p_dp_flip); + void copy_cubemap_to_dp(RID p_source_rd_texture, RID p_dest_texture, const Rect2 &p_rect, float p_z_near, float p_z_far, bool p_dp_flip); void luminance_reduction(RID p_source_texture, const Size2i p_source_size, const Vector p_reduce, RID p_prev_luminance, float p_min_luminance, float p_max_luminance, float p_adjust, bool p_set = false); void bokeh_dof(RID p_base_texture, RID p_depth_texture, const Size2i &p_base_texture_size, RID p_secondary_texture, RID p_bokeh_texture1, RID p_bokeh_texture2, bool p_dof_far, float p_dof_far_begin, float p_dof_far_size, bool p_dof_near, float p_dof_near_begin, float p_dof_near_size, float p_bokeh_size, RS::DOFBokehShape p_bokeh_shape, RS::DOFBlurQuality p_quality, bool p_use_jitter, float p_cam_znear, float p_cam_zfar, bool p_cam_orthogonal); diff --git a/servers/rendering/renderer_rd/renderer_scene_render_forward.cpp b/servers/rendering/renderer_rd/renderer_scene_render_forward.cpp index 337dd5a1115e..0ae1e9c1a8f7 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_forward.cpp +++ b/servers/rendering/renderer_rd/renderer_scene_render_forward.cpp @@ -1722,7 +1722,7 @@ void RendererSceneRenderForward::_render_scene(RID p_render_buffer, const Transf RENDER_TIMESTAMP("Render Opaque Pass"); - RID rp_uniform_set = _setup_render_pass_uniform_set(p_render_buffer, radiance_texture, p_shadow_atlas, p_reflection_atlas, p_cluster_buffer, p_gi_probes, p_lightmaps); + RID rp_uniform_set = _setup_render_pass_uniform_set(p_render_buffer, radiance_texture, p_shadow_atlas, p_reflection_atlas, p_cluster_buffer, p_gi_probes, p_lightmaps, true); bool can_continue_color = !scene_state.used_screen_texture && !using_ssr && !using_sss; bool can_continue_depth = !scene_state.used_depth_texture && !using_ssr && !using_sss; @@ -1838,7 +1838,7 @@ void RendererSceneRenderForward::_render_scene(RID p_render_buffer, const Transf } } -void RendererSceneRenderForward::_render_shadow(RID p_framebuffer, const PagedArray &p_instances, const CameraMatrix &p_projection, const Transform &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane, float p_lod_distance_multiplier, float p_screen_lod_threshold) { +void RendererSceneRenderForward::_render_shadow(RID p_framebuffer, const PagedArray &p_instances, const CameraMatrix &p_projection, const Transform &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane, float p_lod_distance_multiplier, float p_screen_lod_threshold, const Rect2i &p_rect, bool p_flip_y, bool p_clear_region, bool p_begin, bool p_end) { RENDER_TIMESTAMP("Setup Rendering Shadow"); _update_render_base_uniform_set(); @@ -1847,7 +1847,7 @@ void RendererSceneRenderForward::_render_shadow(RID p_framebuffer, const PagedAr scene_state.ubo.dual_paraboloid_side = p_use_dp_flip ? -1 : 1; - _setup_environment(RID(), RID(), p_projection, p_transform, RID(), true, Vector2(1, 1), 1, 32, RID(), true, Color(), 0, p_zfar, false, p_use_pancake); + _setup_environment(RID(), RID(), p_projection, p_transform, RID(), true, Vector2(1, 1), 1, 32, RID(), !p_flip_y, Color(), 0, p_zfar, false, p_use_pancake); if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_DISABLE_LOD) { p_screen_lod_threshold = 0.0; @@ -1865,8 +1865,12 @@ void RendererSceneRenderForward::_render_shadow(RID p_framebuffer, const PagedAr { //regular forward for now - RenderListParameters render_list_params(render_list.elements, render_list.element_count, p_use_dp_flip, pass_mode, true, rp_uniform_set, false, Vector2(), p_camera_plane, p_lod_distance_multiplier, p_screen_lod_threshold); - _render_list_with_threads(&render_list_params, p_framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ); + bool flip_cull = p_use_dp_flip; + if (p_flip_y) { + flip_cull = !flip_cull; + } + RenderListParameters render_list_params(render_list.elements, render_list.element_count, flip_cull, pass_mode, true, rp_uniform_set, false, Vector2(), p_camera_plane, p_lod_distance_multiplier, p_screen_lod_threshold); + _render_list_with_threads(&render_list_params, p_framebuffer, RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD, p_begin ? (p_clear_region ? RD::INITIAL_ACTION_CLEAR_REGION : RD::INITIAL_ACTION_CLEAR) : RD::INITIAL_ACTION_CONTINUE, p_end ? RD::FINAL_ACTION_READ : RD::FINAL_ACTION_CONTINUE, Vector(), 1.0, 0, p_rect); } } @@ -2128,14 +2132,14 @@ void RendererSceneRenderForward::_update_render_base_uniform_set() { { RD::Uniform u; - u.binding = 5; + u.binding = 4; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.ids.push_back(get_omni_light_buffer()); uniforms.push_back(u); } { RD::Uniform u; - u.binding = 6; + u.binding = 5; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.ids.push_back(get_spot_light_buffer()); uniforms.push_back(u); @@ -2143,35 +2147,35 @@ void RendererSceneRenderForward::_update_render_base_uniform_set() { { RD::Uniform u; - u.binding = 7; + u.binding = 6; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.ids.push_back(get_reflection_probe_buffer()); uniforms.push_back(u); } { RD::Uniform u; - u.binding = 8; + u.binding = 7; u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; u.ids.push_back(get_directional_light_buffer()); uniforms.push_back(u); } { RD::Uniform u; - u.binding = 10; + u.binding = 8; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.ids.push_back(scene_state.lightmap_buffer); uniforms.push_back(u); } { RD::Uniform u; - u.binding = 11; + u.binding = 9; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.ids.push_back(scene_state.lightmap_capture_buffer); uniforms.push_back(u); } { RD::Uniform u; - u.binding = 12; + u.binding = 10; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID decal_atlas = storage->decal_atlas_get_texture(); u.ids.push_back(decal_atlas); @@ -2179,7 +2183,7 @@ void RendererSceneRenderForward::_update_render_base_uniform_set() { } { RD::Uniform u; - u.binding = 13; + u.binding = 11; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID decal_atlas = storage->decal_atlas_get_texture_srgb(); u.ids.push_back(decal_atlas); @@ -2187,28 +2191,16 @@ void RendererSceneRenderForward::_update_render_base_uniform_set() { } { RD::Uniform u; - u.binding = 14; + u.binding = 12; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; u.ids.push_back(get_decal_buffer()); uniforms.push_back(u); } - { - RD::Uniform u; - u.binding = 15; - u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; - if (directional_shadow_get_texture().is_valid()) { - u.ids.push_back(directional_shadow_get_texture()); - } else { - u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE)); - } - uniforms.push_back(u); - } - { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; - u.binding = 16; + u.binding = 13; u.ids.push_back(storage->global_variables_get_storage_buffer()); uniforms.push_back(u); } @@ -2216,7 +2208,7 @@ void RendererSceneRenderForward::_update_render_base_uniform_set() { if (!low_end) { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; - u.binding = 17; + u.binding = 14; u.ids.push_back(sdfgi_get_ubo()); uniforms.push_back(u); } @@ -2225,7 +2217,7 @@ void RendererSceneRenderForward::_update_render_base_uniform_set() { } } -RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buffers, RID p_radiance_texture, RID p_shadow_atlas, RID p_reflection_atlas, RID p_cluster_buffer, const PagedArray &p_gi_probes, const PagedArray &p_lightmaps) { +RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buffers, RID p_radiance_texture, RID p_shadow_atlas, RID p_reflection_atlas, RID p_cluster_buffer, const PagedArray &p_gi_probes, const PagedArray &p_lightmaps, bool p_use_directional_shadow_atlas) { if (render_pass_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(render_pass_uniform_set)) { RD::get_singleton()->free(render_pass_uniform_set); } @@ -2284,6 +2276,17 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff RD::Uniform u; u.binding = 3; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; + if (p_use_directional_shadow_atlas && directional_shadow_get_texture().is_valid()) { + u.ids.push_back(directional_shadow_get_texture()); + } else { + u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE)); + } + uniforms.push_back(u); + } + { + RD::Uniform u; + u.binding = 4; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.ids.resize(scene_state.max_lightmaps); RID default_tex = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE); for (uint32_t i = 0; i < scene_state.max_lightmaps; i++) { @@ -2301,7 +2304,7 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff } { RD::Uniform u; - u.binding = 4; + u.binding = 5; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.ids.resize(MAX_GI_PROBES); RID default_tex = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE); @@ -2322,7 +2325,7 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff { RD::Uniform u; - u.binding = 5; + u.binding = 6; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; RID cb = p_cluster_buffer.is_valid() ? p_cluster_buffer : default_vec4_xform_buffer; u.ids.push_back(cb); @@ -2331,7 +2334,7 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff { RD::Uniform u; - u.binding = 6; + u.binding = 7; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID texture = (false && rb && rb->depth.is_valid()) ? rb->depth : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE); u.ids.push_back(texture); @@ -2339,7 +2342,7 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff } { RD::Uniform u; - u.binding = 7; + u.binding = 8; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID bbt = rb ? render_buffers_get_back_buffer_texture(p_render_buffers) : RID(); RID texture = bbt.is_valid() ? bbt : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK); @@ -2350,7 +2353,7 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff if (!low_end) { { RD::Uniform u; - u.binding = 8; + u.binding = 9; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID texture = rb && rb->normal_roughness_buffer.is_valid() ? rb->normal_roughness_buffer : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_NORMAL); u.ids.push_back(texture); @@ -2359,7 +2362,7 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff { RD::Uniform u; - u.binding = 9; + u.binding = 10; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID aot = rb ? render_buffers_get_ao_texture(p_render_buffers) : RID(); RID texture = aot.is_valid() ? aot : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK); @@ -2369,7 +2372,7 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff { RD::Uniform u; - u.binding = 10; + u.binding = 11; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID ambient_buffer = p_render_buffers.is_valid() ? render_buffers_get_gi_ambient_texture(p_render_buffers) : RID(); RID texture = ambient_buffer.is_valid() ? ambient_buffer : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK); @@ -2379,7 +2382,7 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff { RD::Uniform u; - u.binding = 11; + u.binding = 12; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID reflection_buffer = p_render_buffers.is_valid() ? render_buffers_get_gi_reflection_texture(p_render_buffers) : RID(); RID texture = reflection_buffer.is_valid() ? reflection_buffer : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK); @@ -2388,7 +2391,7 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff } { RD::Uniform u; - u.binding = 12; + u.binding = 13; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID t; if (rb && render_buffers_is_sdfgi_enabled(p_render_buffers)) { @@ -2401,7 +2404,7 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff } { RD::Uniform u; - u.binding = 13; + u.binding = 14; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; if (rb && render_buffers_is_sdfgi_enabled(p_render_buffers)) { u.ids.push_back(render_buffers_get_sdfgi_occlusion_texture(p_render_buffers)); @@ -2412,14 +2415,14 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff } { RD::Uniform u; - u.binding = 14; + u.binding = 15; u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER; u.ids.push_back(rb ? render_buffers_get_gi_probe_buffer(p_render_buffers) : render_buffers_get_default_gi_probe_buffer()); uniforms.push_back(u); } { RD::Uniform u; - u.binding = 15; + u.binding = 16; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; RID vfog = RID(); if (rb && render_buffers_has_volumetric_fog(p_render_buffers)) { @@ -2477,10 +2480,20 @@ RID RendererSceneRenderForward::_setup_sdfgi_render_pass_uniform_set(RID p_albed } { - // No Lightmaps + // No directional shadow atlas. RD::Uniform u; u.binding = 3; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; + RID texture = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE); + u.ids.push_back(texture); + uniforms.push_back(u); + } + + { + // No Lightmaps + RD::Uniform u; + u.binding = 4; + u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.ids.resize(scene_state.max_lightmaps); RID default_tex = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE); for (uint32_t i = 0; i < scene_state.max_lightmaps; i++) { @@ -2493,7 +2506,7 @@ RID RendererSceneRenderForward::_setup_sdfgi_render_pass_uniform_set(RID p_albed { // No GIProbes RD::Uniform u; - u.binding = 4; + u.binding = 5; u.uniform_type = RD::UNIFORM_TYPE_TEXTURE; u.ids.resize(MAX_GI_PROBES); RID default_tex = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE); @@ -2506,7 +2519,7 @@ RID RendererSceneRenderForward::_setup_sdfgi_render_pass_uniform_set(RID p_albed { RD::Uniform u; - u.binding = 5; + u.binding = 6; u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER; RID cb = default_vec4_xform_buffer; u.ids.push_back(cb); @@ -2518,28 +2531,28 @@ RID RendererSceneRenderForward::_setup_sdfgi_render_pass_uniform_set(RID p_albed { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; - u.binding = 6; + u.binding = 7; u.ids.push_back(p_albedo_texture); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; - u.binding = 7; + u.binding = 8; u.ids.push_back(p_emission_texture); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; - u.binding = 8; + u.binding = 9; u.ids.push_back(p_emission_aniso_texture); uniforms.push_back(u); } { RD::Uniform u; u.uniform_type = RD::UNIFORM_TYPE_IMAGE; - u.binding = 9; + u.binding = 10; u.ids.push_back(p_geom_facing_texture); uniforms.push_back(u); } diff --git a/servers/rendering/renderer_rd/renderer_scene_render_forward.h b/servers/rendering/renderer_rd/renderer_scene_render_forward.h index bd04c651b658..0b57c7f76c93 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_forward.h +++ b/servers/rendering/renderer_rd/renderer_scene_render_forward.h @@ -257,7 +257,7 @@ class RendererSceneRenderForward : public RendererSceneRenderRD { void _update_render_base_uniform_set(); RID _setup_sdfgi_render_pass_uniform_set(RID p_albedo_texture, RID p_emission_texture, RID p_emission_aniso_texture, RID p_geom_facing_texture); - RID _setup_render_pass_uniform_set(RID p_render_buffers, RID p_radiance_texture, RID p_shadow_atlas, RID p_reflection_atlas, RID p_cluster_buffer, const PagedArray &p_gi_probes, const PagedArray &p_lightmaps); + RID _setup_render_pass_uniform_set(RID p_render_buffers, RID p_radiance_texture, RID p_shadow_atlas, RID p_reflection_atlas, RID p_cluster_buffer, const PagedArray &p_gi_probes, const PagedArray &p_lightmaps, bool p_use_directional_shadow_atlas = false); struct LightmapData { float normal_xform[12]; @@ -701,7 +701,7 @@ class RendererSceneRenderForward : public RendererSceneRenderRD { protected: virtual void _render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray &p_instances, int p_directional_light_count, const PagedArray &p_gi_probes, const PagedArray &p_lightmaps, RID p_environment, RID p_cluster_buffer, uint32_t p_cluster_size, uint32_t p_max_cluster_elements, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_bg_color, float p_lod_threshold); - virtual void _render_shadow(RID p_framebuffer, const PagedArray &p_instances, const CameraMatrix &p_projection, const Transform &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_lod_threshold = 0.0); + virtual void _render_shadow(RID p_framebuffer, const PagedArray &p_instances, const CameraMatrix &p_projection, const Transform &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_lod_threshold = 0.0, const Rect2i &p_rect = Rect2i(), bool p_flip_y = false, bool p_clear_region = true, bool p_begin = true, bool p_end = true); virtual void _render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray &p_instances, RID p_framebuffer, const Rect2i &p_region); virtual void _render_uv2(const PagedArray &p_instances, RID p_framebuffer, const Rect2i &p_region); virtual void _render_sdfgi(RID p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, const PagedArray &p_instances, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture); diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp index bdbc56cd6185..357e7c8d8a98 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp @@ -3564,13 +3564,28 @@ RID RendererSceneRenderRD::shadow_atlas_create() { return shadow_atlas_owner.make_rid(ShadowAtlas()); } -void RendererSceneRenderRD::shadow_atlas_set_size(RID p_atlas, int p_size) { +void RendererSceneRenderRD::_update_shadow_atlas(ShadowAtlas *shadow_atlas) { + if (shadow_atlas->size > 0 && shadow_atlas->depth.is_null()) { + RD::TextureFormat tf; + tf.format = shadow_atlas->use_16_bits ? RD::DATA_FORMAT_D16_UNORM : RD::DATA_FORMAT_D32_SFLOAT; + tf.width = shadow_atlas->size; + tf.height = shadow_atlas->size; + tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; + + shadow_atlas->depth = RD::get_singleton()->texture_create(tf, RD::TextureView()); + Vector fb_tex; + fb_tex.push_back(shadow_atlas->depth); + shadow_atlas->fb = RD::get_singleton()->framebuffer_create(fb_tex); + } +} + +void RendererSceneRenderRD::shadow_atlas_set_size(RID p_atlas, int p_size, bool p_16_bits) { ShadowAtlas *shadow_atlas = shadow_atlas_owner.getornull(p_atlas); ERR_FAIL_COND(!shadow_atlas); ERR_FAIL_COND(p_size < 0); p_size = next_power_of_2(p_size); - if (p_size == shadow_atlas->size) { + if (p_size == shadow_atlas->size && p_16_bits == shadow_atlas->use_16_bits) { return; } @@ -3597,16 +3612,7 @@ void RendererSceneRenderRD::shadow_atlas_set_size(RID p_atlas, int p_size) { shadow_atlas->shadow_owners.clear(); shadow_atlas->size = p_size; - - if (shadow_atlas->size) { - RD::TextureFormat tf; - tf.format = RD::DATA_FORMAT_R32_SFLOAT; - tf.width = shadow_atlas->size; - tf.height = shadow_atlas->size; - tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT; - - shadow_atlas->depth = RD::get_singleton()->texture_create(tf, RD::TextureView()); - } + shadow_atlas->use_16_bits = p_size; } void RendererSceneRenderRD::shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p_quadrant, int p_subdivision) { @@ -3861,10 +3867,24 @@ bool RendererSceneRenderRD::shadow_atlas_update_light(RID p_atlas, RID p_light_i return false; } -void RendererSceneRenderRD::directional_shadow_atlas_set_size(int p_size) { +void RendererSceneRenderRD::_update_directional_shadow_atlas() { + if (directional_shadow.depth.is_null() && directional_shadow.size > 0) { + RD::TextureFormat tf; + tf.format = directional_shadow.use_16_bits ? RD::DATA_FORMAT_D16_UNORM : RD::DATA_FORMAT_D32_SFLOAT; + tf.width = directional_shadow.size; + tf.height = directional_shadow.size; + tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; + + directional_shadow.depth = RD::get_singleton()->texture_create(tf, RD::TextureView()); + Vector fb_tex; + fb_tex.push_back(directional_shadow.depth); + directional_shadow.fb = RD::get_singleton()->framebuffer_create(fb_tex); + } +} +void RendererSceneRenderRD::directional_shadow_atlas_set_size(int p_size, bool p_16_bits) { p_size = nearest_power_of_2_templated(p_size); - if (directional_shadow.size == p_size) { + if (directional_shadow.size == p_size && directional_shadow.use_16_bits == p_16_bits) { return; } @@ -3874,19 +3894,8 @@ void RendererSceneRenderRD::directional_shadow_atlas_set_size(int p_size) { RD::get_singleton()->free(directional_shadow.depth); _clear_shadow_shrink_stages(directional_shadow.shrink_stages); directional_shadow.depth = RID(); + _base_uniforms_changed(); } - - if (p_size > 0) { - RD::TextureFormat tf; - tf.format = RD::DATA_FORMAT_R32_SFLOAT; - tf.width = p_size; - tf.height = p_size; - tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT; - - directional_shadow.depth = RD::get_singleton()->texture_create(tf, RD::TextureView()); - } - - _base_uniforms_changed(); } void RendererSceneRenderRD::set_directional_shadow_count(int p_count) { @@ -4056,29 +4065,6 @@ RendererSceneRenderRD::ShadowCubemap *RendererSceneRenderRD::_get_shadow_cubemap return &shadow_cubemaps[p_size]; } -RendererSceneRenderRD::ShadowMap *RendererSceneRenderRD::_get_shadow_map(const Size2i &p_size) { - if (!shadow_maps.has(p_size)) { - ShadowMap sm; - { - RD::TextureFormat tf; - tf.format = RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_D32_SFLOAT, RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) ? RD::DATA_FORMAT_D32_SFLOAT : RD::DATA_FORMAT_X8_D24_UNORM_PACK32; - tf.width = p_size.width; - tf.height = p_size.height; - tf.usage_bits = RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT; - - sm.depth = RD::get_singleton()->texture_create(tf, RD::TextureView()); - } - - Vector fbtex; - fbtex.push_back(sm.depth); - sm.fb = RD::get_singleton()->framebuffer_create(fbtex); - - shadow_maps[p_size] = sm; - } - - return &shadow_maps[p_size]; -} - ////////////////////////// RID RendererSceneRenderRD::decal_instance_create(RID p_decal) { @@ -7456,26 +7442,31 @@ void RendererSceneRenderRD::render_shadow(RID p_light, RID p_shadow_atlas, int p ERR_FAIL_COND(!light_instance); Rect2i atlas_rect; - RID atlas_texture; + uint32_t atlas_size; + RID atlas_fb; bool using_dual_paraboloid = false; bool using_dual_paraboloid_flip = false; - float znear = 0; - float zfar = 0; RID render_fb; RID render_texture; - float bias = 0; - float normal_bias = 0; + float zfar; bool use_pancake = false; - bool use_linear_depth = false; bool render_cubemap = false; bool finalize_cubemap = false; + bool flip_y = false; + CameraMatrix light_projection; Transform light_transform; + bool clear_region = true; + bool begin_texture = true; + bool end_texture = true; + if (storage->light_get_type(light_instance->light) == RS::LIGHT_DIRECTIONAL) { + _update_directional_shadow_atlas(); + //set pssm stuff if (light_instance->last_scene_shadow_pass != scene_pass) { light_instance->directional_rect = _get_directional_shadow_rect(directional_shadow.size, directional_shadow.light_count, directional_shadow.current_light); @@ -7492,6 +7483,7 @@ void RendererSceneRenderRD::render_shadow(RID p_light, RID p_shadow_atlas, int p atlas_rect.size.width = light_instance->directional_rect.size.x; atlas_rect.size.height = light_instance->directional_rect.size.y; + int pass_count = 1; if (storage->light_directional_get_shadow_mode(light_instance->light) == RS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_4_SPLITS) { atlas_rect.size.width /= 2; atlas_rect.size.height /= 2; @@ -7504,7 +7496,7 @@ void RendererSceneRenderRD::render_shadow(RID p_light, RID p_shadow_atlas, int p atlas_rect.position.x += atlas_rect.size.width; atlas_rect.position.y += atlas_rect.size.height; } - + pass_count = 4; } else if (storage->light_directional_get_shadow_mode(light_instance->light) == RS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS) { atlas_rect.size.height /= 2; @@ -7512,6 +7504,7 @@ void RendererSceneRenderRD::render_shadow(RID p_light, RID p_shadow_atlas, int p } else { atlas_rect.position.y += atlas_rect.size.height; } + pass_count = 2; } light_instance->shadow_transform[p_pass].atlas_rect = atlas_rect; @@ -7519,15 +7512,15 @@ void RendererSceneRenderRD::render_shadow(RID p_light, RID p_shadow_atlas, int p light_instance->shadow_transform[p_pass].atlas_rect.position /= directional_shadow.size; light_instance->shadow_transform[p_pass].atlas_rect.size /= directional_shadow.size; - float bias_mult = light_instance->shadow_transform[p_pass].bias_scale; zfar = storage->light_get_param(light_instance->light, RS::LIGHT_PARAM_RANGE); - bias = storage->light_get_param(light_instance->light, RS::LIGHT_PARAM_SHADOW_BIAS) * bias_mult; - normal_bias = storage->light_get_param(light_instance->light, RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS) * bias_mult; - ShadowMap *shadow_map = _get_shadow_map(atlas_rect.size); - render_fb = shadow_map->fb; - render_texture = shadow_map->depth; - atlas_texture = directional_shadow.depth; + render_fb = directional_shadow.fb; + render_texture = RID(); + flip_y = true; + + clear_region = false; + begin_texture = (directional_shadow.current_light == 1) && (p_pass == 0); //light is 1-index because it was incremented above + end_texture = (directional_shadow.current_light == directional_shadow.light_count) && (p_pass == pass_count - 1); } else { //set from shadow atlas @@ -7536,6 +7529,8 @@ void RendererSceneRenderRD::render_shadow(RID p_light, RID p_shadow_atlas, int p ERR_FAIL_COND(!shadow_atlas); ERR_FAIL_COND(!shadow_atlas->shadow_owners.has(p_light)); + _update_shadow_atlas(shadow_atlas); + uint32_t key = shadow_atlas->shadow_owners[p_light]; uint32_t quadrant = (key >> ShadowAtlas::QUADRANT_SHIFT) & 0x3; @@ -7554,11 +7549,8 @@ void RendererSceneRenderRD::render_shadow(RID p_light, RID p_shadow_atlas, int p atlas_rect.size.width = shadow_size; atlas_rect.size.height = shadow_size; - atlas_texture = shadow_atlas->depth; zfar = storage->light_get_param(light_instance->light, RS::LIGHT_PARAM_RANGE); - bias = storage->light_get_param(light_instance->light, RS::LIGHT_PARAM_SHADOW_BIAS); - normal_bias = storage->light_get_param(light_instance->light, RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS); if (storage->light_get_type(light_instance->light) == RS::LIGHT_OMNI) { if (storage->light_omni_get_shadow_mode(light_instance->light) == RS::LIGHT_OMNI_SHADOW_CUBE) { @@ -7571,6 +7563,10 @@ void RendererSceneRenderRD::render_shadow(RID p_light, RID p_shadow_atlas, int p light_transform = light_instance->shadow_transform[0].transform; render_cubemap = true; finalize_cubemap = p_pass == 5; + atlas_fb = shadow_atlas->fb; + + atlas_size = shadow_atlas->size; + clear_region = false; } else { light_projection = light_instance->shadow_transform[0].camera; @@ -7581,22 +7577,17 @@ void RendererSceneRenderRD::render_shadow(RID p_light, RID p_shadow_atlas, int p using_dual_paraboloid = true; using_dual_paraboloid_flip = p_pass == 1; - - ShadowMap *shadow_map = _get_shadow_map(atlas_rect.size); - render_fb = shadow_map->fb; - render_texture = shadow_map->depth; + render_fb = shadow_atlas->fb; + flip_y = true; } } else if (storage->light_get_type(light_instance->light) == RS::LIGHT_SPOT) { light_projection = light_instance->shadow_transform[0].camera; light_transform = light_instance->shadow_transform[0].transform; - ShadowMap *shadow_map = _get_shadow_map(atlas_rect.size); - render_fb = shadow_map->fb; - render_texture = shadow_map->depth; + render_fb = shadow_atlas->fb; - znear = light_instance->shadow_transform[0].camera.get_z_near(); - use_linear_depth = true; + flip_y = true; } } @@ -7605,25 +7596,19 @@ void RendererSceneRenderRD::render_shadow(RID p_light, RID p_shadow_atlas, int p _render_shadow(render_fb, p_instances, light_projection, light_transform, zfar, 0, 0, false, false, use_pancake, p_camera_plane, p_lod_distance_multiplier, p_screen_lod_threshold); if (finalize_cubemap) { //reblit - atlas_rect.size.height /= 2; - storage->get_effects()->copy_cubemap_to_dp(render_texture, atlas_texture, atlas_rect, light_projection.get_z_near(), light_projection.get_z_far(), 0.0, false); - atlas_rect.position.y += atlas_rect.size.height; - storage->get_effects()->copy_cubemap_to_dp(render_texture, atlas_texture, atlas_rect, light_projection.get_z_near(), light_projection.get_z_far(), 0.0, true); + Rect2 atlas_rect_norm = atlas_rect; + atlas_rect_norm.position.x /= float(atlas_size); + atlas_rect_norm.position.y /= float(atlas_size); + atlas_rect_norm.size.x /= float(atlas_size); + atlas_rect_norm.size.y /= float(atlas_size); + atlas_rect_norm.size.height /= 2; + storage->get_effects()->copy_cubemap_to_dp(render_texture, atlas_fb, atlas_rect_norm, light_projection.get_z_near(), light_projection.get_z_far(), false); + atlas_rect_norm.position.y += atlas_rect_norm.size.height; + storage->get_effects()->copy_cubemap_to_dp(render_texture, atlas_fb, atlas_rect_norm, light_projection.get_z_near(), light_projection.get_z_far(), true); } } else { //render shadow - - _render_shadow(render_fb, p_instances, light_projection, light_transform, zfar, bias, normal_bias, using_dual_paraboloid, using_dual_paraboloid_flip, use_pancake, p_camera_plane, p_lod_distance_multiplier, p_screen_lod_threshold); - - //copy to atlas - if (use_linear_depth) { - storage->get_effects()->copy_depth_to_rect_and_linearize(render_texture, atlas_texture, atlas_rect, true, znear, zfar); - } else { - storage->get_effects()->copy_depth_to_rect(render_texture, atlas_texture, atlas_rect, true); - } - - //does not work from depth to color - //RD::get_singleton()->texture_copy(render_texture, atlas_texture, Vector3(0, 0, 0), Vector3(atlas_rect.position.x, atlas_rect.position.y, 0), Vector3(atlas_rect.size.x, atlas_rect.size.y, 1), 0, 0, 0, 0, true); + _render_shadow(render_fb, p_instances, light_projection, light_transform, zfar, 0, 0, using_dual_paraboloid, using_dual_paraboloid_flip, use_pancake, p_camera_plane, p_lod_distance_multiplier, p_screen_lod_threshold, atlas_rect, flip_y, clear_region, begin_texture, end_texture); } } @@ -8404,6 +8389,9 @@ RendererSceneRenderRD::RendererSceneRenderRD(RendererStorageRD *p_storage) { sdfgi_frames_to_converge = RS::EnvironmentSDFGIFramesToConverge(CLAMP(int32_t(GLOBAL_GET("rendering/sdfgi/frames_to_converge")), 0, int32_t(RS::ENV_SDFGI_CONVERGE_MAX - 1))); sdfgi_frames_to_update_light = RS::EnvironmentSDFGIFramesToUpdateLight(CLAMP(int32_t(GLOBAL_GET("rendering/sdfgi/frames_to_update_lights")), 0, int32_t(RS::ENV_SDFGI_UPDATE_LIGHT_MAX - 1))); + directional_shadow.size = GLOBAL_GET("rendering/quality/directional_shadow/size"); + directional_shadow.use_16_bits = GLOBAL_GET("rendering/quality/directional_shadow/16_bits"); + uint32_t textures_per_stage = RD::get_singleton()->limit_get(RD::LIMIT_MAX_TEXTURES_PER_SHADER_STAGE); low_end = GLOBAL_GET("rendering/quality/rd_renderer/use_low_end_renderer"); @@ -8877,9 +8865,6 @@ RendererSceneRenderRD::RendererSceneRenderRD(RendererStorageRD *p_storage) { } RendererSceneRenderRD::~RendererSceneRenderRD() { - for (Map::Element *E = shadow_maps.front(); E; E = E->next()) { - RD::get_singleton()->free(E->get().depth); - } for (Map::Element *E = shadow_cubemaps.front(); E; E = E->next()) { RD::get_singleton()->free(E->get().cubemap); } diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.h b/servers/rendering/renderer_rd/renderer_scene_render_rd.h index 6179861514ac..af8cdb9b7145 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_rd.h +++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.h @@ -110,7 +110,7 @@ protected: void _setup_giprobes(RID p_render_buffers, const Transform &p_transform, const PagedArray &p_gi_probes, uint32_t &r_gi_probes_used); virtual void _render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray &p_instances, int p_directional_light_count, const PagedArray &p_gi_probes, const PagedArray &p_lightmaps, RID p_environment, RID p_cluster_buffer, uint32_t p_cluster_size, uint32_t p_cluster_max_elements, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_color, float p_screen_lod_threshold) = 0; - virtual void _render_shadow(RID p_framebuffer, const PagedArray &p_instances, const CameraMatrix &p_projection, const Transform &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_lod_threshold = 0.0) = 0; + virtual void _render_shadow(RID p_framebuffer, const PagedArray &p_instances, const CameraMatrix &p_projection, const Transform &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_lod_threshold = 0.0, const Rect2i &p_rect = Rect2i(), bool p_flip_y = false, bool p_clear_region = true, bool p_begin = true, bool p_end = true) = 0; virtual void _render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray &p_instances, RID p_framebuffer, const Rect2i &p_region) = 0; virtual void _render_uv2(const PagedArray &p_instances, RID p_framebuffer, const Rect2i &p_region) = 0; virtual void _render_sdfgi(RID p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, const PagedArray &p_instances, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture) = 0; @@ -572,6 +572,7 @@ private: uint32_t smallest_subdiv = 0; int size = 0; + bool use_16_bits = false; RID depth; RID fb; //for copying @@ -583,6 +584,8 @@ private: RID_Owner shadow_atlas_owner; + void _update_shadow_atlas(ShadowAtlas *shadow_atlas); + bool _shadow_atlas_find_shadow(ShadowAtlas *shadow_atlas, int *p_in_quadrants, int p_quadrant_count, int p_current_subdiv, uint64_t p_tick, int &r_quadrant, int &r_shadow); RS::ShadowQuality shadows_quality = RS::SHADOW_QUALITY_MAX; //So it always updates when first set @@ -603,9 +606,11 @@ private: struct DirectionalShadow { RID depth; + RID fb; //when renderign direct int light_count = 0; int size = 0; + bool use_16_bits = false; int current_light = 0; Vector shrink_stages; @@ -615,6 +620,8 @@ private: void _allocate_shadow_shrink_stages(RID p_base, int p_base_size, Vector &shrink_stages, uint32_t p_target_size); void _clear_shadow_shrink_stages(Vector &shrink_stages); + void _update_directional_shadow_atlas(); + /* SHADOW CUBEMAPS */ struct ShadowCubemap { @@ -625,14 +632,6 @@ private: Map shadow_cubemaps; ShadowCubemap *_get_shadow_cubemap(int p_size); - struct ShadowMap { - RID depth; - RID fb; - }; - - Map shadow_maps; - ShadowMap *_get_shadow_map(const Size2i &p_size); - void _create_shadow_cubemaps(); /* LIGHT INSTANCE */ @@ -1555,7 +1554,7 @@ public: /* SHADOW ATLAS API */ RID shadow_atlas_create(); - void shadow_atlas_set_size(RID p_atlas, int p_size); + void shadow_atlas_set_size(RID p_atlas, int p_size, bool p_16_bits = false); void shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p_quadrant, int p_subdivision); bool shadow_atlas_update_light(RID p_atlas, RID p_light_intance, float p_coverage, uint64_t p_light_version); _FORCE_INLINE_ bool shadow_atlas_owns_light_instance(RID p_atlas, RID p_light_intance) { @@ -1576,7 +1575,7 @@ public: return Size2(atlas->size, atlas->size); } - void directional_shadow_atlas_set_size(int p_size); + void directional_shadow_atlas_set_size(int p_size, bool p_16_bits = false); int get_directional_light_shadow_size(RID p_light_intance); void set_directional_shadow_count(int p_count); diff --git a/servers/rendering/renderer_rd/shaders/cube_to_dp.glsl b/servers/rendering/renderer_rd/shaders/cube_to_dp.glsl index 54d67db6c62f..c3ac0bee575e 100644 --- a/servers/rendering/renderer_rd/shaders/cube_to_dp.glsl +++ b/servers/rendering/renderer_rd/shaders/cube_to_dp.glsl @@ -1,33 +1,48 @@ -#[compute] +#[vertex] #version 450 VERSION_DEFINES -layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; +layout(push_constant, binding = 1, std430) uniform Params { + float z_far; + float z_near; + bool z_flip; + uint pad; + vec4 screen_rect; +} +params; + +layout(location = 0) out vec2 uv_interp; + +void main() { + vec2 base_arr[4] = vec2[](vec2(0.0, 0.0), vec2(0.0, 1.0), vec2(1.0, 1.0), vec2(1.0, 0.0)); + uv_interp = base_arr[gl_VertexIndex]; + vec2 screen_pos = uv_interp * params.screen_rect.zw + params.screen_rect.xy; + gl_Position = vec4(screen_pos * 2.0 - 1.0, 0.0, 1.0); +} + +#[fragment] + +#version 450 + +VERSION_DEFINES + +layout(location = 0) in vec2 uv_interp; layout(set = 0, binding = 0) uniform samplerCube source_cube; layout(push_constant, binding = 1, std430) uniform Params { - ivec2 screen_size; - ivec2 offset; - float bias; float z_far; float z_near; bool z_flip; + uint pad; + vec4 screen_rect; } params; -layout(r32f, set = 1, binding = 0) uniform restrict writeonly image2D depth_buffer; - void main() { - ivec2 pos = ivec2(gl_GlobalInvocationID.xy); - if (any(greaterThan(pos, params.screen_size))) { //too large, do nothing - return; - } - - vec2 pixel_size = 1.0 / vec2(params.screen_size); - vec2 uv = (vec2(pos) + 0.5) * pixel_size; + vec2 uv = uv_interp; vec3 normal = vec3(uv * 2.0 - 1.0, 0.0); @@ -65,5 +80,5 @@ void main() { float linear_depth = 2.0 * params.z_near * params.z_far / (params.z_far + params.z_near - depth * (params.z_far - params.z_near)); depth = (linear_depth * depth_fix) / params.z_far; - imageStore(depth_buffer, pos + params.offset, vec4(depth)); + gl_FragDepth = depth; } diff --git a/servers/rendering/renderer_rd/shaders/gi.glsl b/servers/rendering/renderer_rd/shaders/gi.glsl index 9b8beaa9e773..35522103df49 100644 --- a/servers/rendering/renderer_rd/shaders/gi.glsl +++ b/servers/rendering/renderer_rd/shaders/gi.glsl @@ -655,7 +655,8 @@ void main() { return; } - vec4 ambient_light = vec4(0.0), reflection_light = vec4(0.0); + vec4 ambient_light = vec4(0.0); + vec4 reflection_light = vec4(0.0); vec3 vertex = reconstruct_position(pos); vertex.y = -vertex.y; diff --git a/servers/rendering/renderer_rd/shaders/resolve.glsl b/servers/rendering/renderer_rd/shaders/resolve.glsl index 7cb5235a5681..e83c4ca93b74 100644 --- a/servers/rendering/renderer_rd/shaders/resolve.glsl +++ b/servers/rendering/renderer_rd/shaders/resolve.glsl @@ -71,19 +71,19 @@ void main() { group1.y = texelFetch(source_depth, pos, 1).r; //4X - if (params.sample_count <= 4) { + if (params.sample_count >= 4) { group1.z = texelFetch(source_depth, pos, 2).r; group1.w = texelFetch(source_depth, pos, 3).r; } //8X - if (params.sample_count <= 8) { + if (params.sample_count >= 8) { group2.x = texelFetch(source_depth, pos, 4).r; group2.y = texelFetch(source_depth, pos, 5).r; group2.z = texelFetch(source_depth, pos, 6).r; group2.w = texelFetch(source_depth, pos, 7).r; } //16X - if (params.sample_count <= 16) { + if (params.sample_count >= 16) { group3.x = texelFetch(source_depth, pos, 8).r; group3.y = texelFetch(source_depth, pos, 9).r; group3.z = texelFetch(source_depth, pos, 10).r; @@ -115,7 +115,6 @@ void main() { } if (freq.w < min_f) { best_index = 3; - min_f = freq.w; } } else if (params.sample_count == 8) { vec4 freq0 = vec4(equal(group1, vec4(group1.x))); diff --git a/servers/rendering/renderer_rd/shaders/scene_forward.glsl b/servers/rendering/renderer_rd/shaders/scene_forward.glsl index aa32188a2604..ea203c8abeef 100644 --- a/servers/rendering/renderer_rd/shaders/scene_forward.glsl +++ b/servers/rendering/renderer_rd/shaders/scene_forward.glsl @@ -1282,7 +1282,7 @@ float light_process_spot_shadow(uint idx, vec3 vertex, vec3 normal) { } else { #endif //hard shadow - vec4 shadow_uv = vec4(splane.xy * spot_lights.data[idx].atlas_rect.zw + spot_lights.data[idx].atlas_rect.xy, z_norm, 1.0); + vec4 shadow_uv = vec4(splane.xy * spot_lights.data[idx].atlas_rect.zw + spot_lights.data[idx].atlas_rect.xy, splane.z, 1.0); shadow = sample_pcf_shadow(shadow_atlas, spot_lights.data[idx].soft_shadow_scale * scene_data.shadow_atlas_pixel_size, shadow_uv); #ifdef USE_SOFT_SHADOWS diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_inc.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_inc.glsl index a37e32e1fc7a..e9b79e1560d9 100644 --- a/servers/rendering/renderer_rd/shaders/scene_forward_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/scene_forward_inc.glsl @@ -153,22 +153,22 @@ scene_data; #define INSTANCE_FLAGS_SKELETON (1 << 19) #define INSTANCE_FLAGS_NON_UNIFORM_SCALE (1 << 20) -layout(set = 0, binding = 5, std430) restrict readonly buffer OmniLights { +layout(set = 0, binding = 4, std430) restrict readonly buffer OmniLights { LightData data[]; } omni_lights; -layout(set = 0, binding = 6, std430) restrict readonly buffer SpotLights { +layout(set = 0, binding = 5, std430) restrict readonly buffer SpotLights { LightData data[]; } spot_lights; -layout(set = 0, binding = 7) buffer restrict readonly ReflectionProbeData { +layout(set = 0, binding = 6) buffer restrict readonly ReflectionProbeData { ReflectionData data[]; } reflections; -layout(set = 0, binding = 8, std140) uniform DirectionalLights { +layout(set = 0, binding = 7, std140) uniform DirectionalLights { DirectionalLightData data[MAX_DIRECTIONAL_LIGHT_DATA_STRUCTS]; } directional_lights; @@ -180,7 +180,7 @@ struct Lightmap { mat3 normal_xform; }; -layout(set = 0, binding = 10, std140) restrict readonly buffer Lightmaps { +layout(set = 0, binding = 8, std140) restrict readonly buffer Lightmaps { Lightmap data[]; } lightmaps; @@ -189,22 +189,20 @@ struct LightmapCapture { vec4 sh[9]; }; -layout(set = 0, binding = 11, std140) restrict readonly buffer LightmapCaptures { +layout(set = 0, binding = 9, std140) restrict readonly buffer LightmapCaptures { LightmapCapture data[]; } lightmap_captures; -layout(set = 0, binding = 12) uniform texture2D decal_atlas; -layout(set = 0, binding = 13) uniform texture2D decal_atlas_srgb; +layout(set = 0, binding = 10) uniform texture2D decal_atlas; +layout(set = 0, binding = 11) uniform texture2D decal_atlas_srgb; -layout(set = 0, binding = 14, std430) restrict readonly buffer Decals { +layout(set = 0, binding = 12, std430) restrict readonly buffer Decals { DecalData data[]; } decals; -layout(set = 0, binding = 15) uniform texture2D directional_shadow_atlas; - -layout(set = 0, binding = 16, std430) restrict readonly buffer GlobalVariableData { +layout(set = 0, binding = 13, std430) restrict readonly buffer GlobalVariableData { vec4 data[]; } global_variables; @@ -218,7 +216,7 @@ struct SDFGIProbeCascadeData { float to_cell; // 1/bounds * grid_size }; -layout(set = 0, binding = 17, std140) uniform SDFGI { +layout(set = 0, binding = 14, std140) uniform SDFGI { vec3 grid_size; uint max_cascades; @@ -268,13 +266,15 @@ layout(set = 1, binding = 1) uniform textureCubeArray reflection_atlas; layout(set = 1, binding = 2) uniform texture2D shadow_atlas; -layout(set = 1, binding = 3) uniform texture2DArray lightmap_textures[MAX_LIGHTMAP_TEXTURES]; +layout(set = 1, binding = 3) uniform texture2D directional_shadow_atlas; + +layout(set = 1, binding = 4) uniform texture2DArray lightmap_textures[MAX_LIGHTMAP_TEXTURES]; #ifndef LOW_END_MODE -layout(set = 1, binding = 4) uniform texture3D gi_probe_textures[MAX_GI_PROBES]; +layout(set = 1, binding = 5) uniform texture3D gi_probe_textures[MAX_GI_PROBES]; #endif -layout(set = 1, binding = 5, std430) buffer restrict readonly ClusterBuffer { +layout(set = 1, binding = 6, std430) buffer restrict readonly ClusterBuffer { uint data[]; } cluster_buffer; @@ -283,10 +283,10 @@ cluster_buffer; #ifdef MODE_RENDER_SDF -layout(r16ui, set = 1, binding = 6) uniform restrict writeonly uimage3D albedo_volume_grid; -layout(r32ui, set = 1, binding = 7) uniform restrict writeonly uimage3D emission_grid; -layout(r32ui, set = 1, binding = 8) uniform restrict writeonly uimage3D emission_aniso_grid; -layout(r32ui, set = 1, binding = 9) uniform restrict uimage3D geom_facing_grid; +layout(r16ui, set = 1, binding = 7) uniform restrict writeonly uimage3D albedo_volume_grid; +layout(r32ui, set = 1, binding = 8) uniform restrict writeonly uimage3D emission_grid; +layout(r32ui, set = 1, binding = 9) uniform restrict writeonly uimage3D emission_aniso_grid; +layout(r32ui, set = 1, binding = 10) uniform restrict uimage3D geom_facing_grid; //still need to be present for shaders that use it, so remap them to something #define depth_buffer shadow_atlas @@ -295,17 +295,17 @@ layout(r32ui, set = 1, binding = 9) uniform restrict uimage3D geom_facing_grid; #else -layout(set = 1, binding = 6) uniform texture2D depth_buffer; -layout(set = 1, binding = 7) uniform texture2D color_buffer; +layout(set = 1, binding = 7) uniform texture2D depth_buffer; +layout(set = 1, binding = 8) uniform texture2D color_buffer; #ifndef LOW_END_MODE -layout(set = 1, binding = 8) uniform texture2D normal_roughness_buffer; -layout(set = 1, binding = 9) uniform texture2D ao_buffer; -layout(set = 1, binding = 10) uniform texture2D ambient_buffer; -layout(set = 1, binding = 11) uniform texture2D reflection_buffer; -layout(set = 1, binding = 12) uniform texture2DArray sdfgi_lightprobe_texture; -layout(set = 1, binding = 13) uniform texture3D sdfgi_occlusion_cascades; +layout(set = 1, binding = 9) uniform texture2D normal_roughness_buffer; +layout(set = 1, binding = 10) uniform texture2D ao_buffer; +layout(set = 1, binding = 11) uniform texture2D ambient_buffer; +layout(set = 1, binding = 12) uniform texture2D reflection_buffer; +layout(set = 1, binding = 13) uniform texture2DArray sdfgi_lightprobe_texture; +layout(set = 1, binding = 14) uniform texture3D sdfgi_occlusion_cascades; struct GIProbeData { mat4 xform; @@ -323,12 +323,12 @@ struct GIProbeData { uint mipmaps; }; -layout(set = 1, binding = 14, std140) uniform GIProbes { +layout(set = 1, binding = 15, std140) uniform GIProbes { GIProbeData data[MAX_GI_PROBES]; } gi_probes; -layout(set = 1, binding = 15) uniform texture3D volumetric_fog_texture; +layout(set = 1, binding = 16) uniform texture3D volumetric_fog_texture; #endif // LOW_END_MODE diff --git a/servers/rendering/renderer_scene.h b/servers/rendering/renderer_scene.h index 6ce954d5f54e..d92642886c5c 100644 --- a/servers/rendering/renderer_scene.h +++ b/servers/rendering/renderer_scene.h @@ -95,7 +95,7 @@ public: virtual Variant instance_geometry_get_shader_parameter(RID p_instance, const StringName &p_parameter) const = 0; virtual Variant instance_geometry_get_shader_parameter_default_value(RID p_instance, const StringName &p_parameter) const = 0; - virtual void directional_shadow_atlas_set_size(int p_size) = 0; + virtual void directional_shadow_atlas_set_size(int p_size, bool p_16_bits = false) = 0; /* SKY API */ @@ -173,7 +173,7 @@ public: virtual void directional_shadow_quality_set(RS::ShadowQuality p_quality) = 0; virtual RID shadow_atlas_create() = 0; - virtual void shadow_atlas_set_size(RID p_atlas, int p_size) = 0; + virtual void shadow_atlas_set_size(RID p_atlas, int p_size, bool p_use_16_bits = false) = 0; virtual void shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p_quadrant, int p_subdivision) = 0; /* Render Buffers */ diff --git a/servers/rendering/renderer_scene_cull.h b/servers/rendering/renderer_scene_cull.h index c917e0ba842f..2ffaf48675c3 100644 --- a/servers/rendering/renderer_scene_cull.h +++ b/servers/rendering/renderer_scene_cull.h @@ -947,7 +947,7 @@ public: #define PASSBASE scene_render - PASS1(directional_shadow_atlas_set_size, int) + PASS2(directional_shadow_atlas_set_size, int, bool) PASS1(gi_probe_set_quality, RS::GIProbeQuality) /* SKY API */ @@ -1030,7 +1030,7 @@ public: /* Shadow Atlas */ PASS0R(RID, shadow_atlas_create) - PASS2(shadow_atlas_set_size, RID, int) + PASS3(shadow_atlas_set_size, RID, int, bool) PASS3(shadow_atlas_set_quadrant_subdivision, RID, int, int) PASS1(set_debug_draw_mode, RS::ViewportDebugDraw) diff --git a/servers/rendering/renderer_scene_render.h b/servers/rendering/renderer_scene_render.h index 5a544413872b..ecec03db9403 100644 --- a/servers/rendering/renderer_scene_render.h +++ b/servers/rendering/renderer_scene_render.h @@ -73,11 +73,11 @@ public: virtual RID shadow_atlas_create() = 0; - virtual void shadow_atlas_set_size(RID p_atlas, int p_size) = 0; + virtual void shadow_atlas_set_size(RID p_atlas, int p_size, bool p_16_bits = false) = 0; virtual void shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p_quadrant, int p_subdivision) = 0; virtual bool shadow_atlas_update_light(RID p_atlas, RID p_light_intance, float p_coverage, uint64_t p_light_version) = 0; - virtual void directional_shadow_atlas_set_size(int p_size) = 0; + virtual void directional_shadow_atlas_set_size(int p_size, bool p_16_bits = false) = 0; virtual int get_directional_light_shadow_size(RID p_light_intance) = 0; virtual void set_directional_shadow_count(int p_count) = 0; diff --git a/servers/rendering/renderer_viewport.cpp b/servers/rendering/renderer_viewport.cpp index 9956e4050bf5..d52da5b33115 100644 --- a/servers/rendering/renderer_viewport.cpp +++ b/servers/rendering/renderer_viewport.cpp @@ -831,13 +831,14 @@ void RendererViewport::viewport_set_canvas_stacking(RID p_viewport, RID p_canvas viewport->canvas_map[p_canvas].sublayer = p_sublayer; } -void RendererViewport::viewport_set_shadow_atlas_size(RID p_viewport, int p_size) { +void RendererViewport::viewport_set_shadow_atlas_size(RID p_viewport, int p_size, bool p_16_bits) { Viewport *viewport = viewport_owner.getornull(p_viewport); ERR_FAIL_COND(!viewport); viewport->shadow_atlas_size = p_size; + viewport->shadow_atlas_16_bits = p_16_bits; - RSG::scene->shadow_atlas_set_size(viewport->shadow_atlas, viewport->shadow_atlas_size); + RSG::scene->shadow_atlas_set_size(viewport->shadow_atlas, viewport->shadow_atlas_size, viewport->shadow_atlas_16_bits); } void RendererViewport::viewport_set_shadow_atlas_quadrant_subdivision(RID p_viewport, int p_quadrant, int p_subdiv) { diff --git a/servers/rendering/renderer_viewport.h b/servers/rendering/renderer_viewport.h index c3ff52a836c1..979cbb095b38 100644 --- a/servers/rendering/renderer_viewport.h +++ b/servers/rendering/renderer_viewport.h @@ -81,6 +81,7 @@ public: RID shadow_atlas; int shadow_atlas_size; + bool shadow_atlas_16_bits = false; bool sdf_active; @@ -217,7 +218,7 @@ public: void viewport_set_global_canvas_transform(RID p_viewport, const Transform2D &p_transform); void viewport_set_canvas_stacking(RID p_viewport, RID p_canvas, int p_layer, int p_sublayer); - void viewport_set_shadow_atlas_size(RID p_viewport, int p_size); + void viewport_set_shadow_atlas_size(RID p_viewport, int p_size, bool p_16_bits = false); void viewport_set_shadow_atlas_quadrant_subdivision(RID p_viewport, int p_quadrant, int p_subdiv); void viewport_set_msaa(RID p_viewport, RS::ViewportMSAA p_msaa); diff --git a/servers/rendering/rendering_device.cpp b/servers/rendering/rendering_device.cpp index 9ae3e5819e0a..89483d9f50c8 100644 --- a/servers/rendering/rendering_device.cpp +++ b/servers/rendering/rendering_device.cpp @@ -745,6 +745,7 @@ void RenderingDevice::_bind_methods() { BIND_ENUM_CONSTANT(DYNAMIC_STATE_STENCIL_REFERENCE); BIND_ENUM_CONSTANT(INITIAL_ACTION_CLEAR); //start rendering and clear the framebuffer (supply params) + BIND_ENUM_CONSTANT(INITIAL_ACTION_CLEAR_REGION); //start rendering and clear the framebuffer (supply params) BIND_ENUM_CONSTANT(INITIAL_ACTION_KEEP); //start rendering); but keep attached color texture contents (depth will be cleared) BIND_ENUM_CONSTANT(INITIAL_ACTION_DROP); //start rendering); ignore what is there); just write above it BIND_ENUM_CONSTANT(INITIAL_ACTION_CONTINUE); //continue rendering (framebuffer must have been left in "continue" state as final action previously) diff --git a/servers/rendering/rendering_device.h b/servers/rendering/rendering_device.h index f67e4dfbab33..eb051067d357 100644 --- a/servers/rendering/rendering_device.h +++ b/servers/rendering/rendering_device.h @@ -931,7 +931,8 @@ public: /********************/ enum InitialAction { - INITIAL_ACTION_CLEAR, //start rendering and clear the framebuffer (supply params) + INITIAL_ACTION_CLEAR, //start rendering and clear the whole framebuffer (region or not) (supply params) + INITIAL_ACTION_CLEAR_REGION, //start rendering and clear the framebuffer in the specified region (supply params) INITIAL_ACTION_KEEP, //start rendering, but keep attached color texture contents (depth will be cleared) INITIAL_ACTION_DROP, //start rendering, ignore what is there, just write above it INITIAL_ACTION_CONTINUE, //continue rendering (framebuffer must have been left in "continue" state as final action previously) diff --git a/servers/rendering/rendering_server_default.h b/servers/rendering/rendering_server_default.h index d3cc9999a8af..6d600c61cc6e 100644 --- a/servers/rendering/rendering_server_default.h +++ b/servers/rendering/rendering_server_default.h @@ -551,7 +551,7 @@ public: BIND2(viewport_set_global_canvas_transform, RID, const Transform2D &) BIND4(viewport_set_canvas_stacking, RID, RID, int, int) - BIND2(viewport_set_shadow_atlas_size, RID, int) + BIND3(viewport_set_shadow_atlas_size, RID, int, bool) BIND3(viewport_set_sdf_oversize_and_scale, RID, ViewportSDFOversize, ViewportSDFScale) BIND3(viewport_set_shadow_atlas_quadrant_subdivision, RID, int, int) BIND2(viewport_set_msaa, RID, ViewportMSAA) @@ -572,7 +572,7 @@ public: //from now on, calls forwarded to this singleton #define BINDBASE RSG::scene - BIND1(directional_shadow_atlas_set_size, int) + BIND2(directional_shadow_atlas_set_size, int, bool) BIND1(gi_probe_set_quality, GIProbeQuality) /* SKY API */ diff --git a/servers/rendering/rendering_server_wrap_mt.h b/servers/rendering/rendering_server_wrap_mt.h index 101024c59447..534159e09506 100644 --- a/servers/rendering/rendering_server_wrap_mt.h +++ b/servers/rendering/rendering_server_wrap_mt.h @@ -445,7 +445,7 @@ public: FUNC2(viewport_set_global_canvas_transform, RID, const Transform2D &) FUNC4(viewport_set_canvas_stacking, RID, RID, int, int) - FUNC2(viewport_set_shadow_atlas_size, RID, int) + FUNC3(viewport_set_shadow_atlas_size, RID, int, bool) FUNC3(viewport_set_sdf_oversize_and_scale, RID, ViewportSDFOversize, ViewportSDFScale) FUNC3(viewport_set_shadow_atlas_quadrant_subdivision, RID, int, int) @@ -470,7 +470,7 @@ public: return rendering_server->viewport_get_measured_render_time_gpu(p_viewport); } - FUNC1(directional_shadow_atlas_set_size, int) + FUNC2(directional_shadow_atlas_set_size, int, bool) /* SKY API */ diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp index 367dd7c63848..9ac66cd4bf78 100644 --- a/servers/rendering_server.cpp +++ b/servers/rendering_server.cpp @@ -1661,7 +1661,7 @@ void RenderingServer::_bind_methods() { ClassDB::bind_method(D_METHOD("viewport_set_transparent_background", "viewport", "enabled"), &RenderingServer::viewport_set_transparent_background); ClassDB::bind_method(D_METHOD("viewport_set_global_canvas_transform", "viewport", "transform"), &RenderingServer::viewport_set_global_canvas_transform); ClassDB::bind_method(D_METHOD("viewport_set_canvas_stacking", "viewport", "canvas", "layer", "sublayer"), &RenderingServer::viewport_set_canvas_stacking); - ClassDB::bind_method(D_METHOD("viewport_set_shadow_atlas_size", "viewport", "size"), &RenderingServer::viewport_set_shadow_atlas_size); + ClassDB::bind_method(D_METHOD("viewport_set_shadow_atlas_size", "viewport", "size", "use_16_bits"), &RenderingServer::viewport_set_shadow_atlas_size, DEFVAL(false)); ClassDB::bind_method(D_METHOD("viewport_set_shadow_atlas_quadrant_subdivision", "viewport", "quadrant", "subdivision"), &RenderingServer::viewport_set_shadow_atlas_quadrant_subdivision); ClassDB::bind_method(D_METHOD("viewport_set_msaa", "viewport", "msaa"), &RenderingServer::viewport_set_msaa); ClassDB::bind_method(D_METHOD("viewport_set_use_debanding", "viewport", "enable"), &RenderingServer::viewport_set_use_debanding); @@ -2272,6 +2272,7 @@ RenderingServer::RenderingServer() { GLOBAL_DEF("rendering/quality/directional_shadow/soft_shadow_quality", 2); GLOBAL_DEF("rendering/quality/directional_shadow/soft_shadow_quality.mobile", 0); ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/directional_shadow/soft_shadow_quality", PropertyInfo(Variant::INT, "rendering/quality/directional_shadow/soft_shadow_quality", PROPERTY_HINT_ENUM, "Hard (Fastest),Soft Low (Fast),Soft Medium (Average),Soft High (Slow),Soft Ultra (Slowest)")); + GLOBAL_DEF("rendering/quality/directional_shadow/16_bits", true); GLOBAL_DEF("rendering/quality/shadows/soft_shadow_quality", 2); GLOBAL_DEF("rendering/quality/shadows/soft_shadow_quality.mobile", 0); @@ -2282,18 +2283,6 @@ RenderingServer::RenderingServer() { GLOBAL_DEF("rendering/quality/rd_renderer/use_low_end_renderer", false); GLOBAL_DEF("rendering/quality/rd_renderer/use_low_end_renderer.mobile", true); - GLOBAL_DEF("rendering/quality/shadow_atlas/size", 4096); - GLOBAL_DEF("rendering/quality/shadow_atlas/size.mobile", 2048); - ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/shadow_atlas/size", PropertyInfo(Variant::INT, "rendering/quality/shadow_atlas/size", PROPERTY_HINT_RANGE, "256,16384")); - GLOBAL_DEF("rendering/quality/shadow_atlas/quadrant_0_subdiv", 1); - GLOBAL_DEF("rendering/quality/shadow_atlas/quadrant_1_subdiv", 2); - GLOBAL_DEF("rendering/quality/shadow_atlas/quadrant_2_subdiv", 3); - GLOBAL_DEF("rendering/quality/shadow_atlas/quadrant_3_subdiv", 4); - ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/shadow_atlas/quadrant_0_subdiv", PropertyInfo(Variant::INT, "rendering/quality/shadow_atlas/quadrant_0_subdiv", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows")); - ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/shadow_atlas/quadrant_1_subdiv", PropertyInfo(Variant::INT, "rendering/quality/shadow_atlas/quadrant_1_subdiv", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows")); - ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/shadow_atlas/quadrant_2_subdiv", PropertyInfo(Variant::INT, "rendering/quality/shadow_atlas/quadrant_2_subdiv", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows")); - ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/shadow_atlas/quadrant_3_subdiv", PropertyInfo(Variant::INT, "rendering/quality/shadow_atlas/quadrant_3_subdiv", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows")); - GLOBAL_DEF("rendering/quality/reflections/roughness_layers", 8); GLOBAL_DEF("rendering/quality/reflections/texture_array_reflections", true); GLOBAL_DEF("rendering/quality/reflections/texture_array_reflections.mobile", false); diff --git a/servers/rendering_server.h b/servers/rendering_server.h index 8693f733e270..c4483133e4ee 100644 --- a/servers/rendering_server.h +++ b/servers/rendering_server.h @@ -798,7 +798,7 @@ public: virtual void viewport_set_sdf_oversize_and_scale(RID p_viewport, ViewportSDFOversize p_oversize, ViewportSDFScale p_scale) = 0; - virtual void viewport_set_shadow_atlas_size(RID p_viewport, int p_size) = 0; + virtual void viewport_set_shadow_atlas_size(RID p_viewport, int p_size, bool p_16_bits = false) = 0; virtual void viewport_set_shadow_atlas_quadrant_subdivision(RID p_viewport, int p_quadrant, int p_subdiv) = 0; enum ViewportMSAA { @@ -868,7 +868,7 @@ public: virtual float viewport_get_measured_render_time_cpu(RID p_viewport) const = 0; virtual float viewport_get_measured_render_time_gpu(RID p_viewport) const = 0; - virtual void directional_shadow_atlas_set_size(int p_size) = 0; + virtual void directional_shadow_atlas_set_size(int p_size, bool p_16_bits = false) = 0; /* SKY API */