WIP: eevee-next-world-irradiance #108304
|
@ -596,6 +596,7 @@ class RENDER_PT_eevee_next_indirect_lighting(RenderButtonsPanel, Panel):
|
|||
col.label(text=cache_info)
|
||||
|
||||
col.prop(props, "gi_auto_bake")
|
||||
col.prop(props, "gi_diffuse_bounces")
|
||||
col.prop(props, "gi_irradiance_samples")
|
||||
|
||||
|
||||
|
|
|
@ -499,6 +499,7 @@ set(GLSL_SRC
|
|||
engines/eevee_next/shaders/eevee_surf_lib.glsl
|
||||
engines/eevee_next/shaders/eevee_surf_shadow_frag.glsl
|
||||
engines/eevee_next/shaders/eevee_surf_world_frag.glsl
|
||||
engines/eevee_next/shaders/eevee_surfel_bounce_comp.glsl
|
||||
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
|
||||
|
|
|
@ -535,19 +535,20 @@ void Instance::light_bake_irradiance(LightCache *&r_light_cache,
|
|||
return;
|
||||
}
|
||||
|
||||
/* TODO(fclem): Multiple bounce. We need to use the previous bounce result. */
|
||||
for (int bounce = 0; bounce < 1; bounce++) {
|
||||
for (auto i : light_probes.grids.index_range()) {
|
||||
custom_pipeline_wrapper([&]() {
|
||||
/* TODO: lightprobe visibility group option. */
|
||||
manager->begin_sync();
|
||||
render_sync();
|
||||
manager->end_sync();
|
||||
irradiance_cache.bake.surfels_create(light_probes.grids[i]);
|
||||
irradiance_cache.bake.surfels_lights_eval();
|
||||
});
|
||||
for (auto i : light_probes.grids.index_range()) {
|
||||
custom_pipeline_wrapper([&]() {
|
||||
/* TODO: lightprobe visibility group option. */
|
||||
manager->begin_sync();
|
||||
render_sync();
|
||||
manager->end_sync();
|
||||
irradiance_cache.bake.surfels_create(light_probes.grids[i]);
|
||||
irradiance_cache.bake.surfels_lights_eval();
|
||||
});
|
||||
|
||||
sampling.reset();
|
||||
int bounce_len = scene->eevee.gi_diffuse_bounces;
|
||||
/* Start at bounce 1 as 0 bounce is no indirect lighting. */
|
||||
for (int bounce = 1; bounce <= bounce_len; bounce++) {
|
||||
sampling.init(scene);
|
||||
while (!sampling.finished()) {
|
||||
context_wrapper([&]() {
|
||||
/* Batch ray cast by pack of 16 to avoid too much overhead of
|
||||
|
@ -556,11 +557,19 @@ void Instance::light_bake_irradiance(LightCache *&r_light_cache,
|
|||
sampling.step();
|
||||
irradiance_cache.bake.propagate_light_sample();
|
||||
}
|
||||
if (sampling.finished()) {
|
||||
irradiance_cache.bake.accumulate_bounce();
|
||||
}
|
||||
irradiance_cache.bake.read_result(r_light_cache->grids[i]);
|
||||
});
|
||||
// do_update = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (bounce_len == 0) {
|
||||
/* Still read result for debugging surfel direct lighting. */
|
||||
context_wrapper([&]() { irradiance_cache.bake.read_result(r_light_cache->grids[i]); });
|
||||
}
|
||||
}
|
||||
|
||||
r_light_cache->flag &= ~LIGHTCACHE_BAKING;
|
||||
|
|
|
@ -124,6 +124,7 @@ void IrradianceBake::sync()
|
|||
PassSimple::Sub &sub = pass.sub("ListSort");
|
||||
sub.shader_set(inst_.shaders.static_shader_get(SURFEL_LIST_SORT));
|
||||
sub.bind_ssbo(SURFEL_BUF_SLOT, &surfels_buf_);
|
||||
sub.bind_ssbo(CAPTURE_BUF_SLOT, &capture_info_buf_);
|
||||
sub.bind_ssbo("list_start_buf", &list_start_buf_);
|
||||
sub.bind_ssbo("list_info_buf", &list_info_buf_);
|
||||
sub.barrier(GPU_BARRIER_SHADER_STORAGE);
|
||||
|
@ -143,6 +144,15 @@ void IrradianceBake::sync()
|
|||
pass.init();
|
||||
/* TODO */
|
||||
}
|
||||
{
|
||||
PassSimple &pass = surfel_light_bounce_ps_;
|
||||
pass.init();
|
||||
pass.shader_set(inst_.shaders.static_shader_get(SURFEL_BOUNCE));
|
||||
pass.bind_ssbo(SURFEL_BUF_SLOT, &surfels_buf_);
|
||||
pass.bind_ssbo(CAPTURE_BUF_SLOT, &capture_info_buf_);
|
||||
pass.barrier(GPU_BARRIER_SHADER_STORAGE);
|
||||
pass.dispatch(&dispatch_per_surfel_);
|
||||
}
|
||||
}
|
||||
|
||||
void IrradianceBake::surfels_create(const IrradianceGrid &grid)
|
||||
|
@ -304,6 +314,11 @@ void IrradianceBake::propagate_light_sample()
|
|||
inst_.manager->submit(surfel_light_propagate_ps_, ray_view);
|
||||
}
|
||||
|
||||
void IrradianceBake::accumulate_bounce()
|
||||
{
|
||||
inst_.manager->submit(surfel_light_bounce_ps_);
|
||||
}
|
||||
|
||||
void IrradianceBake::read_result(LightCacheIrradianceGrid &light_cache_grid)
|
||||
{
|
||||
switch (inst_.debug_mode) {
|
||||
|
|
|
@ -39,6 +39,8 @@ class IrradianceBake {
|
|||
PassSimple surfel_light_eval_ps_ = {"LightEval"};
|
||||
/** Propagate light from surfel to surfel. */
|
||||
PassSimple surfel_light_propagate_ps_ = {"LightPropagate"};
|
||||
/** Start of a light bounce. Accumulate light from previous propagation. */
|
||||
PassSimple surfel_light_bounce_ps_ = {"LightBounce"};
|
||||
/** Capture surfel lighting to irradiance samples. */
|
||||
PassSimple irradiance_capture_ps_ = {"IrradianceCapture"};
|
||||
|
||||
|
@ -85,6 +87,8 @@ class IrradianceBake {
|
|||
void surfels_lights_eval();
|
||||
/** Propagate light from surfel to surfel in a random direction over the sphere. */
|
||||
void propagate_light_sample();
|
||||
/** Accumulate light inside `surfel.radiance_bounce` to `surfel.radiance`. */
|
||||
void accumulate_bounce();
|
||||
|
||||
/** Read grid final irradiance back to CPU into \a light_cache_grid . */
|
||||
void read_result(LightCacheIrradianceGrid &light_cache_grid);
|
||||
|
|
|
@ -26,6 +26,7 @@ void Sampling::init(const Scene *scene)
|
|||
{
|
||||
if (inst_.is_baking()) {
|
||||
sample_count_ = max_ii(1, scene->eevee.gi_irradiance_samples);
|
||||
sample_ = 0;
|
||||
}
|
||||
else {
|
||||
sample_count_ = inst_.is_viewport() ? scene->eevee.taa_samples :
|
||||
|
|
|
@ -172,6 +172,8 @@ const char *ShaderModule::static_shader_create_info_name_get(eShaderType shader_
|
|||
return "eevee_shadow_tag_usage_opaque";
|
||||
case SHADOW_TILEMAP_TAG_USAGE_TRANSPARENT:
|
||||
return "eevee_shadow_tag_usage_transparent";
|
||||
case SURFEL_BOUNCE:
|
||||
return "eevee_surfel_bounce";
|
||||
case SURFEL_LIGHT:
|
||||
return "eevee_surfel_light";
|
||||
case SURFEL_LIST_BUILD:
|
||||
|
|
|
@ -80,6 +80,7 @@ enum eShaderType {
|
|||
SHADOW_TILEMAP_TAG_USAGE_OPAQUE,
|
||||
SHADOW_TILEMAP_TAG_USAGE_TRANSPARENT,
|
||||
|
||||
SURFEL_BOUNCE,
|
||||
SURFEL_LIGHT,
|
||||
SURFEL_LIST_BUILD,
|
||||
SURFEL_LIST_SORT,
|
||||
|
|
|
@ -3,8 +3,6 @@ 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)) {
|
||||
|
@ -13,9 +11,7 @@ void main()
|
|||
out_color = vec4(pow(surfel.normal * 0.5 + 0.5, vec3(2.2)), 0.0);
|
||||
break;
|
||||
case DEBUG_IRRADIANCE_CACHE_SURFELS_IRRADIANCE:
|
||||
out_color = (radiance_bounce.w > 0.0) ?
|
||||
vec4(radiance + radiance_bounce.rgb / radiance_bounce.w, 0.0) :
|
||||
vec4(radiance, 0.0);
|
||||
out_color = vec4(radiance, 0.0);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
|
||||
/**
|
||||
* Accumulate light from a bounce of indirect light into each surfel radiance.
|
||||
* This feeds back the light for the next bounce.
|
||||
*/
|
||||
|
||||
#pragma BLENDER_REQUIRE(common_math_lib.glsl)
|
||||
|
||||
void main()
|
||||
{
|
||||
int surfel_index = int(gl_GlobalInvocationID);
|
||||
if (surfel_index >= capture_info_buf.surfel_len) {
|
||||
return;
|
||||
}
|
||||
|
||||
vec4 radiance_bounce_front = surfel_buf[surfel_index].radiance_bounce_front;
|
||||
vec4 radiance_bounce_back = surfel_buf[surfel_index].radiance_bounce_back;
|
||||
surfel_buf[surfel_index].radiance_front += radiance_bounce_front.rgb *
|
||||
safe_rcp(radiance_bounce_front.w);
|
||||
surfel_buf[surfel_index].radiance_back += radiance_bounce_back.rgb *
|
||||
safe_rcp(radiance_bounce_back.w);
|
||||
surfel_buf[surfel_index].radiance_bounce_front = vec4(0.0);
|
||||
surfel_buf[surfel_index].radiance_bounce_back = vec4(0.0);
|
||||
}
|
|
@ -20,13 +20,13 @@
|
|||
*/
|
||||
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);
|
||||
bool facing = dot(-L, surfel_a.normal) > 0.0;
|
||||
vec3 irradiance = facing ? surfel_a.radiance_front : surfel_a.radiance_back;
|
||||
irradiance *= M_1_PI;
|
||||
|
||||
if (NL > 0.0) {
|
||||
surfel_b.radiance_bounce_front += vec4(surfel_b.albedo_front * irradiance * pdf, pdf);
|
||||
|
|
|
@ -18,41 +18,45 @@ GPU_SHADER_CREATE_INFO(eevee_debug_surfels)
|
|||
.push_constant(Type::INT, "debug_mode")
|
||||
.do_static_compilation(true);
|
||||
|
||||
GPU_SHADER_CREATE_INFO(eevee_surfel_common)
|
||||
.storage_buf(SURFEL_BUF_SLOT, Qualifier::READ_WRITE, "Surfel", "surfel_buf[]")
|
||||
.storage_buf(CAPTURE_BUF_SLOT, Qualifier::READ, "CaptureInfoData", "capture_info_buf");
|
||||
|
||||
GPU_SHADER_CREATE_INFO(eevee_surfel_light)
|
||||
.local_group_size(SURFEL_GROUP_SIZE)
|
||||
.additional_info("eevee_shared",
|
||||
"draw_view",
|
||||
"eevee_utility_texture",
|
||||
"eevee_surfel_common",
|
||||
"eevee_light_data",
|
||||
"eevee_shadow_data")
|
||||
.compute_source("eevee_surfel_light_comp.glsl")
|
||||
.storage_buf(SURFEL_BUF_SLOT, Qualifier::READ_WRITE, "Surfel", "surfel_buf[]")
|
||||
.storage_buf(CAPTURE_BUF_SLOT, Qualifier::READ, "CaptureInfoData", "capture_info_buf")
|
||||
.do_static_compilation(true);
|
||||
|
||||
GPU_SHADER_CREATE_INFO(eevee_surfel_bounce)
|
||||
.local_group_size(SURFEL_GROUP_SIZE)
|
||||
.additional_info("eevee_shared", "eevee_surfel_common")
|
||||
.compute_source("eevee_surfel_bounce_comp.glsl")
|
||||
.do_static_compilation(true);
|
||||
|
||||
GPU_SHADER_CREATE_INFO(eevee_surfel_list_build)
|
||||
.local_group_size(SURFEL_GROUP_SIZE)
|
||||
.additional_info("eevee_shared", "draw_view")
|
||||
.additional_info("eevee_shared", "eevee_surfel_common", "draw_view")
|
||||
.storage_buf(0, Qualifier::READ_WRITE, "int", "list_start_buf[]")
|
||||
.storage_buf(SURFEL_BUF_SLOT, Qualifier::READ_WRITE, "Surfel", "surfel_buf[]")
|
||||
.storage_buf(CAPTURE_BUF_SLOT, Qualifier::READ, "CaptureInfoData", "capture_info_buf")
|
||||
.storage_buf(6, Qualifier::READ_WRITE, "SurfelListInfoData", "list_info_buf")
|
||||
.compute_source("eevee_surfel_list_build_comp.glsl")
|
||||
.do_static_compilation(true);
|
||||
|
||||
GPU_SHADER_CREATE_INFO(eevee_surfel_list_sort)
|
||||
.local_group_size(SURFEL_LIST_GROUP_SIZE)
|
||||
.additional_info("eevee_shared", "draw_view")
|
||||
.additional_info("eevee_shared", "eevee_surfel_common", "draw_view")
|
||||
.storage_buf(0, Qualifier::READ_WRITE, "int", "list_start_buf[]")
|
||||
.storage_buf(SURFEL_BUF_SLOT, Qualifier::READ_WRITE, "Surfel", "surfel_buf[]")
|
||||
.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")
|
||||
.additional_info("eevee_shared", "eevee_surfel_common", "draw_view")
|
||||
.compute_source("eevee_surfel_ray_comp.glsl")
|
||||
.do_static_compilation(true);
|
||||
|
|
Loading…
Reference in New Issue