diff options
Diffstat (limited to 'source/blender/draw/engines/eevee/eevee_engine.c')
-rw-r--r-- | source/blender/draw/engines/eevee/eevee_engine.c | 137 |
1 files changed, 131 insertions, 6 deletions
diff --git a/source/blender/draw/engines/eevee/eevee_engine.c b/source/blender/draw/engines/eevee/eevee_engine.c index b698574f9d7..bac96ab1079 100644 --- a/source/blender/draw/engines/eevee/eevee_engine.c +++ b/source/blender/draw/engines/eevee/eevee_engine.c @@ -166,7 +166,9 @@ static void eevee_cache_finish(void *vedata) EEVEE_materials_cache_finish(sldata, vedata); EEVEE_lights_cache_finish(sldata, vedata); EEVEE_lightprobes_cache_finish(sldata, vedata); + EEVEE_renderpasses_cache_finish(sldata, vedata); + EEVEE_subsurface_draw_init(sldata, vedata); EEVEE_effects_draw_init(sldata, vedata); EEVEE_volumes_draw_init(sldata, vedata); @@ -213,6 +215,10 @@ static void eevee_draw_scene(void *vedata) loop_len = MAX2(1, scene->eevee.taa_samples); } + if (stl->effects->bypass_drawing) { + loop_len = 0; + } + while (loop_len--) { float clear_col[4] = {0.0f, 0.0f, 0.0f, 0.0f}; float clear_depth = 1.0f; @@ -351,11 +357,18 @@ static void eevee_draw_scene(void *vedata) EEVEE_renderpasses_draw(sldata, vedata); } + if (stl->effects->bypass_drawing) { + /* Restore the depth from sample 1. */ + GPU_framebuffer_blit(fbl->double_buffer_depth_fb, 0, dfbl->default_fb, 0, GPU_DEPTH_BIT); + } + EEVEE_renderpasses_draw_debug(vedata); EEVEE_volumes_free_smoke_textures(); stl->g_data->view_updated = false; + + DRW_view_set_active(NULL); } static void eevee_view_update(void *vedata) @@ -370,7 +383,7 @@ static void eevee_id_object_update(void *UNUSED(vedata), Object *object) { EEVEE_LightProbeEngineData *ped = EEVEE_lightprobe_data_get(object); if (ped != NULL && ped->dd.recalc != 0) { - ped->need_update = (ped->dd.recalc & (ID_RECALC_TRANSFORM)) != 0; + ped->need_update = (ped->dd.recalc & ID_RECALC_TRANSFORM) != 0; ped->dd.recalc = 0; } EEVEE_LightEngineData *led = EEVEE_light_data_get(object); @@ -381,6 +394,7 @@ static void eevee_id_object_update(void *UNUSED(vedata), Object *object) EEVEE_ObjectEngineData *oedata = EEVEE_object_data_get(object); if (oedata != NULL && oedata->dd.recalc != 0) { oedata->need_update = true; + oedata->geom_update = (oedata->dd.recalc & (ID_RECALC_GEOMETRY)) != 0; oedata->dd.recalc = 0; } } @@ -390,6 +404,11 @@ static void eevee_id_world_update(void *vedata, World *wo) EEVEE_StorageList *stl = ((EEVEE_Data *)vedata)->stl; LightCache *lcache = stl->g_data->light_cache; + if (lcache == NULL || lcache == stl->lookdev_lightcache) { + /* Avoid Lookdev viewport clearing the update flag (see T67741). */ + return; + } + EEVEE_WorldEngineData *wedata = EEVEE_world_data_ensure(wo); if (wedata != NULL && wedata->dd.recalc != 0) { @@ -400,7 +419,7 @@ static void eevee_id_world_update(void *vedata, World *wo) } } -static void eevee_id_update(void *vedata, ID *id) +void eevee_id_update(void *vedata, ID *id) { /* Handle updates based on ID type. */ switch (GS(id->name)) { @@ -416,23 +435,129 @@ static void eevee_id_update(void *vedata, ID *id) } } +static void eevee_render_reset_passes(EEVEE_Data *vedata) +{ + /* Reset passlist. This is safe as they are stored into managed memory chunks. */ + memset(vedata->psl, 0, sizeof(*vedata->psl)); +} + static void eevee_render_to_image(void *vedata, RenderEngine *engine, struct RenderLayer *render_layer, const rcti *rect) { + EEVEE_Data *ved = (EEVEE_Data *)vedata; const DRWContextState *draw_ctx = DRW_context_state_get(); + Depsgraph *depsgraph = draw_ctx->depsgraph; + Scene *scene = DEG_get_evaluated_scene(depsgraph); + EEVEE_ViewLayerData *sldata = EEVEE_view_layer_data_ensure(); + const bool do_motion_blur = (scene->eevee.flag & SCE_EEVEE_MOTION_BLUR_ENABLED) != 0; + const bool do_motion_blur_fx = do_motion_blur && (scene->eevee.motion_blur_max > 0); - if (!EEVEE_render_init(vedata, engine, draw_ctx->depsgraph)) { + if (!EEVEE_render_init(vedata, engine, depsgraph)) { return; } + EEVEE_PrivateData *g_data = ved->stl->g_data; + + int steps = max_ii(1, scene->eevee.motion_blur_steps); + int time_steps_tot = (do_motion_blur) ? steps : 1; + g_data->render_tot_samples = divide_ceil_u(scene->eevee.taa_render_samples, time_steps_tot); + /* Centered on frame for now. */ + float time = CFRA - scene->eevee.motion_blur_shutter / 2.0f; + float time_step = scene->eevee.motion_blur_shutter / time_steps_tot; + for (int i = 0; i < time_steps_tot && !RE_engine_test_break(engine); i++) { + float time_prev = time; + float time_curr = time + time_step * 0.5f; + float time_next = time + time_step; + time += time_step; + + /* Previous motion step. */ + if (do_motion_blur_fx) { + if (i > 0) { + /* The previous step of this iteration N is exactly the next step of iteration N - 1. + * So we just swap the resources to avoid too much re-evaluation. */ + EEVEE_motion_blur_swap_data(vedata); + } + else { + EEVEE_motion_blur_step_set(ved, MB_PREV); + RE_engine_frame_set(engine, floorf(time_prev), fractf(time_prev)); + + EEVEE_render_view_sync(vedata, engine, depsgraph); + EEVEE_render_cache_init(sldata, vedata); + + DRW_render_object_iter(vedata, engine, depsgraph, EEVEE_render_cache); + + EEVEE_motion_blur_cache_finish(vedata); + EEVEE_materials_cache_finish(sldata, vedata); + eevee_render_reset_passes(vedata); + } + } + + /* Next motion step. */ + if (do_motion_blur_fx) { + EEVEE_motion_blur_step_set(ved, MB_NEXT); + RE_engine_frame_set(engine, floorf(time_next), fractf(time_next)); - DRW_render_object_iter(vedata, engine, draw_ctx->depsgraph, EEVEE_render_cache); + EEVEE_render_view_sync(vedata, engine, depsgraph); + EEVEE_render_cache_init(sldata, vedata); - /* Actually do the rendering. */ - EEVEE_render_draw(vedata, engine, render_layer, rect); + DRW_render_object_iter(vedata, engine, depsgraph, EEVEE_render_cache); + + EEVEE_motion_blur_cache_finish(vedata); + EEVEE_materials_cache_finish(sldata, vedata); + eevee_render_reset_passes(vedata); + } + + /* Current motion step. */ + { + if (do_motion_blur) { + EEVEE_motion_blur_step_set(ved, MB_CURR); + RE_engine_frame_set(engine, floorf(time_curr), fractf(time_curr)); + } + + EEVEE_render_view_sync(vedata, engine, depsgraph); + EEVEE_render_cache_init(sldata, vedata); + + DRW_render_object_iter(vedata, engine, depsgraph, EEVEE_render_cache); + + EEVEE_motion_blur_cache_finish(vedata); + EEVEE_volumes_cache_finish(sldata, vedata); + EEVEE_materials_cache_finish(sldata, vedata); + EEVEE_lights_cache_finish(sldata, vedata); + EEVEE_lightprobes_cache_finish(sldata, vedata); + EEVEE_renderpasses_cache_finish(sldata, vedata); + + EEVEE_subsurface_draw_init(sldata, vedata); + EEVEE_effects_draw_init(sldata, vedata); + EEVEE_volumes_draw_init(sldata, vedata); + } + + /* Actual drawing. */ + { + EEVEE_renderpasses_output_init(sldata, vedata, g_data->render_tot_samples * time_steps_tot); + + EEVEE_temporal_sampling_create_view(vedata); + EEVEE_render_draw(vedata, engine, render_layer, rect); + + if (i < time_steps_tot - 1) { + /* Don't reset after the last loop. Since EEVEE_render_read_result + * might need some DRWPasses. */ + DRW_cache_restart(); + } + } + } EEVEE_volumes_free_smoke_textures(); + EEVEE_motion_blur_data_free(&ved->stl->effects->motion_blur); + + if (RE_engine_test_break(engine)) { + return; + } + + EEVEE_render_read_result(vedata, engine, render_layer, rect); + + /* Restore original viewport size. */ + DRW_render_viewport_size_set((int[2]){g_data->size_orig[0], g_data->size_orig[1]}); } static void eevee_engine_free(void) |