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(