WIP: eevee-next-world-irradiance #108304
|
@ -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
|
||||
|
||||
|
|
|
@ -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_);
|
||||
}
|
||||
}
|
||||
{
|
||||
|
|
|
@ -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 "";
|
||||
|
|
|
@ -83,6 +83,7 @@ enum eShaderType {
|
|||
SURFEL_LIGHT,
|
||||
SURFEL_LIST_BUILD,
|
||||
SURFEL_LIST_SORT,
|
||||
SURFEL_RAY,
|
||||
|
||||
MAX_SHADER_TYPE,
|
||||
};
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue