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.
10 changed files with 144 additions and 21 deletions
Showing only changes of commit db3028a624 - Show all commits

View File

@ -502,6 +502,7 @@ set(GLSL_SRC
engines/eevee_next/shaders/eevee_surfel_light_comp.glsl
engines/eevee_next/shaders/eevee_surfel_list_build_comp.glsl
engines/eevee_next/shaders/eevee_surfel_list_sort_comp.glsl
engines/eevee_next/shaders/eevee_surfel_ray_comp.glsl
engines/eevee_next/shaders/eevee_transparency_lib.glsl
engines/eevee_next/shaders/eevee_velocity_lib.glsl

View File

@ -49,7 +49,7 @@ void IrradianceCache::debug_pass_sync()
debug_surfels_ps_.state_set(DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH |
DRW_STATE_DEPTH_LESS_EQUAL);
debug_surfels_ps_.shader_set(inst_.shaders.static_shader_get(DEBUG_SURFELS));
debug_surfels_ps_.push_constant("surfel_radius", 0.5f / 4.0f);
debug_surfels_ps_.push_constant("surfel_radius", 1.5f / 4.0f);
debug_surfels_ps_.push_constant("debug_mode", static_cast<int>(inst_.debug_mode));
surfels_buf_.clear();
@ -130,7 +130,12 @@ void IrradianceBake::sync()
sub.dispatch(&dispatch_per_list_);
}
{
// PassSimple::Sub &sub = pass.sub("LightPropagate");
PassSimple::Sub &sub = pass.sub("RayEval");
sub.shader_set(inst_.shaders.static_shader_get(SURFEL_RAY));
sub.bind_ssbo(SURFEL_BUF_SLOT, &surfels_buf_);
sub.bind_ssbo(CAPTURE_BUF_SLOT, &capture_info_buf_);
sub.barrier(GPU_BARRIER_SHADER_STORAGE);
sub.dispatch(&dispatch_per_surfel_);
}
}
{

View File

@ -178,6 +178,8 @@ const char *ShaderModule::static_shader_create_info_name_get(eShaderType shader_
return "eevee_surfel_list_build";
case SURFEL_LIST_SORT:
return "eevee_surfel_list_sort";
case SURFEL_RAY:
return "eevee_surfel_ray";
/* To avoid compiler warning about missing case. */
case MAX_SHADER_TYPE:
return "";

View File

@ -83,6 +83,7 @@ enum eShaderType {
SURFEL_LIGHT,
SURFEL_LIST_BUILD,
SURFEL_LIST_SORT,
SURFEL_RAY,
MAX_SHADER_TYPE,
};

View File

@ -840,12 +840,22 @@ struct Surfel {
/** Next surfel index in the ray link-list. */
int next;
/** Surface albedo to apply to incoming radiance. */
packed_float3 albedo;
packed_float3 albedo_front;
int _pad0;
packed_float3 albedo_back;
/** Distance along the ray direction for sorting. */
float ray_distance;
/** Accumulated reflected radiance. */
packed_float3 radiance;
int _pad0;
/** Reflected radiance from previous bounce. */
packed_float3 radiance_front;
int _pad1;
packed_float3 radiance_back;
int _pad2;
/**
* Accumulated reflected radiance for the current bounce.
* Weight is stored in the fourth component.
*/
float4 radiance_bounce_front;
float4 radiance_bounce_back;
};
BLI_STATIC_ASSERT_ALIGN(Surfel, 16)

View File

@ -3,13 +3,19 @@ void main()
{
Surfel surfel = surfels_buf[surfel_index];
vec4 radiance_bounce = gl_FrontFacing ? surfel.radiance_bounce_front :
surfel.radiance_bounce_back;
vec3 radiance = gl_FrontFacing ? surfel.radiance_front : surfel.radiance_back;
switch (eDebugMode(debug_mode)) {
default:
case DEBUG_IRRADIANCE_CACHE_SURFELS_NORMAL:
out_color = vec4(pow(surfel.normal * 0.5 + 0.5, vec3(2.2)), 0.0);
break;
case DEBUG_IRRADIANCE_CACHE_SURFELS_IRRADIANCE:
out_color = vec4(surfel.radiance, 0.0);
out_color = (radiance_bounce.w > 0.0) ?
vec4(radiance + radiance_bounce.rgb / radiance_bounce.w, 0.0) :
vec4(radiance, 0.0);
break;
}
@ -18,13 +24,4 @@ void main()
discard;
return;
}
/* Display backfacing surfels with a transparent checkerboard grid. */
if (!gl_FrontFacing) {
ivec2 grid_uv = ivec2(gl_FragCoord) / 5;
if ((grid_uv.x + grid_uv.y) % 2 == 0) {
discard;
return;
}
}
}

View File

@ -45,8 +45,14 @@ void main()
if (capture_info_buf.do_surfel_output) {
surfel_buf[surfel_id].position = g_data.P;
surfel_buf[surfel_id].normal = gl_FrontFacing ? g_data.Ng : -g_data.Ng;
surfel_buf[surfel_id].albedo = albedo;
surfel_buf[surfel_id].radiance = g_emission;
surfel_buf[surfel_id].albedo_front = albedo;
surfel_buf[surfel_id].radiance_front = g_emission;
/* TODO(fclem): 2nd surface evaluation. */
surfel_buf[surfel_id].albedo_back = albedo;
surfel_buf[surfel_id].radiance_back = g_emission;
surfel_buf[surfel_id].radiance_bounce_front = vec4(0.0);
surfel_buf[surfel_id].radiance_bounce_back = vec4(0.0);
}
}
}

