WIP: eevee-next-world-irradiance #108304

Closed
Jeroen Bakker wants to merge 79 commits from Jeroen-Bakker:eevee-next-world-irradiance into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
7 changed files with 18 additions and 3 deletions
Showing only changes of commit d3e761cda3 - Show all commits

View File

@ -137,6 +137,7 @@ void IrradianceCache::display_pass_draw(View &view, GPUFrameBuffer *view_fb)
display_grids_ps_.push_constant("sphere_radius", 0.3f); /* TODO property */ display_grids_ps_.push_constant("sphere_radius", 0.3f); /* TODO property */
display_grids_ps_.push_constant("grid_resolution", grid_size); display_grids_ps_.push_constant("grid_resolution", grid_size);
display_grids_ps_.push_constant("grid_to_world", grid.object_to_world); display_grids_ps_.push_constant("grid_to_world", grid.object_to_world);
display_grids_ps_.push_constant("world_to_grid", grid.world_to_object);
display_grids_ps_.bind_texture("irradiance_a_tx", &irradiance_a_tx_); display_grids_ps_.bind_texture("irradiance_a_tx", &irradiance_a_tx_);
display_grids_ps_.bind_texture("irradiance_b_tx", &irradiance_b_tx_); display_grids_ps_.bind_texture("irradiance_b_tx", &irradiance_b_tx_);
@ -281,6 +282,8 @@ void IrradianceBake::surfels_create(const Object &probe_object)
dispatch_per_grid_sample_ = math::divide_ceil(grid_resolution, int3(IRRADIANCE_GRID_GROUP_SIZE)); dispatch_per_grid_sample_ = math::divide_ceil(grid_resolution, int3(IRRADIANCE_GRID_GROUP_SIZE));
capture_info_buf_.irradiance_grid_size = grid_resolution; capture_info_buf_.irradiance_grid_size = grid_resolution;
capture_info_buf_.irradiance_grid_local_to_world = grid_local_to_world; capture_info_buf_.irradiance_grid_local_to_world = grid_local_to_world;
capture_info_buf_.irradiance_grid_world_to_local_rotation = float4x4(
(invert(normalize(float3x3(grid_local_to_world)))));
capture_info_buf_.irradiance_accum_solid_angle = 0.0f; capture_info_buf_.irradiance_accum_solid_angle = 0.0f;
/* Divide by twice the sample count because each ray is evaluated in both directions. */ /* Divide by twice the sample count because each ray is evaluated in both directions. */
capture_info_buf_.irradiance_sample_solid_angle = 4.0f * float(M_PI) / capture_info_buf_.irradiance_sample_solid_angle = 4.0f * float(M_PI) /

View File

@ -29,6 +29,8 @@ void LightProbeModule::sync_grid(const Object *ob, ObjectHandle &handle)
grid.initialized = true; grid.initialized = true;
grid.updated = true; grid.updated = true;
grid.object_to_world = float4x4(ob->object_to_world); grid.object_to_world = float4x4(ob->object_to_world);
grid.world_to_object = float4x4(
math::normalize(math::transpose(float3x3(grid.object_to_world))));
grid.cache = ob->lightprobe_cache; grid.cache = ob->lightprobe_cache;
} }
} }

View File

@ -25,8 +25,10 @@ struct LightProbe {
}; };
struct IrradianceGrid : public LightProbe { struct IrradianceGrid : public LightProbe {
/** Reference to the light-cache data. Should be refreshed every sync. */ /** Copy of the transform matrix. */
float4x4 object_to_world; float4x4 object_to_world;
/** Precomputed inverse transform with normalized axes. No position. Used for rotating SH. */
float4x4 world_to_object;
/** /**
* Reference to the light-cache data. * Reference to the light-cache data.
* Do not try to dereference it before LightProbeModule::end_sync() as the grid could * Do not try to dereference it before LightProbeModule::end_sync() as the grid could

View File

@ -876,6 +876,9 @@ struct CaptureInfoData {
float irradiance_accum_solid_angle; float irradiance_accum_solid_angle;
/** Transform of the lightprobe object. */ /** Transform of the lightprobe object. */
float4x4 irradiance_grid_local_to_world; float4x4 irradiance_grid_local_to_world;
/** Transform vectors from world space to local space. Does not have location component. */
/** TODO(fclem): This could be a float3x4 or a float3x3 if padded correctly. */
float4x4 irradiance_grid_world_to_local_rotation;
}; };
BLI_STATIC_ASSERT_ALIGN(CaptureInfoData, 16) BLI_STATIC_ASSERT_ALIGN(CaptureInfoData, 16)

View File

@ -1,4 +1,5 @@
#pragma BLENDER_REQUIRE(common_view_lib.glsl) #pragma BLENDER_REQUIRE(common_view_lib.glsl)
#pragma BLENDER_REQUIRE(common_math_lib.glsl)
#pragma BLENDER_REQUIRE(eevee_spherical_harmonics_lib.glsl) #pragma BLENDER_REQUIRE(eevee_spherical_harmonics_lib.glsl)
void main() void main()
@ -19,7 +20,8 @@ void main()
vec3 vN = vec3(lP, sqrt(max(0.0, 1.0 - dist_sqr))); vec3 vN = vec3(lP, sqrt(max(0.0, 1.0 - dist_sqr)));
vec3 N = normal_view_to_world(vN); vec3 N = normal_view_to_world(vN);
vec3 lN = transform_direction(world_to_grid, N);
vec4 irradiance = spherical_harmonics_evaluate_lambert(N, sh); vec4 irradiance = spherical_harmonics_evaluate_lambert(lN, sh);
out_color = vec4(irradiance.rgb, 0.0); out_color = vec4(irradiance.rgb, 0.0);
} }

View File

@ -16,8 +16,10 @@
void irradiance_capture(vec3 L, vec3 irradiance, inout SphericalHarmonicL1 sh) void irradiance_capture(vec3 L, vec3 irradiance, inout SphericalHarmonicL1 sh)
{ {
vec3 lL = transform_direction(capture_info_buf.irradiance_grid_world_to_local_rotation, L);
spherical_harmonics_encode_signal_sample( spherical_harmonics_encode_signal_sample(
L, vec4(irradiance, 1.0) * capture_info_buf.irradiance_sample_solid_angle, sh); lL, vec4(irradiance, 1.0) * capture_info_buf.irradiance_sample_solid_angle, sh);
} }
void irradiance_capture(Surfel surfel_emitter, vec3 P, inout SphericalHarmonicL1 sh) void irradiance_capture(Surfel surfel_emitter, vec3 P, inout SphericalHarmonicL1 sh)

View File

@ -74,6 +74,7 @@ GPU_SHADER_CREATE_INFO(eevee_display_probe_grid)
.push_constant(Type::FLOAT, "sphere_radius") .push_constant(Type::FLOAT, "sphere_radius")
.push_constant(Type::IVEC3, "grid_resolution") .push_constant(Type::IVEC3, "grid_resolution")
.push_constant(Type::MAT4, "grid_to_world") .push_constant(Type::MAT4, "grid_to_world")
.push_constant(Type::MAT4, "world_to_grid")
.sampler(0, ImageType::FLOAT_3D, "irradiance_a_tx") .sampler(0, ImageType::FLOAT_3D, "irradiance_a_tx")
.sampler(1, ImageType::FLOAT_3D, "irradiance_b_tx") .sampler(1, ImageType::FLOAT_3D, "irradiance_b_tx")
.sampler(2, ImageType::FLOAT_3D, "irradiance_c_tx") .sampler(2, ImageType::FLOAT_3D, "irradiance_c_tx")