diff options
Diffstat (limited to 'source/blender/draw/engines/eevee/eevee_lights.c')
-rw-r--r-- | source/blender/draw/engines/eevee/eevee_lights.c | 101 |
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); } } |