From e12c08e8d170b7ca40f204a5b0423c23a9fbc2c1 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 17 Apr 2019 06:17:24 +0200 Subject: ClangFormat: apply to source, most of intern Apply clang format as proposed in T53211. For details on usage and instructions for migrating branches without conflicts, see: https://wiki.blender.org/wiki/Tools/ClangFormat --- .../blender/draw/engines/eevee/eevee_lightprobes.c | 2082 ++++++++++---------- 1 file changed, 1068 insertions(+), 1014 deletions(-) (limited to 'source/blender/draw/engines/eevee/eevee_lightprobes.c') diff --git a/source/blender/draw/engines/eevee/eevee_lightprobes.c b/source/blender/draw/engines/eevee/eevee_lightprobes.c index 5d4601df7cf..550821ee92a 100644 --- a/source/blender/draw/engines/eevee/eevee_lightprobes.c +++ b/source/blender/draw/engines/eevee/eevee_lightprobes.c @@ -43,703 +43,734 @@ #include "eevee_lightcache.h" #include "eevee_private.h" - #include "WM_api.h" #include "WM_types.h" static struct { - struct GPUTexture *hammersley; - struct GPUTexture *planar_pool_placeholder; - struct GPUTexture *depth_placeholder; - struct GPUTexture *depth_array_placeholder; - struct GPUTexture *cube_face_minmaxz; - - struct GPUVertFormat *format_probe_display_cube; - struct GPUVertFormat *format_probe_display_planar; + struct GPUTexture *hammersley; + struct GPUTexture *planar_pool_placeholder; + struct GPUTexture *depth_placeholder; + struct GPUTexture *depth_array_placeholder; + struct GPUTexture *cube_face_minmaxz; + + struct GPUVertFormat *format_probe_display_cube; + struct GPUVertFormat *format_probe_display_planar; } e_data = {NULL}; /* Engine data */ - /* *********** FUNCTIONS *********** */ /* TODO find a better way than this. This does not support dupli objects if * the original object is hidden. */ bool EEVEE_lightprobes_obj_visibility_cb(bool vis_in, void *user_data) { - EEVEE_ObjectEngineData *oed = (EEVEE_ObjectEngineData *)user_data; + EEVEE_ObjectEngineData *oed = (EEVEE_ObjectEngineData *)user_data; - /* test disabled if group is NULL */ - if (oed->test_data->collection == NULL) { - return vis_in; - } + /* test disabled if group is NULL */ + if (oed->test_data->collection == NULL) { + return vis_in; + } - if (oed->test_data->cached == false) { - oed->ob_vis_dirty = true; - } + 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; - } + /* 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_collection_has_object_recursive(oed->test_data->collection, oed->ob); - oed->ob_vis = (oed->test_data->invert) ? !oed->ob_vis : oed->ob_vis; - } + if (oed->ob_vis_dirty) { + oed->ob_vis_dirty = false; + oed->ob_vis = BKE_collection_has_object_recursive(oed->test_data->collection, oed->ob); + oed->ob_vis = (oed->test_data->invert) ? !oed->ob_vis : oed->ob_vis; + } - return vis_in && oed->ob_vis; + return vis_in && oed->ob_vis; } static struct GPUTexture *create_hammersley_sample_texture(int samples) { - struct GPUTexture *tex; - float (*texels)[2] = MEM_mallocN(sizeof(float[2]) * samples, "hammersley_tex"); - int i; - - for (i = 0; i < samples; i++) { - double dphi; - BLI_hammersley_1d(i, &dphi); - float phi = (float)dphi * 2.0f * M_PI; - texels[i][0] = cosf(phi); - texels[i][1] = sinf(phi); - } - - tex = DRW_texture_create_1d(samples, GPU_RG16F, DRW_TEX_WRAP, (float *)texels); - MEM_freeN(texels); - return tex; + struct GPUTexture *tex; + float(*texels)[2] = MEM_mallocN(sizeof(float[2]) * samples, "hammersley_tex"); + int i; + + for (i = 0; i < samples; i++) { + double dphi; + BLI_hammersley_1d(i, &dphi); + float phi = (float)dphi * 2.0f * M_PI; + texels[i][0] = cosf(phi); + texels[i][1] = sinf(phi); + } + + tex = DRW_texture_create_1d(samples, GPU_RG16F, DRW_TEX_WRAP, (float *)texels); + MEM_freeN(texels); + return tex; } static void planar_pool_ensure_alloc(EEVEE_Data *vedata, int num_planar_ref) { - EEVEE_TextureList *txl = vedata->txl; - - /* XXX TODO OPTIMISATION : This is a complete waist of texture memory. - * Instead of allocating each planar probe for each viewport, - * only alloc them once using the biggest viewport resolution. */ - const float *viewport_size = DRW_viewport_size_get(); - - /* TODO get screen percentage from layer setting */ - // const DRWContextState *draw_ctx = DRW_context_state_get(); - // ViewLayer *view_layer = draw_ctx->view_layer; - float screen_percentage = 1.0f; - - int width = max_ii(1, (int)(viewport_size[0] * screen_percentage)); - int height = max_ii(1, (int)(viewport_size[1] * screen_percentage)); - - /* Fix case were the pool was allocated width the dummy size (1,1,1). */ - if (txl->planar_pool && (num_planar_ref > 0) && - (GPU_texture_width(txl->planar_pool) != width || - GPU_texture_height(txl->planar_pool) != height)) - { - DRW_TEXTURE_FREE_SAFE(txl->planar_pool); - DRW_TEXTURE_FREE_SAFE(txl->planar_depth); - } - - /* We need an Array texture so allocate it ourself */ - if (!txl->planar_pool) { - if (num_planar_ref > 0) { - txl->planar_pool = DRW_texture_create_2d_array(width, height, max_ii(1, num_planar_ref), - GPU_R11F_G11F_B10F, DRW_TEX_FILTER | DRW_TEX_MIPMAP, NULL); - txl->planar_depth = DRW_texture_create_2d_array(width, height, max_ii(1, num_planar_ref), - GPU_DEPTH_COMPONENT24, 0, NULL); - } - else if (num_planar_ref == 0) { - /* Makes Opengl Happy : Create a placeholder texture that will never be sampled but still bound to shader. */ - txl->planar_pool = DRW_texture_create_2d_array(1, 1, 1, GPU_RGBA8, DRW_TEX_FILTER | DRW_TEX_MIPMAP, NULL); - txl->planar_depth = DRW_texture_create_2d_array(1, 1, 1, GPU_DEPTH_COMPONENT24, 0, NULL); - } - } + EEVEE_TextureList *txl = vedata->txl; + + /* XXX TODO OPTIMISATION : This is a complete waist of texture memory. + * Instead of allocating each planar probe for each viewport, + * only alloc them once using the biggest viewport resolution. */ + const float *viewport_size = DRW_viewport_size_get(); + + /* TODO get screen percentage from layer setting */ + // const DRWContextState *draw_ctx = DRW_context_state_get(); + // ViewLayer *view_layer = draw_ctx->view_layer; + float screen_percentage = 1.0f; + + int width = max_ii(1, (int)(viewport_size[0] * screen_percentage)); + int height = max_ii(1, (int)(viewport_size[1] * screen_percentage)); + + /* Fix case were the pool was allocated width the dummy size (1,1,1). */ + if (txl->planar_pool && (num_planar_ref > 0) && + (GPU_texture_width(txl->planar_pool) != width || + GPU_texture_height(txl->planar_pool) != height)) { + DRW_TEXTURE_FREE_SAFE(txl->planar_pool); + DRW_TEXTURE_FREE_SAFE(txl->planar_depth); + } + + /* We need an Array texture so allocate it ourself */ + if (!txl->planar_pool) { + if (num_planar_ref > 0) { + txl->planar_pool = DRW_texture_create_2d_array(width, + height, + max_ii(1, num_planar_ref), + GPU_R11F_G11F_B10F, + DRW_TEX_FILTER | DRW_TEX_MIPMAP, + NULL); + txl->planar_depth = DRW_texture_create_2d_array( + width, height, max_ii(1, num_planar_ref), GPU_DEPTH_COMPONENT24, 0, NULL); + } + else if (num_planar_ref == 0) { + /* Makes Opengl Happy : Create a placeholder texture that will never be sampled but still bound to shader. */ + txl->planar_pool = DRW_texture_create_2d_array( + 1, 1, 1, GPU_RGBA8, DRW_TEX_FILTER | DRW_TEX_MIPMAP, NULL); + txl->planar_depth = DRW_texture_create_2d_array(1, 1, 1, GPU_DEPTH_COMPONENT24, 0, NULL); + } + } } void EEVEE_lightprobes_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) { - EEVEE_CommonUniformBuffer *common_data = &sldata->common_data; - EEVEE_StorageList *stl = vedata->stl; + EEVEE_CommonUniformBuffer *common_data = &sldata->common_data; + EEVEE_StorageList *stl = vedata->stl; - const DRWContextState *draw_ctx = DRW_context_state_get(); - const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph); + const DRWContextState *draw_ctx = DRW_context_state_get(); + const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph); - if (!e_data.hammersley) { - EEVEE_shaders_lightprobe_shaders_init(); - e_data.hammersley = create_hammersley_sample_texture(HAMMERSLEY_SIZE); - } + if (!e_data.hammersley) { + EEVEE_shaders_lightprobe_shaders_init(); + e_data.hammersley = create_hammersley_sample_texture(HAMMERSLEY_SIZE); + } - /* Use fallback if we don't have gpu texture allocated an we cannot restore them. */ - bool use_fallback_lightcache = (scene_eval->eevee.light_cache == NULL) || - ((scene_eval->eevee.light_cache->grid_tx.tex == NULL) && - (scene_eval->eevee.light_cache->grid_tx.data == NULL)) || - ((scene_eval->eevee.light_cache->cube_tx.tex == NULL) && - (scene_eval->eevee.light_cache->cube_tx.data == NULL)); + /* Use fallback if we don't have gpu texture allocated an we cannot restore them. */ + bool use_fallback_lightcache = (scene_eval->eevee.light_cache == NULL) || + ((scene_eval->eevee.light_cache->grid_tx.tex == NULL) && + (scene_eval->eevee.light_cache->grid_tx.data == NULL)) || + ((scene_eval->eevee.light_cache->cube_tx.tex == NULL) && + (scene_eval->eevee.light_cache->cube_tx.data == NULL)); - if (use_fallback_lightcache && (sldata->fallback_lightcache == NULL)) { + if (use_fallback_lightcache && (sldata->fallback_lightcache == NULL)) { #if defined(IRRADIANCE_SH_L2) - int grid_res = 4; + int grid_res = 4; #elif defined(IRRADIANCE_CUBEMAP) - int grid_res = 8; + int grid_res = 8; #elif defined(IRRADIANCE_HL2) - int grid_res = 4; + int grid_res = 4; #endif - int cube_res = OCTAHEDRAL_SIZE_FROM_CUBESIZE(scene_eval->eevee.gi_cubemap_resolution); - int vis_res = scene_eval->eevee.gi_visibility_resolution; - sldata->fallback_lightcache = EEVEE_lightcache_create(1, 1, cube_res, vis_res, (int[3]){grid_res, grid_res, 1}); - } - - stl->g_data->light_cache = (use_fallback_lightcache) ? sldata->fallback_lightcache : scene_eval->eevee.light_cache; - - EEVEE_lightcache_load(stl->g_data->light_cache); - - if (!sldata->probes) { - sldata->probes = MEM_callocN(sizeof(EEVEE_LightProbesInfo), "EEVEE_LightProbesInfo"); - sldata->probe_ubo = DRW_uniformbuffer_create(sizeof(EEVEE_LightProbe) * MAX_PROBE, NULL); - sldata->grid_ubo = DRW_uniformbuffer_create(sizeof(EEVEE_LightGrid) * MAX_GRID, NULL); - sldata->planar_ubo = DRW_uniformbuffer_create(sizeof(EEVEE_PlanarReflection) * MAX_PLANAR, NULL); - } - - common_data->prb_num_planar = 0; - common_data->prb_num_render_cube = 1; - common_data->prb_num_render_grid = 1; - - common_data->spec_toggle = true; - common_data->ssr_toggle = true; - common_data->sss_toggle = true; - - /* Placeholder planar pool: used when rendering planar reflections (avoid dependency loop). */ - if (!e_data.planar_pool_placeholder) { - e_data.planar_pool_placeholder = DRW_texture_create_2d_array(1, 1, 1, GPU_RGBA8, DRW_TEX_FILTER, NULL); - } + int cube_res = OCTAHEDRAL_SIZE_FROM_CUBESIZE(scene_eval->eevee.gi_cubemap_resolution); + int vis_res = scene_eval->eevee.gi_visibility_resolution; + sldata->fallback_lightcache = EEVEE_lightcache_create( + 1, 1, cube_res, vis_res, (int[3]){grid_res, grid_res, 1}); + } + + stl->g_data->light_cache = (use_fallback_lightcache) ? sldata->fallback_lightcache : + scene_eval->eevee.light_cache; + + EEVEE_lightcache_load(stl->g_data->light_cache); + + if (!sldata->probes) { + sldata->probes = MEM_callocN(sizeof(EEVEE_LightProbesInfo), "EEVEE_LightProbesInfo"); + sldata->probe_ubo = DRW_uniformbuffer_create(sizeof(EEVEE_LightProbe) * MAX_PROBE, NULL); + sldata->grid_ubo = DRW_uniformbuffer_create(sizeof(EEVEE_LightGrid) * MAX_GRID, NULL); + sldata->planar_ubo = DRW_uniformbuffer_create(sizeof(EEVEE_PlanarReflection) * MAX_PLANAR, + NULL); + } + + common_data->prb_num_planar = 0; + common_data->prb_num_render_cube = 1; + common_data->prb_num_render_grid = 1; + + common_data->spec_toggle = true; + common_data->ssr_toggle = true; + common_data->sss_toggle = true; + + /* Placeholder planar pool: used when rendering planar reflections (avoid dependency loop). */ + if (!e_data.planar_pool_placeholder) { + e_data.planar_pool_placeholder = DRW_texture_create_2d_array( + 1, 1, 1, GPU_RGBA8, DRW_TEX_FILTER, NULL); + } } /* Only init the passes useful for rendering the light cache. */ -void EEVEE_lightbake_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, GPUTexture *rt_color, GPUTexture *rt_depth) +void EEVEE_lightbake_cache_init(EEVEE_ViewLayerData *sldata, + EEVEE_Data *vedata, + GPUTexture *rt_color, + GPUTexture *rt_depth) { - EEVEE_PassList *psl = vedata->psl; - LightCache *light_cache = vedata->stl->g_data->light_cache; - EEVEE_LightProbesInfo *pinfo = sldata->probes; - - { - psl->probe_glossy_compute = DRW_pass_create("LightProbe Glossy Compute", DRW_STATE_WRITE_COLOR); - - DRWShadingGroup *grp = DRW_shgroup_create( - EEVEE_shaders_probe_filter_glossy_sh_get(), psl->probe_glossy_compute); - - DRW_shgroup_uniform_float(grp, "intensityFac", &pinfo->intensity_fac, 1); - DRW_shgroup_uniform_float(grp, "sampleCount", &pinfo->samples_len, 1); - DRW_shgroup_uniform_float(grp, "invSampleCount", &pinfo->samples_len_inv, 1); - DRW_shgroup_uniform_float(grp, "roughnessSquared", &pinfo->roughness, 1); - DRW_shgroup_uniform_float(grp, "lodFactor", &pinfo->lodfactor, 1); - DRW_shgroup_uniform_float(grp, "lodMax", &pinfo->lod_rt_max, 1); - DRW_shgroup_uniform_float(grp, "texelSize", &pinfo->texel_size, 1); - DRW_shgroup_uniform_float(grp, "paddingSize", &pinfo->padding_size, 1); - DRW_shgroup_uniform_float(grp, "fireflyFactor", &pinfo->firefly_fac, 1); - DRW_shgroup_uniform_int(grp, "Layer", &pinfo->layer, 1); - DRW_shgroup_uniform_texture(grp, "texHammersley", e_data.hammersley); - // DRW_shgroup_uniform_texture(grp, "texJitter", e_data.jitter); - DRW_shgroup_uniform_texture(grp, "probeHdr", rt_color); - DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo); - - struct GPUBatch *geom = DRW_cache_fullscreen_quad_get(); - DRW_shgroup_call_add(grp, geom, NULL); - } - - { - psl->probe_diffuse_compute = DRW_pass_create("LightProbe Diffuse Compute", DRW_STATE_WRITE_COLOR); - - DRWShadingGroup *grp = DRW_shgroup_create( - EEVEE_shaders_probe_filter_diffuse_sh_get(), psl->probe_diffuse_compute); + EEVEE_PassList *psl = vedata->psl; + LightCache *light_cache = vedata->stl->g_data->light_cache; + EEVEE_LightProbesInfo *pinfo = sldata->probes; + + { + psl->probe_glossy_compute = DRW_pass_create("LightProbe Glossy Compute", + DRW_STATE_WRITE_COLOR); + + DRWShadingGroup *grp = DRW_shgroup_create(EEVEE_shaders_probe_filter_glossy_sh_get(), + psl->probe_glossy_compute); + + DRW_shgroup_uniform_float(grp, "intensityFac", &pinfo->intensity_fac, 1); + DRW_shgroup_uniform_float(grp, "sampleCount", &pinfo->samples_len, 1); + DRW_shgroup_uniform_float(grp, "invSampleCount", &pinfo->samples_len_inv, 1); + DRW_shgroup_uniform_float(grp, "roughnessSquared", &pinfo->roughness, 1); + DRW_shgroup_uniform_float(grp, "lodFactor", &pinfo->lodfactor, 1); + DRW_shgroup_uniform_float(grp, "lodMax", &pinfo->lod_rt_max, 1); + DRW_shgroup_uniform_float(grp, "texelSize", &pinfo->texel_size, 1); + DRW_shgroup_uniform_float(grp, "paddingSize", &pinfo->padding_size, 1); + DRW_shgroup_uniform_float(grp, "fireflyFactor", &pinfo->firefly_fac, 1); + DRW_shgroup_uniform_int(grp, "Layer", &pinfo->layer, 1); + DRW_shgroup_uniform_texture(grp, "texHammersley", e_data.hammersley); + // DRW_shgroup_uniform_texture(grp, "texJitter", e_data.jitter); + DRW_shgroup_uniform_texture(grp, "probeHdr", rt_color); + DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo); + + struct GPUBatch *geom = DRW_cache_fullscreen_quad_get(); + DRW_shgroup_call_add(grp, geom, NULL); + } + + { + psl->probe_diffuse_compute = DRW_pass_create("LightProbe Diffuse Compute", + DRW_STATE_WRITE_COLOR); + + DRWShadingGroup *grp = DRW_shgroup_create(EEVEE_shaders_probe_filter_diffuse_sh_get(), + psl->probe_diffuse_compute); #ifdef IRRADIANCE_SH_L2 - DRW_shgroup_uniform_int(grp, "probeSize", &pinfo->shres, 1); + DRW_shgroup_uniform_int(grp, "probeSize", &pinfo->shres, 1); #else - DRW_shgroup_uniform_float(grp, "sampleCount", &pinfo->samples_len, 1); - DRW_shgroup_uniform_float(grp, "invSampleCount", &pinfo->samples_len_inv, 1); - DRW_shgroup_uniform_float(grp, "lodFactor", &pinfo->lodfactor, 1); - DRW_shgroup_uniform_float(grp, "lodMax", &pinfo->lod_rt_max, 1); - DRW_shgroup_uniform_texture(grp, "texHammersley", e_data.hammersley); + DRW_shgroup_uniform_float(grp, "sampleCount", &pinfo->samples_len, 1); + DRW_shgroup_uniform_float(grp, "invSampleCount", &pinfo->samples_len_inv, 1); + DRW_shgroup_uniform_float(grp, "lodFactor", &pinfo->lodfactor, 1); + DRW_shgroup_uniform_float(grp, "lodMax", &pinfo->lod_rt_max, 1); + DRW_shgroup_uniform_texture(grp, "texHammersley", e_data.hammersley); #endif - DRW_shgroup_uniform_float(grp, "intensityFac", &pinfo->intensity_fac, 1); - DRW_shgroup_uniform_texture(grp, "probeHdr", rt_color); - DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo); - - struct GPUBatch *geom = DRW_cache_fullscreen_quad_get(); - DRW_shgroup_call_add(grp, geom, NULL); - } - - { - psl->probe_visibility_compute = DRW_pass_create("LightProbe Visibility Compute", DRW_STATE_WRITE_COLOR); - - DRWShadingGroup *grp = DRW_shgroup_create(EEVEE_shaders_probe_filter_visibility_sh_get(), psl->probe_visibility_compute); - DRW_shgroup_uniform_int(grp, "outputSize", &pinfo->shres, 1); - DRW_shgroup_uniform_float(grp, "visibilityRange", &pinfo->visibility_range, 1); - DRW_shgroup_uniform_float(grp, "visibilityBlur", &pinfo->visibility_blur, 1); - DRW_shgroup_uniform_float(grp, "sampleCount", &pinfo->samples_len, 1); - DRW_shgroup_uniform_float(grp, "invSampleCount", &pinfo->samples_len_inv, 1); - DRW_shgroup_uniform_float(grp, "storedTexelSize", &pinfo->texel_size, 1); - DRW_shgroup_uniform_float(grp, "nearClip", &pinfo->near_clip, 1); - DRW_shgroup_uniform_float(grp, "farClip", &pinfo->far_clip, 1); - DRW_shgroup_uniform_texture(grp, "texHammersley", e_data.hammersley); - DRW_shgroup_uniform_texture(grp, "probeDepth", rt_depth); - DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo); - - struct GPUBatch *geom = DRW_cache_fullscreen_quad_get(); - DRW_shgroup_call_add(grp, geom, NULL); - } - - { - psl->probe_grid_fill = DRW_pass_create("LightProbe Grid Floodfill", DRW_STATE_WRITE_COLOR); - - DRWShadingGroup *grp = DRW_shgroup_create( - EEVEE_shaders_probe_grid_fill_sh_get(), psl->probe_grid_fill); - - DRW_shgroup_uniform_texture_ref(grp, "irradianceGrid", &light_cache->grid_tx.tex); - - struct GPUBatch *geom = DRW_cache_fullscreen_quad_get(); - DRW_shgroup_call_add(grp, geom, NULL); - } + DRW_shgroup_uniform_float(grp, "intensityFac", &pinfo->intensity_fac, 1); + DRW_shgroup_uniform_texture(grp, "probeHdr", rt_color); + DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo); + + struct GPUBatch *geom = DRW_cache_fullscreen_quad_get(); + DRW_shgroup_call_add(grp, geom, NULL); + } + + { + psl->probe_visibility_compute = DRW_pass_create("LightProbe Visibility Compute", + DRW_STATE_WRITE_COLOR); + + DRWShadingGroup *grp = DRW_shgroup_create(EEVEE_shaders_probe_filter_visibility_sh_get(), + psl->probe_visibility_compute); + DRW_shgroup_uniform_int(grp, "outputSize", &pinfo->shres, 1); + DRW_shgroup_uniform_float(grp, "visibilityRange", &pinfo->visibility_range, 1); + DRW_shgroup_uniform_float(grp, "visibilityBlur", &pinfo->visibility_blur, 1); + DRW_shgroup_uniform_float(grp, "sampleCount", &pinfo->samples_len, 1); + DRW_shgroup_uniform_float(grp, "invSampleCount", &pinfo->samples_len_inv, 1); + DRW_shgroup_uniform_float(grp, "storedTexelSize", &pinfo->texel_size, 1); + DRW_shgroup_uniform_float(grp, "nearClip", &pinfo->near_clip, 1); + DRW_shgroup_uniform_float(grp, "farClip", &pinfo->far_clip, 1); + DRW_shgroup_uniform_texture(grp, "texHammersley", e_data.hammersley); + DRW_shgroup_uniform_texture(grp, "probeDepth", rt_depth); + DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo); + + struct GPUBatch *geom = DRW_cache_fullscreen_quad_get(); + DRW_shgroup_call_add(grp, geom, NULL); + } + + { + psl->probe_grid_fill = DRW_pass_create("LightProbe Grid Floodfill", DRW_STATE_WRITE_COLOR); + + DRWShadingGroup *grp = DRW_shgroup_create(EEVEE_shaders_probe_grid_fill_sh_get(), + psl->probe_grid_fill); + + DRW_shgroup_uniform_texture_ref(grp, "irradianceGrid", &light_cache->grid_tx.tex); + + struct GPUBatch *geom = DRW_cache_fullscreen_quad_get(); + DRW_shgroup_call_add(grp, geom, NULL); + } } void EEVEE_lightprobes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) { - EEVEE_TextureList *txl = vedata->txl; - EEVEE_PassList *psl = vedata->psl; - EEVEE_StorageList *stl = vedata->stl; - EEVEE_LightProbesInfo *pinfo = sldata->probes; - LightCache *lcache = stl->g_data->light_cache; - const DRWContextState *draw_ctx = DRW_context_state_get(); - const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph); - - pinfo->num_planar = 0; - pinfo->vis_data.collection = NULL; - pinfo->do_grid_update = false; - pinfo->do_cube_update = false; - - { - psl->probe_background = DRW_pass_create("World Probe Background Pass", DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL); - - struct GPUBatch *geom = DRW_cache_fullscreen_quad_get(); - DRWShadingGroup *grp = NULL; - - Scene *scene = draw_ctx->scene; - World *wo = scene->world; - - const float *col = G_draw.block.colorBackground; - - /* LookDev */ - EEVEE_lookdev_cache_init(vedata, &grp, psl->probe_background, 1.0f, wo, pinfo); - /* END */ - if (!grp && wo) { - col = &wo->horr; - - if (wo->use_nodes && wo->nodetree) { - static float error_col[3] = {1.0f, 0.0f, 1.0f}; - struct GPUMaterial *gpumat = EEVEE_material_world_lightprobe_get(scene, wo); - - eGPUMaterialStatus status = GPU_material_status(gpumat); - - switch (status) { - case GPU_MAT_SUCCESS: - grp = DRW_shgroup_material_create(gpumat, psl->probe_background); - DRW_shgroup_uniform_float_copy(grp, "backgroundAlpha", 1.0f); - /* TODO (fclem): remove those (need to clean the GLSL files). */ - DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo); - DRW_shgroup_uniform_block(grp, "grid_block", sldata->grid_ubo); - DRW_shgroup_uniform_block(grp, "probe_block", sldata->probe_ubo); - DRW_shgroup_uniform_block(grp, "planar_block", sldata->planar_ubo); - DRW_shgroup_uniform_block(grp, "light_block", sldata->light_ubo); - DRW_shgroup_uniform_block(grp, "shadow_block", sldata->shadow_ubo); - DRW_shgroup_call_add(grp, geom, NULL); - break; - default: - col = error_col; - break; - } - } - } - - /* Fallback if shader fails or if not using nodetree. */ - if (grp == NULL) { - grp = DRW_shgroup_create(EEVEE_shaders_probe_default_sh_get(), psl->probe_background); - DRW_shgroup_uniform_vec3(grp, "color", col, 1); - DRW_shgroup_uniform_float_copy(grp, "backgroundAlpha", 1.0f); - DRW_shgroup_call_add(grp, geom, NULL); - } - } - - if (DRW_state_draw_support() && !LOOK_DEV_STUDIO_LIGHT_ENABLED(draw_ctx->v3d)) { - DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_CULL_BACK; - psl->probe_display = DRW_pass_create("LightProbe Display", state); - - /* Cube Display */ - if (scene_eval->eevee.flag & SCE_EEVEE_SHOW_CUBEMAPS && lcache->cube_len > 1) { - int cube_len = lcache->cube_len - 1; /* don't count the world. */ - DRWShadingGroup *grp = DRW_shgroup_empty_tri_batch_create( - EEVEE_shaders_probe_cube_display_sh_get(), psl->probe_display, cube_len * 2); - - DRW_shgroup_uniform_texture_ref(grp, "probeCubes", &lcache->cube_tx.tex); - DRW_shgroup_uniform_block(grp, "probe_block", sldata->probe_ubo); - DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo); - DRW_shgroup_uniform_vec3(grp, "screen_vecs[0]", DRW_viewport_screenvecs_get(), 2); - DRW_shgroup_uniform_float_copy(grp, "sphere_size", scene_eval->eevee.gi_cubemap_draw_size * 0.5f); - /* TODO (fclem) get rid of those UBO. */ - DRW_shgroup_uniform_block(grp, "planar_block", sldata->planar_ubo); - DRW_shgroup_uniform_block(grp, "grid_block", sldata->grid_ubo); - } - - /* Grid Display */ - if (scene_eval->eevee.flag & SCE_EEVEE_SHOW_IRRADIANCE) { - EEVEE_LightGrid *egrid = lcache->grid_data + 1; - for (int p = 1; p < lcache->grid_len; ++p, egrid++) { - DRWShadingGroup *shgrp = DRW_shgroup_create( - EEVEE_shaders_probe_grid_display_sh_get(), psl->probe_display); - - DRW_shgroup_uniform_int(shgrp, "offset", &egrid->offset, 1); - DRW_shgroup_uniform_ivec3(shgrp, "grid_resolution", egrid->resolution, 1); - DRW_shgroup_uniform_vec3(shgrp, "corner", egrid->corner, 1); - DRW_shgroup_uniform_vec3(shgrp, "increment_x", egrid->increment_x, 1); - DRW_shgroup_uniform_vec3(shgrp, "increment_y", egrid->increment_y, 1); - DRW_shgroup_uniform_vec3(shgrp, "increment_z", egrid->increment_z, 1); - DRW_shgroup_uniform_vec3(shgrp, "screen_vecs[0]", DRW_viewport_screenvecs_get(), 2); - DRW_shgroup_uniform_texture_ref(shgrp, "irradianceGrid", &lcache->grid_tx.tex); - DRW_shgroup_uniform_float_copy(shgrp, "sphere_size", scene_eval->eevee.gi_irradiance_draw_size * 0.5f); - /* TODO (fclem) get rid of those UBO. */ - DRW_shgroup_uniform_block(shgrp, "probe_block", sldata->probe_ubo); - DRW_shgroup_uniform_block(shgrp, "planar_block", sldata->planar_ubo); - DRW_shgroup_uniform_block(shgrp, "grid_block", sldata->grid_ubo); - DRW_shgroup_uniform_block(shgrp, "common_block", sldata->common_ubo); - int tri_count = egrid->resolution[0] * egrid->resolution[1] * egrid->resolution[2] * 2; - DRW_shgroup_call_procedural_triangles_add(shgrp, tri_count, NULL); - } - } - - /* Planar Display */ - DRW_shgroup_instance_format(e_data.format_probe_display_planar, { - {"probe_id", DRW_ATTR_INT, 1}, - {"probe_mat", DRW_ATTR_FLOAT, 16}, - }); - - DRWShadingGroup *grp = DRW_shgroup_instance_create( - EEVEE_shaders_probe_planar_display_sh_get(), - psl->probe_display, - DRW_cache_quad_get(), - e_data.format_probe_display_planar); - stl->g_data->planar_display_shgrp = grp; - DRW_shgroup_uniform_texture_ref(grp, "probePlanars", &txl->planar_pool); - } - else { - stl->g_data->planar_display_shgrp = NULL; - } - - { - psl->probe_planar_downsample_ps = DRW_pass_create("LightProbe Planar Downsample", DRW_STATE_WRITE_COLOR); - - DRWShadingGroup *grp = DRW_shgroup_create( - EEVEE_shaders_probe_planar_downsample_sh_get(), psl->probe_planar_downsample_ps); - - DRW_shgroup_uniform_texture_ref(grp, "source", &txl->planar_pool); - DRW_shgroup_uniform_float(grp, "fireflyFactor", &sldata->common_data.ssr_firefly_fac, 1); - DRW_shgroup_call_instances_add(grp, DRW_cache_fullscreen_quad_get(), NULL, (uint *)&pinfo->num_planar); - } + EEVEE_TextureList *txl = vedata->txl; + EEVEE_PassList *psl = vedata->psl; + EEVEE_StorageList *stl = vedata->stl; + EEVEE_LightProbesInfo *pinfo = sldata->probes; + LightCache *lcache = stl->g_data->light_cache; + const DRWContextState *draw_ctx = DRW_context_state_get(); + const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph); + + pinfo->num_planar = 0; + pinfo->vis_data.collection = NULL; + pinfo->do_grid_update = false; + pinfo->do_cube_update = false; + + { + psl->probe_background = DRW_pass_create("World Probe Background Pass", + DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL); + + struct GPUBatch *geom = DRW_cache_fullscreen_quad_get(); + DRWShadingGroup *grp = NULL; + + Scene *scene = draw_ctx->scene; + World *wo = scene->world; + + const float *col = G_draw.block.colorBackground; + + /* LookDev */ + EEVEE_lookdev_cache_init(vedata, &grp, psl->probe_background, 1.0f, wo, pinfo); + /* END */ + if (!grp && wo) { + col = &wo->horr; + + if (wo->use_nodes && wo->nodetree) { + static float error_col[3] = {1.0f, 0.0f, 1.0f}; + struct GPUMaterial *gpumat = EEVEE_material_world_lightprobe_get(scene, wo); + + eGPUMaterialStatus status = GPU_material_status(gpumat); + + switch (status) { + case GPU_MAT_SUCCESS: + grp = DRW_shgroup_material_create(gpumat, psl->probe_background); + DRW_shgroup_uniform_float_copy(grp, "backgroundAlpha", 1.0f); + /* TODO (fclem): remove those (need to clean the GLSL files). */ + DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo); + DRW_shgroup_uniform_block(grp, "grid_block", sldata->grid_ubo); + DRW_shgroup_uniform_block(grp, "probe_block", sldata->probe_ubo); + DRW_shgroup_uniform_block(grp, "planar_block", sldata->planar_ubo); + DRW_shgroup_uniform_block(grp, "light_block", sldata->light_ubo); + DRW_shgroup_uniform_block(grp, "shadow_block", sldata->shadow_ubo); + DRW_shgroup_call_add(grp, geom, NULL); + break; + default: + col = error_col; + break; + } + } + } + + /* Fallback if shader fails or if not using nodetree. */ + if (grp == NULL) { + grp = DRW_shgroup_create(EEVEE_shaders_probe_default_sh_get(), psl->probe_background); + DRW_shgroup_uniform_vec3(grp, "color", col, 1); + DRW_shgroup_uniform_float_copy(grp, "backgroundAlpha", 1.0f); + DRW_shgroup_call_add(grp, geom, NULL); + } + } + + if (DRW_state_draw_support() && !LOOK_DEV_STUDIO_LIGHT_ENABLED(draw_ctx->v3d)) { + DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | + DRW_STATE_CULL_BACK; + psl->probe_display = DRW_pass_create("LightProbe Display", state); + + /* Cube Display */ + if (scene_eval->eevee.flag & SCE_EEVEE_SHOW_CUBEMAPS && lcache->cube_len > 1) { + int cube_len = lcache->cube_len - 1; /* don't count the world. */ + DRWShadingGroup *grp = DRW_shgroup_empty_tri_batch_create( + EEVEE_shaders_probe_cube_display_sh_get(), psl->probe_display, cube_len * 2); + + DRW_shgroup_uniform_texture_ref(grp, "probeCubes", &lcache->cube_tx.tex); + DRW_shgroup_uniform_block(grp, "probe_block", sldata->probe_ubo); + DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo); + DRW_shgroup_uniform_vec3(grp, "screen_vecs[0]", DRW_viewport_screenvecs_get(), 2); + DRW_shgroup_uniform_float_copy( + grp, "sphere_size", scene_eval->eevee.gi_cubemap_draw_size * 0.5f); + /* TODO (fclem) get rid of those UBO. */ + DRW_shgroup_uniform_block(grp, "planar_block", sldata->planar_ubo); + DRW_shgroup_uniform_block(grp, "grid_block", sldata->grid_ubo); + } + + /* Grid Display */ + if (scene_eval->eevee.flag & SCE_EEVEE_SHOW_IRRADIANCE) { + EEVEE_LightGrid *egrid = lcache->grid_data + 1; + for (int p = 1; p < lcache->grid_len; ++p, egrid++) { + DRWShadingGroup *shgrp = DRW_shgroup_create(EEVEE_shaders_probe_grid_display_sh_get(), + psl->probe_display); + + DRW_shgroup_uniform_int(shgrp, "offset", &egrid->offset, 1); + DRW_shgroup_uniform_ivec3(shgrp, "grid_resolution", egrid->resolution, 1); + DRW_shgroup_uniform_vec3(shgrp, "corner", egrid->corner, 1); + DRW_shgroup_uniform_vec3(shgrp, "increment_x", egrid->increment_x, 1); + DRW_shgroup_uniform_vec3(shgrp, "increment_y", egrid->increment_y, 1); + DRW_shgroup_uniform_vec3(shgrp, "increment_z", egrid->increment_z, 1); + DRW_shgroup_uniform_vec3(shgrp, "screen_vecs[0]", DRW_viewport_screenvecs_get(), 2); + DRW_shgroup_uniform_texture_ref(shgrp, "irradianceGrid", &lcache->grid_tx.tex); + DRW_shgroup_uniform_float_copy( + shgrp, "sphere_size", scene_eval->eevee.gi_irradiance_draw_size * 0.5f); + /* TODO (fclem) get rid of those UBO. */ + DRW_shgroup_uniform_block(shgrp, "probe_block", sldata->probe_ubo); + DRW_shgroup_uniform_block(shgrp, "planar_block", sldata->planar_ubo); + DRW_shgroup_uniform_block(shgrp, "grid_block", sldata->grid_ubo); + DRW_shgroup_uniform_block(shgrp, "common_block", sldata->common_ubo); + int tri_count = egrid->resolution[0] * egrid->resolution[1] * egrid->resolution[2] * 2; + DRW_shgroup_call_procedural_triangles_add(shgrp, tri_count, NULL); + } + } + + /* Planar Display */ + DRW_shgroup_instance_format(e_data.format_probe_display_planar, + { + {"probe_id", DRW_ATTR_INT, 1}, + {"probe_mat", DRW_ATTR_FLOAT, 16}, + }); + + DRWShadingGroup *grp = DRW_shgroup_instance_create(EEVEE_shaders_probe_planar_display_sh_get(), + psl->probe_display, + DRW_cache_quad_get(), + e_data.format_probe_display_planar); + stl->g_data->planar_display_shgrp = grp; + DRW_shgroup_uniform_texture_ref(grp, "probePlanars", &txl->planar_pool); + } + else { + stl->g_data->planar_display_shgrp = NULL; + } + + { + psl->probe_planar_downsample_ps = DRW_pass_create("LightProbe Planar Downsample", + DRW_STATE_WRITE_COLOR); + + DRWShadingGroup *grp = DRW_shgroup_create(EEVEE_shaders_probe_planar_downsample_sh_get(), + psl->probe_planar_downsample_ps); + + DRW_shgroup_uniform_texture_ref(grp, "source", &txl->planar_pool); + DRW_shgroup_uniform_float(grp, "fireflyFactor", &sldata->common_data.ssr_firefly_fac, 1); + DRW_shgroup_call_instances_add( + grp, DRW_cache_fullscreen_quad_get(), NULL, (uint *)&pinfo->num_planar); + } } static bool eevee_lightprobes_culling_test(Object *ob) { - LightProbe *probe = (LightProbe *)ob->data; - - switch (probe->type) { - case LIGHTPROBE_TYPE_PLANAR: - { - /* See if this planar probe is inside the view frustum. If not, no need to update it. */ - /* NOTE: this could be bypassed if we want feedback loop mirrors for rendering. */ - BoundBox bbox; float tmp[4][4]; - const float min[3] = {-1.0f, -1.0f, -1.0f}; - const float max[3] = { 1.0f, 1.0f, 1.0f}; - BKE_boundbox_init_from_minmax(&bbox, min, max); - - copy_m4_m4(tmp, ob->obmat); - normalize_v3(tmp[2]); - mul_v3_fl(tmp[2], probe->distinf); - - for (int v = 0; v < 8; ++v) { - mul_m4_v3(tmp, bbox.vec[v]); - } - return DRW_culling_box_test(&bbox); - } - case LIGHTPROBE_TYPE_CUBE: - return true; /* TODO */ - case LIGHTPROBE_TYPE_GRID: - return true; /* TODO */ - } - BLI_assert(0); - return true; + LightProbe *probe = (LightProbe *)ob->data; + + switch (probe->type) { + case LIGHTPROBE_TYPE_PLANAR: { + /* See if this planar probe is inside the view frustum. If not, no need to update it. */ + /* NOTE: this could be bypassed if we want feedback loop mirrors for rendering. */ + BoundBox bbox; + float tmp[4][4]; + const float min[3] = {-1.0f, -1.0f, -1.0f}; + const float max[3] = {1.0f, 1.0f, 1.0f}; + BKE_boundbox_init_from_minmax(&bbox, min, max); + + copy_m4_m4(tmp, ob->obmat); + normalize_v3(tmp[2]); + mul_v3_fl(tmp[2], probe->distinf); + + for (int v = 0; v < 8; ++v) { + mul_m4_v3(tmp, bbox.vec[v]); + } + return DRW_culling_box_test(&bbox); + } + case LIGHTPROBE_TYPE_CUBE: + return true; /* TODO */ + case LIGHTPROBE_TYPE_GRID: + return true; /* TODO */ + } + BLI_assert(0); + return true; } void EEVEE_lightprobes_cache_add(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, Object *ob) { - EEVEE_LightProbesInfo *pinfo = sldata->probes; - LightProbe *probe = (LightProbe *)ob->data; - - if ((probe->type == LIGHTPROBE_TYPE_CUBE && pinfo->num_cube >= MAX_PROBE) || - (probe->type == LIGHTPROBE_TYPE_GRID && pinfo->num_grid >= MAX_PROBE) || - (probe->type == LIGHTPROBE_TYPE_PLANAR && pinfo->num_planar >= MAX_PLANAR)) - { - printf("Too many probes in the view !!!\n"); - return; - } - - if (probe->type == LIGHTPROBE_TYPE_PLANAR) { - if (!eevee_lightprobes_culling_test(ob)) { - return; /* Culled */ - } - EEVEE_lightprobes_planar_data_from_object(ob, - &pinfo->planar_data[pinfo->num_planar], - &pinfo->planar_vis_tests[pinfo->num_planar]); - /* Debug Display */ - DRWShadingGroup *grp = vedata->stl->g_data->planar_display_shgrp; - if (grp && (probe->flag & LIGHTPROBE_FLAG_SHOW_DATA)) { - DRW_shgroup_call_dynamic_add(grp, &pinfo->num_planar, ob->obmat); - } - - pinfo->num_planar++; - } - else { - EEVEE_LightProbeEngineData *ped = EEVEE_lightprobe_data_ensure(ob); - if (ped->need_update) { - if (probe->type == LIGHTPROBE_TYPE_GRID) { - pinfo->do_grid_update = true; - } - else { - pinfo->do_cube_update = true; - } - ped->need_update = false; - } - } + EEVEE_LightProbesInfo *pinfo = sldata->probes; + LightProbe *probe = (LightProbe *)ob->data; + + if ((probe->type == LIGHTPROBE_TYPE_CUBE && pinfo->num_cube >= MAX_PROBE) || + (probe->type == LIGHTPROBE_TYPE_GRID && pinfo->num_grid >= MAX_PROBE) || + (probe->type == LIGHTPROBE_TYPE_PLANAR && pinfo->num_planar >= MAX_PLANAR)) { + printf("Too many probes in the view !!!\n"); + return; + } + + if (probe->type == LIGHTPROBE_TYPE_PLANAR) { + if (!eevee_lightprobes_culling_test(ob)) { + return; /* Culled */ + } + EEVEE_lightprobes_planar_data_from_object( + ob, &pinfo->planar_data[pinfo->num_planar], &pinfo->planar_vis_tests[pinfo->num_planar]); + /* Debug Display */ + DRWShadingGroup *grp = vedata->stl->g_data->planar_display_shgrp; + if (grp && (probe->flag & LIGHTPROBE_FLAG_SHOW_DATA)) { + DRW_shgroup_call_dynamic_add(grp, &pinfo->num_planar, ob->obmat); + } + + pinfo->num_planar++; + } + else { + EEVEE_LightProbeEngineData *ped = EEVEE_lightprobe_data_ensure(ob); + if (ped->need_update) { + if (probe->type == LIGHTPROBE_TYPE_GRID) { + pinfo->do_grid_update = true; + } + else { + pinfo->do_cube_update = true; + } + ped->need_update = false; + } + } } void EEVEE_lightprobes_grid_data_from_object(Object *ob, EEVEE_LightGrid *egrid, int *offset) { - LightProbe *probe = (LightProbe *)ob->data; - - copy_v3_v3_int(egrid->resolution, &probe->grid_resolution_x); - - /* Save current offset and advance it for the next grid. */ - egrid->offset = *offset; - *offset += egrid->resolution[0] * egrid->resolution[1] * egrid->resolution[2]; - - /* Add one for level 0 */ - float fac = 1.0f / max_ff(1e-8f, probe->falloff); - egrid->attenuation_scale = fac / max_ff(1e-8f, probe->distinf); - egrid->attenuation_bias = fac; - - /* Update transforms */ - float cell_dim[3], half_cell_dim[3]; - cell_dim[0] = 2.0f / egrid->resolution[0]; - cell_dim[1] = 2.0f / egrid->resolution[1]; - cell_dim[2] = 2.0f / egrid->resolution[2]; - - mul_v3_v3fl(half_cell_dim, cell_dim, 0.5f); - - /* Matrix converting world space to cell ranges. */ - invert_m4_m4(egrid->mat, ob->obmat); - - /* First cell. */ - copy_v3_fl(egrid->corner, -1.0f); - add_v3_v3(egrid->corner, half_cell_dim); - mul_m4_v3(ob->obmat, egrid->corner); - - /* Opposite neighbor cell. */ - copy_v3_fl3(egrid->increment_x, cell_dim[0], 0.0f, 0.0f); - add_v3_v3(egrid->increment_x, half_cell_dim); - add_v3_fl(egrid->increment_x, -1.0f); - mul_m4_v3(ob->obmat, egrid->increment_x); - sub_v3_v3(egrid->increment_x, egrid->corner); - - copy_v3_fl3(egrid->increment_y, 0.0f, cell_dim[1], 0.0f); - add_v3_v3(egrid->increment_y, half_cell_dim); - add_v3_fl(egrid->increment_y, -1.0f); - mul_m4_v3(ob->obmat, egrid->increment_y); - sub_v3_v3(egrid->increment_y, egrid->corner); - - copy_v3_fl3(egrid->increment_z, 0.0f, 0.0f, cell_dim[2]); - add_v3_v3(egrid->increment_z, half_cell_dim); - add_v3_fl(egrid->increment_z, -1.0f); - mul_m4_v3(ob->obmat, egrid->increment_z); - sub_v3_v3(egrid->increment_z, egrid->corner); - - /* Visibility bias */ - egrid->visibility_bias = 0.05f * probe->vis_bias; - egrid->visibility_bleed = probe->vis_bleedbias; - egrid->visibility_range = 1.0f + sqrtf(max_fff(len_squared_v3(egrid->increment_x), - len_squared_v3(egrid->increment_y), - len_squared_v3(egrid->increment_z))); + LightProbe *probe = (LightProbe *)ob->data; + + copy_v3_v3_int(egrid->resolution, &probe->grid_resolution_x); + + /* Save current offset and advance it for the next grid. */ + egrid->offset = *offset; + *offset += egrid->resolution[0] * egrid->resolution[1] * egrid->resolution[2]; + + /* Add one for level 0 */ + float fac = 1.0f / max_ff(1e-8f, probe->falloff); + egrid->attenuation_scale = fac / max_ff(1e-8f, probe->distinf); + egrid->attenuation_bias = fac; + + /* Update transforms */ + float cell_dim[3], half_cell_dim[3]; + cell_dim[0] = 2.0f / egrid->resolution[0]; + cell_dim[1] = 2.0f / egrid->resolution[1]; + cell_dim[2] = 2.0f / egrid->resolution[2]; + + mul_v3_v3fl(half_cell_dim, cell_dim, 0.5f); + + /* Matrix converting world space to cell ranges. */ + invert_m4_m4(egrid->mat, ob->obmat); + + /* First cell. */ + copy_v3_fl(egrid->corner, -1.0f); + add_v3_v3(egrid->corner, half_cell_dim); + mul_m4_v3(ob->obmat, egrid->corner); + + /* Opposite neighbor cell. */ + copy_v3_fl3(egrid->increment_x, cell_dim[0], 0.0f, 0.0f); + add_v3_v3(egrid->increment_x, half_cell_dim); + add_v3_fl(egrid->increment_x, -1.0f); + mul_m4_v3(ob->obmat, egrid->increment_x); + sub_v3_v3(egrid->increment_x, egrid->corner); + + copy_v3_fl3(egrid->increment_y, 0.0f, cell_dim[1], 0.0f); + add_v3_v3(egrid->increment_y, half_cell_dim); + add_v3_fl(egrid->increment_y, -1.0f); + mul_m4_v3(ob->obmat, egrid->increment_y); + sub_v3_v3(egrid->increment_y, egrid->corner); + + copy_v3_fl3(egrid->increment_z, 0.0f, 0.0f, cell_dim[2]); + add_v3_v3(egrid->increment_z, half_cell_dim); + add_v3_fl(egrid->increment_z, -1.0f); + mul_m4_v3(ob->obmat, egrid->increment_z); + sub_v3_v3(egrid->increment_z, egrid->corner); + + /* Visibility bias */ + egrid->visibility_bias = 0.05f * probe->vis_bias; + egrid->visibility_bleed = probe->vis_bleedbias; + egrid->visibility_range = 1.0f + sqrtf(max_fff(len_squared_v3(egrid->increment_x), + len_squared_v3(egrid->increment_y), + len_squared_v3(egrid->increment_z))); } void EEVEE_lightprobes_cube_data_from_object(Object *ob, EEVEE_LightProbe *eprobe) { - LightProbe *probe = (LightProbe *)ob->data; - - /* Update transforms */ - copy_v3_v3(eprobe->position, ob->obmat[3]); - - /* Attenuation */ - eprobe->attenuation_type = probe->attenuation_type; - eprobe->attenuation_fac = 1.0f / max_ff(1e-8f, probe->falloff); - - unit_m4(eprobe->attenuationmat); - scale_m4_fl(eprobe->attenuationmat, probe->distinf); - mul_m4_m4m4(eprobe->attenuationmat, ob->obmat, eprobe->attenuationmat); - invert_m4(eprobe->attenuationmat); - - /* Parallax */ - unit_m4(eprobe->parallaxmat); - - if ((probe->flag & LIGHTPROBE_FLAG_CUSTOM_PARALLAX) != 0) { - eprobe->parallax_type = probe->parallax_type; - scale_m4_fl(eprobe->parallaxmat, probe->distpar); - } - else { - eprobe->parallax_type = probe->attenuation_type; - scale_m4_fl(eprobe->parallaxmat, probe->distinf); - } - - mul_m4_m4m4(eprobe->parallaxmat, ob->obmat, eprobe->parallaxmat); - invert_m4(eprobe->parallaxmat); + LightProbe *probe = (LightProbe *)ob->data; + + /* Update transforms */ + copy_v3_v3(eprobe->position, ob->obmat[3]); + + /* Attenuation */ + eprobe->attenuation_type = probe->attenuation_type; + eprobe->attenuation_fac = 1.0f / max_ff(1e-8f, probe->falloff); + + unit_m4(eprobe->attenuationmat); + scale_m4_fl(eprobe->attenuationmat, probe->distinf); + mul_m4_m4m4(eprobe->attenuationmat, ob->obmat, eprobe->attenuationmat); + invert_m4(eprobe->attenuationmat); + + /* Parallax */ + unit_m4(eprobe->parallaxmat); + + if ((probe->flag & LIGHTPROBE_FLAG_CUSTOM_PARALLAX) != 0) { + eprobe->parallax_type = probe->parallax_type; + scale_m4_fl(eprobe->parallaxmat, probe->distpar); + } + else { + eprobe->parallax_type = probe->attenuation_type; + scale_m4_fl(eprobe->parallaxmat, probe->distinf); + } + + mul_m4_m4m4(eprobe->parallaxmat, ob->obmat, eprobe->parallaxmat); + invert_m4(eprobe->parallaxmat); } -void EEVEE_lightprobes_planar_data_from_object(Object *ob, EEVEE_PlanarReflection *eplanar, EEVEE_LightProbeVisTest *vis_test) +void EEVEE_lightprobes_planar_data_from_object(Object *ob, + EEVEE_PlanarReflection *eplanar, + EEVEE_LightProbeVisTest *vis_test) { - LightProbe *probe = (LightProbe *)ob->data; - float normat[4][4], imat[4][4]; - - vis_test->collection = probe->visibility_grp; - vis_test->invert = probe->flag & LIGHTPROBE_FLAG_INVERT_GROUP; - vis_test->cached = false; - - /* Computing mtx : matrix that mirror position around object's XY plane. */ - normalize_m4_m4(normat, ob->obmat); /* object > world */ - invert_m4_m4(imat, normat); /* world > object */ - /* XY reflection plane */ - imat[0][2] = -imat[0][2]; - imat[1][2] = -imat[1][2]; - imat[2][2] = -imat[2][2]; - imat[3][2] = -imat[3][2]; /* world > object > mirrored obj */ - mul_m4_m4m4(eplanar->mtx, normat, imat); /* world > object > mirrored obj > world */ - - /* Compute clip plane equation / normal. */ - copy_v3_v3(eplanar->plane_equation, ob->obmat[2]); - normalize_v3(eplanar->plane_equation); /* plane normal */ - eplanar->plane_equation[3] = -dot_v3v3(eplanar->plane_equation, ob->obmat[3]); - eplanar->clipsta = probe->clipsta; - - /* Compute XY clip planes. */ - normalize_v3_v3(eplanar->clip_vec_x, ob->obmat[0]); - normalize_v3_v3(eplanar->clip_vec_y, ob->obmat[1]); - - float vec[3] = {0.0f, 0.0f, 0.0f}; - vec[0] = 1.0f; vec[1] = 0.0f; vec[2] = 0.0f; - mul_m4_v3(ob->obmat, vec); /* Point on the edge */ - eplanar->clip_edge_x_pos = dot_v3v3(eplanar->clip_vec_x, vec); - - vec[0] = 0.0f; vec[1] = 1.0f; vec[2] = 0.0f; - mul_m4_v3(ob->obmat, vec); /* Point on the edge */ - eplanar->clip_edge_y_pos = dot_v3v3(eplanar->clip_vec_y, vec); - - vec[0] = -1.0f; vec[1] = 0.0f; vec[2] = 0.0f; - mul_m4_v3(ob->obmat, vec); /* Point on the edge */ - eplanar->clip_edge_x_neg = dot_v3v3(eplanar->clip_vec_x, vec); - - vec[0] = 0.0f; vec[1] = -1.0f; vec[2] = 0.0f; - mul_m4_v3(ob->obmat, vec); /* Point on the edge */ - eplanar->clip_edge_y_neg = dot_v3v3(eplanar->clip_vec_y, vec); - - /* Facing factors */ - float max_angle = max_ff(1e-2f, 1.0f - probe->falloff) * M_PI * 0.5f; - float min_angle = 0.0f; - eplanar->facing_scale = 1.0f / max_ff(1e-8f, cosf(min_angle) - cosf(max_angle)); - eplanar->facing_bias = -min_ff(1.0f - 1e-8f, cosf(max_angle)) * eplanar->facing_scale; - - /* Distance factors */ - float max_dist = probe->distinf; - float min_dist = min_ff(1.0f - 1e-8f, 1.0f - probe->falloff) * probe->distinf; - eplanar->attenuation_scale = -1.0f / max_ff(1e-8f, max_dist - min_dist); - eplanar->attenuation_bias = max_dist * -eplanar->attenuation_scale; + LightProbe *probe = (LightProbe *)ob->data; + float normat[4][4], imat[4][4]; + + vis_test->collection = probe->visibility_grp; + vis_test->invert = probe->flag & LIGHTPROBE_FLAG_INVERT_GROUP; + vis_test->cached = false; + + /* Computing mtx : matrix that mirror position around object's XY plane. */ + normalize_m4_m4(normat, ob->obmat); /* object > world */ + invert_m4_m4(imat, normat); /* world > object */ + /* XY reflection plane */ + imat[0][2] = -imat[0][2]; + imat[1][2] = -imat[1][2]; + imat[2][2] = -imat[2][2]; + imat[3][2] = -imat[3][2]; /* world > object > mirrored obj */ + mul_m4_m4m4(eplanar->mtx, normat, imat); /* world > object > mirrored obj > world */ + + /* Compute clip plane equation / normal. */ + copy_v3_v3(eplanar->plane_equation, ob->obmat[2]); + normalize_v3(eplanar->plane_equation); /* plane normal */ + eplanar->plane_equation[3] = -dot_v3v3(eplanar->plane_equation, ob->obmat[3]); + eplanar->clipsta = probe->clipsta; + + /* Compute XY clip planes. */ + normalize_v3_v3(eplanar->clip_vec_x, ob->obmat[0]); + normalize_v3_v3(eplanar->clip_vec_y, ob->obmat[1]); + + float vec[3] = {0.0f, 0.0f, 0.0f}; + vec[0] = 1.0f; + vec[1] = 0.0f; + vec[2] = 0.0f; + mul_m4_v3(ob->obmat, vec); /* Point on the edge */ + eplanar->clip_edge_x_pos = dot_v3v3(eplanar->clip_vec_x, vec); + + vec[0] = 0.0f; + vec[1] = 1.0f; + vec[2] = 0.0f; + mul_m4_v3(ob->obmat, vec); /* Point on the edge */ + eplanar->clip_edge_y_pos = dot_v3v3(eplanar->clip_vec_y, vec); + + vec[0] = -1.0f; + vec[1] = 0.0f; + vec[2] = 0.0f; + mul_m4_v3(ob->obmat, vec); /* Point on the edge */ + eplanar->clip_edge_x_neg = dot_v3v3(eplanar->clip_vec_x, vec); + + vec[0] = 0.0f; + vec[1] = -1.0f; + vec[2] = 0.0f; + mul_m4_v3(ob->obmat, vec); /* Point on the edge */ + eplanar->clip_edge_y_neg = dot_v3v3(eplanar->clip_vec_y, vec); + + /* Facing factors */ + float max_angle = max_ff(1e-2f, 1.0f - probe->falloff) * M_PI * 0.5f; + float min_angle = 0.0f; + eplanar->facing_scale = 1.0f / max_ff(1e-8f, cosf(min_angle) - cosf(max_angle)); + eplanar->facing_bias = -min_ff(1.0f - 1e-8f, cosf(max_angle)) * eplanar->facing_scale; + + /* Distance factors */ + float max_dist = probe->distinf; + float min_dist = min_ff(1.0f - 1e-8f, 1.0f - probe->falloff) * probe->distinf; + eplanar->attenuation_scale = -1.0f / max_ff(1e-8f, max_dist - min_dist); + eplanar->attenuation_bias = max_dist * -eplanar->attenuation_scale; } -static void lightbake_planar_compute_render_matrices( - EEVEE_PlanarReflection *eplanar, DRWMatrixState *r_matstate, - const float viewmat[4][4], const float winmat[4][4]) +static void lightbake_planar_compute_render_matrices(EEVEE_PlanarReflection *eplanar, + DRWMatrixState *r_matstate, + const float viewmat[4][4], + const float winmat[4][4]) { - /* Temporal sampling jitter should be already applied to the DRW_MAT_WIN. */ - copy_m4_m4(r_matstate->winmat, winmat); - /* Invert X to avoid flipping the triangle facing direction. */ - r_matstate->winmat[0][0] = -r_matstate->winmat[0][0]; - r_matstate->winmat[1][0] = -r_matstate->winmat[1][0]; - r_matstate->winmat[2][0] = -r_matstate->winmat[2][0]; - r_matstate->winmat[3][0] = -r_matstate->winmat[3][0]; - /* Reflect Camera Matrix. */ - mul_m4_m4m4(r_matstate->viewmat, viewmat, eplanar->mtx); - /* Apply Projection Matrix. */ - mul_m4_m4m4(r_matstate->persmat, r_matstate->winmat, r_matstate->viewmat); + /* Temporal sampling jitter should be already applied to the DRW_MAT_WIN. */ + copy_m4_m4(r_matstate->winmat, winmat); + /* Invert X to avoid flipping the triangle facing direction. */ + r_matstate->winmat[0][0] = -r_matstate->winmat[0][0]; + r_matstate->winmat[1][0] = -r_matstate->winmat[1][0]; + r_matstate->winmat[2][0] = -r_matstate->winmat[2][0]; + r_matstate->winmat[3][0] = -r_matstate->winmat[3][0]; + /* Reflect Camera Matrix. */ + mul_m4_m4m4(r_matstate->viewmat, viewmat, eplanar->mtx); + /* Apply Projection Matrix. */ + mul_m4_m4m4(r_matstate->persmat, r_matstate->winmat, r_matstate->viewmat); } static void eevee_lightprobes_extract_from_cache(EEVEE_LightProbesInfo *pinfo, LightCache *lcache) { - /* copy the entire cache for now (up to MAX_PROBE) */ - /* TODO Frutum cull to only add visible probes. */ - memcpy(pinfo->probe_data, lcache->cube_data, sizeof(EEVEE_LightProbe) * max_ii(1, min_ii(lcache->cube_len, MAX_PROBE))); - /* TODO compute the max number of grid based on sample count. */ - memcpy(pinfo->grid_data, lcache->grid_data, sizeof(EEVEE_LightGrid) * max_ii(1, min_ii(lcache->grid_len, MAX_GRID))); + /* copy the entire cache for now (up to MAX_PROBE) */ + /* TODO Frutum cull to only add visible probes. */ + memcpy(pinfo->probe_data, + lcache->cube_data, + sizeof(EEVEE_LightProbe) * max_ii(1, min_ii(lcache->cube_len, MAX_PROBE))); + /* TODO compute the max number of grid based on sample count. */ + memcpy(pinfo->grid_data, + lcache->grid_data, + sizeof(EEVEE_LightGrid) * max_ii(1, min_ii(lcache->grid_len, MAX_GRID))); } void EEVEE_lightprobes_cache_finish(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) { - EEVEE_StorageList *stl = vedata->stl; - LightCache *light_cache = stl->g_data->light_cache; - EEVEE_LightProbesInfo *pinfo = sldata->probes; - const DRWContextState *draw_ctx = DRW_context_state_get(); - const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph); - - eevee_lightprobes_extract_from_cache(sldata->probes, light_cache); - - DRW_uniformbuffer_update(sldata->probe_ubo, &sldata->probes->probe_data); - DRW_uniformbuffer_update(sldata->grid_ubo, &sldata->probes->grid_data); - - /* For shading, save max level of the octahedron map */ - sldata->common_data.prb_lod_cube_max = (float)light_cache->mips_len - 1.0f; - sldata->common_data.prb_lod_planar_max = (float)MAX_PLANAR_LOD_LEVEL; - sldata->common_data.prb_irradiance_vis_size = light_cache->vis_res; - sldata->common_data.prb_irradiance_smooth = SQUARE(scene_eval->eevee.gi_irradiance_smoothing); - sldata->common_data.prb_num_render_cube = max_ii(1, light_cache->cube_len); - sldata->common_data.prb_num_render_grid = max_ii(1, light_cache->grid_len); - sldata->common_data.prb_num_planar = pinfo->num_planar; - - if (pinfo->num_planar != pinfo->cache_num_planar) { - DRW_TEXTURE_FREE_SAFE(vedata->txl->planar_pool); - DRW_TEXTURE_FREE_SAFE(vedata->txl->planar_depth); - pinfo->cache_num_planar = pinfo->num_planar; - } - planar_pool_ensure_alloc(vedata, pinfo->num_planar); - - /* If lightcache auto-update is enable we tag the relevant part - * of the cache to update and fire up a baking job. */ - if (!DRW_state_is_image_render() && !DRW_state_is_opengl_render() && - (pinfo->do_grid_update || pinfo->do_cube_update)) - { - BLI_assert(draw_ctx->evil_C); - - if (draw_ctx->scene->eevee.flag & SCE_EEVEE_GI_AUTOBAKE) { - Scene *scene_orig = DEG_get_input_scene(draw_ctx->depsgraph); - if (scene_orig->eevee.light_cache != NULL) { - if (pinfo->do_grid_update) { - scene_orig->eevee.light_cache->flag |= LIGHTCACHE_UPDATE_GRID; - } - /* If we update grid we need to update the cubemaps too. - * So always refresh cubemaps. */ - scene_orig->eevee.light_cache->flag |= LIGHTCACHE_UPDATE_CUBE; - /* Tag the lightcache to auto update. */ - scene_orig->eevee.light_cache->flag |= LIGHTCACHE_UPDATE_AUTO; - /* Use a notifier to trigger the operator after drawing. */ - WM_event_add_notifier(draw_ctx->evil_C, NC_LIGHTPROBE, scene_orig); - } - } - } + EEVEE_StorageList *stl = vedata->stl; + LightCache *light_cache = stl->g_data->light_cache; + EEVEE_LightProbesInfo *pinfo = sldata->probes; + const DRWContextState *draw_ctx = DRW_context_state_get(); + const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph); + + eevee_lightprobes_extract_from_cache(sldata->probes, light_cache); + + DRW_uniformbuffer_update(sldata->probe_ubo, &sldata->probes->probe_data); + DRW_uniformbuffer_update(sldata->grid_ubo, &sldata->probes->grid_data); + + /* For shading, save max level of the octahedron map */ + sldata->common_data.prb_lod_cube_max = (float)light_cache->mips_len - 1.0f; + sldata->common_data.prb_lod_planar_max = (float)MAX_PLANAR_LOD_LEVEL; + sldata->common_data.prb_irradiance_vis_size = light_cache->vis_res; + sldata->common_data.prb_irradiance_smooth = SQUARE(scene_eval->eevee.gi_irradiance_smoothing); + sldata->common_data.prb_num_render_cube = max_ii(1, light_cache->cube_len); + sldata->common_data.prb_num_render_grid = max_ii(1, light_cache->grid_len); + sldata->common_data.prb_num_planar = pinfo->num_planar; + + if (pinfo->num_planar != pinfo->cache_num_planar) { + DRW_TEXTURE_FREE_SAFE(vedata->txl->planar_pool); + DRW_TEXTURE_FREE_SAFE(vedata->txl->planar_depth); + pinfo->cache_num_planar = pinfo->num_planar; + } + planar_pool_ensure_alloc(vedata, pinfo->num_planar); + + /* If lightcache auto-update is enable we tag the relevant part + * of the cache to update and fire up a baking job. */ + if (!DRW_state_is_image_render() && !DRW_state_is_opengl_render() && + (pinfo->do_grid_update || pinfo->do_cube_update)) { + BLI_assert(draw_ctx->evil_C); + + if (draw_ctx->scene->eevee.flag & SCE_EEVEE_GI_AUTOBAKE) { + Scene *scene_orig = DEG_get_input_scene(draw_ctx->depsgraph); + if (scene_orig->eevee.light_cache != NULL) { + if (pinfo->do_grid_update) { + scene_orig->eevee.light_cache->flag |= LIGHTCACHE_UPDATE_GRID; + } + /* If we update grid we need to update the cubemaps too. + * So always refresh cubemaps. */ + scene_orig->eevee.light_cache->flag |= LIGHTCACHE_UPDATE_CUBE; + /* Tag the lightcache to auto update. */ + scene_orig->eevee.light_cache->flag |= LIGHTCACHE_UPDATE_AUTO; + /* Use a notifier to trigger the operator after drawing. */ + WM_event_add_notifier(draw_ctx->evil_C, NC_LIGHTPROBE, scene_orig); + } + } + } } /* -------------------------------------------------------------------- */ @@ -747,215 +778,226 @@ void EEVEE_lightprobes_cache_finish(EEVEE_ViewLayerData *sldata, EEVEE_Data *ved * \{ */ typedef struct EEVEE_BakeRenderData { - EEVEE_Data *vedata; - EEVEE_ViewLayerData *sldata; - struct GPUFrameBuffer **face_fb; /* should contain 6 framebuffer */ + EEVEE_Data *vedata; + EEVEE_ViewLayerData *sldata; + struct GPUFrameBuffer **face_fb; /* should contain 6 framebuffer */ } EEVEE_BakeRenderData; -static void render_cubemap( - void (*callback)(int face, EEVEE_BakeRenderData *user_data), EEVEE_BakeRenderData *user_data, - const float pos[3], float clipsta, float clipend) +static void render_cubemap(void (*callback)(int face, EEVEE_BakeRenderData *user_data), + EEVEE_BakeRenderData *user_data, + const float pos[3], + float clipsta, + float clipend) { - DRWMatrixState matstate; - - /* Move to capture position */ - float posmat[4][4]; - unit_m4(posmat); - negate_v3_v3(posmat[3], pos); - - perspective_m4(matstate.winmat, -clipsta, clipsta, -clipsta, clipsta, clipsta, clipend); - invert_m4_m4(matstate.wininv, matstate.winmat); - - /* 1 - Render to each cubeface individually. - * We do this instead of using geometry shader because a) it's faster, - * b) it's easier than fixing the nodetree shaders (for view dependent effects). */ - for (int i = 0; i < 6; ++i) { - /* Setup custom matrices */ - mul_m4_m4m4(matstate.viewmat, cubefacemat[i], posmat); - mul_m4_m4m4(matstate.persmat, matstate.winmat, matstate.viewmat); - invert_m4_m4(matstate.persinv, matstate.persmat); - invert_m4_m4(matstate.viewinv, matstate.viewmat); - invert_m4_m4(matstate.wininv, matstate.winmat); - - DRW_viewport_matrix_override_set_all(&matstate); - - callback(i, user_data); - } + DRWMatrixState matstate; + + /* Move to capture position */ + float posmat[4][4]; + unit_m4(posmat); + negate_v3_v3(posmat[3], pos); + + perspective_m4(matstate.winmat, -clipsta, clipsta, -clipsta, clipsta, clipsta, clipend); + invert_m4_m4(matstate.wininv, matstate.winmat); + + /* 1 - Render to each cubeface individually. + * We do this instead of using geometry shader because a) it's faster, + * b) it's easier than fixing the nodetree shaders (for view dependent effects). */ + for (int i = 0; i < 6; ++i) { + /* Setup custom matrices */ + mul_m4_m4m4(matstate.viewmat, cubefacemat[i], posmat); + mul_m4_m4m4(matstate.persmat, matstate.winmat, matstate.viewmat); + invert_m4_m4(matstate.persinv, matstate.persmat); + invert_m4_m4(matstate.viewinv, matstate.viewmat); + invert_m4_m4(matstate.wininv, matstate.winmat); + + DRW_viewport_matrix_override_set_all(&matstate); + + callback(i, user_data); + } } -static void render_reflections( - void (*callback)(int face, EEVEE_BakeRenderData *user_data), EEVEE_BakeRenderData *user_data, - EEVEE_PlanarReflection *planar_data, int ref_count) +static void render_reflections(void (*callback)(int face, EEVEE_BakeRenderData *user_data), + EEVEE_BakeRenderData *user_data, + EEVEE_PlanarReflection *planar_data, + int ref_count) { - DRWMatrixState matstate; - - float original_viewmat[4][4], original_winmat[4][4]; - DRW_viewport_matrix_get(original_viewmat, DRW_MAT_VIEW); - DRW_viewport_matrix_get(original_winmat, DRW_MAT_WIN); - - for (int i = 0; i < ref_count; ++i) { - /* Setup custom matrices */ - lightbake_planar_compute_render_matrices(planar_data + i, &matstate, original_viewmat, original_winmat); - invert_m4_m4(matstate.persinv, matstate.persmat); - invert_m4_m4(matstate.viewinv, matstate.viewmat); - invert_m4_m4(matstate.wininv, matstate.winmat); - DRW_viewport_matrix_override_set_all(&matstate); - - callback(i, user_data); - } + DRWMatrixState matstate; + + float original_viewmat[4][4], original_winmat[4][4]; + DRW_viewport_matrix_get(original_viewmat, DRW_MAT_VIEW); + DRW_viewport_matrix_get(original_winmat, DRW_MAT_WIN); + + for (int i = 0; i < ref_count; ++i) { + /* Setup custom matrices */ + lightbake_planar_compute_render_matrices( + planar_data + i, &matstate, original_viewmat, original_winmat); + invert_m4_m4(matstate.persinv, matstate.persmat); + invert_m4_m4(matstate.viewinv, matstate.viewmat); + invert_m4_m4(matstate.wininv, matstate.winmat); + DRW_viewport_matrix_override_set_all(&matstate); + + callback(i, user_data); + } } static void lightbake_render_world_face(int face, EEVEE_BakeRenderData *user_data) { - EEVEE_PassList *psl = user_data->vedata->psl; - struct GPUFrameBuffer **face_fb = user_data->face_fb; - - /* For world probe, we don't need to clear the color buffer - * since we render the background directly. */ - GPU_framebuffer_bind(face_fb[face]); - GPU_framebuffer_clear_depth(face_fb[face], 1.0f); - DRW_draw_pass(psl->probe_background); + EEVEE_PassList *psl = user_data->vedata->psl; + struct GPUFrameBuffer **face_fb = user_data->face_fb; + + /* For world probe, we don't need to clear the color buffer + * since we render the background directly. */ + GPU_framebuffer_bind(face_fb[face]); + GPU_framebuffer_clear_depth(face_fb[face], 1.0f); + DRW_draw_pass(psl->probe_background); } -void EEVEE_lightbake_render_world(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata, struct GPUFrameBuffer *face_fb[6]) +void EEVEE_lightbake_render_world(EEVEE_ViewLayerData *UNUSED(sldata), + EEVEE_Data *vedata, + struct GPUFrameBuffer *face_fb[6]) { - EEVEE_BakeRenderData brdata = { - .vedata = vedata, - .face_fb = face_fb, - }; + EEVEE_BakeRenderData brdata = { + .vedata = vedata, + .face_fb = face_fb, + }; - render_cubemap(lightbake_render_world_face, &brdata, (float[3]){0.0f}, 1.0f, 10.0f); + render_cubemap(lightbake_render_world_face, &brdata, (float[3]){0.0f}, 1.0f, 10.0f); } static void lightbake_render_scene_face(int face, EEVEE_BakeRenderData *user_data) { - EEVEE_ViewLayerData *sldata = user_data->sldata; - EEVEE_PassList *psl = user_data->vedata->psl; - struct GPUFrameBuffer **face_fb = user_data->face_fb; - - /* Be sure that cascaded shadow maps are updated. */ - EEVEE_draw_shadows(sldata, user_data->vedata); - - GPU_framebuffer_bind(face_fb[face]); - GPU_framebuffer_clear_depth(face_fb[face], 1.0f); - - DRW_draw_pass(psl->depth_pass); - DRW_draw_pass(psl->depth_pass_cull); - DRW_draw_pass(psl->probe_background); - DRW_draw_pass(psl->material_pass); - DRW_draw_pass(psl->material_pass_cull); - DRW_draw_pass(psl->sss_pass); /* Only output standard pass */ - DRW_draw_pass(psl->sss_pass_cull); - EEVEE_draw_default_passes(psl); + EEVEE_ViewLayerData *sldata = user_data->sldata; + EEVEE_PassList *psl = user_data->vedata->psl; + struct GPUFrameBuffer **face_fb = user_data->face_fb; + + /* Be sure that cascaded shadow maps are updated. */ + EEVEE_draw_shadows(sldata, user_data->vedata); + + GPU_framebuffer_bind(face_fb[face]); + GPU_framebuffer_clear_depth(face_fb[face], 1.0f); + + DRW_draw_pass(psl->depth_pass); + DRW_draw_pass(psl->depth_pass_cull); + DRW_draw_pass(psl->probe_background); + DRW_draw_pass(psl->material_pass); + DRW_draw_pass(psl->material_pass_cull); + DRW_draw_pass(psl->sss_pass); /* Only output standard pass */ + DRW_draw_pass(psl->sss_pass_cull); + EEVEE_draw_default_passes(psl); } /* Render the scene to the probe_rt texture. */ -void EEVEE_lightbake_render_scene( - EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, struct GPUFrameBuffer *face_fb[6], - const float pos[3], float near_clip, float far_clip) +void EEVEE_lightbake_render_scene(EEVEE_ViewLayerData *sldata, + EEVEE_Data *vedata, + struct GPUFrameBuffer *face_fb[6], + const float pos[3], + float near_clip, + float far_clip) { - EEVEE_BakeRenderData brdata = { - .vedata = vedata, - .sldata = sldata, - .face_fb = face_fb, - }; + EEVEE_BakeRenderData brdata = { + .vedata = vedata, + .sldata = sldata, + .face_fb = face_fb, + }; - render_cubemap(lightbake_render_scene_face, &brdata, pos, near_clip, far_clip); + render_cubemap(lightbake_render_scene_face, &brdata, pos, near_clip, far_clip); } static void lightbake_render_scene_reflected(int layer, EEVEE_BakeRenderData *user_data) { - EEVEE_Data *vedata = user_data->vedata; - EEVEE_ViewLayerData *sldata = user_data->sldata; - EEVEE_PassList *psl = vedata->psl; - EEVEE_TextureList *txl = vedata->txl; - EEVEE_FramebufferList *fbl = vedata->fbl; - EEVEE_LightProbesInfo *pinfo = sldata->probes; - EEVEE_PlanarReflection *eplanar = pinfo->planar_data + layer; - - GPU_framebuffer_ensure_config(&fbl->planarref_fb, { - GPU_ATTACHMENT_TEXTURE_LAYER(txl->planar_depth, layer), - GPU_ATTACHMENT_TEXTURE_LAYER(txl->planar_pool, layer) - }); - - /* Use visibility info for this planar reflection. */ - pinfo->vis_data = pinfo->planar_vis_tests[layer]; - - /* Avoid using the texture attached to framebuffer when rendering. */ - /* XXX */ - GPUTexture *tmp_planar_pool = txl->planar_pool; - GPUTexture *tmp_planar_depth = txl->planar_depth; - txl->planar_pool = e_data.planar_pool_placeholder; - txl->planar_depth = e_data.depth_array_placeholder; - - /* Be sure that cascaded shadow maps are updated. */ - DRW_stats_group_start("Planar Reflection"); - - /* Be sure that cascaded shadow maps are updated. */ - EEVEE_draw_shadows(sldata, vedata); - - /* Compute offset plane equation (fix missing texels near reflection plane). */ - copy_v4_v4(sldata->clip_data.clip_planes[0], eplanar->plane_equation); - sldata->clip_data.clip_planes[0][3] += eplanar->clipsta; - /* Set clipping plane */ - DRW_uniformbuffer_update(sldata->clip_ubo, &sldata->clip_data); - DRW_state_clip_planes_len_set(1); - - GPU_framebuffer_bind(fbl->planarref_fb); - GPU_framebuffer_clear_depth(fbl->planarref_fb, 1.0); - - float prev_background_alpha = vedata->stl->g_data->background_alpha; - vedata->stl->g_data->background_alpha = 1.0f; - - /* Slight modification: we handle refraction as normal - * shading and don't do SSRefraction. */ - - DRW_draw_pass(psl->depth_pass_clip); - DRW_draw_pass(psl->depth_pass_clip_cull); - DRW_draw_pass(psl->refract_depth_pass); - DRW_draw_pass(psl->refract_depth_pass_cull); - - DRW_draw_pass(psl->probe_background); - EEVEE_create_minmax_buffer(vedata, tmp_planar_depth, layer); - EEVEE_occlusion_compute(sldata, vedata, tmp_planar_depth, layer); - - GPU_framebuffer_bind(fbl->planarref_fb); - - /* Shading pass */ - EEVEE_draw_default_passes(psl); - DRW_draw_pass(psl->material_pass); - DRW_draw_pass(psl->material_pass_cull); - DRW_draw_pass(psl->sss_pass); /* Only output standard pass */ - DRW_draw_pass(psl->sss_pass_cull); - DRW_draw_pass(psl->refract_pass); - - /* Transparent */ - if (DRW_state_is_image_render()) { - /* Do the reordering only for offline because it can be costly. */ - DRW_pass_sort_shgroup_z(psl->transparent_pass); - } - DRW_draw_pass(psl->transparent_pass); - - DRW_state_clip_planes_reset(); - - DRW_stats_group_end(); - - /* Restore */ - txl->planar_pool = tmp_planar_pool; - txl->planar_depth = tmp_planar_depth; - - vedata->stl->g_data->background_alpha = prev_background_alpha; + EEVEE_Data *vedata = user_data->vedata; + EEVEE_ViewLayerData *sldata = user_data->sldata; + EEVEE_PassList *psl = vedata->psl; + EEVEE_TextureList *txl = vedata->txl; + EEVEE_FramebufferList *fbl = vedata->fbl; + EEVEE_LightProbesInfo *pinfo = sldata->probes; + EEVEE_PlanarReflection *eplanar = pinfo->planar_data + layer; + + GPU_framebuffer_ensure_config(&fbl->planarref_fb, + {GPU_ATTACHMENT_TEXTURE_LAYER(txl->planar_depth, layer), + GPU_ATTACHMENT_TEXTURE_LAYER(txl->planar_pool, layer)}); + + /* Use visibility info for this planar reflection. */ + pinfo->vis_data = pinfo->planar_vis_tests[layer]; + + /* Avoid using the texture attached to framebuffer when rendering. */ + /* XXX */ + GPUTexture *tmp_planar_pool = txl->planar_pool; + GPUTexture *tmp_planar_depth = txl->planar_depth; + txl->planar_pool = e_data.planar_pool_placeholder; + txl->planar_depth = e_data.depth_array_placeholder; + + /* Be sure that cascaded shadow maps are updated. */ + DRW_stats_group_start("Planar Reflection"); + + /* Be sure that cascaded shadow maps are updated. */ + EEVEE_draw_shadows(sldata, vedata); + + /* Compute offset plane equation (fix missing texels near reflection plane). */ + copy_v4_v4(sldata->clip_data.clip_planes[0], eplanar->plane_equation); + sldata->clip_data.clip_planes[0][3] += eplanar->clipsta; + /* Set clipping plane */ + DRW_uniformbuffer_update(sldata->clip_ubo, &sldata->clip_data); + DRW_state_clip_planes_len_set(1); + + GPU_framebuffer_bind(fbl->planarref_fb); + GPU_framebuffer_clear_depth(fbl->planarref_fb, 1.0); + + float prev_background_alpha = vedata->stl->g_data->background_alpha; + vedata->stl->g_data->background_alpha = 1.0f; + + /* Slight modification: we handle refraction as normal + * shading and don't do SSRefraction. */ + + DRW_draw_pass(psl->depth_pass_clip); + DRW_draw_pass(psl->depth_pass_clip_cull); + DRW_draw_pass(psl->refract_depth_pass); + DRW_draw_pass(psl->refract_depth_pass_cull); + + DRW_draw_pass(psl->probe_background); + EEVEE_create_minmax_buffer(vedata, tmp_planar_depth, layer); + EEVEE_occlusion_compute(sldata, vedata, tmp_planar_depth, layer); + + GPU_framebuffer_bind(fbl->planarref_fb); + + /* Shading pass */ + EEVEE_draw_default_passes(psl); + DRW_draw_pass(psl->material_pass); + DRW_draw_pass(psl->material_pass_cull); + DRW_draw_pass(psl->sss_pass); /* Only output standard pass */ + DRW_draw_pass(psl->sss_pass_cull); + DRW_draw_pass(psl->refract_pass); + + /* Transparent */ + if (DRW_state_is_image_render()) { + /* Do the reordering only for offline because it can be costly. */ + DRW_pass_sort_shgroup_z(psl->transparent_pass); + } + DRW_draw_pass(psl->transparent_pass); + + DRW_state_clip_planes_reset(); + + DRW_stats_group_end(); + + /* Restore */ + txl->planar_pool = tmp_planar_pool; + txl->planar_depth = tmp_planar_depth; + + vedata->stl->g_data->background_alpha = prev_background_alpha; } -static void eevee_lightbake_render_scene_to_planars( - EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) +static void eevee_lightbake_render_scene_to_planars(EEVEE_ViewLayerData *sldata, + EEVEE_Data *vedata) { - EEVEE_BakeRenderData brdata = { - .vedata = vedata, - .sldata = sldata, - }; - - render_reflections(lightbake_render_scene_reflected, &brdata, sldata->probes->planar_data, sldata->probes->num_planar); + EEVEE_BakeRenderData brdata = { + .vedata = vedata, + .sldata = sldata, + }; + + render_reflections(lightbake_render_scene_reflected, + &brdata, + sldata->probes->planar_data, + sldata->probes->num_planar); } /** \} */ @@ -964,284 +1006,296 @@ static void eevee_lightbake_render_scene_to_planars( * \{ */ /* Glossy filter rt_color to light_cache->cube_tx.tex at index probe_idx */ -void EEVEE_lightbake_filter_glossy( - EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, - struct GPUTexture *rt_color, struct GPUFrameBuffer *fb, - int probe_idx, float intensity, int maxlevel, float filter_quality, float firefly_fac) +void EEVEE_lightbake_filter_glossy(EEVEE_ViewLayerData *sldata, + EEVEE_Data *vedata, + struct GPUTexture *rt_color, + struct GPUFrameBuffer *fb, + int probe_idx, + float intensity, + int maxlevel, + float filter_quality, + float firefly_fac) { - EEVEE_PassList *psl = vedata->psl; - EEVEE_LightProbesInfo *pinfo = sldata->probes; - LightCache *light_cache = vedata->stl->g_data->light_cache; - - float target_size = (float)GPU_texture_width(rt_color); - - /* Max lod used from the render target probe */ - pinfo->lod_rt_max = floorf(log2f(target_size)) - 2.0f; - pinfo->intensity_fac = intensity; - - /* Start fresh */ - GPU_framebuffer_ensure_config(&fb, { - GPU_ATTACHMENT_NONE, - GPU_ATTACHMENT_NONE - }); - - /* 2 - Let gpu create Mipmaps for Filtered Importance Sampling. */ - /* Bind next framebuffer to be able to gen. mips for probe_rt. */ - EEVEE_downsample_cube_buffer(vedata, rt_color, (int)(pinfo->lod_rt_max)); - - /* 3 - Render to probe array to the specified layer, do prefiltering. */ - int mipsize = GPU_texture_width(light_cache->cube_tx.tex); - for (int i = 0; i < maxlevel + 1; i++) { - float bias = (i == 0) ? -1.0f : 1.0f; - pinfo->texel_size = 1.0f / (float)mipsize; - pinfo->padding_size = (i == maxlevel) ? 0 : (float)(1 << (maxlevel - i - 1)); - pinfo->padding_size *= pinfo->texel_size; - pinfo->layer = probe_idx; - pinfo->roughness = i / (float)maxlevel; - pinfo->roughness *= pinfo->roughness; /* Disney Roughness */ - pinfo->roughness *= pinfo->roughness; /* Distribute Roughness accros lod more evenly */ - CLAMP(pinfo->roughness, 1e-8f, 0.99999f); /* Avoid artifacts */ + EEVEE_PassList *psl = vedata->psl; + EEVEE_LightProbesInfo *pinfo = sldata->probes; + LightCache *light_cache = vedata->stl->g_data->light_cache; + + float target_size = (float)GPU_texture_width(rt_color); + + /* Max lod used from the render target probe */ + pinfo->lod_rt_max = floorf(log2f(target_size)) - 2.0f; + pinfo->intensity_fac = intensity; + + /* Start fresh */ + GPU_framebuffer_ensure_config(&fb, {GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_NONE}); + + /* 2 - Let gpu create Mipmaps for Filtered Importance Sampling. */ + /* Bind next framebuffer to be able to gen. mips for probe_rt. */ + EEVEE_downsample_cube_buffer(vedata, rt_color, (int)(pinfo->lod_rt_max)); + + /* 3 - Render to probe array to the specified layer, do prefiltering. */ + int mipsize = GPU_texture_width(light_cache->cube_tx.tex); + for (int i = 0; i < maxlevel + 1; i++) { + float bias = (i == 0) ? -1.0f : 1.0f; + pinfo->texel_size = 1.0f / (float)mipsize; + pinfo->padding_size = (i == maxlevel) ? 0 : (float)(1 << (maxlevel - i - 1)); + pinfo->padding_size *= pinfo->texel_size; + pinfo->layer = probe_idx; + pinfo->roughness = i / (float)maxlevel; + pinfo->roughness *= pinfo->roughness; /* Disney Roughness */ + pinfo->roughness *= pinfo->roughness; /* Distribute Roughness accros lod more evenly */ + CLAMP(pinfo->roughness, 1e-8f, 0.99999f); /* Avoid artifacts */ #if 1 /* Variable Sample count (fast) */ - switch (i) { - case 0: pinfo->samples_len = 1.0f; break; - case 1: pinfo->samples_len = 16.0f; break; - case 2: pinfo->samples_len = 32.0f; break; - case 3: pinfo->samples_len = 64.0f; break; - default: pinfo->samples_len = 128.0f; break; - } + switch (i) { + case 0: + pinfo->samples_len = 1.0f; + break; + case 1: + pinfo->samples_len = 16.0f; + break; + case 2: + pinfo->samples_len = 32.0f; + break; + case 3: + pinfo->samples_len = 64.0f; + break; + default: + pinfo->samples_len = 128.0f; + break; + } #else /* Constant Sample count (slow) */ - pinfo->samples_len = 1024.0f; + pinfo->samples_len = 1024.0f; #endif - /* Cannot go higher than HAMMERSLEY_SIZE */ - CLAMP(filter_quality, 1.0f, 8.0f); - pinfo->samples_len *= filter_quality; - - pinfo->samples_len_inv = 1.0f / pinfo->samples_len; - pinfo->lodfactor = bias + 0.5f * log((float)(target_size * target_size) * pinfo->samples_len_inv) / log(2); - pinfo->firefly_fac = (firefly_fac > 0.0) ? firefly_fac : 1e16; - - GPU_framebuffer_ensure_config(&fb, { - GPU_ATTACHMENT_NONE, - GPU_ATTACHMENT_TEXTURE_MIP(light_cache->cube_tx.tex, i) - }); - GPU_framebuffer_bind(fb); - GPU_framebuffer_viewport_set(fb, 0, 0, mipsize, mipsize); - DRW_draw_pass(psl->probe_glossy_compute); - - mipsize /= 2; - CLAMP_MIN(mipsize, 1); - } + /* Cannot go higher than HAMMERSLEY_SIZE */ + CLAMP(filter_quality, 1.0f, 8.0f); + pinfo->samples_len *= filter_quality; + + pinfo->samples_len_inv = 1.0f / pinfo->samples_len; + pinfo->lodfactor = bias + + 0.5f * log((float)(target_size * target_size) * pinfo->samples_len_inv) / + log(2); + pinfo->firefly_fac = (firefly_fac > 0.0) ? firefly_fac : 1e16; + + GPU_framebuffer_ensure_config( + &fb, {GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE_MIP(light_cache->cube_tx.tex, i)}); + GPU_framebuffer_bind(fb); + GPU_framebuffer_viewport_set(fb, 0, 0, mipsize, mipsize); + DRW_draw_pass(psl->probe_glossy_compute); + + mipsize /= 2; + CLAMP_MIN(mipsize, 1); + } } /* Diffuse filter rt_color to light_cache->grid_tx.tex at index grid_offset */ -void EEVEE_lightbake_filter_diffuse( - EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, - struct GPUTexture *rt_color, struct GPUFrameBuffer *fb, - int grid_offset, float intensity) +void EEVEE_lightbake_filter_diffuse(EEVEE_ViewLayerData *sldata, + EEVEE_Data *vedata, + struct GPUTexture *rt_color, + struct GPUFrameBuffer *fb, + int grid_offset, + float intensity) { - EEVEE_PassList *psl = vedata->psl; - EEVEE_LightProbesInfo *pinfo = sldata->probes; - LightCache *light_cache = vedata->stl->g_data->light_cache; + EEVEE_PassList *psl = vedata->psl; + EEVEE_LightProbesInfo *pinfo = sldata->probes; + LightCache *light_cache = vedata->stl->g_data->light_cache; - float target_size = (float)GPU_texture_width(rt_color); + float target_size = (float)GPU_texture_width(rt_color); - pinfo->intensity_fac = intensity; + pinfo->intensity_fac = intensity; - /* find cell position on the virtual 3D texture */ - /* NOTE : Keep in sync with load_irradiance_cell() */ + /* find cell position on the virtual 3D texture */ + /* NOTE : Keep in sync with load_irradiance_cell() */ #if defined(IRRADIANCE_SH_L2) - int size[2] = {3, 3}; + int size[2] = {3, 3}; #elif defined(IRRADIANCE_CUBEMAP) - int size[2] = {8, 8}; - pinfo->samples_len = 1024.0f; + int size[2] = {8, 8}; + pinfo->samples_len = 1024.0f; #elif defined(IRRADIANCE_HL2) - int size[2] = {3, 2}; - pinfo->samples_len = 1024.0f; + int size[2] = {3, 2}; + pinfo->samples_len = 1024.0f; #endif - int cell_per_row = GPU_texture_width(light_cache->grid_tx.tex) / size[0]; - int x = size[0] * (grid_offset % cell_per_row); - int y = size[1] * (grid_offset / cell_per_row); + int cell_per_row = GPU_texture_width(light_cache->grid_tx.tex) / size[0]; + int x = size[0] * (grid_offset % cell_per_row); + int y = size[1] * (grid_offset / cell_per_row); #ifndef IRRADIANCE_SH_L2 - /* Tweaking parameters to balance perf. vs precision */ - const float bias = 0.0f; - pinfo->samples_len_inv = 1.0f / pinfo->samples_len; - pinfo->lodfactor = bias + 0.5f * log((float)(target_size * target_size) * pinfo->samples_len_inv) / log(2); - pinfo->lod_rt_max = floorf(log2f(target_size)) - 2.0f; + /* Tweaking parameters to balance perf. vs precision */ + const float bias = 0.0f; + pinfo->samples_len_inv = 1.0f / pinfo->samples_len; + pinfo->lodfactor = bias + 0.5f * + log((float)(target_size * target_size) * pinfo->samples_len_inv) / + log(2); + pinfo->lod_rt_max = floorf(log2f(target_size)) - 2.0f; #else - pinfo->shres = 32; /* Less texture fetches & reduce branches */ - pinfo->lod_rt_max = 2.0f; /* Improve cache reuse */ + pinfo->shres = 32; /* Less texture fetches & reduce branches */ + pinfo->lod_rt_max = 2.0f; /* Improve cache reuse */ #endif - /* Start fresh */ - GPU_framebuffer_ensure_config(&fb, { - GPU_ATTACHMENT_NONE, - GPU_ATTACHMENT_NONE - }); - - /* 4 - Compute diffuse irradiance */ - EEVEE_downsample_cube_buffer(vedata, rt_color, (int)(pinfo->lod_rt_max)); - - GPU_framebuffer_ensure_config(&fb, { - GPU_ATTACHMENT_NONE, - GPU_ATTACHMENT_TEXTURE_LAYER(light_cache->grid_tx.tex, 0) - }); - GPU_framebuffer_bind(fb); - GPU_framebuffer_viewport_set(fb, x, y, size[0], size[1]); - DRW_draw_pass(psl->probe_diffuse_compute); + /* Start fresh */ + GPU_framebuffer_ensure_config(&fb, {GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_NONE}); + + /* 4 - Compute diffuse irradiance */ + EEVEE_downsample_cube_buffer(vedata, rt_color, (int)(pinfo->lod_rt_max)); + + GPU_framebuffer_ensure_config( + &fb, {GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE_LAYER(light_cache->grid_tx.tex, 0)}); + GPU_framebuffer_bind(fb); + GPU_framebuffer_viewport_set(fb, x, y, size[0], size[1]); + DRW_draw_pass(psl->probe_diffuse_compute); } /* Filter rt_depth to light_cache->grid_tx.tex at index grid_offset */ -void EEVEE_lightbake_filter_visibility( - EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, - struct GPUTexture *UNUSED(rt_depth), struct GPUFrameBuffer *fb, - int grid_offset, float clipsta, float clipend, - float vis_range, float vis_blur, int vis_size) +void EEVEE_lightbake_filter_visibility(EEVEE_ViewLayerData *sldata, + EEVEE_Data *vedata, + struct GPUTexture *UNUSED(rt_depth), + struct GPUFrameBuffer *fb, + int grid_offset, + float clipsta, + float clipend, + float vis_range, + float vis_blur, + int vis_size) { - EEVEE_PassList *psl = vedata->psl; - EEVEE_LightProbesInfo *pinfo = sldata->probes; - LightCache *light_cache = vedata->stl->g_data->light_cache; - - pinfo->samples_len = 512.0f; /* TODO refine */ - pinfo->samples_len_inv = 1.0f / pinfo->samples_len; - pinfo->shres = vis_size; - pinfo->visibility_range = vis_range; - pinfo->visibility_blur = vis_blur; - pinfo->near_clip = -clipsta; - pinfo->far_clip = -clipend; - pinfo->texel_size = 1.0f / (float)vis_size; - - int cell_per_col = GPU_texture_height(light_cache->grid_tx.tex) / vis_size; - int cell_per_row = GPU_texture_width(light_cache->grid_tx.tex) / vis_size; - int x = vis_size * (grid_offset % cell_per_row); - int y = vis_size * ((grid_offset / cell_per_row) % cell_per_col); - int layer = 1 + ((grid_offset / cell_per_row) / cell_per_col); - - GPU_framebuffer_ensure_config(&fb, { - GPU_ATTACHMENT_NONE, - GPU_ATTACHMENT_TEXTURE_LAYER(light_cache->grid_tx.tex, layer) - }); - GPU_framebuffer_bind(fb); - GPU_framebuffer_viewport_set(fb, x, y, vis_size, vis_size); - DRW_draw_pass(psl->probe_visibility_compute); + EEVEE_PassList *psl = vedata->psl; + EEVEE_LightProbesInfo *pinfo = sldata->probes; + LightCache *light_cache = vedata->stl->g_data->light_cache; + + pinfo->samples_len = 512.0f; /* TODO refine */ + pinfo->samples_len_inv = 1.0f / pinfo->samples_len; + pinfo->shres = vis_size; + pinfo->visibility_range = vis_range; + pinfo->visibility_blur = vis_blur; + pinfo->near_clip = -clipsta; + pinfo->far_clip = -clipend; + pinfo->texel_size = 1.0f / (float)vis_size; + + int cell_per_col = GPU_texture_height(light_cache->grid_tx.tex) / vis_size; + int cell_per_row = GPU_texture_width(light_cache->grid_tx.tex) / vis_size; + int x = vis_size * (grid_offset % cell_per_row); + int y = vis_size * ((grid_offset / cell_per_row) % cell_per_col); + int layer = 1 + ((grid_offset / cell_per_row) / cell_per_col); + + GPU_framebuffer_ensure_config( + &fb, {GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE_LAYER(light_cache->grid_tx.tex, layer)}); + GPU_framebuffer_bind(fb); + GPU_framebuffer_viewport_set(fb, x, y, vis_size, vis_size); + DRW_draw_pass(psl->probe_visibility_compute); } /* Actually a simple downsampling */ static void downsample_planar(void *vedata, int level) { - EEVEE_PassList *psl = ((EEVEE_Data *)vedata)->psl; - EEVEE_StorageList *stl = ((EEVEE_Data *)vedata)->stl; - - const float *size = DRW_viewport_size_get(); - copy_v2_v2(stl->g_data->planar_texel_size, size); - for (int i = 0; i < level - 1; ++i) { - stl->g_data->planar_texel_size[0] /= 2.0f; - stl->g_data->planar_texel_size[1] /= 2.0f; - min_ff(floorf(stl->g_data->planar_texel_size[0]), 1.0f); - min_ff(floorf(stl->g_data->planar_texel_size[1]), 1.0f); - } - invert_v2(stl->g_data->planar_texel_size); - - DRW_draw_pass(psl->probe_planar_downsample_ps); + EEVEE_PassList *psl = ((EEVEE_Data *)vedata)->psl; + EEVEE_StorageList *stl = ((EEVEE_Data *)vedata)->stl; + + const float *size = DRW_viewport_size_get(); + copy_v2_v2(stl->g_data->planar_texel_size, size); + for (int i = 0; i < level - 1; ++i) { + stl->g_data->planar_texel_size[0] /= 2.0f; + stl->g_data->planar_texel_size[1] /= 2.0f; + min_ff(floorf(stl->g_data->planar_texel_size[0]), 1.0f); + min_ff(floorf(stl->g_data->planar_texel_size[1]), 1.0f); + } + invert_v2(stl->g_data->planar_texel_size); + + DRW_draw_pass(psl->probe_planar_downsample_ps); } static void EEVEE_lightbake_filter_planar(EEVEE_Data *vedata) { - EEVEE_TextureList *txl = vedata->txl; - EEVEE_FramebufferList *fbl = vedata->fbl; + EEVEE_TextureList *txl = vedata->txl; + EEVEE_FramebufferList *fbl = vedata->fbl; - DRW_stats_group_start("Planar Probe Downsample"); + DRW_stats_group_start("Planar Probe Downsample"); - GPU_framebuffer_ensure_config(&fbl->planar_downsample_fb, { - GPU_ATTACHMENT_NONE, - GPU_ATTACHMENT_TEXTURE(txl->planar_pool) - }); + GPU_framebuffer_ensure_config(&fbl->planar_downsample_fb, + {GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(txl->planar_pool)}); - GPU_framebuffer_recursive_downsample(fbl->planar_downsample_fb, MAX_PLANAR_LOD_LEVEL, &downsample_planar, vedata); - DRW_stats_group_end(); + GPU_framebuffer_recursive_downsample( + fbl->planar_downsample_fb, MAX_PLANAR_LOD_LEVEL, &downsample_planar, vedata); + DRW_stats_group_end(); } /** \} */ void EEVEE_lightprobes_refresh_planar(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) { - EEVEE_CommonUniformBuffer *common_data = &sldata->common_data; - EEVEE_LightProbesInfo *pinfo = sldata->probes; - DRWMatrixState saved_mats; + EEVEE_CommonUniformBuffer *common_data = &sldata->common_data; + EEVEE_LightProbesInfo *pinfo = sldata->probes; + DRWMatrixState saved_mats; - if (pinfo->num_planar == 0) { - /* Disable SSR if we cannot read previous frame */ - common_data->ssr_toggle = vedata->stl->g_data->valid_double_buffer; - common_data->prb_num_planar = 0; - return; - } + if (pinfo->num_planar == 0) { + /* Disable SSR if we cannot read previous frame */ + common_data->ssr_toggle = vedata->stl->g_data->valid_double_buffer; + common_data->prb_num_planar = 0; + return; + } - /* We need to save the Matrices before overidding them */ - DRW_viewport_matrix_get_all(&saved_mats); + /* We need to save the Matrices before overidding them */ + DRW_viewport_matrix_get_all(&saved_mats); - /* Temporary Remove all planar reflections (avoid lag effect). */ - common_data->prb_num_planar = 0; - /* Turn off ssr to avoid black specular */ - common_data->ssr_toggle = false; - common_data->sss_toggle = false; + /* Temporary Remove all planar reflections (avoid lag effect). */ + common_data->prb_num_planar = 0; + /* Turn off ssr to avoid black specular */ + common_data->ssr_toggle = false; + common_data->sss_toggle = false; - common_data->ray_type = EEVEE_RAY_GLOSSY; - common_data->ray_depth = 1.0f; - DRW_uniformbuffer_update(sldata->common_ubo, &sldata->common_data); + common_data->ray_type = EEVEE_RAY_GLOSSY; + common_data->ray_depth = 1.0f; + DRW_uniformbuffer_update(sldata->common_ubo, &sldata->common_data); - /* Rendering happens here! */ - eevee_lightbake_render_scene_to_planars(sldata, vedata); + /* Rendering happens here! */ + eevee_lightbake_render_scene_to_planars(sldata, vedata); - /* Make sure no aditionnal visibility check runs after this. */ - pinfo->vis_data.collection = NULL; + /* Make sure no aditionnal visibility check runs after this. */ + pinfo->vis_data.collection = NULL; - DRW_uniformbuffer_update(sldata->planar_ubo, &sldata->probes->planar_data); + DRW_uniformbuffer_update(sldata->planar_ubo, &sldata->probes->planar_data); - /* Restore */ - common_data->prb_num_planar = pinfo->num_planar; - common_data->ssr_toggle = true; - common_data->sss_toggle = true; + /* Restore */ + common_data->prb_num_planar = pinfo->num_planar; + common_data->ssr_toggle = true; + common_data->sss_toggle = true; - /* Prefilter for SSR */ - if ((vedata->stl->effects->enabled_effects & EFFECT_SSR) != 0) { - EEVEE_lightbake_filter_planar(vedata); - } + /* Prefilter for SSR */ + if ((vedata->stl->effects->enabled_effects & EFFECT_SSR) != 0) { + EEVEE_lightbake_filter_planar(vedata); + } - DRW_viewport_matrix_override_set_all(&saved_mats); + DRW_viewport_matrix_override_set_all(&saved_mats); - if (DRW_state_is_image_render()) { - /* Sort transparents because planar reflections could have re-sorted them. */ - DRW_pass_sort_shgroup_z(vedata->psl->transparent_pass); - } + if (DRW_state_is_image_render()) { + /* Sort transparents because planar reflections could have re-sorted them. */ + DRW_pass_sort_shgroup_z(vedata->psl->transparent_pass); + } - /* Disable SSR if we cannot read previous frame */ - common_data->ssr_toggle = vedata->stl->g_data->valid_double_buffer; + /* Disable SSR if we cannot read previous frame */ + common_data->ssr_toggle = vedata->stl->g_data->valid_double_buffer; } void EEVEE_lightprobes_refresh(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) { - const DRWContextState *draw_ctx = DRW_context_state_get(); - const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph); - LightCache *light_cache = vedata->stl->g_data->light_cache; - - if ((light_cache->flag & LIGHTCACHE_UPDATE_WORLD) && - (light_cache->flag & LIGHTCACHE_BAKED) == 0) - { - DRWMatrixState saved_mats; - DRW_viewport_matrix_get_all(&saved_mats); - EEVEE_lightbake_update_world_quick(sldata, vedata, scene_eval); - DRW_viewport_matrix_override_set_all(&saved_mats); - } + const DRWContextState *draw_ctx = DRW_context_state_get(); + const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph); + LightCache *light_cache = vedata->stl->g_data->light_cache; + + if ((light_cache->flag & LIGHTCACHE_UPDATE_WORLD) && + (light_cache->flag & LIGHTCACHE_BAKED) == 0) { + DRWMatrixState saved_mats; + DRW_viewport_matrix_get_all(&saved_mats); + EEVEE_lightbake_update_world_quick(sldata, vedata, scene_eval); + DRW_viewport_matrix_override_set_all(&saved_mats); + } } void EEVEE_lightprobes_free(void) { - MEM_SAFE_FREE(e_data.format_probe_display_cube); - MEM_SAFE_FREE(e_data.format_probe_display_planar); - DRW_TEXTURE_FREE_SAFE(e_data.hammersley); - DRW_TEXTURE_FREE_SAFE(e_data.planar_pool_placeholder); - DRW_TEXTURE_FREE_SAFE(e_data.depth_placeholder); - DRW_TEXTURE_FREE_SAFE(e_data.depth_array_placeholder); + MEM_SAFE_FREE(e_data.format_probe_display_cube); + MEM_SAFE_FREE(e_data.format_probe_display_planar); + DRW_TEXTURE_FREE_SAFE(e_data.hammersley); + DRW_TEXTURE_FREE_SAFE(e_data.planar_pool_placeholder); + DRW_TEXTURE_FREE_SAFE(e_data.depth_placeholder); + DRW_TEXTURE_FREE_SAFE(e_data.depth_array_placeholder); } -- cgit v1.2.3