diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2018-01-29 20:16:11 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2018-01-30 00:00:15 +0300 |
commit | ba9a4deddad599fbbbcfe7305b1937aa95f495bd (patch) | |
tree | 0b07e703c9271d5e4dc4a9b5310742d300b628a2 /source/blender/draw/engines | |
parent | 847613c34ecdd61effe820e5e4cabe9c3dc4915c (diff) |
Eevee: Initial Final Render support.
TAA / multiple samples is not working at the moment.
Diffstat (limited to 'source/blender/draw/engines')
8 files changed, 353 insertions, 87 deletions
diff --git a/source/blender/draw/engines/eevee/eevee_depth_of_field.c b/source/blender/draw/engines/eevee/eevee_depth_of_field.c index 124873add96..f5fc79aba4f 100644 --- a/source/blender/draw/engines/eevee/eevee_depth_of_field.c +++ b/source/blender/draw/engines/eevee/eevee_depth_of_field.c @@ -75,7 +75,7 @@ static void eevee_create_shader_depth_of_field(void) datatoc_effect_dof_frag_glsl, "#define STEP_RESOLVE\n"); } -int EEVEE_depth_of_field_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata) +int EEVEE_depth_of_field_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata, Object *camera) { EEVEE_StorageList *stl = vedata->stl; EEVEE_FramebufferList *fbl = vedata->fbl; @@ -88,17 +88,15 @@ int EEVEE_depth_of_field_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *v if (BKE_collection_engine_property_value_get_bool(props, "dof_enable")) { Scene *scene = draw_ctx->scene; - View3D *v3d = draw_ctx->v3d; RegionView3D *rv3d = draw_ctx->rv3d; if (!e_data.dof_downsample_sh) { eevee_create_shader_depth_of_field(); } - if (rv3d->persp == RV3D_CAMOB && v3d->camera) { + if (camera) { const float *viewport_size = DRW_viewport_size_get(); - Object *camera_object = DEG_get_evaluated_object(draw_ctx->depsgraph, v3d->camera); - Camera *cam = (Camera *)camera_object->data; + Camera *cam = (Camera *)camera->data; /* Retreive Near and Far distance */ effects->dof_near_far[0] = -cam->clipsta; @@ -147,7 +145,7 @@ int EEVEE_depth_of_field_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *v float rotation = cam->gpu_dof.rotation; float ratio = 1.0f / cam->gpu_dof.ratio; float sensor = BKE_camera_sensor_size(cam->sensor_fit, cam->sensor_x, cam->sensor_y); - float focus_dist = BKE_camera_object_dof_distance(camera_object); + float focus_dist = BKE_camera_object_dof_distance(camera); float focal_len = cam->lens; UNUSED_VARS(rotation, ratio); @@ -163,9 +161,13 @@ int EEVEE_depth_of_field_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *v float focal_len_scaled = scale_camera * focal_len; float sensor_scaled = scale_camera * sensor; + if (rv3d != NULL) { + sensor_scaled *= rv3d->viewcamtexcofac[0]; + } + effects->dof_params[0] = aperture * fabsf(focal_len_scaled / (focus_dist - focal_len_scaled)); effects->dof_params[1] = -focus_dist; - effects->dof_params[2] = viewport_size[0] / (rv3d->viewcamtexcofac[0] * sensor_scaled); + effects->dof_params[2] = viewport_size[0] / sensor_scaled; effects->dof_bokeh[0] = blades; effects->dof_bokeh[1] = rotation; effects->dof_bokeh[2] = ratio; diff --git a/source/blender/draw/engines/eevee/eevee_effects.c b/source/blender/draw/engines/eevee/eevee_effects.c index 5821111c59d..c1ac085230e 100644 --- a/source/blender/draw/engines/eevee/eevee_effects.c +++ b/source/blender/draw/engines/eevee/eevee_effects.c @@ -27,8 +27,6 @@ #include "DRW_render.h" -#include "BKE_global.h" /* for G.debug_value */ - #include "eevee_private.h" #include "GPU_texture.h" #include "GPU_extensions.h" @@ -100,7 +98,7 @@ static void eevee_create_shader_downsample(void) "#define COPY_DEPTH\n"); } -void EEVEE_effects_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) +void EEVEE_effects_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, Object *camera) { EEVEE_CommonUniformBuffer *common_data = &sldata->common_data; EEVEE_StorageList *stl = vedata->stl; @@ -122,9 +120,9 @@ void EEVEE_effects_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) effects = stl->effects; effects->enabled_effects = 0; - effects->enabled_effects |= EEVEE_motion_blur_init(sldata, vedata); + effects->enabled_effects |= EEVEE_motion_blur_init(sldata, vedata, camera); effects->enabled_effects |= EEVEE_bloom_init(sldata, vedata); - effects->enabled_effects |= EEVEE_depth_of_field_init(sldata, vedata); + effects->enabled_effects |= EEVEE_depth_of_field_init(sldata, vedata, camera); effects->enabled_effects |= EEVEE_temporal_sampling_init(sldata, vedata); effects->enabled_effects |= EEVEE_occlusion_init(sldata, vedata); effects->enabled_effects |= EEVEE_subsurface_init(sldata, vedata); @@ -406,7 +404,6 @@ void EEVEE_draw_effects(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) EEVEE_FramebufferList *fbl = vedata->fbl; EEVEE_StorageList *stl = vedata->stl; EEVEE_EffectsInfo *effects = stl->effects; - DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get(); DefaultTextureList *dtxl = DRW_viewport_texture_list_get(); /* only once per frame after the first post process */ @@ -427,42 +424,9 @@ void EEVEE_draw_effects(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) EEVEE_depth_of_field_draw(vedata); EEVEE_bloom_draw(vedata); - /* Restore default framebuffer */ - DRW_framebuffer_texture_attach(dfbl->default_fb, dtxl->depth, 0, 0); - DRW_framebuffer_bind(dfbl->default_fb); - - /* Tonemapping */ - DRW_transform_to_display(effects->source_buffer); - - /* Debug : Ouput buffer to view. */ - switch (G.debug_value) { - case 1: - if (txl->maxzbuffer) DRW_transform_to_display(txl->maxzbuffer); - break; - case 2: - if (stl->g_data->ssr_pdf_output) DRW_transform_to_display(stl->g_data->ssr_pdf_output); - break; - case 3: - if (txl->ssr_normal_input) DRW_transform_to_display(txl->ssr_normal_input); - break; - case 4: - if (txl->ssr_specrough_input) DRW_transform_to_display(txl->ssr_specrough_input); - break; - case 5: - if (txl->color_double_buffer) DRW_transform_to_display(txl->color_double_buffer); - break; - case 6: - if (stl->g_data->gtao_horizons_debug) DRW_transform_to_display(stl->g_data->gtao_horizons_debug); - break; - case 7: - if (txl->gtao_horizons) DRW_transform_to_display(txl->gtao_horizons); - break; - case 8: - if (txl->sss_data) DRW_transform_to_display(txl->sss_data); - break; - default: - break; - } + /* Save the final texture and framebuffer for final transformation or read. */ + effects->final_tx = effects->source_buffer; + effects->final_fb = (effects->target_buffer != fbl->main) ? fbl->main : fbl->effect_fb; /* If no post processes is enabled, buffers are still not swapped, do it now. */ SWAP_DOUBLE_BUFFERS(); diff --git a/source/blender/draw/engines/eevee/eevee_engine.c b/source/blender/draw/engines/eevee/eevee_engine.c index d06aac18877..8e74f3344dd 100644 --- a/source/blender/draw/engines/eevee/eevee_engine.c +++ b/source/blender/draw/engines/eevee/eevee_engine.c @@ -29,9 +29,13 @@ #include "BLI_rand.h" #include "BKE_object.h" +#include "BKE_global.h" /* for G.debug_value */ +#include "BKE_screen.h" #include "DNA_world_types.h" +#include "ED_screen.h" + #include "GPU_material.h" #include "GPU_glew.h" @@ -52,6 +56,11 @@ static void eevee_engine_init(void *ved) EEVEE_StorageList *stl = ((EEVEE_Data *)vedata)->stl; EEVEE_ViewLayerData *sldata = EEVEE_view_layer_data_ensure(); + const DRWContextState *draw_ctx = DRW_context_state_get(); + View3D *v3d = draw_ctx->v3d; + RegionView3D *rv3d = draw_ctx->rv3d; + Object *camera = (rv3d->persp == RV3D_CAMOB) ? v3d->camera : NULL; + if (!stl->g_data) { /* Alloc transient pointers */ stl->g_data = MEM_callocN(sizeof(*stl->g_data), __func__); @@ -71,8 +80,7 @@ static void eevee_engine_init(void *ved) } /* EEVEE_effects_init needs to go first for TAA */ - EEVEE_effects_init(sldata, vedata); - + EEVEE_effects_init(sldata, vedata, camera); EEVEE_materials_init(sldata, stl, fbl); EEVEE_lights_init(sldata); EEVEE_lightprobes_init(sldata, vedata); @@ -160,12 +168,14 @@ static void eevee_cache_finish(void *vedata) static void eevee_draw_background(void *vedata) { EEVEE_PassList *psl = ((EEVEE_Data *)vedata)->psl; + EEVEE_TextureList *txl = ((EEVEE_Data *)vedata)->txl; EEVEE_StorageList *stl = ((EEVEE_Data *)vedata)->stl; EEVEE_FramebufferList *fbl = ((EEVEE_Data *)vedata)->fbl; EEVEE_ViewLayerData *sldata = EEVEE_view_layer_data_ensure(); /* Default framebuffer and texture */ DefaultTextureList *dtxl = DRW_viewport_texture_list_get(); + DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get(); /* Number of iteration: needed for all temporal effect (SSR, TAA) * when using opengl render. */ @@ -176,14 +186,10 @@ static void eevee_draw_background(void *vedata) double offset[3] = {0.0, 0.0, 0.0}; double r[3]; - if (DRW_state_is_image_render()) { - BLI_halton_3D(primes, offset, stl->effects->taa_current_sample, r); - /* Set jitter offset */ - EEVEE_update_noise(psl, fbl, r); - } - else if ((stl->effects->enabled_effects & EFFECT_TAA) != 0) { + if (DRW_state_is_image_render() || + ((stl->effects->enabled_effects & EFFECT_TAA) != 0)) + { BLI_halton_3D(primes, offset, stl->effects->taa_current_sample, r); - /* Set jitter offset */ EEVEE_update_noise(psl, fbl, r); } @@ -281,6 +287,43 @@ static void eevee_draw_background(void *vedata) } } + /* Restore default framebuffer */ + DRW_framebuffer_texture_attach(dfbl->default_fb, dtxl->depth, 0, 0); + DRW_framebuffer_bind(dfbl->default_fb); + + /* Tonemapping */ + DRW_transform_to_display(stl->effects->final_tx); + + /* Debug : Ouput buffer to view. */ + switch (G.debug_value) { + case 1: + if (txl->maxzbuffer) DRW_transform_to_display(txl->maxzbuffer); + break; + case 2: + if (stl->g_data->ssr_pdf_output) DRW_transform_to_display(stl->g_data->ssr_pdf_output); + break; + case 3: + if (txl->ssr_normal_input) DRW_transform_to_display(txl->ssr_normal_input); + break; + case 4: + if (txl->ssr_specrough_input) DRW_transform_to_display(txl->ssr_specrough_input); + break; + case 5: + if (txl->color_double_buffer) DRW_transform_to_display(txl->color_double_buffer); + break; + case 6: + if (stl->g_data->gtao_horizons_debug) DRW_transform_to_display(stl->g_data->gtao_horizons_debug); + break; + case 7: + if (txl->gtao_horizons) DRW_transform_to_display(txl->gtao_horizons); + break; + case 8: + if (txl->sss_data) DRW_transform_to_display(txl->sss_data); + break; + default: + break; + } + EEVEE_volumes_free_smoke_textures(); stl->g_data->view_updated = false; @@ -329,6 +372,17 @@ static void eevee_id_update(void *vedata, ID *id) } } +static void eevee_render_to_image(void *vedata, struct RenderEngine *engine, struct Depsgraph *depsgraph) +{ + EEVEE_render_init(vedata, engine, depsgraph); + + DRW_render_object_iter(vedata, engine, depsgraph, EEVEE_render_cache); + /* Actually do the rendering. */ + EEVEE_render_draw(vedata, engine, depsgraph); + /* Write outputs to RenderResult. */ + EEVEE_render_output(vedata, engine, depsgraph); +} + static void eevee_engine_free(void) { EEVEE_bloom_free(); @@ -364,7 +418,8 @@ static void eevee_view_layer_settings_create(RenderEngine *UNUSED(engine), IDPro BKE_collection_engine_property_add_int(props, "gi_cubemap_resolution", 512); BKE_collection_engine_property_add_int(props, "gi_visibility_resolution", 32); - BKE_collection_engine_property_add_int(props, "taa_samples", 8); + BKE_collection_engine_property_add_int(props, "taa_samples", 16); + BKE_collection_engine_property_add_int(props, "taa_render_samples", 64); BKE_collection_engine_property_add_bool(props, "sss_enable", false); BKE_collection_engine_property_add_int(props, "sss_samples", 7); @@ -436,12 +491,13 @@ DrawEngineType draw_engine_eevee_type = { NULL, /* Everything is drawn in the background pass (see comment on function) */ &eevee_view_update, &eevee_id_update, + &eevee_render_to_image, }; RenderEngineType DRW_engine_viewport_eevee_type = { NULL, NULL, EEVEE_ENGINE, N_("Eevee"), RE_INTERNAL | RE_USE_SHADING_NODES, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, &DRW_render_to_image, NULL, NULL, NULL, NULL, NULL, &eevee_layer_collection_settings_create, &eevee_view_layer_settings_create, &draw_engine_eevee_type, diff --git a/source/blender/draw/engines/eevee/eevee_materials.c b/source/blender/draw/engines/eevee/eevee_materials.c index ff9d6024ff8..62cf8c86b88 100644 --- a/source/blender/draw/engines/eevee/eevee_materials.c +++ b/source/blender/draw/engines/eevee/eevee_materials.c @@ -569,7 +569,6 @@ void EEVEE_materials_init(EEVEE_ViewLayerData *sldata, EEVEE_StorageList *stl, E { /* Update view_vecs */ - const bool is_persp = DRW_viewport_is_persp_get(); float invproj[4][4], winmat[4][4]; /* view vectors for the corners of the view frustum. * Can be used to recreate the world space position easily */ @@ -582,6 +581,7 @@ void EEVEE_materials_init(EEVEE_ViewLayerData *sldata, EEVEE_StorageList *stl, E /* invert the view matrix */ DRW_viewport_matrix_get(winmat, DRW_MAT_WIN); invert_m4_m4(invproj, winmat); + const bool is_persp = (winmat[3][3] == 0.0f); /* convert the view vectors to view space */ for (int i = 0; i < 3; i++) { diff --git a/source/blender/draw/engines/eevee/eevee_motion_blur.c b/source/blender/draw/engines/eevee/eevee_motion_blur.c index b05fbf8c7fb..037bbe3b6c9 100644 --- a/source/blender/draw/engines/eevee/eevee_motion_blur.c +++ b/source/blender/draw/engines/eevee/eevee_motion_blur.c @@ -93,27 +93,15 @@ static void eevee_motion_blur_camera_get_matrix_at_time( CameraParams params; BKE_camera_params_init(¶ms); - /* copy of BKE_camera_params_from_view3d */ - { - params.lens = v3d->lens; - params.clipsta = v3d->near; - params.clipend = v3d->far; - - /* camera view */ + if (v3d != NULL) { + BKE_camera_params_from_view3d(¶ms, draw_ctx->depsgraph, v3d, rv3d); + BKE_camera_params_compute_viewplane(¶ms, ar->winx, ar->winy, 1.0f, 1.0f); + } + else { BKE_camera_params_from_object(¶ms, &cam_cpy); - - params.zoom = BKE_screen_view3d_zoom_to_fac(rv3d->camzoom); - - params.offsetx = 2.0f * rv3d->camdx * params.zoom; - params.offsety = 2.0f * rv3d->camdy * params.zoom; - - params.shiftx *= params.zoom; - params.shifty *= params.zoom; - - params.zoom = CAMERA_PARAM_ZOOM_INIT_CAMOB / params.zoom; + BKE_camera_params_compute_viewplane(¶ms, scene->r.xsch, scene->r.ysch, scene->r.xasp, scene->r.yasp); } - BKE_camera_params_compute_viewplane(¶ms, ar->winx, ar->winy, 1.0f, 1.0f); BKE_camera_params_compute_matrix(¶ms); /* FIXME Should be done per view (MULTIVIEW) */ @@ -127,7 +115,7 @@ static void eevee_create_shader_motion_blur(void) e_data.motion_blur_sh = DRW_shader_create_fullscreen(datatoc_effect_motion_blur_frag_glsl, NULL); } -int EEVEE_motion_blur_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata) +int EEVEE_motion_blur_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata, Object *camera) { EEVEE_StorageList *stl = vedata->stl; EEVEE_EffectsInfo *effects = stl->effects; @@ -144,11 +132,11 @@ int EEVEE_motion_blur_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *veda if (BKE_collection_engine_property_value_get_bool(props, "motion_blur_enable")) { /* Update Motion Blur Matrices */ - if (rv3d->persp == RV3D_CAMOB && v3d->camera) { + if (camera) { float persmat[4][4]; float ctime = BKE_scene_frame_get(scene); float delta = BKE_collection_engine_property_value_get_float(props, "motion_blur_shutter"); - Object *camera_object = DEG_get_evaluated_object(draw_ctx->depsgraph, v3d->camera); + Object *camera_object = DEG_get_evaluated_object(draw_ctx->depsgraph, camera); /* Current matrix */ eevee_motion_blur_camera_get_matrix_at_time(scene, diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h index 648048d44fb..9d801ac1575 100644 --- a/source/blender/draw/engines/eevee/eevee_private.h +++ b/source/blender/draw/engines/eevee/eevee_private.h @@ -517,6 +517,8 @@ typedef struct EEVEE_EffectsInfo { /* Not alloced, just a copy of a *GPUtexture in EEVEE_TextureList. */ struct GPUTexture *source_buffer; /* latest updated texture */ struct GPUFrameBuffer *target_buffer; /* next target to render to */ + struct GPUTexture *final_tx; /* Final color to transform to display color space. */ + struct GPUFrameBuffer *final_fb; /* Framebuffer with final_tx as attachement. */ } EEVEE_EffectsInfo; enum { @@ -730,6 +732,10 @@ typedef struct EEVEE_PrivateData { /* For double buffering */ bool view_updated; bool valid_double_buffer; + /* Render Matrices */ + float persmat[4][4], persinv[4][4]; + float viewmat[4][4], viewinv[4][4]; + float winmat[4][4], wininv[4][4]; } EEVEE_PrivateData; /* Transient data */ /* eevee_data.c */ @@ -786,7 +792,7 @@ void EEVEE_lightprobes_refresh(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata); void EEVEE_lightprobes_free(void); /* eevee_depth_of_field.c */ -int EEVEE_depth_of_field_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata); +int EEVEE_depth_of_field_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, Object *camera); void EEVEE_depth_of_field_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata); void EEVEE_depth_of_field_draw(EEVEE_Data *vedata); void EEVEE_depth_of_field_free(void); @@ -821,7 +827,7 @@ void EEVEE_subsurface_compute(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata); void EEVEE_subsurface_free(void); /* eevee_motion_blur.c */ -int EEVEE_motion_blur_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata); +int EEVEE_motion_blur_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, Object *camera); void EEVEE_motion_blur_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata); void EEVEE_motion_blur_draw(EEVEE_Data *vedata); void EEVEE_motion_blur_free(void); @@ -842,7 +848,7 @@ void EEVEE_volumes_free_smoke_textures(void); void EEVEE_volumes_free(void); /* eevee_effects.c */ -void EEVEE_effects_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata); +void EEVEE_effects_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, Object *camera); void EEVEE_effects_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata); void EEVEE_create_minmax_buffer(EEVEE_Data *vedata, struct GPUTexture *depth_src, int layer); void EEVEE_downsample_buffer(EEVEE_Data *vedata, struct GPUFrameBuffer *fb_src, struct GPUTexture *texture_src, int level); @@ -851,6 +857,12 @@ void EEVEE_effects_do_gtao(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata); void EEVEE_draw_effects(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata); void EEVEE_effects_free(void); +/* eevee_ */ +void EEVEE_render_init(EEVEE_Data *vedata, struct RenderEngine *engine, struct Depsgraph *depsgraph); +void EEVEE_render_cache(void *vedata, struct Object *ob, struct RenderEngine *engine, struct Depsgraph *depsgraph); +void EEVEE_render_draw(EEVEE_Data *vedata, struct RenderEngine *engine, struct Depsgraph *depsgraph); +void EEVEE_render_output(EEVEE_Data *vedata, struct RenderEngine *engine, struct Depsgraph *depsgraph); + /* Shadow Matrix */ static const float texcomat[4][4] = { /* From NDC to TexCo */ {0.5f, 0.0f, 0.0f, 0.0f}, diff --git a/source/blender/draw/engines/eevee/eevee_render.c b/source/blender/draw/engines/eevee/eevee_render.c new file mode 100644 index 00000000000..c6db8ee29d7 --- /dev/null +++ b/source/blender/draw/engines/eevee/eevee_render.c @@ -0,0 +1,238 @@ +/* + * Copyright 2016, Blender Foundation. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor(s): Blender Institute + * + */ + +/** \file eevee_render.c + * \ingroup draw_engine + */ + +/** + * Render functions for final render outputs. + */ + +#include "DRW_engine.h" +#include "DRW_render.h" + +#include "BLI_rand.h" + +#include "DEG_depsgraph_query.h" + +#include "GPU_framebuffer.h" +#include "GPU_glew.h" + +#include "RE_pipeline.h" + +#include "eevee_private.h" + +void EEVEE_render_init(EEVEE_Data *ved, RenderEngine *engine, struct Depsgraph *depsgraph) +{ + EEVEE_Data *vedata = (EEVEE_Data *)ved; + EEVEE_PassList *psl = vedata->psl; + EEVEE_StorageList *stl = vedata->stl; + EEVEE_TextureList *txl = vedata->txl; + EEVEE_FramebufferList *fbl = vedata->fbl; + EEVEE_ViewLayerData *sldata = EEVEE_view_layer_data_ensure(); + Scene *scene = DEG_get_evaluated_scene(depsgraph); + const float *viewport_size = DRW_viewport_size_get(); + + /* Init default FB and render targets: + * In render mode the default framebuffer is not generated + * because there is no viewport. So we need to manually create it or + * not use it. For code clarity we just allocate it make use of it. */ + DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get(); + DefaultTextureList *dtxl = DRW_viewport_texture_list_get(); + + /* NOTE : use 32 bit format for precision in render mode. */ + DRWFboTexture dtex = {&dtxl->depth, DRW_TEX_DEPTH_24_STENCIL_8, 0}; + DRW_framebuffer_init(&dfbl->default_fb, &draw_engine_eevee_type, + (int)viewport_size[0], (int)viewport_size[1], + &dtex, 1); + + DRWFboTexture tex = {&txl->color, DRW_TEX_RGBA_32, DRW_TEX_FILTER | DRW_TEX_MIPMAP}; + DRW_framebuffer_init(&fbl->main, &draw_engine_eevee_type, + (int)viewport_size[0], (int)viewport_size[1], + &tex, 1); + + /* Alloc transient data. */ + if (!stl->g_data) { + stl->g_data = MEM_callocN(sizeof(*stl->g_data), __func__); + } + EEVEE_PrivateData *g_data = stl->g_data; + g_data->background_alpha = 1.0f; /* TODO option */ + g_data->valid_double_buffer = 0; + + /* Alloc common ubo data. */ + if (sldata->common_ubo == NULL) { + sldata->common_ubo = DRW_uniformbuffer_create(sizeof(sldata->common_data), &sldata->common_data); + } + + /* Set the pers & view matrix. */ + struct Object *camera = RE_GetCamera(engine->re); + float frame = BKE_scene_frame_get(scene); + RE_GetCameraWindow(engine->re, camera, frame, g_data->winmat); + RE_GetCameraModelMatrix(engine->re, camera, g_data->viewinv); + + invert_m4_m4(g_data->viewmat, g_data->viewinv); + mul_m4_m4m4(g_data->persmat, g_data->winmat, g_data->viewmat); + invert_m4_m4(g_data->persinv, g_data->persmat); + invert_m4_m4(g_data->wininv, g_data->winmat); + + DRW_viewport_matrix_override_set(g_data->persmat, DRW_MAT_PERS); + DRW_viewport_matrix_override_set(g_data->persinv, DRW_MAT_PERSINV); + DRW_viewport_matrix_override_set(g_data->winmat, DRW_MAT_WIN); + DRW_viewport_matrix_override_set(g_data->wininv, DRW_MAT_WININV); + DRW_viewport_matrix_override_set(g_data->viewmat, DRW_MAT_VIEW); + DRW_viewport_matrix_override_set(g_data->viewinv, DRW_MAT_VIEWINV); + + /* EEVEE_effects_init needs to go first for TAA */ + EEVEE_effects_init(sldata, vedata, camera); + EEVEE_materials_init(sldata, stl, fbl); + EEVEE_lights_init(sldata); + EEVEE_lightprobes_init(sldata, vedata); + + /* INIT CACHE */ + EEVEE_bloom_cache_init(sldata, vedata); + EEVEE_depth_of_field_cache_init(sldata, vedata); + EEVEE_effects_cache_init(sldata, vedata); + EEVEE_lightprobes_cache_init(sldata, vedata); + EEVEE_lights_cache_init(sldata, psl); + EEVEE_materials_cache_init(vedata); + EEVEE_motion_blur_cache_init(sldata, vedata); + EEVEE_occlusion_cache_init(sldata, vedata); + EEVEE_screen_raytrace_cache_init(sldata, vedata); + EEVEE_subsurface_cache_init(sldata, vedata); + EEVEE_temporal_sampling_cache_init(sldata, vedata); + EEVEE_volumes_cache_init(sldata, vedata); +} + +void EEVEE_render_cache( + void *vedata, struct Object *ob, + struct RenderEngine *UNUSED(engine), struct Depsgraph *UNUSED(depsgraph)) +{ + EEVEE_ViewLayerData *sldata = EEVEE_view_layer_data_ensure(); + + if (DRW_check_object_visible_within_active_context(ob) == false) { + return; + } + + if (ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT)) { + EEVEE_materials_cache_populate(vedata, sldata, ob); + + const bool cast_shadow = true; + + if (cast_shadow) { + EEVEE_lights_cache_shcaster_object_add(sldata, ob); + } + } + else if (ob->type == OB_LIGHTPROBE) { + EEVEE_lightprobes_cache_add(sldata, ob); + } + else if (ob->type == OB_LAMP) { + EEVEE_lights_cache_add(sldata, ob); + } +} + +void EEVEE_render_draw(EEVEE_Data *vedata, struct RenderEngine *UNUSED(engine), struct Depsgraph *UNUSED(depsgraph)) +{ + EEVEE_PassList *psl = vedata->psl; + EEVEE_StorageList *stl = vedata->stl; + EEVEE_FramebufferList *fbl = vedata->fbl; + DefaultTextureList *dtxl = DRW_viewport_texture_list_get(); + EEVEE_ViewLayerData *sldata = EEVEE_view_layer_data_ensure(); + EEVEE_PrivateData *g_data = stl->g_data; + + /* FINISH CACHE */ + EEVEE_materials_cache_finish(vedata); + EEVEE_lights_cache_finish(sldata); + EEVEE_lightprobes_cache_finish(sldata, vedata); + + { + float clear_col[4] = {0.0f, 0.0f, 0.0f, 0.6f}; + unsigned int primes[3] = {2, 3, 7}; + double offset[3] = {0.0, 0.0, 0.0}; + double r[3]; + + BLI_halton_3D(primes, offset, stl->effects->taa_current_sample, r); + EEVEE_update_noise(psl, fbl, r); + + /* Refresh Probes & shadows */ + EEVEE_lightprobes_refresh(sldata, vedata); + DRW_uniformbuffer_update(sldata->common_ubo, &sldata->common_data); + EEVEE_draw_shadows(sldata, psl); + + DRW_viewport_matrix_override_set(g_data->persmat, DRW_MAT_PERS); + DRW_viewport_matrix_override_set(g_data->persinv, DRW_MAT_PERSINV); + DRW_viewport_matrix_override_set(g_data->winmat, DRW_MAT_WIN); + DRW_viewport_matrix_override_set(g_data->wininv, DRW_MAT_WININV); + DRW_viewport_matrix_override_set(g_data->viewmat, DRW_MAT_VIEW); + DRW_viewport_matrix_override_set(g_data->viewinv, DRW_MAT_VIEWINV); + + DRW_framebuffer_texture_detach(dtxl->depth); + DRW_framebuffer_texture_attach(fbl->main, dtxl->depth, 0, 0); + DRW_framebuffer_bind(fbl->main); + DRW_framebuffer_clear(true, true, true, clear_col, 1.0f); + /* Depth prepass */ + DRW_draw_pass(psl->depth_pass); + DRW_draw_pass(psl->depth_pass_cull); + /* Create minmax texture */ + EEVEE_create_minmax_buffer(vedata, dtxl->depth, -1); + EEVEE_occlusion_compute(sldata, vedata, dtxl->depth, -1); + EEVEE_volumes_compute(sldata, vedata); + /* Shading pass */ + DRW_draw_pass(psl->background_pass); + EEVEE_draw_default_passes(psl); + DRW_draw_pass(psl->material_pass); + EEVEE_subsurface_data_render(sldata, vedata); + /* Effects pre-transparency */ + EEVEE_subsurface_compute(sldata, vedata); + EEVEE_reflection_compute(sldata, vedata); + EEVEE_occlusion_draw_debug(sldata, vedata); + DRW_draw_pass(psl->probe_display); + EEVEE_refraction_compute(sldata, vedata); + /* Opaque refraction */ + DRW_draw_pass(psl->refract_depth_pass); + DRW_draw_pass(psl->refract_depth_pass_cull); + DRW_draw_pass(psl->refract_pass); + /* Volumetrics Resolve Opaque */ + EEVEE_volumes_resolve(sldata, vedata); + /* Transparent */ + DRW_pass_sort_shgroup_z(psl->transparent_pass); + DRW_draw_pass(psl->transparent_pass); + /* Post Process */ + EEVEE_draw_effects(sldata, vedata); + } +} + +void EEVEE_render_output(EEVEE_Data *vedata, RenderEngine *engine, struct Depsgraph *UNUSED(depsgraph)) +{ + EEVEE_StorageList *stl = vedata->stl; + + const char *viewname = NULL; + const float *render_size = DRW_viewport_size_get(); + + RenderResult *rr = RE_engine_begin_result(engine, 0, 0, (int)render_size[0], (int)render_size[1], NULL, viewname); + RenderLayer *rl = rr->layers.first; + RenderPass *rp = RE_pass_find_by_name(rl, RE_PASSNAME_COMBINED, viewname); + + DRW_framebuffer_bind(stl->effects->final_fb); + DRW_framebuffer_read_data(0, 0, (int)render_size[0], (int)render_size[1], 4, 0, rp->rect); + + RE_engine_end_result(engine, rr, false, false, false); +}
\ No newline at end of file diff --git a/source/blender/draw/engines/eevee/eevee_temporal_sampling.c b/source/blender/draw/engines/eevee/eevee_temporal_sampling.c index 3ed2a20e68c..f4bf554f5b3 100644 --- a/source/blender/draw/engines/eevee/eevee_temporal_sampling.c +++ b/source/blender/draw/engines/eevee/eevee_temporal_sampling.c @@ -142,6 +142,8 @@ int EEVEE_temporal_sampling_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data return EFFECT_TAA | EFFECT_DOUBLE_BUFFER | EFFECT_POST_BUFFER; } + effects->taa_current_sample = 1; + /* Cleanup to release memory */ DRW_TEXTURE_FREE_SAFE(txl->depth_double_buffer); DRW_FRAMEBUFFER_FREE_SAFE(fbl->depth_double_buffer_fb); @@ -189,7 +191,9 @@ void EEVEE_temporal_sampling_draw(EEVEE_Data *vedata) DRW_draw_pass(psl->taa_resolve); /* Restore the depth from sample 1. */ - DRW_framebuffer_blit(fbl->depth_double_buffer_fb, fbl->main, true, false); + if (!DRW_state_is_image_render()) { + DRW_framebuffer_blit(fbl->depth_double_buffer_fb, fbl->main, true, false); + } /* Special Swap */ SWAP(struct GPUFrameBuffer *, fbl->effect_fb, fbl->double_buffer); @@ -202,7 +206,9 @@ void EEVEE_temporal_sampling_draw(EEVEE_Data *vedata) /* Save the depth buffer for the next frame. * This saves us from doing anything special * in the other mode engines. */ - DRW_framebuffer_blit(fbl->main, fbl->depth_double_buffer_fb, true, false); + if (!DRW_state_is_image_render()) { + DRW_framebuffer_blit(fbl->main, fbl->depth_double_buffer_fb, true, false); + } } /* Make each loop count when doing a render. */ |