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.
7 changed files with 184 additions and 5 deletions
Showing only changes of commit dddfcd6f7a - Show all commits

View File

@ -1747,6 +1747,7 @@ constexpr IDTypeInfo get_type_info()
IDTypeInfo IDType_ID_SCE = get_type_info();
const char *RE_engine_id_BLENDER_EEVEE = "BLENDER_EEVEE";
const char *RE_engine_id_BLENDER_EEVEE_NEXT = "BLENDER_EEVEE_NEXT";
const char *RE_engine_id_BLENDER_WORKBENCH = "BLENDER_WORKBENCH";
const char *RE_engine_id_BLENDER_WORKBENCH_NEXT = "BLENDER_WORKBENCH_NEXT";
const char *RE_engine_id_CYCLES = "CYCLES";
@ -2935,7 +2936,8 @@ bool BKE_scene_use_spherical_stereo(Scene *scene)
bool BKE_scene_uses_blender_eevee(const Scene *scene)
{
return STREQ(scene->r.engine, RE_engine_id_BLENDER_EEVEE);
return STREQ(scene->r.engine, RE_engine_id_BLENDER_EEVEE) ||
STREQ(scene->r.engine, RE_engine_id_BLENDER_EEVEE_NEXT);
}
bool BKE_scene_uses_blender_workbench(const Scene *scene)

View File

@ -146,6 +146,7 @@ set(SRC
engines/eevee_next/eevee_instance.cc
engines/eevee_next/eevee_irradiance_cache.cc
engines/eevee_next/eevee_light.cc
engines/eevee_next/eevee_lightprobe.cc
engines/eevee_next/eevee_lightcache.cc
engines/eevee_next/eevee_material.cc
engines/eevee_next/eevee_motion_blur.cc

View File

@ -107,6 +107,7 @@ void Instance::begin_sync()
shadows.begin_sync();
pipelines.begin_sync();
cryptomatte.begin_sync();
light_probes.begin_sync();
gpencil_engine_enabled = false;
@ -138,7 +139,8 @@ void Instance::scene_sync()
void Instance::object_sync(Object *ob)
{
const bool is_renderable_type = ELEM(ob->type, OB_CURVES, OB_GPENCIL_LEGACY, OB_MESH, OB_LAMP);
const bool is_renderable_type = ELEM(
ob->type, OB_CURVES, OB_GPENCIL_LEGACY, OB_MESH, OB_LAMP, OB_LIGHTPROBE);
const int ob_visibility = DRW_object_visibility_in_active_context(ob);
const bool partsys_is_visible = (ob_visibility & OB_VISIBLE_PARTICLES) != 0 &&
(ob->type == OB_MESH);
@ -179,6 +181,9 @@ void Instance::object_sync(Object *ob)
case OB_GPENCIL_LEGACY:
sync.sync_gpencil(ob, ob_handle, res_handle);
break;
case OB_LIGHTPROBE:
light_probes.sync_probe(ob, ob_handle);
break;
default:
break;
}
@ -207,6 +212,7 @@ void Instance::end_sync()
film.end_sync();
cryptomatte.end_sync();
pipelines.end_sync();
light_probes.end_sync();
}
void Instance::render_sync()

View File

