diff options
Diffstat (limited to 'servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp')
-rw-r--r-- | servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp | 182 |
1 files changed, 57 insertions, 125 deletions
diff --git a/servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp b/servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp index 0d341581a6..9e6225a97a 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp +++ b/servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp @@ -3100,25 +3100,22 @@ RS::EnvironmentSSRRoughnessQuality RasterizerSceneRD::environment_get_ssr_roughn return ssr_roughness_quality; } -void RasterizerSceneRD::environment_set_ssao(RID p_env, bool p_enable, float p_rejection_radius, float p_intensity, int p_levels, float p_light_affect, float p_ao_channel_affect) { +void RasterizerSceneRD::environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_bias, float p_light_affect, float p_ao_channel_affect, RS::EnvironmentSSAOBlur p_blur, float p_bilateral_sharpness) { Environment *env = environment_owner.getornull(p_env); ERR_FAIL_COND(!env); env->ssao_enabled = p_enable; - - env->ssao_rejection_radius = p_rejection_radius; + env->ssao_radius = p_radius; env->ssao_intensity = p_intensity; - env->ssao_levels = p_levels; + env->ssao_bias = p_bias; env->ssao_direct_light_affect = p_light_affect; env->ssao_ao_channel_affect = p_ao_channel_affect; + env->ssao_blur = p_blur; } -void RasterizerSceneRD::environment_set_ssao_settings(RS::EnvironmentSSAOQuality p_quality, bool p_full_samples, float p_noise_tolerance, float p_blur_tolerance, float p_upsample_tolerance) { +void RasterizerSceneRD::environment_set_ssao_quality(RS::EnvironmentSSAOQuality p_quality, bool p_half_size) { ssao_quality = p_quality; - ssao_full_samples = p_full_samples; - ssao_noise_tolerance = Math::lerp(-8.0f, 0.0f, p_noise_tolerance); - ssao_blur_tolerance = Math::lerp(-8.0f, -1.0f, p_blur_tolerance); - ssao_upsample_tolerance = Math::lerp(-12.0f, -1.0f, p_upsample_tolerance); + ssao_half_size = p_half_size; } bool RasterizerSceneRD::environment_is_ssao_enabled(RID p_env) const { @@ -5038,33 +5035,21 @@ void RasterizerSceneRD::_free_render_buffer_data(RenderBuffers *rb) { rb->luminance.current = RID(); } - if (rb->ssao.ao_full.is_valid()) { - RD::get_singleton()->free(rb->ssao.ao_full); - RD::get_singleton()->free(rb->ssao.linear_depth); - rb->ssao.ao_full = RID(); - rb->ssao.linear_depth = RID(); - - for (int i = 0; i < rb->ssao.depth_slices.size(); i++) { - RD::get_singleton()->free(rb->ssao.depth_slices[i]); - } - for (int i = 0; i < rb->ssao.depth_tiled_slices.size(); i++) { - RD::get_singleton()->free(rb->ssao.depth_tiled_slices[i]); - } - for (int i = 0; i < rb->ssao.ao_slices.size(); i++) { - RD::get_singleton()->free(rb->ssao.ao_slices[i]); + if (rb->ssao.ao[0].is_valid()) { + RD::get_singleton()->free(rb->ssao.depth); + RD::get_singleton()->free(rb->ssao.ao[0]); + if (rb->ssao.ao[1].is_valid()) { + RD::get_singleton()->free(rb->ssao.ao[1]); } - for (int i = 0; i < rb->ssao.filtered_ao_slices.size(); i++) { - RD::get_singleton()->free(rb->ssao.filtered_ao_slices[i]); - } - for (int i = 0; i < rb->ssao.high_quality_ao_slices.size(); i++) { - RD::get_singleton()->free(rb->ssao.high_quality_ao_slices[i]); + if (rb->ssao.ao_full.is_valid()) { + RD::get_singleton()->free(rb->ssao.ao_full); } + rb->ssao.depth = RID(); + rb->ssao.ao[0] = RID(); + rb->ssao.ao[1] = RID(); + rb->ssao.ao_full = RID(); rb->ssao.depth_slices.clear(); - rb->ssao.depth_tiled_slices.clear(); - rb->ssao.ao_slices.clear(); - rb->ssao.filtered_ao_slices.clear(); - rb->ssao.high_quality_ao_slices.clear(); } if (rb->ssr.blur_radius[0].is_valid()) { @@ -5163,117 +5148,64 @@ void RasterizerSceneRD::_process_ssao(RID p_render_buffers, RID p_environment, R RENDER_TIMESTAMP("Process SSAO"); - int size_x = rb->width; - int size_y = rb->height; - const int buffer_widths[6] = { - (size_x + 1) / 2, - (size_x + 3) / 4, - (size_x + 7) / 8, - (size_x + 15) / 16, - (size_x + 31) / 32, - (size_x + 63) / 64 - }; - const int buffer_heights[6] = { - (size_y + 1) / 2, - (size_y + 3) / 4, - (size_y + 7) / 8, - (size_y + 15) / 16, - (size_y + 31) / 32, - (size_y + 63) / 64 - }; - - if (!rb->ssao.ao_full.is_valid()) { - //allocate SSAO buffers - - { - for (uint32_t i = 0; i < 4; i++) { - RD::TextureFormat tf; - tf.format = RD::DATA_FORMAT_R32_SFLOAT; - tf.width = buffer_widths[i]; - tf.height = buffer_heights[i]; - tf.mipmaps = 1; - tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT; - RID slice = RD::get_singleton()->texture_create(tf, RD::TextureView()); - rb->ssao.depth_slices.push_back(slice); - } + if (rb->ssao.ao[0].is_valid() && rb->ssao.ao_full.is_valid() != ssao_half_size) { + RD::get_singleton()->free(rb->ssao.depth); + RD::get_singleton()->free(rb->ssao.ao[0]); + if (rb->ssao.ao[1].is_valid()) { + RD::get_singleton()->free(rb->ssao.ao[1]); } - - { - for (uint32_t i = 2; i < 6; i++) { - RD::TextureFormat tf; - tf.format = RD::DATA_FORMAT_R16_SFLOAT; - tf.type = RD::TEXTURE_TYPE_2D_ARRAY; - tf.array_layers = 16; - tf.width = buffer_widths[i]; - tf.height = buffer_heights[i]; - tf.mipmaps = 1; - tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT; - RID slice = RD::get_singleton()->texture_create(tf, RD::TextureView()); - rb->ssao.depth_tiled_slices.push_back(slice); - } + if (rb->ssao.ao_full.is_valid()) { + RD::get_singleton()->free(rb->ssao.ao_full); } - { - for (uint32_t i = 0; i < 3; i++) { - RD::TextureFormat tf; - tf.format = RD::DATA_FORMAT_R8_UNORM; - tf.width = buffer_widths[i]; - tf.height = buffer_heights[i]; - tf.mipmaps = 1; - tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT; - RID slice = RD::get_singleton()->texture_create(tf, RD::TextureView()); - rb->ssao.ao_slices.push_back(slice); - } - } + rb->ssao.depth = RID(); + rb->ssao.ao[0] = RID(); + rb->ssao.ao[1] = RID(); + rb->ssao.ao_full = RID(); + rb->ssao.depth_slices.clear(); + } - { - for (uint32_t i = 0; i < 4; i++) { - RD::TextureFormat tf; - tf.format = RD::DATA_FORMAT_R8_UNORM; - tf.width = buffer_widths[i]; - tf.height = buffer_heights[i]; - tf.mipmaps = 1; - tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT; - RID slice = RD::get_singleton()->texture_create(tf, RD::TextureView()); - rb->ssao.high_quality_ao_slices.push_back(slice); - } - } + if (!rb->ssao.ao[0].is_valid()) { + //allocate depth slices { - for (uint32_t i = 0; i < 4; i++) { - RD::TextureFormat tf; - tf.format = RD::DATA_FORMAT_R8_UNORM; - tf.width = buffer_widths[i]; - tf.height = buffer_heights[i]; - tf.mipmaps = 1; - tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT; - RID slice = RD::get_singleton()->texture_create(tf, RD::TextureView()); - rb->ssao.filtered_ao_slices.push_back(slice); + RD::TextureFormat tf; + tf.format = RD::DATA_FORMAT_R32_SFLOAT; + tf.width = rb->width / 2; + tf.height = rb->height / 2; + tf.mipmaps = Image::get_image_required_mipmaps(tf.width, tf.height, Image::FORMAT_RF) + 1; + tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT; + rb->ssao.depth = RD::get_singleton()->texture_create(tf, RD::TextureView()); + for (uint32_t i = 0; i < tf.mipmaps; i++) { + RID slice = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rb->ssao.depth, 0, i); + rb->ssao.depth_slices.push_back(slice); } } { RD::TextureFormat tf; tf.format = RD::DATA_FORMAT_R8_UNORM; - tf.width = size_x; - tf.height = size_y; + tf.width = ssao_half_size ? rb->width / 2 : rb->width; + tf.height = ssao_half_size ? rb->height / 2 : rb->height; tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT; - rb->ssao.ao_full = RD::get_singleton()->texture_create(tf, RD::TextureView()); + rb->ssao.ao[0] = RD::get_singleton()->texture_create(tf, RD::TextureView()); + rb->ssao.ao[1] = RD::get_singleton()->texture_create(tf, RD::TextureView()); } - { + if (ssao_half_size) { + //upsample texture RD::TextureFormat tf; - tf.format = RD::DATA_FORMAT_R16_UNORM; - tf.width = size_x; - tf.height = size_y; + tf.format = RD::DATA_FORMAT_R8_UNORM; + tf.width = rb->width; + tf.height = rb->height; tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT; - rb->ssao.linear_depth = RD::get_singleton()->texture_create(tf, RD::TextureView()); + rb->ssao.ao_full = RD::get_singleton()->texture_create(tf, RD::TextureView()); } _render_buffers_uniform_set_changed(p_render_buffers); } - storage->get_effects()->generate_ssao(rb->depth_texture, Size2i(size_x, size_y), rb->ssao.depth_slices, rb->ssao.linear_depth, rb->ssao.depth_tiled_slices, rb->ssao.ao_slices, rb->ssao.high_quality_ao_slices, rb->ssao.filtered_ao_slices, rb->ssao.ao_full, p_projection, ssao_noise_tolerance, ssao_blur_tolerance, ssao_upsample_tolerance, env->ssao_rejection_radius, env->ssao_intensity, env->ssao_levels, ssao_quality, ssao_full_samples); + storage->get_effects()->generate_ssao(rb->depth_texture, p_normal_buffer, Size2i(rb->width, rb->height), rb->ssao.depth, rb->ssao.depth_slices, rb->ssao.ao[0], rb->ssao.ao_full.is_valid(), rb->ssao.ao[1], rb->ssao.ao_full, env->ssao_intensity, env->ssao_radius, env->ssao_bias, p_projection, ssao_quality, env->ssao_blur, env->ssao_blur_edge_sharpness); } void RasterizerSceneRD::_render_buffers_post_process_and_tonemap(RID p_render_buffers, RID p_environment, RID p_camera_effects, const CameraMatrix &p_projection) { @@ -5438,9 +5370,9 @@ void RasterizerSceneRD::_render_buffers_debug_draw(RID p_render_buffers, RID p_s } } - if (debug_draw == RS::VIEWPORT_DEBUG_DRAW_SSAO && rb->ssao.ao_full.is_valid()) { + if (debug_draw == RS::VIEWPORT_DEBUG_DRAW_SSAO && rb->ssao.ao[0].is_valid()) { Size2 rtsize = storage->render_target_get_size(rb->render_target); - RID ao_buf = rb->ssao.ao_full; + RID ao_buf = rb->ssao.ao_full.is_valid() ? rb->ssao.ao_full : rb->ssao.ao[0]; effects->copy_to_fb_rect(ao_buf, storage->render_target_get_rd_framebuffer(rb->render_target), Rect2(Vector2(), rtsize), false, true); } @@ -5616,7 +5548,7 @@ RID RasterizerSceneRD::render_buffers_get_ao_texture(RID p_render_buffers) { RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers); ERR_FAIL_COND_V(!rb, RID()); - return rb->ssao.ao_full; + return rb->ssao.ao_full.is_valid() ? rb->ssao.ao_full : rb->ssao.ao[0]; } RID RasterizerSceneRD::render_buffers_get_gi_probe_buffer(RID p_render_buffers) { @@ -8402,7 +8334,7 @@ RasterizerSceneRD::RasterizerSceneRD(RasterizerStorageRD *p_storage) { camera_effects_set_dof_blur_bokeh_shape(RS::DOFBokehShape(int(GLOBAL_GET("rendering/quality/depth_of_field/depth_of_field_bokeh_shape")))); camera_effects_set_dof_blur_quality(RS::DOFBlurQuality(int(GLOBAL_GET("rendering/quality/depth_of_field/depth_of_field_bokeh_quality"))), GLOBAL_GET("rendering/quality/depth_of_field/depth_of_field_use_jitter")); - environment_set_ssao_settings(RS::EnvironmentSSAOQuality(int(GLOBAL_GET("rendering/ssao/quality"))), GLOBAL_GET("rendering/ssao/full_samples"), GLOBAL_GET("rendering/ssao/noise_tolerance"), GLOBAL_GET("rendering/ssao/blur_tolerance"), GLOBAL_GET("rendering/ssao/upsample_tolerance")); + environment_set_ssao_quality(RS::EnvironmentSSAOQuality(int(GLOBAL_GET("rendering/quality/ssao/quality"))), GLOBAL_GET("rendering/quality/ssao/half_size")); screen_space_roughness_limiter = GLOBAL_GET("rendering/quality/screen_filters/screen_space_roughness_limiter_enabled"); screen_space_roughness_limiter_amount = GLOBAL_GET("rendering/quality/screen_filters/screen_space_roughness_limiter_amount"); screen_space_roughness_limiter_limit = GLOBAL_GET("rendering/quality/screen_filters/screen_space_roughness_limiter_limit"); |