View File

@ -35,7 +35,8 @@ void light_eval_surfel(
}
LIGHT_FOREACH_END
LIGHT_FOREACH_BEGIN_LOCAL_NO_CULL (light_cull_buf, l_idx) {
LIGHT_FOREACH_BEGIN_LOCAL_NO_CULL(light_cull_buf, l_idx)
{
light_eval_ex(diffuse,
reflection,
false,
@ -73,7 +74,13 @@ void main()
light_eval_surfel(diffuse_data, surfel.position, surfel.normal, thickness, diffuse_light);
surfel.radiance += diffuse_light * surfel.albedo;
surfel_buf[index].radiance_front += diffuse_light * surfel.albedo_front;
surfel_buf[index] = surfel;
diffuse_data.N = -surfel.normal;
diffuse_light = vec3(0.0);
reflection_light = vec3(0.0);
light_eval_surfel(diffuse_data, surfel.position, -surfel.normal, thickness, diffuse_light);
surfel_buf[index].radiance_back += diffuse_light * surfel.albedo_back;
}

View File

@ -0,0 +1,86 @@
/**
* For every surfel, compute the incomming radiance from both side.
* For that, walk the ray surfel linked-list and gather the light from the neighbor surfels.
*
* Dispatched as 1 thread per surfel.
*/
#pragma BLENDER_REQUIRE(common_view_lib.glsl)
#pragma BLENDER_REQUIRE(gpu_shader_utildefines_lib.glsl)
#pragma BLENDER_REQUIRE(gpu_shader_math_base_lib.glsl)
/**
* Evaluate radiance transfer from `surfel_a` to `surfel_b`.
* Assume ray direction is uniformly distributed over the sphere.
* NOTE: In practice the ray is not evenly distributed but that's a by-product
* of the surfel list method.
*
* Return radiance + pdf.
*/
void radiance_transfer(Surfel surfel_a, inout Surfel surfel_b)
{
bool facing = dot(surfel_a.normal, surfel_b.normal) < 0.0;
vec3 L = normalize(surfel_a.position - surfel_b.position);
vec3 N = surfel_b.normal;
float NL = dot(N, L);
float pdf = abs(NL);
vec3 irradiance = facing ? surfel_a.radiance_front : surfel_a.radiance_back;
if (NL > 0.0) {
surfel_b.radiance_bounce_front += vec4(surfel_b.albedo_front * irradiance * pdf, pdf);
}
else {
surfel_b.radiance_bounce_back += vec4(surfel_b.albedo_back * irradiance * pdf, pdf);
}
}
void sky_radiance(inout Surfel surfel)
{
vec3 L = cameraVec(surfel.position);
vec3 N = surfel.normal;
float NL = dot(N, L);
/* TODO(fclem): Sky cubemap sampling. */
vec3 Li = vec3(0.0);
/* Assume white albedo. */
// float pdf = M_1_PI;
float pdf = abs(NL);
vec3 radiance = Li;
if (NL > 0.0) {
surfel.radiance_bounce_front += vec4(radiance * pdf, pdf);
}
else {
surfel.radiance_bounce_back += vec4(radiance * pdf, pdf);
}
}
void main()
{
int surfel_index = int(gl_GlobalInvocationID);
if (surfel_index >= capture_info_buf.surfel_len) {
return;
}
Surfel surfel = surfel_buf[surfel_index];
vec4 radiance_with_pdf = vec4(0.0);
if (surfel.next > -1) {
radiance_transfer(surfel_buf[surfel.next], surfel);
}
else {
sky_radiance(surfel);
}
if (surfel.prev > -1) {
radiance_transfer(surfel_buf[surfel.prev], surfel);
}
else {
sky_radiance(surfel);
}
surfel_buf[surfel_index].radiance_bounce_front = surfel.radiance_bounce_front;
surfel_buf[surfel_index].radiance_bounce_back = surfel.radiance_bounce_back;
}

View File

@ -48,3 +48,11 @@ GPU_SHADER_CREATE_INFO(eevee_surfel_list_sort)
.storage_buf(6, Qualifier::READ, "SurfelListInfoData", "list_info_buf")
.compute_source("eevee_surfel_list_sort_comp.glsl")
.do_static_compilation(true);
GPU_SHADER_CREATE_INFO(eevee_surfel_ray)
.local_group_size(SURFEL_GROUP_SIZE)
.additional_info("eevee_shared", "draw_view")
.storage_buf(SURFEL_BUF_SLOT, Qualifier::READ_WRITE, "Surfel", "surfel_buf[]")
.storage_buf(CAPTURE_BUF_SLOT, Qualifier::READ, "CaptureInfoData", "capture_info_buf")
.compute_source("eevee_surfel_ray_comp.glsl")
.do_static_compilation(true);