diff --git a/source/blender/draw/engines/eevee/eevee_lightprobes.c b/source/blender/draw/engines/eevee/eevee_lightprobes.c index 59e8e76bc52..3a7aa2b75d9 100644 --- a/source/blender/draw/engines/eevee/eevee_lightprobes.c +++ b/source/blender/draw/engines/eevee/eevee_lightprobes.c @@ -36,6 +36,7 @@ #include "DNA_view3d_types.h" #include "BKE_object.h" +#include "BKE_group.h" #include "MEM_guardedalloc.h" #include "GPU_material.h" @@ -386,6 +387,9 @@ void EEVEE_lightprobes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedat EEVEE_StorageList *stl = vedata->stl; EEVEE_LightProbesInfo *pinfo = sldata->probes; + /* Make sure no aditionnal visibility check runs by default. */ + pinfo->vis_data.group = NULL; + pinfo->do_cube_update = false; pinfo->num_cube = 1; /* at least one for the world */ pinfo->num_grid = 1; @@ -571,6 +575,30 @@ void EEVEE_lightprobes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedat } } +bool EEVEE_lightprobes_obj_visibility_cb(bool vis_in, void *user_data) +{ + EEVEE_ObjectEngineData *oed = (EEVEE_ObjectEngineData *)user_data; + + /* test disabled if group is NULL */ + if (oed->test_data->group == NULL) + return vis_in; + + if (oed->test_data->cached == false) + oed->ob_vis_dirty = true; + + /* early out, don't need to compute ob_vis yet. */ + if (vis_in == false) + return vis_in; + + if (oed->ob_vis_dirty) { + oed->ob_vis_dirty = false; + oed->ob_vis = BKE_group_object_exists(oed->test_data->group, oed->ob); + oed->ob_vis = (oed->test_data->invert) ? !oed->ob_vis : oed->ob_vis; + } + + return vis_in && oed->ob_vis; +} + void EEVEE_lightprobes_cache_add(EEVEE_ViewLayerData *sldata, Object *ob) { EEVEE_LightProbesInfo *pinfo = sldata->probes; @@ -1228,6 +1256,9 @@ static void render_scene_to_probe( DRW_uniformbuffer_update(sldata->common_ubo, &sldata->common_data); for (int i = 0; i < 6; ++i) { + /* Recompute only on 1st drawloop. */ + pinfo->vis_data.cached = (i != 0); + /* Setup custom matrices */ mul_m4_m4m4(viewmat, cubefacemat[i], posmat); mul_m4_m4m4(persmat, winmat, viewmat); @@ -1260,6 +1291,9 @@ static void render_scene_to_probe( DRW_draw_pass(psl->sss_pass); /* Only output standard pass */ } + /* Make sure no aditionnal visibility check runs after this. */ + pinfo->vis_data.group = NULL; + /* Restore */ txl->planar_pool = tmp_planar_pool; txl->maxzbuffer = tmp_maxz; @@ -1269,6 +1303,7 @@ static void render_scene_to_planar( EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, int layer, EEVEE_LightProbeEngineData *ped) { + EEVEE_LightProbesInfo *pinfo = sldata->probes; EEVEE_FramebufferList *fbl = vedata->fbl; EEVEE_TextureList *txl = vedata->txl; EEVEE_PassList *psl = vedata->psl; @@ -1286,6 +1321,9 @@ static void render_scene_to_planar( DRW_viewport_matrix_override_set_all(&ped->mats); + /* Don't reuse previous visibility. */ + pinfo->vis_data.cached = false; + /* Be sure that cascaded shadow maps are updated. */ EEVEE_draw_shadows(sldata, psl); @@ -1348,6 +1386,9 @@ static void render_scene_to_planar( DRW_state_invert_facing(); DRW_state_clip_planes_reset(); + /* Make sure no aditionnal visibility check runs after this. */ + pinfo->vis_data.group = NULL; + /* Restore */ txl->planar_pool = tmp_planar_pool; txl->planar_depth = tmp_planar_depth; @@ -1499,6 +1540,9 @@ void EEVEE_lightprobes_refresh_planar(EEVEE_ViewLayerData *sldata, EEVEE_Data *v for (int i = 0; (ob = pinfo->probes_planar_ref[i]) && (i < MAX_PLANAR); i++) { EEVEE_LightProbeEngineData *ped = EEVEE_lightprobe_data_ensure(ob); + LightProbe *prb = (LightProbe *)ob->data; + pinfo->vis_data.group = prb->visibility_grp; + pinfo->vis_data.invert = prb->flag & LIGHTPROBE_FLAG_INVERT_GROUP; render_scene_to_planar(sldata, vedata, i, ped); } @@ -1546,6 +1590,8 @@ static void lightprobes_refresh_cube(EEVEE_ViewLayerData *sldata, EEVEE_Data *ve continue; } LightProbe *prb = (LightProbe *)ob->data; + pinfo->vis_data.group = prb->visibility_grp; + pinfo->vis_data.invert = prb->flag & LIGHTPROBE_FLAG_INVERT_GROUP; render_scene_to_probe(sldata, vedata, ob->obmat[3], prb->clipsta, prb->clipend); glossy_filter_probe(sldata, vedata, psl, i, prb->intensity); ped->need_update = false; @@ -1652,6 +1698,8 @@ static void lightprobes_refresh_all_no_world(EEVEE_ViewLayerData *sldata, EEVEE_ egrid->level_bias = (float)(1 << 0); DRW_uniformbuffer_update(sldata->grid_ubo, &sldata->probes->grid_data); } + pinfo->vis_data.group = prb->visibility_grp; + pinfo->vis_data.invert = prb->flag & LIGHTPROBE_FLAG_INVERT_GROUP; render_scene_to_probe(sldata, vedata, pos, prb->clipsta, prb->clipend); diffuse_filter_probe(sldata, vedata, psl, egrid->offset + cell_id, prb->clipsta, prb->clipend, egrid->visibility_range, prb->vis_blur, diff --git a/source/blender/draw/engines/eevee/eevee_materials.c b/source/blender/draw/engines/eevee/eevee_materials.c index 3749ab11007..9a53bafa91f 100644 --- a/source/blender/draw/engines/eevee/eevee_materials.c +++ b/source/blender/draw/engines/eevee/eevee_materials.c @@ -990,18 +990,18 @@ void EEVEE_materials_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) } -#define ADD_SHGROUP_CALL(shgrp, ob, geom) do { \ +#define ADD_SHGROUP_CALL(shgrp, ob, geom, oedata) do { \ if (is_sculpt_mode_draw) { \ DRW_shgroup_call_sculpt_add(shgrp, ob, ob->obmat); \ } \ else { \ - DRW_shgroup_call_object_add(shgrp, geom, ob); \ + DRW_shgroup_call_object_add_with_callback(shgrp, geom, ob, EEVEE_lightprobes_obj_visibility_cb, oedata); \ } \ } while (0) -#define ADD_SHGROUP_CALL_SAFE(shgrp, ob, geom) do { \ +#define ADD_SHGROUP_CALL_SAFE(shgrp, ob, geom, oedata) do { \ if (shgrp) { \ - ADD_SHGROUP_CALL(shgrp, ob, geom); \ + ADD_SHGROUP_CALL(shgrp, ob, geom, oedata); \ } \ } while (0) @@ -1391,12 +1391,16 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata, EEVEE_ViewLayerData *sld continue; } + EEVEE_ObjectEngineData *oedata = EEVEE_object_data_ensure(ob); + oedata->ob = ob; + oedata->test_data = &sldata->probes->vis_data; + /* Shading pass */ - ADD_SHGROUP_CALL(shgrp_array[i], ob, mat_geom[i]); + ADD_SHGROUP_CALL(shgrp_array[i], ob, mat_geom[i], oedata); /* Depth Prepass */ - ADD_SHGROUP_CALL_SAFE(shgrp_depth_array[i], ob, mat_geom[i]); - ADD_SHGROUP_CALL_SAFE(shgrp_depth_clip_array[i], ob, mat_geom[i]); + ADD_SHGROUP_CALL_SAFE(shgrp_depth_array[i], ob, mat_geom[i], oedata); + ADD_SHGROUP_CALL_SAFE(shgrp_depth_clip_array[i], ob, mat_geom[i], oedata); /* Shadow Pass */ if (ma->use_nodes && ma->nodetree && (ma->blend_method != MA_BM_SOLID)) { diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h index 9c4d7d65ccd..b34b1dc8697 100644 --- a/source/blender/draw/engines/eevee/eevee_private.h +++ b/source/blender/draw/engines/eevee/eevee_private.h @@ -416,6 +416,13 @@ typedef struct EEVEE_PlanarReflection { } EEVEE_PlanarReflection; /* ************ PROBE DATA ************* */ + +typedef struct EEVEE_LightProbeVisTest{ + bool invert; + bool cached; /* Reuse last test results */ + struct Group *group; /* Skip test if NULL */ +} EEVEE_LightProbeVisTest; + typedef struct EEVEE_LightProbesInfo { int num_cube, cache_num_cube; int num_grid, cache_num_grid; @@ -458,6 +465,8 @@ typedef struct EEVEE_LightProbesInfo { struct EEVEE_LightProbe probe_data[MAX_PROBE]; struct EEVEE_LightGrid grid_data[MAX_GRID]; struct EEVEE_PlanarReflection planar_data[MAX_PLANAR]; + /* Probe Visibility Group */ + EEVEE_LightProbeVisTest vis_data; } EEVEE_LightProbesInfo; /* EEVEE_LightProbesInfo->update_flag */ @@ -735,6 +744,10 @@ typedef struct EEVEE_LightProbeEngineData { typedef struct EEVEE_ObjectEngineData { ObjectEngineData engine_data; + Object *ob; /* self reference */ + EEVEE_LightProbeVisTest *test_data; + bool ob_vis, ob_vis_dirty; + bool need_update; unsigned int shadow_caster_id; } EEVEE_ObjectEngineData; @@ -823,6 +836,7 @@ void EEVEE_draw_shadows(EEVEE_ViewLayerData *sldata, EEVEE_PassList *psl); void EEVEE_lights_free(void); /* eevee_lightprobes.c */ +bool EEVEE_lightprobes_obj_visibility_cb(bool vis_in, void *user_data); bool EEVEE_lightprobes_all_probes_ready(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata); void EEVEE_lightprobes_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata); void EEVEE_lightprobes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);