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.
This commit is contained in:
Clément Foucault
2024-05-26 20:23:42 +02:00
parent eaf1454475
commit 0e11f168db
13 changed files with 59 additions and 13 deletions

View File

@@ -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")

View File

@@ -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

View File

@@ -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.

View File

@@ -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_);

View File

@@ -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;

View File

@@ -38,6 +38,7 @@ void main()
uniform_buf.ao.distance,
uniform_buf.ao.thickness,
uniform_buf.ao.angle_bias,
2,
10,
false);

View File

@@ -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);

View File

@@ -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)));

View File

@@ -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);

View File

@@ -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")

View File

@@ -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, \

View File

@@ -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;

View File

@@ -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(