WIP: eevee-next-world-irradiance #108304
|
@ -1747,6 +1747,7 @@ constexpr IDTypeInfo get_type_info()
|
||||||
IDTypeInfo IDType_ID_SCE = 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 = "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 = "BLENDER_WORKBENCH";
|
||||||
const char *RE_engine_id_BLENDER_WORKBENCH_NEXT = "BLENDER_WORKBENCH_NEXT";
|
const char *RE_engine_id_BLENDER_WORKBENCH_NEXT = "BLENDER_WORKBENCH_NEXT";
|
||||||
const char *RE_engine_id_CYCLES = "CYCLES";
|
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)
|
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)
|
bool BKE_scene_uses_blender_workbench(const Scene *scene)
|
||||||
|
|
|
@ -146,6 +146,7 @@ set(SRC
|
||||||
engines/eevee_next/eevee_instance.cc
|
engines/eevee_next/eevee_instance.cc
|
||||||
engines/eevee_next/eevee_irradiance_cache.cc
|
engines/eevee_next/eevee_irradiance_cache.cc
|
||||||
engines/eevee_next/eevee_light.cc
|
engines/eevee_next/eevee_light.cc
|
||||||
|
engines/eevee_next/eevee_lightprobe.cc
|
||||||
engines/eevee_next/eevee_lightcache.cc
|
engines/eevee_next/eevee_lightcache.cc
|
||||||
engines/eevee_next/eevee_material.cc
|
engines/eevee_next/eevee_material.cc
|
||||||
engines/eevee_next/eevee_motion_blur.cc
|
engines/eevee_next/eevee_motion_blur.cc
|
||||||
|
|
|
@ -107,6 +107,7 @@ void Instance::begin_sync()
|
||||||
shadows.begin_sync();
|
shadows.begin_sync();
|
||||||
pipelines.begin_sync();
|
pipelines.begin_sync();
|
||||||
cryptomatte.begin_sync();
|
cryptomatte.begin_sync();
|
||||||
|
light_probes.begin_sync();
|
||||||
|
|
||||||
gpencil_engine_enabled = false;
|
gpencil_engine_enabled = false;
|
||||||
|
|
||||||
|
@ -138,7 +139,8 @@ void Instance::scene_sync()
|
||||||
|
|
||||||
void Instance::object_sync(Object *ob)
|
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 int ob_visibility = DRW_object_visibility_in_active_context(ob);
|
||||||
const bool partsys_is_visible = (ob_visibility & OB_VISIBLE_PARTICLES) != 0 &&
|
const bool partsys_is_visible = (ob_visibility & OB_VISIBLE_PARTICLES) != 0 &&
|
||||||
(ob->type == OB_MESH);
|
(ob->type == OB_MESH);
|
||||||
|
@ -179,6 +181,9 @@ void Instance::object_sync(Object *ob)
|
||||||
case OB_GPENCIL_LEGACY:
|
case OB_GPENCIL_LEGACY:
|
||||||
sync.sync_gpencil(ob, ob_handle, res_handle);
|
sync.sync_gpencil(ob, ob_handle, res_handle);
|
||||||
break;
|
break;
|
||||||
|
case OB_LIGHTPROBE:
|
||||||
|
light_probes.sync_probe(ob, ob_handle);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -207,6 +212,7 @@ void Instance::end_sync()
|
||||||
film.end_sync();
|
film.end_sync();
|
||||||
cryptomatte.end_sync();
|
cryptomatte.end_sync();
|
||||||
pipelines.end_sync();
|
pipelines.end_sync();
|
||||||
|
light_probes.end_sync();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Instance::render_sync()
|
void Instance::render_sync()
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include "eevee_hizbuffer.hh"
|
#include "eevee_hizbuffer.hh"
|
||||||
#include "eevee_irradiance_cache.hh"
|
#include "eevee_irradiance_cache.hh"
|
||||||
#include "eevee_light.hh"
|
#include "eevee_light.hh"
|
||||||
|
#include "eevee_lightprobe.hh"
|
||||||
#include "eevee_material.hh"
|
#include "eevee_material.hh"
|
||||||
#include "eevee_motion_blur.hh"
|
#include "eevee_motion_blur.hh"
|
||||||
#include "eevee_pipeline.hh"
|
#include "eevee_pipeline.hh"
|
||||||
|
@ -63,6 +64,7 @@ class Instance {
|
||||||
RenderBuffers render_buffers;
|
RenderBuffers render_buffers;
|
||||||
MainView main_view;
|
MainView main_view;
|
||||||
World world;
|
World world;
|
||||||
|
LightProbeModule light_probes;
|
||||||
IrradianceCache irradiance_cache;
|
IrradianceCache irradiance_cache;
|
||||||
|
|
||||||
/** Input data. */
|
/** Input data. */
|
||||||
|
@ -108,6 +110,7 @@ class Instance {
|
||||||
render_buffers(*this),
|
render_buffers(*this),
|
||||||
main_view(*this),
|
main_view(*this),
|
||||||
world(*this),
|
world(*this),
|
||||||
|
light_probes(*this),
|
||||||
irradiance_cache(*this){};
|
irradiance_cache(*this){};
|
||||||
~Instance(){};
|
~Instance(){};
|
||||||
|
|
||||||
|
|
|
@ -29,9 +29,6 @@ class IrradianceCache {
|
||||||
Framebuffer empty_raster_fb_ = {"empty_raster_fb_"};
|
Framebuffer empty_raster_fb_ = {"empty_raster_fb_"};
|
||||||
View view_ = {"ortho_raster_view"};
|
View view_ = {"ortho_raster_view"};
|
||||||
|
|
||||||
/* TODO: Remove this. */
|
|
||||||
void generate_random_surfels();
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
IrradianceCache(Instance &inst) : inst_(inst){};
|
IrradianceCache(Instance &inst) : inst_(inst){};
|
||||||
~IrradianceCache(){};
|
~IrradianceCache(){};
|
||||||
|
|
|
@ -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
|
|
@ -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
|
Loading…
Reference in New Issue