Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/draw/engines/eevee/eevee_lights.c')
-rw-r--r--source/blender/draw/engines/eevee/eevee_lights.c101
1 files changed, 58 insertions, 43 deletions
diff --git a/source/blender/draw/engines/eevee/eevee_lights.c b/source/blender/draw/engines/eevee/eevee_lights.c
index f5673d1a616..2c970fa5285 100644
--- a/source/blender/draw/engines/eevee/eevee_lights.c
+++ b/source/blender/draw/engines/eevee/eevee_lights.c
@@ -37,6 +37,8 @@
#define SHADOW_CASTER_ALLOC_CHUNK 16
+// #define DEBUG_CSM
+
static struct {
struct GPUShader *shadow_sh;
struct GPUShader *shadow_store_cube_sh[SHADOW_METHOD_MAX];
@@ -148,7 +150,7 @@ void EEVEE_lights_init(EEVEE_ViewLayerData *sldata)
DRW_TEXTURE_FREE_SAFE(sldata->shadow_cube_blur);
/* Compute adequate size for the octahedral map. */
- linfo->shadow_cube_store_size = (int)ceil(sqrt((sh_cube_size * sh_cube_size) * 6.0f));
+ linfo->shadow_cube_store_size = OCTAHEDRAL_SIZE_FROM_CUBESIZE(sh_cube_size);
CLAMP(linfo->shadow_cube_store_size, 1, 4096);
CLAMP(sh_cube_size, 1, 4096);
@@ -235,9 +237,9 @@ static GPUShader *eevee_lights_get_store_sh(int shadow_method, bool high_blur, b
return *shader;
}
-static DRWPass *eevee_lights_cube_store_pass_get(EEVEE_PassList *psl, EEVEE_ViewLayerData *sldata, int shadow_method, int shadow_samples_ct)
+static DRWPass *eevee_lights_cube_store_pass_get(EEVEE_PassList *psl, EEVEE_ViewLayerData *sldata, int shadow_method, int shadow_samples_len)
{
- bool high_blur = shadow_samples_ct > 16;
+ bool high_blur = shadow_samples_len > 16;
DRWPass **pass = (high_blur) ? &psl->shadow_cube_store_pass : &psl->shadow_cube_store_high_pass;
if (*pass == NULL) {
EEVEE_LampsInfo *linfo = sldata->lamps;
@@ -252,9 +254,9 @@ static DRWPass *eevee_lights_cube_store_pass_get(EEVEE_PassList *psl, EEVEE_View
return *pass;
}
-static DRWPass *eevee_lights_cascade_store_pass_get(EEVEE_PassList *psl, EEVEE_ViewLayerData *sldata, int shadow_method, int shadow_samples_ct)
+static DRWPass *eevee_lights_cascade_store_pass_get(EEVEE_PassList *psl, EEVEE_ViewLayerData *sldata, int shadow_method, int shadow_samples_len)
{
- bool high_blur = shadow_samples_ct > 16;
+ bool high_blur = shadow_samples_len > 16;
DRWPass **pass = (high_blur) ? &psl->shadow_cascade_store_pass : &psl->shadow_cascade_store_high_pass;
if (*pass == NULL) {
EEVEE_LampsInfo *linfo = sldata->lamps;
@@ -280,8 +282,8 @@ void EEVEE_lights_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
linfo->num_light = 0;
linfo->num_cube_layer = 0;
linfo->num_cascade_layer = 0;
- linfo->gpu_cube_ct = linfo->gpu_cascade_ct = linfo->gpu_shadow_ct = 0;
- linfo->cpu_cube_ct = linfo->cpu_cascade_ct = 0;
+ linfo->gpu_cube_len = linfo->gpu_cascade_len = linfo->gpu_shadow_len = 0;
+ linfo->cpu_cube_len = linfo->cpu_cascade_len = 0;
memset(linfo->light_ref, 0, sizeof(linfo->light_ref));
memset(linfo->shadow_cube_ref, 0, sizeof(linfo->shadow_cube_ref));
memset(linfo->shadow_cascade_ref, 0, sizeof(linfo->shadow_cascade_ref));
@@ -334,7 +336,7 @@ void EEVEE_lights_cache_add(EEVEE_ViewLayerData *sldata, Object *ob)
/* Step 1 find all lamps in the scene and setup them */
if (linfo->num_light >= MAX_LIGHT) {
- printf("Too many lamps in the scene !!!\n");
+ printf("Too many lights in the scene !!!\n");
}
else {
Lamp *la = (Lamp *)ob->data;
@@ -361,56 +363,56 @@ void EEVEE_lights_cache_add(EEVEE_ViewLayerData *sldata, Object *ob)
int sh_nbr = 1; /* TODO : MSM */
int cascade_nbr = la->cascade_count;
- if ((linfo->gpu_cascade_ct + sh_nbr) <= MAX_SHADOW_CASCADE) {
+ if ((linfo->gpu_cascade_len + sh_nbr) <= MAX_SHADOW_CASCADE) {
/* Save Light object. */
- linfo->shadow_cascade_ref[linfo->cpu_cascade_ct] = ob;
+ linfo->shadow_cascade_ref[linfo->cpu_cascade_len] = ob;
/* Store indices. */
EEVEE_ShadowCascadeData *data = &led->data.scad;
- data->shadow_id = linfo->gpu_shadow_ct;
- data->cascade_id = linfo->gpu_cascade_ct;
+ data->shadow_id = linfo->gpu_shadow_len;
+ data->cascade_id = linfo->gpu_cascade_len;
data->layer_id = linfo->num_cascade_layer;
/* Increment indices. */
- linfo->gpu_shadow_ct += 1;
- linfo->gpu_cascade_ct += sh_nbr;
+ linfo->gpu_shadow_len += 1;
+ linfo->gpu_cascade_len += sh_nbr;
linfo->num_cascade_layer += sh_nbr * cascade_nbr;
- linfo->cpu_cascade_ct += 1;
+ linfo->cpu_cascade_len += 1;
}
}
else if (la->type == LA_SPOT || la->type == LA_LOCAL || la->type == LA_AREA) {
int sh_nbr = 1; /* TODO : MSM */
- if ((linfo->gpu_cube_ct + sh_nbr) <= MAX_SHADOW_CUBE) {
+ if ((linfo->gpu_cube_len + sh_nbr) <= MAX_SHADOW_CUBE) {
/* Save Light object. */
- linfo->shadow_cube_ref[linfo->cpu_cube_ct] = ob;
+ linfo->shadow_cube_ref[linfo->cpu_cube_len] = ob;
/* For light update tracking. */
if ((prev_cube_sh_id >= 0) &&
(prev_cube_sh_id < linfo->shcaster_backbuffer->count))
{
- linfo->new_shadow_id[prev_cube_sh_id] = linfo->cpu_cube_ct;
+ linfo->new_shadow_id[prev_cube_sh_id] = linfo->cpu_cube_len;
}
- led->prev_cube_shadow_id = linfo->cpu_cube_ct;
+ led->prev_cube_shadow_id = linfo->cpu_cube_len;
/* Saving lamp bounds for later. */
- BLI_assert(linfo->cpu_cube_ct >= 0 && linfo->cpu_cube_ct < MAX_LIGHT);
- copy_v3_v3(linfo->shadow_bounds[linfo->cpu_cube_ct].center, ob->obmat[3]);
- linfo->shadow_bounds[linfo->cpu_cube_ct].radius = la->clipend;
+ BLI_assert(linfo->cpu_cube_len >= 0 && linfo->cpu_cube_len < MAX_LIGHT);
+ copy_v3_v3(linfo->shadow_bounds[linfo->cpu_cube_len].center, ob->obmat[3]);
+ linfo->shadow_bounds[linfo->cpu_cube_len].radius = la->clipend;
EEVEE_ShadowCubeData *data = &led->data.scd;
/* Store indices. */
- data->shadow_id = linfo->gpu_shadow_ct;
- data->cube_id = linfo->gpu_cube_ct;
+ data->shadow_id = linfo->gpu_shadow_len;
+ data->cube_id = linfo->gpu_cube_len;
data->layer_id = linfo->num_cube_layer;
/* Increment indices. */
- linfo->gpu_shadow_ct += 1;
- linfo->gpu_cube_ct += sh_nbr;
+ linfo->gpu_shadow_len += 1;
+ linfo->gpu_cube_len += sh_nbr;
linfo->num_cube_layer += sh_nbr;
- linfo->cpu_cube_ct += 1;
+ linfo->cpu_cube_len += 1;
}
}
}
@@ -423,7 +425,7 @@ void EEVEE_lights_cache_add(EEVEE_ViewLayerData *sldata, Object *ob)
/* Add a shadow caster to the shadowpasses */
void EEVEE_lights_cache_shcaster_add(
- EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_StorageList *stl, struct Gwn_Batch *geom, Object *ob)
+ EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_StorageList *stl, struct GPUBatch *geom, Object *ob)
{
DRW_shgroup_call_object_add(
stl->g_data->shadow_shgrp,
@@ -432,7 +434,7 @@ void EEVEE_lights_cache_shcaster_add(
void EEVEE_lights_cache_shcaster_material_add(
EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_PassList *psl, struct GPUMaterial *gpumat,
- struct Gwn_Batch *geom, struct Object *ob, float *alpha_threshold)
+ struct GPUBatch *geom, struct Object *ob, float *alpha_threshold)
{
/* TODO / PERF : reuse the same shading group for objects with the same material */
DRWShadingGroup *grp = DRW_shgroup_material_create(gpumat, psl->shadow_pass);
@@ -871,13 +873,13 @@ static void eevee_shadow_cascade_setup(
/* Given 8 frustum corners */
float corners[8][3] = {
/* Near Cap */
- {-1.0f, -1.0f, splits_start_ndc[c]},
{ 1.0f, -1.0f, splits_start_ndc[c]},
+ {-1.0f, -1.0f, splits_start_ndc[c]},
{-1.0f, 1.0f, splits_start_ndc[c]},
{ 1.0f, 1.0f, splits_start_ndc[c]},
/* Far Cap */
- {-1.0f, -1.0f, splits_end_ndc[c]},
{ 1.0f, -1.0f, splits_end_ndc[c]},
+ {-1.0f, -1.0f, splits_end_ndc[c]},
{-1.0f, 1.0f, splits_end_ndc[c]},
{ 1.0f, 1.0f, splits_end_ndc[c]}
};
@@ -890,8 +892,17 @@ static void eevee_shadow_cascade_setup(
float center[3];
frustum_min_bounding_sphere(corners, center, &(sh_data->radius[c]));
+#ifdef DEBUG_CSM
+ float dbg_col[4] = {0.0f, 0.0f, 0.0f, 1.0f};
+ if (c < 3) {
+ dbg_col[c] = 1.0f;
+ }
+ DRW_debug_bbox((BoundBox *)&corners, dbg_col);
+ DRW_debug_sphere(center, sh_data->radius[c], dbg_col);
+#endif
+
/* Project into lightspace */
- mul_mat3_m4_v3(viewmat, center);
+ mul_m4_v3(viewmat, center);
/* Snap projection center to nearest texel to cancel shimmering. */
float shadow_origin[2], shadow_texco[2];
@@ -919,6 +930,10 @@ static void eevee_shadow_cascade_setup(
mul_m4_m4m4(sh_data->viewprojmat[c], projmat, viewmat);
mul_m4_m4m4(cascade_data->shadowmat[c], texcomat, sh_data->viewprojmat[c]);
+
+#ifdef DEBUG_CSM
+ DRW_debug_m4_as_bbox(sh_data->viewprojmat[c], dbg_col, true);
+#endif
}
ubo_data->bias = 0.05f * la->bias;
@@ -993,7 +1008,7 @@ void EEVEE_lights_update(EEVEE_ViewLayerData *sldata)
for (i = 0; i < frontbuffer->count; i++, flag++, shcaster++) {
/* Run intersection checks to fill the bitfields. */
bsphere = linfo->shadow_bounds;
- for (int j = 0; j < linfo->cpu_cube_ct; j++, bsphere++) {
+ for (int j = 0; j < linfo->cpu_cube_len; j++, bsphere++) {
bool iter = sphere_bbox_intersect(bsphere, &shcaster->bbox);
lightbits_set_single(&shcaster->bits, j, iter);
}
@@ -1086,7 +1101,7 @@ void EEVEE_draw_shadows(EEVEE_ViewLayerData *sldata, EEVEE_PassList *psl)
DRW_uniformbuffer_update(sldata->shadow_render_ubo, srd);
/* Render shadow cube */
- /* Render 6 faces separatly: seems to be faster for the general case.
+ /* Render 6 faces separately: seems to be faster for the general case.
* The only time it's more beneficial is when the CPU culling overhead
* outweight the instancing overhead. which is rarelly the case. */
for (int j = 0; j < 6; j++) {
@@ -1139,19 +1154,19 @@ void EEVEE_draw_shadows(EEVEE_ViewLayerData *sldata, EEVEE_PassList *psl)
filter_pixel_size = max_ff(0.0f, filter_pixel_size - 3.0f);
/* Compute number of concentric samples. Depends directly on filter size. */
float pix_size_sqr = filter_pixel_size * filter_pixel_size;
- srd->shadow_samples_ct = min_ii(max_sample, 4 + 8 * (int)filter_pixel_size + 4 * (int)(pix_size_sqr));
+ srd->shadow_samples_len = min_ii(max_sample, 4 + 8 * (int)filter_pixel_size + 4 * (int)(pix_size_sqr));
}
else {
linfo->filter_size = 0.0f;
- srd->shadow_samples_ct = 4;
+ srd->shadow_samples_len = 4;
}
- srd->shadow_inv_samples_ct = 1.0f / (float)srd->shadow_samples_ct;
+ srd->shadow_samples_len_inv = 1.0f / (float)srd->shadow_samples_len;
DRW_uniformbuffer_update(sldata->shadow_render_ubo, srd);
GPU_framebuffer_texture_layer_attach(sldata->shadow_cube_store_fb, sldata->shadow_cube_pool, 0, evscd->layer_id, 0);
GPU_framebuffer_bind(sldata->shadow_cube_store_fb);
- DRWPass *store_pass = eevee_lights_cube_store_pass_get(psl, sldata, linfo->shadow_method, srd->shadow_samples_ct);
+ DRWPass *store_pass = eevee_lights_cube_store_pass_get(psl, sldata, linfo->shadow_method, srd->shadow_samples_len);
DRW_draw_pass(store_pass);
led->need_update = false;
@@ -1193,7 +1208,7 @@ void EEVEE_draw_shadows(EEVEE_ViewLayerData *sldata, EEVEE_PassList *psl)
invert_m4_m4(render_mats.mat[DRW_MAT_VIEWINV], viewmat);
/* Render shadow cascades */
- /* Render cascade separatly: seems to be faster for the general case.
+ /* Render cascade separately: seems to be faster for the general case.
* The only time it's more beneficial is when the CPU culling overhead
* outweight the instancing overhead. which is rarelly the case. */
for (int j = 0; j < la->cascade_count; j++) {
@@ -1240,20 +1255,20 @@ void EEVEE_draw_shadows(EEVEE_ViewLayerData *sldata, EEVEE_PassList *psl)
filter_pixel_size = max_ff(0.0f, filter_pixel_size - 3.0f);
/* Compute number of concentric samples. Depends directly on filter size. */
float pix_size_sqr = filter_pixel_size * filter_pixel_size;
- srd->shadow_samples_ct = min_ii(max_sample, 4 + 8 * (int)filter_pixel_size + 4 * (int)(pix_size_sqr));
+ srd->shadow_samples_len = min_ii(max_sample, 4 + 8 * (int)filter_pixel_size + 4 * (int)(pix_size_sqr));
}
else {
linfo->filter_size = 0.0f;
- srd->shadow_samples_ct = 4;
+ srd->shadow_samples_len = 4;
}
- srd->shadow_inv_samples_ct = 1.0f / (float)srd->shadow_samples_ct;
+ srd->shadow_samples_len_inv = 1.0f / (float)srd->shadow_samples_len;
DRW_uniformbuffer_update(sldata->shadow_render_ubo, &linfo->shadow_render_data);
int layer = evscd->layer_id + linfo->current_shadow_cascade;
GPU_framebuffer_texture_layer_attach(sldata->shadow_cascade_store_fb, sldata->shadow_cascade_pool, 0, layer, 0);
GPU_framebuffer_bind(sldata->shadow_cascade_store_fb);
- DRWPass *store_pass = eevee_lights_cascade_store_pass_get(psl, sldata, linfo->shadow_method, srd->shadow_samples_ct);
+ DRWPass *store_pass = eevee_lights_cascade_store_pass_get(psl, sldata, linfo->shadow_method, srd->shadow_samples_len);
DRW_draw_pass(store_pass);
}
}