From 0e11f168dbb26ee0b2e0161d76fec91664cdc3cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Sun, 26 May 2024 20:23:42 +0200 Subject: [PATCH] EEVEE-Next: Expose Fast GI ray and step count This allow to reduce the amount of noise and reduce the lost energy caused by low thickness and large stride (low sample count). Actual number of rays is twice the UI count. --- scripts/startup/bl_ui/properties_render.py | 4 ++++ .../blender/blenkernel/BKE_blender_version.h | 2 +- .../blenloader/intern/versioning_400.cc | 8 +++++++ .../draw/engines/eevee_next/eevee_raytrace.cc | 4 ++++ .../draw/engines/eevee_next/eevee_raytrace.hh | 2 ++ .../eevee_ambient_occlusion_pass_comp.glsl | 1 + .../shaders/eevee_horizon_scan_comp.glsl | 3 ++- .../shaders/eevee_horizon_scan_eval_lib.glsl | 17 +++++++++----- .../shaders/eevee_nodetree_lib.glsl | 1 + .../shaders/infos/eevee_tracing_info.hh | 2 ++ source/blender/makesdna/DNA_scene_defaults.h | 3 +++ source/blender/makesdna/DNA_scene_types.h | 3 +++ source/blender/makesrna/intern/rna_scene.cc | 22 ++++++++++++++----- 13 files changed, 59 insertions(+), 13 deletions(-) diff --git a/scripts/startup/bl_ui/properties_render.py b/scripts/startup/bl_ui/properties_render.py index 898bb7106f0..11d83759375 100644 --- a/scripts/startup/bl_ui/properties_render.py +++ b/scripts/startup/bl_ui/properties_render.py @@ -622,6 +622,10 @@ class RENDER_PT_eevee_next_gi_approximation(RenderButtonsPanel, Panel): layout.use_property_split = True layout.use_property_decorate = False + col = layout.column( align=True) + col.prop(props, "fast_gi_ray_count", text="Rays") + col.prop(props, "fast_gi_step_count", text="Steps") + col = layout.column() col.prop(props, "horizon_quality", text="Precision") col.prop(props, "horizon_thickness", text="Thickness") diff --git a/source/blender/blenkernel/BKE_blender_version.h b/source/blender/blenkernel/BKE_blender_version.h index 519eaa13660..2d0c4065e9d 100644 --- a/source/blender/blenkernel/BKE_blender_version.h +++ b/source/blender/blenkernel/BKE_blender_version.h @@ -29,7 +29,7 @@ extern "C" { /* Blender file format version. */ #define BLENDER_FILE_VERSION BLENDER_VERSION -#define BLENDER_FILE_SUBVERSION 43 +#define BLENDER_FILE_SUBVERSION 44 /* Minimum Blender version that supports reading file written with the current * version. Older Blender versions will test this and cancel loading the file, showing a warning to diff --git a/source/blender/blenloader/intern/versioning_400.cc b/source/blender/blenloader/intern/versioning_400.cc index d4981ed31c1..9a1c905046f 100644 --- a/source/blender/blenloader/intern/versioning_400.cc +++ b/source/blender/blenloader/intern/versioning_400.cc @@ -3642,6 +3642,14 @@ void blo_do_versions_400(FileData *fd, Library * /*lib*/, Main *bmain) } } + if (!MAIN_VERSION_FILE_ATLEAST(bmain, 402, 44)) { + const Scene *default_scene = DNA_struct_default_get(Scene); + LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) { + scene->eevee.fast_gi_step_count = default_scene->eevee.fast_gi_step_count; + scene->eevee.fast_gi_ray_count = default_scene->eevee.fast_gi_ray_count; + } + } + /** * Always bump subversion in BKE_blender_version.h when adding versioning * code here, and wrap it inside a MAIN_VERSION_FILE_ATLEAST check. diff --git a/source/blender/draw/engines/eevee_next/eevee_raytrace.cc b/source/blender/draw/engines/eevee_next/eevee_raytrace.cc index 3d4c95d5a7e..d56c127e9ee 100644 --- a/source/blender/draw/engines/eevee_next/eevee_raytrace.cc +++ b/source/blender/draw/engines/eevee_next/eevee_raytrace.cc @@ -30,6 +30,8 @@ void RayTraceModule::init() ray_tracing_options_ = sce_eevee.ray_tracing_options; tracing_method_ = RaytraceEEVEE_Method(sce_eevee.ray_tracing_method); + fast_gi_ray_count_ = sce_eevee.fast_gi_ray_count; + fast_gi_step_count_ = sce_eevee.fast_gi_step_count; float4 data(0.0f); radiance_dummy_black_tx_.ensure_2d( @@ -259,6 +261,8 @@ void RayTraceModule::sync() PassSimple &pass = horizon_scan_ps_; pass.init(); GPUShader *sh = inst_.shaders.static_shader_get(HORIZON_SCAN); + pass.specialize_constant(sh, "fast_gi_slice_count", fast_gi_ray_count_); + pass.specialize_constant(sh, "fast_gi_step_count", fast_gi_step_count_); pass.shader_set(sh); pass.bind_texture("screen_radiance_tx", &downsampled_in_radiance_tx_); pass.bind_texture("screen_normal_tx", &downsampled_in_normal_tx_); diff --git a/source/blender/draw/engines/eevee_next/eevee_raytrace.hh b/source/blender/draw/engines/eevee_next/eevee_raytrace.hh index a935cd8c7c9..78cc6ade640 100644 --- a/source/blender/draw/engines/eevee_next/eevee_raytrace.hh +++ b/source/blender/draw/engines/eevee_next/eevee_raytrace.hh @@ -222,6 +222,8 @@ class RayTraceModule { /** Copy of the scene options to avoid changing parameters during motion blur. */ RaytraceEEVEE ray_tracing_options_; + int fast_gi_ray_count_ = 0; + int fast_gi_step_count_ = 0; RaytraceEEVEE_Method tracing_method_ = RAYTRACE_EEVEE_METHOD_PROBE; diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_ambient_occlusion_pass_comp.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_ambient_occlusion_pass_comp.glsl index 8eab6f9228e..073483f6a60 100644 --- a/source/blender/draw/engines/eevee_next/shaders/eevee_ambient_occlusion_pass_comp.glsl +++ b/source/blender/draw/engines/eevee_next/shaders/eevee_ambient_occlusion_pass_comp.glsl @@ -38,6 +38,7 @@ void main() uniform_buf.ao.distance, uniform_buf.ao.thickness, uniform_buf.ao.angle_bias, + 2, 10, false); diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_horizon_scan_comp.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_horizon_scan_comp.glsl index e5a0ba85921..9cd1bd2b293 100644 --- a/source/blender/draw/engines/eevee_next/shaders/eevee_horizon_scan_comp.glsl +++ b/source/blender/draw/engines/eevee_next/shaders/eevee_horizon_scan_comp.glsl @@ -53,7 +53,8 @@ void main() 1.0e16, uniform_buf.ao.thickness, uniform_buf.ao.angle_bias, - 8, + fast_gi_slice_count, + fast_gi_step_count, false); scan.result = spherical_harmonics_compress(scan.result); diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_horizon_scan_eval_lib.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_horizon_scan_eval_lib.glsl index 2d6ccaf868e..c71f9754203 100644 --- a/source/blender/draw/engines/eevee_next/shaders/eevee_horizon_scan_eval_lib.glsl +++ b/source/blender/draw/engines/eevee_next/shaders/eevee_horizon_scan_eval_lib.glsl @@ -100,13 +100,17 @@ HorizonScanResult horizon_scan_eval(vec3 vP, float search_distance, float global_thickness, float angle_bias, + const int slice_count, const int sample_count, const bool reversed) { vec3 vV = drw_view_incident_vector(vP); - const int slice_len = 2; - vec2 v_dir = sample_circle(noise.x * (0.5 / float(slice_len))); + vec2 v_dir; + if (slice_count <= 2) { + /* We cover half the circle because we trace in both directions. */ + v_dir = sample_circle(noise.x / float(2 * slice_count)); + } float weight_accum = 0.0; float occlusion_accum = 0.0; @@ -116,10 +120,11 @@ HorizonScanResult horizon_scan_eval(vec3 vP, /* NOTE: Full loop unroll hint increases performance on Apple Silicon. */ # pragma clang loop unroll(full) #endif - for (int slice = 0; slice < slice_len; slice++) { -#if 0 /* For debug purpose. For when slice_len is greater than 2. */ - vec2 v_dir = sample_circle(((float(slice) + noise.x) / float(slice_len))); -#endif + for (int slice = 0; slice < slice_count; slice++) { + if (slice_count > 2) { + /* We cover half the circle because we trace in both directions. */ + v_dir = sample_circle(((float(slice) + noise.x) / float(2 * slice_count))); + } /* Setup integration domain around V. */ vec3 vB = normalize(cross(vV, vec3(v_dir, 0.0))); diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_nodetree_lib.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_nodetree_lib.glsl index 9ba63d1f6a8..737fcbb0084 100644 --- a/source/blender/draw/engines/eevee_next/shaders/eevee_nodetree_lib.glsl +++ b/source/blender/draw/engines/eevee_next/shaders/eevee_nodetree_lib.glsl @@ -372,6 +372,7 @@ float ambient_occlusion_eval(vec3 normal, max_distance, uniform_buf.ao.thickness, uniform_buf.ao.angle_bias, + 2, 10, inverted != 0.0); diff --git a/source/blender/draw/engines/eevee_next/shaders/infos/eevee_tracing_info.hh b/source/blender/draw/engines/eevee_next/shaders/infos/eevee_tracing_info.hh index bf9dc0e4ed3..f00595e6917 100644 --- a/source/blender/draw/engines/eevee_next/shaders/infos/eevee_tracing_info.hh +++ b/source/blender/draw/engines/eevee_next/shaders/infos/eevee_tracing_info.hh @@ -198,6 +198,8 @@ GPU_SHADER_CREATE_INFO(eevee_horizon_scan) "eevee_utility_texture", "eevee_hiz_data", "draw_view") + .specialization_constant(Type::INT, "fast_gi_slice_count", 2) + .specialization_constant(Type::INT, "fast_gi_step_count", 8) .sampler(0, ImageType::FLOAT_2D, "screen_radiance_tx") .sampler(1, ImageType::FLOAT_2D, "screen_normal_tx") .image(2, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "horizon_radiance_0_img") diff --git a/source/blender/makesdna/DNA_scene_defaults.h b/source/blender/makesdna/DNA_scene_defaults.h index 7a9865a57cb..94047a0e97a 100644 --- a/source/blender/makesdna/DNA_scene_defaults.h +++ b/source/blender/makesdna/DNA_scene_defaults.h @@ -212,6 +212,9 @@ .gtao_thickness = 0.5f, \ .gtao_focus = 0.05f, \ .gtao_resolution = 2, \ + \ + .fast_gi_step_count = 8, \ + .fast_gi_ray_count = 2, \ \ .bokeh_overblur = 5.0f, \ .bokeh_max_size = 100.0f, \ diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 4699dd52f02..41297f59ac3 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -1863,6 +1863,9 @@ typedef struct SceneEEVEE { float gtao_focus; int gtao_resolution; + int fast_gi_step_count; + int fast_gi_ray_count; + float bokeh_overblur; float bokeh_max_size; float bokeh_threshold; diff --git a/source/blender/makesrna/intern/rna_scene.cc b/source/blender/makesrna/intern/rna_scene.cc index 7feae92623a..9ee208390fe 100644 --- a/source/blender/makesrna/intern/rna_scene.cc +++ b/source/blender/makesrna/intern/rna_scene.cc @@ -7794,11 +7794,11 @@ static void rna_def_raytrace_eevee(BlenderRNA *brna) RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, nullptr); prop = RNA_def_property(srna, "trace_max_roughness", PROP_FLOAT, PROP_FACTOR); - RNA_def_property_ui_text( - prop, - "Raytrace Max Roughness", - "Maximum roughness to use the tracing pipeline for. Higher " - "roughness surfaces will use horizon scan. A value of 1 will disable horizon scan"); + RNA_def_property_ui_text(prop, + "Raytrace Max Roughness", + "Maximum roughness to use the tracing pipeline for. Higher " + "roughness surfaces will use fast GI approximation. A value of 1 will " + "disable fast GI approximation"); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY); RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, nullptr); @@ -8262,6 +8262,18 @@ static void rna_def_scene_eevee(BlenderRNA *brna) RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY); RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, nullptr); + prop = RNA_def_property(srna, "fast_gi_step_count", PROP_INT, PROP_UNSIGNED); + RNA_def_property_range(prop, 1, 64); + RNA_def_property_ui_text(prop, "Step Count", "Amount of screen sample per GI ray"); + RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY); + RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, nullptr); + + prop = RNA_def_property(srna, "fast_gi_ray_count", PROP_INT, PROP_UNSIGNED); + RNA_def_property_range(prop, 1, 16); + RNA_def_property_ui_text(prop, "Ray Count", "Amount of GI ray to trace for each pixel"); + RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY); + RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, nullptr); + prop = RNA_def_property(srna, "horizon_bias", PROP_FLOAT, PROP_FACTOR); RNA_def_property_float_sdna(prop, nullptr, "gtao_focus"); RNA_def_property_ui_text(