WIP: eevee-next-world-irradiance #108304
|
@ -107,6 +107,7 @@
|
||||||
#include "BLO_read_write.h"
|
#include "BLO_read_write.h"
|
||||||
|
|
||||||
#include "engines/eevee/eevee_lightcache.h"
|
#include "engines/eevee/eevee_lightcache.h"
|
||||||
|
#include "engines/eevee_next/eevee_lightcache.h"
|
||||||
|
|
||||||
#include "PIL_time.h"
|
#include "PIL_time.h"
|
||||||
|
|
||||||
|
@ -1439,7 +1440,11 @@ static void scene_blend_read_data(BlendDataReader *reader, ID *id)
|
||||||
EEVEE_lightcache_blend_read_data(reader, sce->eevee.light_cache_data);
|
EEVEE_lightcache_blend_read_data(reader, sce->eevee.light_cache_data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
EEVEE_lightcache_info_update(&sce->eevee);
|
|
||||||
|
RenderEngineType *engine_type = RE_engines_find(sce->r.engine);
|
||||||
|
bool use_eevee_next = STREQ(engine_type->idname, "BLENDER_EEVEE_NEXT");
|
||||||
|
|
||||||
|
(use_eevee_next ? EEVEE_NEXT_lightcache_info_update : EEVEE_lightcache_info_update)(&sce->eevee);
|
||||||
|
|
||||||
BKE_screen_view3d_shading_blend_read_data(reader, &sce->display.shading);
|
BKE_screen_view3d_shading_blend_read_data(reader, &sce->display.shading);
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
|
|
||||||
#include "PIL_time.h"
|
#include "PIL_time.h"
|
||||||
|
|
||||||
|
#include "../eevee_next/eevee_lightcache.h"
|
||||||
#include "eevee_lightcache.h"
|
#include "eevee_lightcache.h"
|
||||||
#include "eevee_private.h"
|
#include "eevee_private.h"
|
||||||
|
|
||||||
|
@ -501,6 +502,11 @@ static void eevee_lightbake_readback_reflections(LightCache *lcache)
|
||||||
|
|
||||||
void EEVEE_lightcache_free(LightCache *lcache)
|
void EEVEE_lightcache_free(LightCache *lcache)
|
||||||
{
|
{
|
||||||
|
if (lcache->version == LIGHTCACHE_NEXT_STATIC_VERSION) {
|
||||||
|
EEVEE_NEXT_lightcache_free(lcache);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
DRW_TEXTURE_FREE_SAFE(lcache->cube_tx.tex);
|
DRW_TEXTURE_FREE_SAFE(lcache->cube_tx.tex);
|
||||||
MEM_SAFE_FREE(lcache->cube_tx.data);
|
MEM_SAFE_FREE(lcache->cube_tx.data);
|
||||||
DRW_TEXTURE_FREE_SAFE(lcache->grid_tx.tex);
|
DRW_TEXTURE_FREE_SAFE(lcache->grid_tx.tex);
|
||||||
|
@ -539,6 +545,10 @@ static void write_lightcache_texture(BlendWriter *writer, LightCacheTexture *tex
|
||||||
|
|
||||||
void EEVEE_lightcache_blend_write(BlendWriter *writer, LightCache *cache)
|
void EEVEE_lightcache_blend_write(BlendWriter *writer, LightCache *cache)
|
||||||
{
|
{
|
||||||
|
if (cache->version == LIGHTCACHE_NEXT_STATIC_VERSION) {
|
||||||
|
EEVEE_NEXT_lightcache_blend_write(writer, cache);
|
||||||
|
}
|
||||||
|
|
||||||
write_lightcache_texture(writer, &cache->grid_tx);
|
write_lightcache_texture(writer, &cache->grid_tx);
|
||||||
write_lightcache_texture(writer, &cache->cube_tx);
|
write_lightcache_texture(writer, &cache->cube_tx);
|
||||||
|
|
||||||
|
@ -579,6 +589,10 @@ static void direct_link_lightcache_texture(BlendDataReader *reader, LightCacheTe
|
||||||
|
|
||||||
void EEVEE_lightcache_blend_read_data(BlendDataReader *reader, LightCache *cache)
|
void EEVEE_lightcache_blend_read_data(BlendDataReader *reader, LightCache *cache)
|
||||||
{
|
{
|
||||||
|
if (cache->version == LIGHTCACHE_NEXT_STATIC_VERSION) {
|
||||||
|
EEVEE_NEXT_lightcache_blend_read_data(reader, cache);
|
||||||
|
}
|
||||||
|
|
||||||
cache->flag &= ~LIGHTCACHE_NOT_USABLE;
|
cache->flag &= ~LIGHTCACHE_NOT_USABLE;
|
||||||
direct_link_lightcache_texture(reader, &cache->cube_tx);
|
direct_link_lightcache_texture(reader, &cache->cube_tx);
|
||||||
direct_link_lightcache_texture(reader, &cache->grid_tx);
|
direct_link_lightcache_texture(reader, &cache->grid_tx);
|
||||||
|
|
|
@ -92,6 +92,22 @@ class LightBake {
|
||||||
void update()
|
void update()
|
||||||
{
|
{
|
||||||
BLI_assert(BLI_thread_is_main());
|
BLI_assert(BLI_thread_is_main());
|
||||||
|
Scene *original_scene = DEG_get_input_scene(depsgraph_);
|
||||||
|
|
||||||
|
if (original_scene->eevee.light_cache_data == nullptr) {
|
||||||
|
LightCache *light_cache = EEVEE_NEXT_lightcache_create();
|
||||||
|
|
||||||
|
LightCacheIrradianceGrid *grids = (LightCacheIrradianceGrid *)MEM_callocN(
|
||||||
|
1 * sizeof(LightCacheIrradianceGrid), "LightCacheIrradianceGrid");
|
||||||
|
grids[0].resolution[0] = 1;
|
||||||
|
grids[0].resolution[1] = 2;
|
||||||
|
grids[0].resolution[2] = 3;
|
||||||
|
light_cache->grid_len = 1;
|
||||||
|
light_cache->grids = grids;
|
||||||
|
original_scene->eevee.light_cache_data = light_cache;
|
||||||
|
}
|
||||||
|
|
||||||
|
EEVEE_NEXT_lightcache_info_update(&original_scene->eevee);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -204,6 +220,10 @@ extern "C" {
|
||||||
|
|
||||||
using namespace blender::eevee;
|
using namespace blender::eevee;
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------- */
|
||||||
|
/** \name Light Bake Job
|
||||||
|
* \{ */
|
||||||
|
|
||||||
wmJob *EEVEE_NEXT_lightbake_job_create(struct wmWindowManager *wm,
|
wmJob *EEVEE_NEXT_lightbake_job_create(struct wmWindowManager *wm,
|
||||||
struct wmWindow *win,
|
struct wmWindow *win,
|
||||||
struct Main *bmain,
|
struct Main *bmain,
|
||||||
|
@ -269,6 +289,113 @@ void EEVEE_NEXT_lightbake_job(void *job_data, bool *stop, bool *do_update, float
|
||||||
{
|
{
|
||||||
reinterpret_cast<LightBake *>(job_data)->run(stop, do_update, progress);
|
reinterpret_cast<LightBake *>(job_data)->run(stop, do_update, progress);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** \} */
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------- */
|
||||||
|
/** \name Light Cache Create / Delete
|
||||||
|
* \{ */
|
||||||
|
|
||||||
|
LightCache *EEVEE_NEXT_lightcache_create()
|
||||||
|
{
|
||||||
|
LightCache *light_cache = (LightCache *)MEM_callocN(sizeof(LightCache), "LightCache");
|
||||||
|
|
||||||
|
light_cache->version = LIGHTCACHE_NEXT_STATIC_VERSION;
|
||||||
|
light_cache->type = LIGHTCACHE_TYPE_STATIC;
|
||||||
|
|
||||||
|
return light_cache;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EEVEE_NEXT_lightcache_free(LightCache *light_cache)
|
||||||
|
{
|
||||||
|
if (light_cache->version < LIGHTCACHE_NEXT_STATIC_VERSION) {
|
||||||
|
/* Allow deleting old EEVEE cache. */
|
||||||
|
DRW_TEXTURE_FREE_SAFE(light_cache->cube_tx.tex);
|
||||||
|
MEM_SAFE_FREE(light_cache->cube_tx.data);
|
||||||
|
DRW_TEXTURE_FREE_SAFE(light_cache->grid_tx.tex);
|
||||||
|
MEM_SAFE_FREE(light_cache->grid_tx.data);
|
||||||
|
if (light_cache->cube_mips) {
|
||||||
|
for (int i = 0; i < light_cache->mips_len; i++) {
|
||||||
|
MEM_SAFE_FREE(light_cache->cube_mips[i].data);
|
||||||
|
}
|
||||||
|
MEM_SAFE_FREE(light_cache->cube_mips);
|
||||||
|
}
|
||||||
|
MEM_SAFE_FREE(light_cache->cube_data);
|
||||||
|
MEM_SAFE_FREE(light_cache->grid_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
MEM_SAFE_FREE(light_cache->grids);
|
||||||
|
MEM_freeN(light_cache);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EEVEE_NEXT_lightcache_info_update(SceneEEVEE *eevee)
|
||||||
|
{
|
||||||
|
LightCache *light_cache = eevee->light_cache_data;
|
||||||
|
|
||||||
|
if (light_cache == nullptr) {
|
||||||
|
BLI_strncpy(eevee->light_cache_info,
|
||||||
|
TIP_("No light cache in this scene"),
|
||||||
|
sizeof(eevee->light_cache_info));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (light_cache->version != LIGHTCACHE_NEXT_STATIC_VERSION) {
|
||||||
|
BLI_strncpy(eevee->light_cache_info,
|
||||||
|
TIP_("Incompatible Light cache version, please bake again"),
|
||||||
|
sizeof(eevee->light_cache_info));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (light_cache->flag & LIGHTCACHE_INVALID) {
|
||||||
|
BLI_strncpy(eevee->light_cache_info,
|
||||||
|
TIP_("Error: Light cache dimensions not supported by the GPU"),
|
||||||
|
sizeof(eevee->light_cache_info));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (light_cache->flag & LIGHTCACHE_BAKING) {
|
||||||
|
BLI_strncpy(
|
||||||
|
eevee->light_cache_info, TIP_("Baking light cache"), sizeof(eevee->light_cache_info));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int irradiance_sample_len = 0;
|
||||||
|
for (const LightCacheIrradianceGrid &grid :
|
||||||
|
blender::Span<LightCacheIrradianceGrid>(light_cache->grids, light_cache->grid_len)) {
|
||||||
|
irradiance_sample_len += grid.resolution[0] * grid.resolution[1] * grid.resolution[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t size_in_bytes = irradiance_sample_len * sizeof(uint16_t) * 4 * 3;
|
||||||
|
|
||||||
|
char formatted_mem[BLI_STR_FORMAT_INT64_BYTE_UNIT_SIZE];
|
||||||
|
BLI_str_format_byte_unit(formatted_mem, size_in_bytes, false);
|
||||||
|
|
||||||
|
BLI_snprintf(eevee->light_cache_info,
|
||||||
|
sizeof(eevee->light_cache_info),
|
||||||
|
TIP_("%d Ref. Cubemaps, %d Irr. Samples (%s in memory)"),
|
||||||
|
light_cache->cube_len,
|
||||||
|
irradiance_sample_len,
|
||||||
|
formatted_mem);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** \} */
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------- */
|
||||||
|
/** \name Light Cache Read/Write to file
|
||||||
|
* \{ */
|
||||||
|
|
||||||
|
void EEVEE_NEXT_lightcache_blend_write(BlendWriter *writer, LightCache *light_cache)
|
||||||
|
{
|
||||||
|
BLO_write_struct_array(
|
||||||
|
writer, LightCacheIrradianceGrid, light_cache->grid_len, light_cache->grids);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EEVEE_NEXT_lightcache_blend_read_data(BlendDataReader *reader, LightCache *light_cache)
|
||||||
|
{
|
||||||
|
BLO_read_data_address(reader, &light_cache->grids);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** \} */
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \} */
|
/** \} */
|
||||||
|
|
|
@ -13,6 +13,10 @@ extern "C" {
|
||||||
/** Opaque type hiding eevee::LightBake. */
|
/** Opaque type hiding eevee::LightBake. */
|
||||||
typedef struct EEVEE_NEXT_LightBake EEVEE_NEXT_LightBake;
|
typedef struct EEVEE_NEXT_LightBake EEVEE_NEXT_LightBake;
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------- */
|
||||||
|
/** \name Light Bake Job
|
||||||
|
* \{ */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create the job description.
|
* Create the job description.
|
||||||
* This is called for async (modal) bake operator.
|
* This is called for async (modal) bake operator.
|
||||||
|
@ -65,6 +69,39 @@ void EEVEE_NEXT_lightbake_job(void *job_data /* EEVEE_NEXT_LightBake */,
|
||||||
bool *do_update,
|
bool *do_update,
|
||||||
float *progress);
|
float *progress);
|
||||||
|
|
||||||
|
/** \} */
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------- */
|
||||||
|
/** \name Light Cache Create / Delete
|
||||||
|
* \{ */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create an empty light-cache.
|
||||||
|
*/
|
||||||
|
struct LightCache *EEVEE_NEXT_lightcache_create(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Free a light-cache and its associated data.
|
||||||
|
*/
|
||||||
|
void EEVEE_NEXT_lightcache_free(struct LightCache *lcache);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the UI message in the render panel about the state of the cache.
|
||||||
|
*/
|
||||||
|
void EEVEE_NEXT_lightcache_info_update(struct SceneEEVEE *eevee);
|
||||||
|
|
||||||
|
/** \} */
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------- */
|
||||||
|
/** \name Light Cache Read/Write to file
|
||||||
|
* \{ */
|
||||||
|
|
||||||
|
void EEVEE_NEXT_lightcache_blend_write(struct BlendWriter *writer, struct LightCache *light_cache);
|
||||||
|
void EEVEE_NEXT_lightcache_blend_read_data(struct BlendDataReader *reader,
|
||||||
|
struct LightCache *light_cache);
|
||||||
|
|
||||||
|
/** \} */
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1533,7 +1533,11 @@ static int light_cache_free_exec(bContext *C, wmOperator * /*op*/)
|
||||||
EEVEE_lightcache_free(scene->eevee.light_cache_data);
|
EEVEE_lightcache_free(scene->eevee.light_cache_data);
|
||||||
scene->eevee.light_cache_data = nullptr;
|
scene->eevee.light_cache_data = nullptr;
|
||||||
|
|
||||||
EEVEE_lightcache_info_update(&scene->eevee);
|
RenderEngineType *engine_type = RE_engines_find(scene->r.engine);
|
||||||
|
bool use_eevee_next = STREQ(engine_type->idname, "BLENDER_EEVEE_NEXT");
|
||||||
|
|
||||||
|
((use_eevee_next) ? EEVEE_NEXT_lightcache_info_update :
|
||||||
|
EEVEE_lightcache_info_update)(&scene->eevee);
|
||||||
|
|
||||||
DEG_id_tag_update(&scene->id, ID_RECALC_COPY_ON_WRITE);
|
DEG_id_tag_update(&scene->id, ID_RECALC_COPY_ON_WRITE);
|
||||||
|
|
||||||
|
|
|
@ -142,6 +142,21 @@ typedef struct LightCacheTexture {
|
||||||
char _pad[2];
|
char _pad[2];
|
||||||
} LightCacheTexture;
|
} LightCacheTexture;
|
||||||
|
|
||||||
|
typedef struct LightCacheIrradianceGrid {
|
||||||
|
/** Transform to local space [0..resolution-1] range. */
|
||||||
|
float world_to_grid[4][4];
|
||||||
|
/** Number of samples in each dimension. */
|
||||||
|
int resolution[3];
|
||||||
|
/** Number of surfels in the cache. */
|
||||||
|
int surfels_len;
|
||||||
|
/** Currently only used at runtime for debugging the baking process. Not written to file. */
|
||||||
|
// struct GPUStorageBuf *surfels;
|
||||||
|
/** Irradiance Data. Stored as spherical harmonic. */
|
||||||
|
// LightCacheTexture *irradiance_L0_L1_a;
|
||||||
|
// LightCacheTexture *irradiance_L0_L1_b;
|
||||||
|
// LightCacheTexture *irradiance_L0_L1_c;
|
||||||
|
} LightCacheIrradianceGrid;
|
||||||
|
|
||||||
typedef struct LightCache {
|
typedef struct LightCache {
|
||||||
int flag;
|
int flag;
|
||||||
/** Version number to know if the cache data is compatible with this version of blender. */
|
/** Version number to know if the cache data is compatible with this version of blender. */
|
||||||
|
@ -167,10 +182,17 @@ typedef struct LightCache {
|
||||||
/* All lightprobes data contained in the cache. */
|
/* All lightprobes data contained in the cache. */
|
||||||
LightProbeCache *cube_data;
|
LightProbeCache *cube_data;
|
||||||
LightGridCache *grid_data;
|
LightGridCache *grid_data;
|
||||||
|
|
||||||
|
/* ---- EEVEE-Next ---- */
|
||||||
|
LightCacheIrradianceGrid *grids;
|
||||||
|
// LightCacheReflectionCube *cubes;
|
||||||
} LightCache;
|
} LightCache;
|
||||||
|
|
||||||
/* Bump the version number for lightcache data structure changes. */
|
/* Bump the version number for lightcache data structure changes. */
|
||||||
#define LIGHTCACHE_STATIC_VERSION 2
|
#define LIGHTCACHE_STATIC_VERSION 2
|
||||||
|
/* Cache generated by EEVEE-Next. Should be removed and be replaced by bumped
|
||||||
|
* LIGHTCACHE_STATIC_VERSION once EEVEE-Next is made default. */
|
||||||
|
#define LIGHTCACHE_NEXT_STATIC_VERSION 3
|
||||||
|
|
||||||
/* LightCache->type */
|
/* LightCache->type */
|
||||||
enum {
|
enum {
|
||||||
|
|
Loading…
Reference in New Issue