DNA: Move irradiance grid light cache data to Object level #106808
|
@ -14,10 +14,49 @@ extern "C" {
|
|||
|
||||
struct LightProbe;
|
||||
struct Main;
|
||||
struct BlendWriter;
|
||||
struct BlendDataReader;
|
||||
struct LightProbeGridCache;
|
||||
struct Object;
|
||||
|
||||
void BKE_lightprobe_type_set(struct LightProbe *probe, short lightprobe_type);
|
||||
void *BKE_lightprobe_add(struct Main *bmain, const char *name);
|
||||
|
||||
void BKE_lightprobe_grid_cache_blend_write(struct BlendWriter *writer,
|
||||
struct LightProbeGridCache **grid_caches,
|
||||
int grid_caches_len);
|
||||
|
||||
void BKE_lightprobe_grid_cache_blend_read(struct BlendDataReader *reader,
|
||||
struct LightProbeGridCache **grid_caches,
|
||||
int grid_caches_len);
|
||||
|
||||
/**
|
||||
* Create a single empty irradiance grid cache.
|
||||
*/
|
||||
struct LightProbeGridCache *BKE_lightprobe_grid_cache_create(void);
|
||||
|
||||
/**
|
||||
* Free a single grid cache.
|
||||
*/
|
||||
void BKE_lightprobe_grid_cache_free(struct LightProbeGridCache *cache);
|
||||
|
||||
/**
|
||||
* Create the grid cache list depending on the lightprobe baking settings.
|
||||
* The list is left empty to be filled by the baking process.
|
||||
*/
|
||||
void BKE_lightprobe_grid_caches_create(struct Object *object);
|
||||
|
||||
/**
|
||||
* Free all irradiance grids allocated for the given object.
|
||||
*/
|
||||
void BKE_lightprobe_grid_caches_free(struct Object *object);
|
||||
|
||||
/**
|
||||
* Return the number of sample stored inside an irradiance cache.
|
||||
* This depends on the light cache type.
|
||||
*/
|
||||
int64_t BKE_lightprobe_grid_cache_sample_count(const struct LightProbeGridCache *cache);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
#include "DNA_lightprobe_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
|
||||
#include "BLI_math_base.h"
|
||||
#include "BLI_span.hh"
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#include "BKE_anim_data.h"
|
||||
|
@ -129,3 +131,174 @@ void *BKE_lightprobe_add(Main *bmain, const char *name)
|
|||
|
||||
return probe;
|
||||
}
|
||||
|
||||
void BKE_lightprobe_grid_cache_blend_write(BlendWriter *writer,
|
||||
LightProbeGridCache **grid_caches,
|
||||
int grid_caches_len)
|
||||
{
|
||||
blender::Span<const LightProbeGridCache *> caches(grid_caches, grid_caches_len);
|
||||
for (const LightProbeGridCache *cache : caches) {
|
||||
if (cache == nullptr) {
|
||||
continue;
|
||||
}
|
||||
|
||||
BLO_write_struct(writer, LightProbeGridCache, cache);
|
||||
|
||||
if (cache->block_infos != nullptr) {
|
||||
BLO_write_struct_array(writer, LightProbeGridCache, cache->block_len, cache->block_infos);
|
||||
}
|
||||
|
||||
int64_t sample_count = BKE_lightprobe_grid_cache_sample_count(cache);
|
||||
|
||||
if (cache->irradiance.L0 != nullptr) {
|
||||
BLO_write_float3_array(writer, sample_count, (float *)cache->irradiance.L0);
|
||||
}
|
||||
if (cache->irradiance.L1_a != nullptr) {
|
||||
BLO_write_float3_array(writer, sample_count, (float *)cache->irradiance.L1_a);
|
||||
}
|
||||
if (cache->irradiance.L1_b != nullptr) {
|
||||
BLO_write_float3_array(writer, sample_count, (float *)cache->irradiance.L1_b);
|
||||
}
|
||||
if (cache->irradiance.L1_c != nullptr) {
|
||||
BLO_write_float3_array(writer, sample_count, (float *)cache->irradiance.L1_c);
|
||||
}
|
||||
|
||||
if (cache->visibility.L0 != nullptr) {
|
||||
BLO_write_int8_array(writer, sample_count, (int8_t *)cache->visibility.L0);
|
||||
}
|
||||
if (cache->visibility.L1_a != nullptr) {
|
||||
BLO_write_int8_array(writer, sample_count, (int8_t *)cache->visibility.L1_a);
|
||||
}
|
||||
if (cache->visibility.L1_b != nullptr) {
|
||||
BLO_write_int8_array(writer, sample_count, (int8_t *)cache->visibility.L1_b);
|
||||
}
|
||||
if (cache->visibility.L1_c != nullptr) {
|
||||
BLO_write_int8_array(writer, sample_count, (int8_t *)cache->visibility.L1_c);
|
||||
}
|
||||
|
||||
if (cache->connectivity.bitmask != nullptr) {
|
||||
BLO_write_struct_array(
|
||||
writer, LightProbeGridCache, sample_count, cache->connectivity.bitmask);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BKE_lightprobe_grid_cache_blend_read(BlendDataReader *reader,
|
||||
LightProbeGridCache **grid_caches,
|
||||
int grid_caches_len)
|
||||
{
|
||||
blender::MutableSpan<LightProbeGridCache *> caches(grid_caches, grid_caches_len);
|
||||
for (LightProbeGridCache *&cache : caches) {
|
||||
if (cache == nullptr) {
|
||||
continue;
|
||||
}
|
||||
|
||||
BLO_read_data_address(reader, &cache);
|
||||
|
||||
if (cache->block_infos != nullptr) {
|
||||
BLO_read_data_address(reader, &cache->block_infos);
|
||||
}
|
||||
|
||||
/* Baking data is not stored. */
|
||||
cache->baking.L0 = nullptr;
|
||||
cache->baking.L1_a = nullptr;
|
||||
cache->baking.L1_b = nullptr;
|
||||
cache->baking.L1_c = nullptr;
|
||||
|
||||
if (cache->irradiance.L0 != nullptr) {
|
||||
BLO_read_data_address(reader, &cache->irradiance.L0);
|
||||
}
|
||||
if (cache->irradiance.L1_a != nullptr) {
|
||||
BLO_read_data_address(reader, &cache->irradiance.L1_a);
|
||||
}
|
||||
if (cache->irradiance.L1_b != nullptr) {
|
||||
BLO_read_data_address(reader, &cache->irradiance.L1_b);
|
||||
}
|
||||
if (cache->irradiance.L1_c != nullptr) {
|
||||
BLO_read_data_address(reader, &cache->irradiance.L1_c);
|
||||
}
|
||||
|
||||
if (cache->visibility.L0 != nullptr) {
|
||||
BLO_read_data_address(reader, &cache->visibility.L0);
|
||||
}
|
||||
if (cache->visibility.L1_a != nullptr) {
|
||||
BLO_read_data_address(reader, &cache->visibility.L1_a);
|
||||
}
|
||||
if (cache->visibility.L1_b != nullptr) {
|
||||
BLO_read_data_address(reader, &cache->visibility.L1_b);
|
||||
}
|
||||
if (cache->visibility.L1_c != nullptr) {
|
||||
BLO_read_data_address(reader, &cache->visibility.L1_c);
|
||||
}
|
||||
|
||||
if (cache->connectivity.bitmask != nullptr) {
|
||||
BLO_read_data_address(reader, &cache->connectivity.bitmask);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T> static void spherical_harmonic_free(T &data)
|
||||
{
|
||||
MEM_SAFE_FREE(data.L0);
|
||||
MEM_SAFE_FREE(data.L1_a);
|
||||
MEM_SAFE_FREE(data.L1_b);
|
||||
MEM_SAFE_FREE(data.L1_c);
|
||||
}
|
||||
|
||||
LightProbeGridCache *BKE_lightprobe_grid_cache_create()
|
||||
{
|
||||
LightProbeGridCache *cache = static_cast<LightProbeGridCache *>(
|
||||
MEM_callocN(sizeof(LightProbeGridCache), "LightProbeGridCache"));
|
||||
cache->cache_type = LIGHTPROBE_CACHE_TYPE_NONE;
|
||||
cache->data_layout = LIGHTPROBE_CACHE_UNIFORM_GRID;
|
||||
return cache;
|
||||
}
|
||||
|
||||
void BKE_lightprobe_grid_cache_free(LightProbeGridCache *cache)
|
||||
{
|
||||
MEM_SAFE_FREE(cache->block_infos);
|
||||
spherical_harmonic_free(cache->baking);
|
||||
spherical_harmonic_free(cache->irradiance);
|
||||
spherical_harmonic_free(cache->visibility);
|
||||
MEM_SAFE_FREE(cache->connectivity.bitmask);
|
||||
|
||||
MEM_SAFE_FREE(cache);
|
||||
}
|
||||
|
||||
void BKE_lightprobe_grid_caches_create(Object *object)
|
||||
{
|
||||
BLI_assert(object->irradiance_caches == nullptr);
|
||||
|
||||
/* Single cache for now. */
|
||||
const int grid_caches_len = 1;
|
||||
LightProbeGridCache **grid_caches = static_cast<LightProbeGridCache **>(
|
||||
MEM_callocN(sizeof(LightProbeGridCache *) * grid_caches_len, "irradiance_caches"));
|
||||
object->irradiance_caches = grid_caches;
|
||||
object->irradiance_caches_len = grid_caches_len;
|
||||
}
|
||||
|
||||
void BKE_lightprobe_grid_caches_free(Object *object)
|
||||
{
|
||||
if (object->irradiance_caches == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
blender::MutableSpan<LightProbeGridCache *> caches(object->irradiance_caches,
|
||||
object->irradiance_caches_len);
|
||||
for (LightProbeGridCache *cache : caches) {
|
||||
if (cache != nullptr) {
|
||||
BKE_lightprobe_grid_cache_free(cache);
|
||||
}
|
||||
}
|
||||
MEM_SAFE_FREE(object->irradiance_caches);
|
||||
object->irradiance_caches_len = 0;
|
||||
}
|
||||
|
||||
int64_t BKE_lightprobe_grid_cache_sample_count(const LightProbeGridCache *cache)
|
||||
{
|
||||
if (cache->cache_type == LIGHTPROBE_CACHE_ADAPTIVE_RESOLUTION) {
|
||||
return cache->block_len * cube_i(cache->block_size);
|
||||
}
|
||||
/* LIGHTPROBE_CACHE_UNIFORM_GRID */
|
||||
return cache->size[0] * cache->size[1] * cache->size[2];
|
||||
}
|
||||
|
|
|
@ -267,6 +267,19 @@ static void object_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const in
|
|||
if (ob_src->lightgroup) {
|
||||
ob_dst->lightgroup = (LightgroupMembership *)MEM_dupallocN(ob_src->lightgroup);
|
||||
}
|
||||
|
||||
if ((flag & LIB_ID_COPY_SET_COPIED_ON_WRITE) != 0) {
|
||||
/* Reference the original object data. */
|
||||
ob_dst->irradiance_caches = ob_src->irradiance_caches;
|
||||
ob_dst->irradiance_caches_len = ob_src->irradiance_caches_len;
|
||||
ob_dst->irradiance_caches_shared = true;
|
||||
}
|
||||
else {
|
||||
/* Do not copy lightprobe's cache. */
|
||||
ob_dst->irradiance_caches = nullptr;
|
||||
ob_dst->irradiance_caches_len = 0;
|
||||
ob_dst->irradiance_caches_shared = false;
|
||||
}
|
||||
}
|
||||
|
||||
static void object_free_data(ID *id)
|
||||
|
@ -319,6 +332,10 @@ static void object_free_data(ID *id)
|
|||
BKE_previewimg_free(&ob->preview);
|
||||
|
||||
MEM_SAFE_FREE(ob->lightgroup);
|
||||
|
||||
if (ob->irradiance_caches_shared == false) {
|
||||
BKE_lightprobe_grid_caches_free(ob);
|
||||
}
|
||||
}
|
||||
|
||||
static void library_foreach_modifiersForeachIDLink(void *user_data,
|
||||
|
@ -597,6 +614,12 @@ static void object_blend_write(BlendWriter *writer, ID *id, const void *id_addre
|
|||
if (ob->lightgroup) {
|
||||
BLO_write_struct(writer, LightgroupMembership, ob->lightgroup);
|
||||
}
|
||||
|
||||
if (ob->irradiance_caches) {
|
||||
BLO_write_pointer_array(writer, ob->irradiance_caches_len, ob->irradiance_caches);
|
||||
BKE_lightprobe_grid_cache_blend_write(
|
||||
writer, ob->irradiance_caches, ob->irradiance_caches_len);
|
||||
}
|
||||
}
|
||||
|
||||
/* XXX deprecated - old animation system */
|
||||
|
@ -815,6 +838,9 @@ static void object_blend_read_data(BlendDataReader *reader, ID *id)
|
|||
BKE_previewimg_blend_read(reader, ob->preview);
|
||||
|
||||
BLO_read_data_address(reader, &ob->lightgroup);
|
||||
|
||||
BLO_read_pointer_array(reader, (void **)&ob->irradiance_caches);
|
||||
BKE_lightprobe_grid_cache_blend_read(reader, ob->irradiance_caches, ob->irradiance_caches_len);
|
||||
}
|
||||
|
||||
/* XXX deprecated - old animation system */
|
||||
|
|
|
@ -41,6 +41,9 @@ void SCENE_OT_view_layer_remove_unused_lightgroups(struct wmOperatorType *ot);
|
|||
void SCENE_OT_light_cache_bake(struct wmOperatorType *ot);
|
||||
void SCENE_OT_light_cache_free(struct wmOperatorType *ot);
|
||||
|
||||
void OBJECT_OT_lightprobe_cache_bake(struct wmOperatorType *ot);
|
||||
void OBJECT_OT_lightprobe_cache_free(struct wmOperatorType *ot);
|
||||
|
||||
void SCENE_OT_render_view_add(struct wmOperatorType *ot);
|
||||
void SCENE_OT_render_view_remove(struct wmOperatorType *ot);
|
||||
|
||||
|
|
|
@ -28,6 +28,9 @@ void ED_operatortypes_render()
|
|||
WM_operatortype_append(OBJECT_OT_material_slot_move);
|
||||
WM_operatortype_append(OBJECT_OT_material_slot_remove_unused);
|
||||
|
||||
WM_operatortype_append(OBJECT_OT_lightprobe_cache_bake);
|
||||
WM_operatortype_append(OBJECT_OT_lightprobe_cache_free);
|
||||
|
||||
WM_operatortype_append(MATERIAL_OT_new);
|
||||
WM_operatortype_append(TEXTURE_OT_new);
|
||||
WM_operatortype_append(WORLD_OT_new);
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#include "BKE_image.h"
|
||||
#include "BKE_layer.h"
|
||||
#include "BKE_lib_id.h"
|
||||
#include "BKE_lightprobe.h"
|
||||
#include "BKE_linestyle.h"
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_material.h"
|
||||
|
@ -53,6 +54,7 @@
|
|||
|
||||
#include "DEG_depsgraph.h"
|
||||
#include "DEG_depsgraph_build.h"
|
||||
#include "DEG_depsgraph_query.h"
|
||||
|
||||
#ifdef WITH_FREESTYLE
|
||||
# include "BKE_freestyle.h"
|
||||
|
@ -1492,6 +1494,87 @@ void SCENE_OT_light_cache_bake(wmOperatorType *ot)
|
|||
RNA_def_property_flag(ot->prop, PROP_SKIP_SAVE);
|
||||
}
|
||||
|
||||
/* NOTE: New version destined to replace the old lightcache bake operator. */
|
||||
|
||||
static int lightprobe_cache_bake_invoke(bContext *C, wmOperator *op, const wmEvent * /*event*/)
|
||||
{
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
Object *active_ob = CTX_data_active_object(C);
|
||||
|
||||
BKE_lightprobe_grid_caches_free(active_ob);
|
||||
BKE_lightprobe_grid_caches_create(active_ob);
|
||||
|
||||
DEG_id_tag_update(&active_ob->id, ID_RECALC_COPY_ON_WRITE);
|
||||
|
||||
WM_event_add_modal_handler(C, op);
|
||||
|
||||
/* store actual owner of job, so modal operator could check for it,
|
||||
* the reason of this is that active scene could change when rendering
|
||||
* several layers from compositor #31800. */
|
||||
op->customdata = scene;
|
||||
|
||||
WM_cursor_wait(false);
|
||||
|
||||
return OPERATOR_RUNNING_MODAL;
|
||||
}
|
||||
|
||||
static int lightprobe_cache_bake_modal(bContext *C, wmOperator *op, const wmEvent *event)
|
||||
{
|
||||
Scene *scene = (Scene *)op->customdata;
|
||||
|
||||
/* No running bake, remove handler and pass through. */
|
||||
if (0 == WM_jobs_test(CTX_wm_manager(C), scene, WM_JOB_TYPE_LIGHT_BAKE)) {
|
||||
return OPERATOR_FINISHED | OPERATOR_PASS_THROUGH;
|
||||
}
|
||||
|
||||
/* Running bake. */
|
||||
switch (event->type) {
|
||||
case EVT_ESCKEY:
|
||||
return OPERATOR_RUNNING_MODAL;
|
||||
}
|
||||
return OPERATOR_PASS_THROUGH;
|
||||
}
|
||||
|
||||
static void lightprobe_cache_bake_cancel(bContext *C, wmOperator *op)
|
||||
{
|
||||
wmWindowManager *wm = CTX_wm_manager(C);
|
||||
Scene *scene = (Scene *)op->customdata;
|
||||
|
||||
/* Kill on cancel, because job is using op->reports. */
|
||||
WM_jobs_kill_type(wm, scene, WM_JOB_TYPE_LIGHT_BAKE);
|
||||
}
|
||||
|
||||
/* Executes blocking render. */
|
||||
static int lightprobe_cache_bake_exec(bContext * /*C*/, wmOperator * /*op*/)
|
||||
{
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
void OBJECT_OT_lightprobe_cache_bake(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name = "Bake Light Cache";
|
||||
ot->idname = "OBJECT_OT_lightprobe_cache_bake";
|
||||
ot->description = "Bake the active view layer lighting";
|
||||
|
||||
/* api callbacks */
|
||||
ot->invoke = lightprobe_cache_bake_invoke;
|
||||
ot->modal = lightprobe_cache_bake_modal;
|
||||
ot->cancel = lightprobe_cache_bake_cancel;
|
||||
ot->exec = lightprobe_cache_bake_exec;
|
||||
|
||||
ot->prop = RNA_def_int(ot->srna,
|
||||
"delay",
|
||||
0,
|
||||
0,
|
||||
2000,
|
||||
"Delay",
|
||||
"Delay in millisecond before baking starts",
|
||||
0,
|
||||
2000);
|
||||
RNA_def_property_flag(ot->prop, PROP_SKIP_SAVE);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
@ -1541,6 +1624,49 @@ void SCENE_OT_light_cache_free(wmOperatorType *ot)
|
|||
ot->poll = light_cache_free_poll;
|
||||
}
|
||||
|
||||
/* NOTE: New version destined to replace the old lightcache bake operator. */
|
||||
|
||||
static bool lightprobe_cache_free_poll(bContext *C)
|
||||
{
|
||||
Object *object = CTX_data_active_object(C);
|
||||
|
||||
return object && object->irradiance_caches != nullptr;
|
||||
}
|
||||
|
||||
static int lightprobe_cache_free_exec(bContext *C, wmOperator * /*op*/)
|
||||
{
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
Object *object = CTX_data_active_object(C);
|
||||
|
||||
/* Kill potential bake job first (see #57011). */
|
||||
wmWindowManager *wm = CTX_wm_manager(C);
|
||||
WM_jobs_kill_type(wm, scene, WM_JOB_TYPE_LIGHT_BAKE);
|
||||
|
||||
if (object->irradiance_caches == nullptr) {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
BKE_lightprobe_grid_caches_free(object);
|
||||
|
||||
DEG_id_tag_update(&object->id, ID_RECALC_COPY_ON_WRITE);
|
||||
|
||||
WM_event_add_notifier(C, NC_OBJECT | ND_OB_SHADING, scene);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
void OBJECT_OT_lightprobe_cache_free(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name = "Delete Light Cache";
|
||||
ot->idname = "OBJECT_OT_lightprobe_cache_free";
|
||||
ot->description = "Delete cached indirect lighting";
|
||||
|
||||
/* api callbacks */
|
||||
ot->exec = lightprobe_cache_free_exec;
|
||||
ot->poll = lightprobe_cache_free_poll;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
|
|
@ -61,9 +61,6 @@ typedef struct LightProbe {
|
|||
struct Image *image;
|
||||
/** Object visibility group, inclusive or exclusive. */
|
||||
struct Collection *visibility_grp;
|
||||
|
||||
/* Runtime display data */
|
||||
float distfalloff, distgridinf;
|
||||
} LightProbe;
|
||||
|
||||
/* Probe->type */
|
||||
|
@ -201,6 +198,114 @@ enum {
|
|||
LIGHTCACHETEX_UINT = (1 << 2),
|
||||
};
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Irradiance grid data storage
|
||||
*
|
||||
* Each spherical harmonic band is stored separately. This allow loading only a specific band.
|
||||
* The layout of each array is set by the #LightProbeGridType.
|
||||
* Any unavailable data is be set to nullptr.
|
||||
* \{ */
|
||||
|
||||
/**
|
||||
* Irradiance data (RGB) stored along visibility (A).
|
||||
* This is the format used during baking and is used for visualizing the baking process.
|
||||
*/
|
||||
typedef struct LightProbeBakingData {
|
||||
float (*L0)[4];
|
||||
float (*L1_a)[4];
|
||||
float (*L1_b)[4];
|
||||
float (*L1_c)[4];
|
||||
} LightProbeBakingData;
|
||||
|
||||
/**
|
||||
* Irradiance stored as RGB triple using scene referred color space.
|
||||
fclem marked this conversation as resolved
Outdated
|
||||
*/
|
||||
typedef struct LightProbeIrradianceData {
|
||||
float (*L0)[3];
|
||||
float (*L1_a)[3];
|
||||
float (*L1_b)[3];
|
||||
float (*L1_c)[3];
|
||||
} LightProbeIrradianceData;
|
||||
|
||||
/**
|
||||
* Normalized visibility of distant light. Used for compositing grids together.
|
||||
*/
|
||||
typedef struct LightProbeVisibilityData {
|
||||
uint8_t *L0;
|
||||
uint8_t *L1_a;
|
||||
uint8_t *L1_b;
|
||||
uint8_t *L1_c;
|
||||
} LightProbeVisibilityData;
|
||||
|
||||
/**
|
||||
* Used to avoid light leaks. Validate visibility between each grid sample.
|
||||
*/
|
||||
typedef struct LightProbeConnectivityData {
|
||||
/** Stores a bitmask of valid connections within a cell. */
|
||||
uint8_t *bitmask;
|
||||
} LightProbeConnectivityData;
|
||||
|
||||
/**
|
||||
* Defines one block of data inside the grid cache data arrays.
|
||||
* The block size if the same for all the blocks.
|
||||
*/
|
||||
typedef struct LightProbeBlockData {
|
||||
/* Offset inside the level-of-detail this block starts. */
|
||||
int offset[3];
|
||||
/* Level-of-detail this block is from. */
|
||||
int level;
|
||||
} LightProbeBlockData;
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name LightProbeGridCache
|
||||
*
|
||||
* \{ */
|
||||
|
||||
typedef struct LightProbeGridCache {
|
||||
/** Allow correct versioning / different types of data for the same layout. */
|
||||
int cache_type;
|
||||
/** Spatial layout type of the data stored inside the data arrays. */
|
||||
int data_layout;
|
||||
|
||||
char _pad0[4];
|
||||
|
||||
/** Number of samples in the highest level of detail. */
|
||||
int size[3];
|
||||
|
||||
/** Sparse or adaptive layout only: number of blocks inside data arrays. */
|
||||
int block_len;
|
||||
/** Sparse or adaptive layout only: size of a block in samples. All 3 dimensions are equal. */
|
||||
int block_size;
|
||||
/** Sparse or adaptive layout only: specify the blocks positions. */
|
||||
LightProbeBlockData *block_infos;
|
||||
|
||||
/** Baked data. */
|
||||
LightProbeBakingData baking;
|
||||
LightProbeIrradianceData irradiance;
|
||||
LightProbeVisibilityData visibility;
|
||||
LightProbeConnectivityData connectivity;
|
||||
} LightProbeGridCache;
|
||||
|
||||
/** #LightProbeGridCache.type (int) */
|
||||
enum {
|
||||
/** Light cache was just created and is not yet baked. */
|
||||
LIGHTPROBE_CACHE_TYPE_NONE = 0,
|
||||
/** Light cache is baked for one specific frame and capture all indirect lighting. */
|
||||
LIGHTPROBE_CACHE_TYPE_STATIC = 1,
|
||||
};
|
||||
|
||||
/** #LightProbeGridCache.data_layout (int) */
|
||||
enum {
|
||||
/** Simple uniform grid. Raw output from GPU. Used during the baking process. */
|
||||
LIGHTPROBE_CACHE_UNIFORM_GRID = 0,
|
||||
/** Fills the space with different level of resolution. More efficient storage. */
|
||||
LIGHTPROBE_CACHE_ADAPTIVE_RESOLUTION = 1,
|
||||
};
|
||||
|
||||
/** \} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -34,6 +34,7 @@ struct FluidsimSettings;
|
|||
struct GeometrySet;
|
||||
struct Ipo;
|
||||
struct LightgroupMembership;
|
||||
struct LightProbeGridCache;
|
||||
struct Material;
|
||||
struct Mesh;
|
||||
struct Object;
|
||||
|
@ -448,6 +449,15 @@ typedef struct Object {
|
|||
/** Lightgroup membership information. */
|
||||
struct LightgroupMembership *lightgroup;
|
||||
|
||||
/** Irradiance caches baked for this object (light-probes only). */
|
||||
struct LightProbeGridCache **irradiance_caches;
|
||||
/** Number of caches inside `irradiance_caches`. */
|
||||
int irradiance_caches_len;
|
||||
/** True if `irradiance_caches` is a reference to the evaluated object's cache. */
|
||||
char irradiance_caches_shared;
|
||||
char _pad9[3];
|
||||
void *_pad10;
|
||||
|
||||
/** Runtime evaluation data (keep last). */
|
||||
Object_Runtime runtime;
|
||||
} Object;
|
||||
|
|
Loading…
Reference in New Issue
scene referred -> scene linear (scene referred is a category of color spaces, scene linear is the specific one)