@ -23,6 +23,7 @@
#include "eevee_hizbuffer.hh"
#include "eevee_irradiance_cache.hh"
#include "eevee_light.hh"
#include "eevee_lightprobe.hh"
#include "eevee_material.hh"
#include "eevee_motion_blur.hh"
#include "eevee_pipeline.hh"
@ -63,6 +64,7 @@ class Instance {
RenderBuffers render_buffers;
MainView main_view;
World world;
LightProbeModule light_probes;
IrradianceCache irradiance_cache;
/** Input data. */
@ -108,6 +110,7 @@ class Instance {
render_buffers(*this),
main_view(*this),
world(*this),
light_probes(*this),
irradiance_cache(*this){};
~Instance(){};

View File

@ -29,9 +29,6 @@ class IrradianceCache {
Framebuffer empty_raster_fb_ = {"empty_raster_fb_"};
View view_ = {"ortho_raster_view"};
/* TODO: Remove this. */
void generate_random_surfels();
public:
IrradianceCache(Instance &inst) : inst_(inst){};
~IrradianceCache(){};

View File

@ -0,0 +1,118 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup eevee
*
* Module that handles light probe update tagging.
* Lighting data is contained in their respective module `IrradianceCache` and `ReflectionProbes`.
*/
#include "DNA_lightprobe_types.h"
#include "WM_api.h"
#include "eevee_instance.hh"
#include "eevee_lightprobe.hh"
namespace blender::eevee {
void LightProbeModule::begin_sync()
{
auto_bake_enabled_ = inst_.is_viewport() &&
(inst_.scene->eevee.flag & SCE_EEVEE_GI_AUTOBAKE) != 0;
grid_update_ = false;
cube_update_ = false;
}
void LightProbeModule::sync_grid(ObjectHandle &handle)
{
LightProbe &grid = grid_map_.lookup_or_add_default(handle.object_key);
grid.used = true;
if (handle.recalc != 0 || grid.initialized == false) {
grid.initialized = true;
grid_update_ = true;
}
}
void LightProbeModule::sync_cube(ObjectHandle &handle)
{
LightProbe &cube = cube_map_.lookup_or_add_default(handle.object_key);
cube.used = true;
if (handle.recalc != 0 || cube.initialized == false) {
cube.initialized = true;
cube_update_ = true;
}
}
void LightProbeModule::sync_probe(const Object *ob, ObjectHandle &handle)
{
const ::LightProbe *light_probe = (const ::LightProbe *)ob->data;
switch (light_probe->type) {
case LIGHTPROBE_TYPE_CUBE:
sync_cube(handle);
return;
case LIGHTPROBE_TYPE_PLANAR:
/* TODO(fclem): Remove support? Add support? */
return;
case LIGHTPROBE_TYPE_GRID:
sync_grid(handle);
return;
}
BLI_assert_unreachable();
}
void LightProbeModule::end_sync()
{
{
/* Check for deleted grid. */
auto it_end = grid_map_.items().end();
for (auto it = grid_map_.items().begin(); it != it_end; ++it) {
LightProbe &grid = (*it).value;
if (!grid.used) {
grid_map_.remove(it);
grid_update_ = true;
continue;
}
/* Untag for next sync. */
grid.used = false;
}
}
{
/* Check for deleted cube. */
auto it_end = cube_map_.items().end();
for (auto it = cube_map_.items().begin(); it != it_end; ++it) {
LightProbe &cube = (*it).value;
if (!cube.used) {
cube_map_.remove(it);
cube_update_ = true;
continue;
}
/* Untag for next sync. */
cube.used = false;
}
}
/* If light-cache auto-update is enable we tag the relevant part
* of the cache to update and fire up a baking job. */
if (auto_bake_enabled_ && (grid_update_ || cube_update_)) {
Scene *original_scene = DEG_get_input_scene(inst_.depsgraph);
LightCache *light_cache = original_scene->eevee.light_cache_data;
if (light_cache != nullptr) {
if (grid_update_) {
light_cache->flag |= LIGHTCACHE_UPDATE_GRID;
}
/* TODO(fclem): Reflection Cubemap should capture albedo + normal and be
* relit at runtime. So no dependency like in the old system. */
if (cube_update_) {
light_cache->flag |= LIGHTCACHE_UPDATE_CUBE;
}
/* Tag the lightcache to auto update. */
light_cache->flag |= LIGHTCACHE_UPDATE_AUTO;
/* Use a notifier to trigger the operator after drawing. */
/* TODO(fclem): Avoid usage of global DRW. */
WM_event_add_notifier(DRW_context_state_get()->evil_C, NC_LIGHTPROBE, original_scene);
}
}
}
} // namespace blender::eevee

View File

@ -0,0 +1,52 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup eevee
*
* Module that handles light probe update tagging.
* Lighting data is contained in their respective module `IrradianceCache` and `ReflectionProbes`.
*/
#pragma once
#include "BLI_map.hh"
#include "eevee_sync.hh"
namespace blender::eevee {
class Instance;
struct LightProbe {
bool used = false;
bool initialized = false;
};
class LightProbeModule {
private:
Instance &inst_;
/** Light Probe map to detect deletion. */
Map<ObjectKey, LightProbe> grid_map_, cube_map_;
/** True if a grid update was detected. It will trigger a bake if auto bake is enabled. */
bool grid_update_;
/** True if a grid update was detected. It will trigger a bake if auto bake is enabled. */
bool cube_update_;
/** True if the auto bake feature is enabled & available in this context. */
bool auto_bake_enabled_;
public:
LightProbeModule(Instance &inst) : inst_(inst){};
~LightProbeModule(){};
void begin_sync();
void sync_cube(ObjectHandle &handle);
void sync_grid(ObjectHandle &handle);
void sync_probe(const Object *ob, ObjectHandle &handle);
void end_sync();
};
} // namespace blender::eevee