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.label(text=cache_info)
|
||||||
|
|
||||||
col.prop(props, "gi_auto_bake")
|
col.prop(props, "gi_auto_bake")
|
||||||
|
col.prop(props, "gi_diffuse_bounces")
|
||||||
col.prop(props, "gi_irradiance_samples")
|
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_lib.glsl
|
||||||
engines/eevee_next/shaders/eevee_surf_shadow_frag.glsl
|
engines/eevee_next/shaders/eevee_surf_shadow_frag.glsl
|
||||||
engines/eevee_next/shaders/eevee_surf_world_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_light_comp.glsl
|
||||||
engines/eevee_next/shaders/eevee_surfel_list_build_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_list_sort_comp.glsl
|
||||||
|
|
|
@ -535,8 +535,6 @@ void Instance::light_bake_irradiance(LightCache *&r_light_cache,
|
||||||
return;
|
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()) {
|
for (auto i : light_probes.grids.index_range()) {
|
||||||
custom_pipeline_wrapper([&]() {
|
custom_pipeline_wrapper([&]() {
|
||||||
/* TODO: lightprobe visibility group option. */
|
/* TODO: lightprobe visibility group option. */
|
||||||
|
@ -547,7 +545,10 @@ void Instance::light_bake_irradiance(LightCache *&r_light_cache,
|
||||||
irradiance_cache.bake.surfels_lights_eval();
|
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()) {
|
while (!sampling.finished()) {
|
||||||
context_wrapper([&]() {
|
context_wrapper([&]() {
|
||||||
/* Batch ray cast by pack of 16 to avoid too much overhead of
|
/* 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();
|
sampling.step();
|
||||||
irradiance_cache.bake.propagate_light_sample();
|
irradiance_cache.bake.propagate_light_sample();
|
||||||
}
|
}
|
||||||
|
if (sampling.finished()) {
|
||||||
|
irradiance_cache.bake.accumulate_bounce();
|
||||||
|
}
|
||||||
irradiance_cache.bake.read_result(r_light_cache->grids[i]);
|
irradiance_cache.bake.read_result(r_light_cache->grids[i]);
|
||||||
});
|
});
|
||||||
// do_update = true;
|
// 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;
|
r_light_cache->flag &= ~LIGHTCACHE_BAKING;
|
||||||
|
|
|
@ -124,6 +124,7 @@ void IrradianceBake::sync()
|
||||||
PassSimple::Sub &sub = pass.sub("ListSort");
|
PassSimple::Sub &sub = pass.sub("ListSort");
|
||||||
sub.shader_set(inst_.shaders.static_shader_get(SURFEL_LIST_SORT));
|
sub.shader_set(inst_.shaders.static_shader_get(SURFEL_LIST_SORT));
|
||||||
sub.bind_ssbo(SURFEL_BUF_SLOT, &surfels_buf_);
|
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_start_buf", &list_start_buf_);
|
||||||
sub.bind_ssbo("list_info_buf", &list_info_buf_);
|
sub.bind_ssbo("list_info_buf", &list_info_buf_);
|
||||||
sub.barrier(GPU_BARRIER_SHADER_STORAGE);
|
sub.barrier(GPU_BARRIER_SHADER_STORAGE);
|
||||||
|
@ -143,6 +144,15 @@ void IrradianceBake::sync()
|
||||||
pass.init();
|
pass.init();
|
||||||
/* TODO */
|
/* 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)
|
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);
|
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)
|
void IrradianceBake::read_result(LightCacheIrradianceGrid &light_cache_grid)
|
||||||
{
|
{
|
||||||
switch (inst_.debug_mode) {
|
switch (inst_.debug_mode) {
|
||||||
|
|
|
@ -39,6 +39,8 @@ class IrradianceBake {
|
||||||
PassSimple surfel_light_eval_ps_ = {"LightEval"};
|
PassSimple surfel_light_eval_ps_ = {"LightEval"};
|
||||||
/** Propagate light from surfel to surfel. */
|
/** Propagate light from surfel to surfel. */
|
||||||
PassSimple surfel_light_propagate_ps_ = {"LightPropagate"};
|
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. */
|
/** Capture surfel lighting to irradiance samples. */
|
||||||
PassSimple irradiance_capture_ps_ = {"IrradianceCapture"};
|
PassSimple irradiance_capture_ps_ = {"IrradianceCapture"};
|
||||||
|
|
||||||
|
@ -85,6 +87,8 @@ class IrradianceBake {
|
||||||
void surfels_lights_eval();
|
void surfels_lights_eval();
|
||||||
/** Propagate light from surfel to surfel in a random direction over the sphere. */
|
/** Propagate light from surfel to surfel in a random direction over the sphere. */
|
||||||
void propagate_light_sample();
|
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 . */
|
/** Read grid final irradiance back to CPU into \a light_cache_grid . */
|
||||||
void read_result(LightCacheIrradianceGrid &light_cache_grid);
|
void read_result(LightCacheIrradianceGrid &light_cache_grid);
|
||||||
|
|
|
@ -26,6 +26,7 @@ void Sampling::init(const Scene *scene)
|
||||||
{
|
{
|
||||||
if (inst_.is_baking()) {
|
if (inst_.is_baking()) {
|
||||||
sample_count_ = max_ii(1, scene->eevee.gi_irradiance_samples);
|
sample_count_ = max_ii(1, scene->eevee.gi_irradiance_samples);
|
||||||
|
sample_ = 0;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
sample_count_ = inst_.is_viewport() ? scene->eevee.taa_samples :
|
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";
|
return "eevee_shadow_tag_usage_opaque";
|
||||||
case SHADOW_TILEMAP_TAG_USAGE_TRANSPARENT:
|
case SHADOW_TILEMAP_TAG_USAGE_TRANSPARENT:
|
||||||
return "eevee_shadow_tag_usage_transparent";
|
return "eevee_shadow_tag_usage_transparent";
|
||||||
|
case SURFEL_BOUNCE:
|
||||||
|
return "eevee_surfel_bounce";
|
||||||
case SURFEL_LIGHT:
|
case SURFEL_LIGHT:
|
||||||
return "eevee_surfel_light";
|
return "eevee_surfel_light";
|
||||||
case SURFEL_LIST_BUILD:
|
case SURFEL_LIST_BUILD:
|
||||||
|
|
|
@ -80,6 +80,7 @@ enum eShaderType {
|
||||||
SHADOW_TILEMAP_TAG_USAGE_OPAQUE,
|
SHADOW_TILEMAP_TAG_USAGE_OPAQUE,
|
||||||
SHADOW_TILEMAP_TAG_USAGE_TRANSPARENT,
|
SHADOW_TILEMAP_TAG_USAGE_TRANSPARENT,
|
||||||
|
|
||||||
|
SURFEL_BOUNCE,
|
||||||
SURFEL_LIGHT,
|
SURFEL_LIGHT,
|
||||||
SURFEL_LIST_BUILD,
|
SURFEL_LIST_BUILD,
|
||||||
SURFEL_LIST_SORT,
|
SURFEL_LIST_SORT,
|
||||||
|
|
|
@ -3,8 +3,6 @@ void main()
|
||||||
{
|
{
|
||||||
Surfel surfel = surfels_buf[surfel_index];
|
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;
|
vec3 radiance = gl_FrontFacing ? surfel.radiance_front : surfel.radiance_back;
|
||||||
|
|
||||||
switch (eDebugMode(debug_mode)) {
|
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);
|
out_color = vec4(pow(surfel.normal * 0.5 + 0.5, vec3(2.2)), 0.0);
|
||||||
break;
|
break;
|
||||||
case DEBUG_IRRADIANCE_CACHE_SURFELS_IRRADIANCE:
|
case DEBUG_IRRADIANCE_CACHE_SURFELS_IRRADIANCE:
|
||||||
out_color = (radiance_bounce.w > 0.0) ?
|
out_color = vec4(radiance, 0.0);
|
||||||
vec4(radiance + radiance_bounce.rgb / radiance_bounce.w, 0.0) :
|
|
||||||
vec4(radiance, 0.0);
|
|
||||||
break;
|
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)
|
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 L = normalize(surfel_a.position - surfel_b.position);
|
||||||
vec3 N = surfel_b.normal;
|
vec3 N = surfel_b.normal;
|
||||||
float NL = dot(N, L);
|
float NL = dot(N, L);
|
||||||
float pdf = abs(NL);
|
float pdf = abs(NL);
|
||||||
|
bool facing = dot(-L, surfel_a.normal) > 0.0;
|
||||||
vec3 irradiance = facing ? surfel_a.radiance_front : surfel_a.radiance_back;
|
vec3 irradiance = facing ? surfel_a.radiance_front : surfel_a.radiance_back;
|
||||||
|
irradiance *= M_1_PI;
|
||||||
|
|
||||||
if (NL > 0.0) {
|
if (NL > 0.0) {
|
||||||
surfel_b.radiance_bounce_front += vec4(surfel_b.albedo_front * irradiance * pdf, pdf);
|
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")
|
.push_constant(Type::INT, "debug_mode")
|
||||||
.do_static_compilation(true);
|
.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)
|
GPU_SHADER_CREATE_INFO(eevee_surfel_light)
|
||||||
.local_group_size(SURFEL_GROUP_SIZE)
|
.local_group_size(SURFEL_GROUP_SIZE)
|
||||||
.additional_info("eevee_shared",
|
.additional_info("eevee_shared",
|
||||||
"draw_view",
|
"draw_view",
|
||||||
"eevee_utility_texture",
|
"eevee_utility_texture",
|
||||||
|
"eevee_surfel_common",
|
||||||
"eevee_light_data",
|
"eevee_light_data",
|
||||||
"eevee_shadow_data")
|
"eevee_shadow_data")
|
||||||
.compute_source("eevee_surfel_light_comp.glsl")
|
.compute_source("eevee_surfel_light_comp.glsl")
|
||||||
.storage_buf(SURFEL_BUF_SLOT, Qualifier::READ_WRITE, "Surfel", "surfel_buf[]")
|
.do_static_compilation(true);
|
||||||
.storage_buf(CAPTURE_BUF_SLOT, Qualifier::READ, "CaptureInfoData", "capture_info_buf")
|
|
||||||
|
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);
|
.do_static_compilation(true);
|
||||||
|
|
||||||
GPU_SHADER_CREATE_INFO(eevee_surfel_list_build)
|
GPU_SHADER_CREATE_INFO(eevee_surfel_list_build)
|
||||||
.local_group_size(SURFEL_GROUP_SIZE)
|
.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(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")
|
.storage_buf(6, Qualifier::READ_WRITE, "SurfelListInfoData", "list_info_buf")
|
||||||
.compute_source("eevee_surfel_list_build_comp.glsl")
|
.compute_source("eevee_surfel_list_build_comp.glsl")
|
||||||
.do_static_compilation(true);
|
.do_static_compilation(true);
|
||||||
|
|
||||||
GPU_SHADER_CREATE_INFO(eevee_surfel_list_sort)
|
GPU_SHADER_CREATE_INFO(eevee_surfel_list_sort)
|
||||||
.local_group_size(SURFEL_LIST_GROUP_SIZE)
|
.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(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")
|
.storage_buf(6, Qualifier::READ, "SurfelListInfoData", "list_info_buf")
|
||||||
.compute_source("eevee_surfel_list_sort_comp.glsl")
|
.compute_source("eevee_surfel_list_sort_comp.glsl")
|
||||||
.do_static_compilation(true);
|
.do_static_compilation(true);
|
||||||
|
|
||||||
GPU_SHADER_CREATE_INFO(eevee_surfel_ray)
|
GPU_SHADER_CREATE_INFO(eevee_surfel_ray)
|
||||||
.local_group_size(SURFEL_GROUP_SIZE)
|
.local_group_size(SURFEL_GROUP_SIZE)
|
||||||
.additional_info("eevee_shared", "draw_view")
|
.additional_info("eevee_shared", "eevee_surfel_common", "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")
|
.compute_source("eevee_surfel_ray_comp.glsl")
|
||||||
.do_static_compilation(true);
|
.do_static_compilation(true);
|
||||||
|
|
Loading…
Reference in New Issue