EEVEE-Next: Irradiance Grid smooth transitions

Smooth the transition at grid bounds.

The transition size is fixed at 1 grid cell,
but it may be useful to expose a user setting for controlling this.

Pull Request: https://projects.blender.org/blender/blender/pulls/112842
This commit is contained in:
Miguel Pozo
2023-12-18 16:25:20 +01:00
parent 8c91fc62a4
commit 97785b6fbb
7 changed files with 46 additions and 9 deletions

View File

@@ -143,6 +143,7 @@ void RayTraceModule::sync()
inst_.bind_uniform_data(&pass);
inst_.irradiance_cache.bind_resources(pass);
inst_.reflection_probes.bind_resources(pass);
inst_.sampling.bind_resources(pass);
pass.dispatch(raytrace_tracing_dispatch_buf_);
pass.barrier(GPU_BARRIER_SHADER_IMAGE_ACCESS);
}

View File

@@ -216,6 +216,7 @@ void ReflectionProbeModule::begin_sync()
pass.push_constant("reflection_probe_count", &reflection_probe_count_);
pass.bind_ssbo("reflection_probe_buf", &data_buf_);
instance_.irradiance_cache.bind_resources(pass);
instance_.sampling.bind_resources(pass);
pass.dispatch(&dispatch_probe_select_);
pass.barrier(GPU_BARRIER_UNIFORM);
}

View File

@@ -1476,6 +1476,15 @@ BLI_STATIC_ASSERT_ALIGN(UniformData, 16)
/* __cplusplus is true when compiling with MSL, so include if inside a shader. */
#if !defined(__cplusplus) || defined(GPU_SHADER)
# if defined(GPU_FRAGMENT_SHADER)
# define UTIL_TEXEL vec2(gl_FragCoord)
# elif defined(GPU_COMPUTE_SHADER)
# define UTIL_TEXEL vec2(gl_GlobalInvocationID)
# else
# define UTIL_TEXEL vec2(gl_VertexID, 0)
# endif
/* Fetch texel. Wrapping if above range. */
float4 utility_tx_fetch(sampler2DArray util_tx, float2 texel, float layer)
{

View File

@@ -7,11 +7,15 @@
* - grids_infos_buf
* - bricks_infos_buf
* - irradiance_atlas_tx
* Needed for sampling (not for upload):
* - util_tx
* - sampling_buf
*/
#pragma BLENDER_REQUIRE(gpu_shader_codegen_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_lightprobe_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_spherical_harmonics_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_sampling_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_reflection_probe_eval_lib.glsl)
#pragma BLENDER_REQUIRE(gpu_shader_math_base_lib.glsl)
@@ -126,19 +130,35 @@ SphericalHarmonicL1 lightprobe_irradiance_sample(
sampler3D atlas_tx, vec3 P, vec3 V, vec3 Ng, const bool do_bias)
{
vec3 lP;
int index = 0;
int index = -1;
int i = 0;
#ifdef IRRADIANCE_GRID_UPLOAD
index = grid_start_index;
i = grid_start_index;
#endif
for (; index < IRRADIANCE_GRID_MAX; index++) {
#ifdef IRRADIANCE_GRID_SAMPLING
float random = interlieved_gradient_noise(UTIL_TEXEL, 0.0, 0.0);
random = fract(random + sampling_rng_1D_get(SAMPLING_LIGHTPROBE));
#endif
for (; i < IRRADIANCE_GRID_MAX; i++) {
/* Last grid is tagged as invalid to stop the iteration. */
if (grids_infos_buf[index].grid_size.x == -1) {
if (grids_infos_buf[i].grid_size.x == -1) {
/* Sample the last grid instead. */
index -= 1;
index = i - 1;
break;
}
/* If sample fall inside the grid, step out of the loop. */
if (lightprobe_irradiance_grid_local_coord(grids_infos_buf[index], P, lP)) {
if (lightprobe_irradiance_grid_local_coord(grids_infos_buf[i], P, lP)) {
index = i;
#ifdef IRRADIANCE_GRID_SAMPLING
float distance_to_border = reduce_min(min(lP, vec3(grids_infos_buf[i].grid_size) - lP));
if (distance_to_border < random) {
/* Remap random to the remaining interval. */
random = (random - distance_to_border) / (1.0 - distance_to_border);
/* Try to sample another grid to get smooth transitions at borders. */
continue;
}
#endif
break;
}
}

View File

@@ -204,7 +204,8 @@ GPU_SHADER_CREATE_INFO(eevee_volume_probe_data)
/* NOTE: Use uint instead of IrradianceBrickPacked because Metal needs to know the exact type.
*/
.storage_buf(IRRADIANCE_BRICK_BUF_SLOT, Qualifier::READ, "uint", "bricks_infos_buf[]")
.sampler(IRRADIANCE_ATLAS_TEX_SLOT, ImageType::FLOAT_3D, "irradiance_atlas_tx");
.sampler(IRRADIANCE_ATLAS_TEX_SLOT, ImageType::FLOAT_3D, "irradiance_atlas_tx")
.define("IRRADIANCE_GRID_SAMPLING");
GPU_SHADER_CREATE_INFO(eevee_lightprobe_data)
.additional_info("eevee_reflection_probe_data", "eevee_volume_probe_data");

View File

@@ -46,7 +46,7 @@ GPU_SHADER_CREATE_INFO(eevee_reflection_probe_select)
"ReflectionProbeData",
"reflection_probe_buf[REFLECTION_PROBES_MAX]")
.push_constant(Type::INT, "reflection_probe_count")
.additional_info("eevee_shared", "eevee_volume_probe_data")
.additional_info("eevee_shared", "eevee_sampling_data", "eevee_volume_probe_data")
.compute_source("eevee_reflection_probe_select_comp.glsl")
.do_static_compilation(true);

View File

@@ -78,7 +78,11 @@ EEVEE_RAYTRACE_CLOSURE_VARIATION(eevee_ray_generate)
GPU_SHADER_CREATE_INFO(eevee_ray_trace_fallback)
.do_static_compilation(true)
.local_group_size(RAYTRACE_GROUP_SIZE, RAYTRACE_GROUP_SIZE)
.additional_info("eevee_shared", "eevee_global_ubo", "draw_view", "eevee_lightprobe_data")
.additional_info("eevee_shared",
"eevee_global_ubo",
"draw_view",
"eevee_sampling_data",
"eevee_lightprobe_data")
.image(0, GPU_RGBA16F, Qualifier::READ, ImageType::FLOAT_2D, "ray_data_img")
.image(1, RAYTRACE_RAYTIME_FORMAT, Qualifier::WRITE, ImageType::FLOAT_2D, "ray_time_img")
.image(2, RAYTRACE_RADIANCE_FORMAT, Qualifier::WRITE, ImageType::FLOAT_2D, "ray_radiance_img")
@@ -210,6 +214,7 @@ GPU_SHADER_CREATE_INFO(eevee_horizon_denoise)
.additional_info("eevee_shared",
"eevee_gbuffer_data",
"eevee_global_ubo",
"eevee_sampling_data",
"eevee_lightprobe_data",
"draw_view")
.sampler(1, ImageType::DEPTH_2D, "depth_tx")