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.
9 changed files with 97 additions and 7 deletions
Showing only changes of commit ff5db3a72e - Show all commits

View File

@ -487,6 +487,7 @@ set(GLSL_SRC
engines/eevee_next/shaders/eevee_shadow_tag_usage_comp.glsl
engines/eevee_next/shaders/eevee_shadow_tag_usage_frag.glsl
engines/eevee_next/shaders/eevee_shadow_tag_usage_lib.glsl
engines/eevee_next/shaders/eevee_shadow_tag_usage_surfels_comp.glsl
engines/eevee_next/shaders/eevee_shadow_tag_usage_vert.glsl
engines/eevee_next/shaders/eevee_shadow_test.glsl
engines/eevee_next/shaders/eevee_shadow_tilemap_bounds_comp.glsl

View File

@ -171,6 +171,8 @@ void IrradianceBake::sync()
inst_.shadows.bind_resources(&pass);
/* Sync with the surfel creation stage. */
pass.barrier(GPU_BARRIER_SHADER_STORAGE);
pass.barrier(GPU_BARRIER_SHADER_IMAGE_ACCESS);
pass.barrier(GPU_BARRIER_TEXTURE_FETCH);
pass.dispatch(&dispatch_per_surfel_);
}
{

View File

@ -29,8 +29,6 @@ class IrradianceBake {
/** Light cache being baked. */
LightCache *light_cache_ = nullptr;
/** Surface elements that represent the scene. */
SurfelBuf surfels_buf_;
/** Capture state. */
CaptureInfoBuf capture_info_buf_;
/** Framebuffer. */
@ -77,8 +75,6 @@ class IrradianceBake {
Texture irradiance_L0_L1_b_tx_ = {"irradiance_L0_L1_b_tx_"};
Texture irradiance_L0_L1_c_tx_ = {"irradiance_L0_L1_c_tx_"};
/* Surfel per unit distance. */
float surfel_density_ = 2.0f;
/* Orientation of the irradiance grid being baked. */
math::Quaternion grid_orientation_;
/* Object center of the irradiance grid being baked. */
@ -87,6 +83,11 @@ class IrradianceBake {
Vector<float3> grid_bbox_vertices;
public:
/** Surface elements that represent the scene. */
SurfelBuf surfels_buf_;
/* Surfel per unit distance. */
float surfel_density_ = 2.0f;
IrradianceBake(Instance &inst) : inst_(inst){};
void sync();

View File

@ -174,6 +174,8 @@ const char *ShaderModule::static_shader_create_info_name_get(eShaderType shader_
return "eevee_shadow_tag_update";
case SHADOW_TILEMAP_TAG_USAGE_OPAQUE:
return "eevee_shadow_tag_usage_opaque";
case SHADOW_TILEMAP_TAG_USAGE_SURFELS:
return "eevee_shadow_tag_usage_surfels";
case SHADOW_TILEMAP_TAG_USAGE_TRANSPARENT:
return "eevee_shadow_tag_usage_transparent";
case SURFEL_BOUNCE:

View File

@ -82,6 +82,7 @@ enum eShaderType {
SHADOW_TILEMAP_INIT,
SHADOW_TILEMAP_TAG_UPDATE,
SHADOW_TILEMAP_TAG_USAGE_OPAQUE,
SHADOW_TILEMAP_TAG_USAGE_SURFELS,
SHADOW_TILEMAP_TAG_USAGE_TRANSPARENT,
SURFEL_BOUNCE,

View File

@ -706,6 +706,29 @@ void ShadowModule::begin_sync()
PassMain &pass = tilemap_usage_ps_;
pass.init();
if (inst_.is_baking()) {
SurfelBuf &surfels_buf = inst_.irradiance_cache.bake.surfels_buf_;
float surfel_coverage_area = inst_.irradiance_cache.bake.surfel_density_;
/* Directional shadows. */
float texel_size = ShadowDirectional::tile_size_get(0) / float(SHADOW_PAGE_RES);
int directional_level = std::max(0, int(std::ceil(log2(surfel_coverage_area / texel_size))));
/* Punctual shadows. */
float projection_ratio = tilemap_pixel_radius() / (surfel_coverage_area / 2.0);
PassMain::Sub &sub = pass.sub("Surfels");
sub.shader_set(inst_.shaders.static_shader_get(SHADOW_TILEMAP_TAG_USAGE_SURFELS));
sub.bind_ssbo("tilemaps_buf", &tilemap_pool.tilemaps_data);
sub.bind_ssbo("tiles_buf", &tilemap_pool.tiles_data);
sub.bind_ssbo("surfels_buf", &surfels_buf);
sub.push_constant("directional_level", directional_level);
sub.push_constant("tilemap_projection_ratio", projection_ratio);
inst_.lights.bind_resources(&sub);
sub.dispatch(int3(surfels_buf.size(), 1, 1));
return; /* Skip opaque and transparent tagging for light baking. */
}
{
/** Use depth buffer to tag needed shadow pages for opaque geometry. */
PassMain::Sub &sub = pass.sub("Opaque");
@ -766,7 +789,7 @@ void ShadowModule::sync_object(const ObjectHandle &handle,
curr_casters_.append(resource_handle.raw);
}
if (is_alpha_blend) {
if (is_alpha_blend && !inst_.is_baking()) {
tilemap_usage_transparent_ps_->draw(box_batch_, resource_handle);
}
}

View File

@ -24,6 +24,22 @@ void shadow_tag_usage_tile(LightData light, ivec2 tile_co, int lod, int tilemap_
atomicOr(tiles_buf[tile_index], SHADOW_IS_USED);
}
void shadow_tag_usage_tilemap_directional_at_level(uint l_idx, vec3 P, int level)
{
LightData light = light_buf[l_idx];
if (light.tilemap_index == LIGHT_NO_SHADOW) {
return;
}
vec3 lP = shadow_world_to_local(light, P);
level = clamp(level, light.clipmap_lod_min, light.clipmap_lod_max);
ShadowCoordinates coord = shadow_directional_coordinates_at_level(light, lP, level);
shadow_tag_usage_tile(light, coord.tile_coord, 0, coord.tilemap_index);
}
void shadow_tag_usage_tilemap_directional(uint l_idx, vec3 P, vec3 V, float radius)
{
LightData light = light_buf[l_idx];
@ -59,7 +75,7 @@ void shadow_tag_usage_tilemap_directional(uint l_idx, vec3 P, vec3 V, float radi
}
}
void shadow_tag_usage_tilemap_punctual(uint l_idx, vec3 P, vec3 V, float dist_to_cam, float radius)
void shadow_tag_usage_tilemap_punctual(uint l_idx, vec3 P, float dist_to_cam, float radius)
{
LightData light = light_buf[l_idx];
@ -159,7 +175,7 @@ void shadow_tag_usage(vec3 vP, vec3 P, vec3 V, float radius, float dist_to_cam,
LIGHT_FOREACH_END
LIGHT_FOREACH_BEGIN_LOCAL (light_cull_buf, light_zbin_buf, light_tile_buf, pixel, vP.z, l_idx) {
shadow_tag_usage_tilemap_punctual(l_idx, P, V, dist_to_cam, radius);
shadow_tag_usage_tilemap_punctual(l_idx, P, dist_to_cam, radius);
}
LIGHT_FOREACH_END
}
@ -170,3 +186,20 @@ void shadow_tag_usage(vec3 vP, vec3 P, vec2 pixel)
shadow_tag_usage(vP, P, vec3(0), 0, dist_to_cam, pixel);
}
void shadow_tag_usage_surfel(Surfel surfel, int directional_level)
{
vec3 P = surfel.position;
LIGHT_FOREACH_BEGIN_DIRECTIONAL (light_cull_buf, l_idx) {
shadow_tag_usage_tilemap_directional_at_level(l_idx, P, directional_level);
}
LIGHT_FOREACH_END
LIGHT_FOREACH_BEGIN_LOCAL_NO_CULL(light_cull_buf, l_idx)
{
float dist_to_cam = 1; /* Set it to 1 to avoid changing footprint_ratio. */
shadow_tag_usage_tilemap_punctual(l_idx, P, dist_to_cam, 0);
}
LIGHT_FOREACH_END
}

View File

@ -0,0 +1,16 @@
/**
* Virtual shadowmapping: Usage tagging
*
* Shadow pages are only allocated if they are visible.
* This pass iterates the surfels buffer and tag all tiles that are needed for light shadowing as
* needed.
*/
#pragma BLENDER_REQUIRE(eevee_shadow_tag_usage_lib.glsl)
void main()
{
Surfel surfel = surfels_buf[gl_GlobalInvocationID.x];
shadow_tag_usage_surfel(surfel, directional_level);
}

View File

@ -60,6 +60,17 @@ GPU_SHADER_CREATE_INFO(eevee_shadow_tag_usage_opaque)
.additional_info("eevee_shared", "draw_view", "draw_view_culling", "eevee_light_data")
.compute_source("eevee_shadow_tag_usage_comp.glsl");
GPU_SHADER_CREATE_INFO(eevee_shadow_tag_usage_surfels)
.do_static_compilation(true)
.local_group_size(1, 1, 1)
.storage_buf(5, Qualifier::READ_WRITE, "ShadowTileMapData", "tilemaps_buf[]")
.storage_buf(6, Qualifier::READ_WRITE, "ShadowTileDataPacked", "tiles_buf[]")
.storage_buf(7, Qualifier::READ_WRITE, "Surfel", "surfels_buf[]")
.push_constant(Type::INT, "directional_level")
.push_constant(Type::FLOAT, "tilemap_projection_ratio")
.additional_info("eevee_shared", "draw_view", "draw_view_culling", "eevee_light_data")
.compute_source("eevee_shadow_tag_usage_surfels_comp.glsl");
GPU_SHADER_INTERFACE_INFO(eevee_shadow_tag_transparent_iface, "interp")
.smooth(Type::VEC3, "P")
.smooth(Type::VEC3, "vP")