This repository has been archived on 2023-10-09. You can view files and clone it, but cannot push or open issues or pull requests.
Files
blender-archive/source/blender/draw/engines/eevee/eevee_effects.c

204 lines
6.3 KiB
C
Raw Normal View History

/*
* 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
*
*/
/* Gather all screen space effects technique such as Bloom, Motion Blur, DoF, SSAO, SSR, ...
*/
/** \file eevee_effects.c
* \ingroup draw_engine
*/
#include "DRW_render.h"
#include "DNA_anim_types.h"
#include "DNA_view3d_types.h"
#include "BKE_object.h"
#include "BKE_animsys.h"
#include "eevee_private.h"
#include "GPU_texture.h"
typedef struct EEVEE_ProbeData {
short probe_id, shadow_id;
} EEVEE_ProbeData;
/* TODO Option */
#define PROBE_SIZE 512
static struct {
struct GPUShader *motion_blur_sh;
struct GPUShader *tonemap_sh;
} e_data = {NULL}; /* Engine data */
extern char datatoc_effect_motion_blur_frag_glsl[];
extern char datatoc_tonemap_frag_glsl[];
void EEVEE_effects_init(EEVEE_Data *vedata)
{
EEVEE_StorageList *stl = vedata->stl;
EEVEE_FramebufferList *fbl = vedata->fbl;
EEVEE_TextureList *txl = vedata->txl;
/* Ping Pong buffer */
DRWFboTexture tex = {&txl->color_post, DRW_BUF_RGBA_16, DRW_TEX_FILTER};
const float *viewport_size = DRW_viewport_size_get();
DRW_framebuffer_init(&fbl->effect_fb,
(int)viewport_size[0], (int)viewport_size[1],
&tex, 1);
if (!e_data.motion_blur_sh) {
e_data.motion_blur_sh = DRW_shader_create_fullscreen(datatoc_effect_motion_blur_frag_glsl, NULL);
}
if (!e_data.tonemap_sh) {
e_data.tonemap_sh = DRW_shader_create_fullscreen(datatoc_tonemap_frag_glsl, NULL);
}
if (!stl->effects) {
stl->effects = MEM_callocN(sizeof(EEVEE_EffectsInfo), "EEVEE_EffectsInfo");
}
{
/* Update Motion Blur Matrices */
EEVEE_EffectsInfo *effects = stl->effects;
#if ENABLE_EFFECT_MOTION_BLUR
const DRWContextState *draw_ctx = DRW_context_state_get();
Scene *scene = draw_ctx->scene;
View3D *v3d = draw_ctx->v3d;
RegionView3D *rv3d = draw_ctx->rv3d;
if (rv3d->persp == RV3D_CAMOB && v3d->camera) {
float ctime = BKE_scene_frame_get(scene);
float past_obmat[4][4], future_obmat[4][4], winmat[4][4];
DRW_viewport_matrix_get(winmat, DRW_MAT_WIN);
/* HACK */
Object cam_cpy;
memcpy(&cam_cpy, v3d->camera, sizeof(cam_cpy));
/* Past matrix */
/* FIXME : This is a temporal solution that does not take care of parent animations */
/* Recalc Anim manualy */
BKE_animsys_evaluate_animdata(scene, &cam_cpy.id, cam_cpy.adt, ctime - 1.0, ADT_RECALC_ANIM);
BKE_object_where_is_calc_time(scene, &cam_cpy, ctime - 1.0);
normalize_m4_m4(past_obmat, cam_cpy.obmat);
invert_m4(past_obmat);
mul_m4_m4m4(effects->past_world_to_ndc, winmat, past_obmat);
#if 0 /* for future high quality blur */
/* Future matrix */
/* Recalc Anim manualy */
BKE_animsys_evaluate_animdata(scene, &cam_cpy.id, cam_cpy.adt, ctime + 1.0, ADT_RECALC_ANIM);
BKE_object_where_is_calc_time(scene, &cam_cpy, ctime + 1.0);
normalize_m4_m4(past_obmat, cam_cpy.obmat);
invert_m4(past_obmat);
mul_m4_m4m4(effects->past_world_to_ndc, winmat, past_obmat);
#else
UNUSED_VARS(future_obmat);
#endif
/* Current matrix */
DRW_viewport_matrix_get(effects->current_ndc_to_world, DRW_MAT_PERSINV);
effects->blur_amount = 0.5f;
effects->final_color = txl->color_post;
effects->enabled_effects |= EFFECT_MOTION_BLUR;
}
else {
#endif /* ENABLE_EFFECT_MOTION_BLUR */
effects->blur_amount = 0.0f;
effects->final_color = txl->color;
effects->enabled_effects &= ~EFFECT_MOTION_BLUR;
#if ENABLE_EFFECT_MOTION_BLUR
}
#endif
}
}
void EEVEE_effects_cache_init(EEVEE_Data *vedata)
{
EEVEE_PassList *psl = vedata->psl;
EEVEE_StorageList *stl = vedata->stl;
EEVEE_TextureList *txl = vedata->txl;
EEVEE_EffectsInfo *effects = stl->effects;
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
struct Batch *quad = DRW_cache_fullscreen_quad_get();
{
psl->motion_blur = DRW_pass_create("Motion Blur", DRW_STATE_WRITE_COLOR);
DRWShadingGroup *grp = DRW_shgroup_create(e_data.motion_blur_sh, psl->motion_blur);
DRW_shgroup_uniform_float(grp, "blurAmount", &effects->blur_amount, 1);
DRW_shgroup_uniform_mat4(grp, "currInvViewProjMatrix", (float *)effects->current_ndc_to_world);
DRW_shgroup_uniform_mat4(grp, "pastViewProjMatrix", (float *)effects->past_world_to_ndc);
DRW_shgroup_uniform_buffer(grp, "colorBuffer", &txl->color, 0);
DRW_shgroup_uniform_buffer(grp, "depthBuffer", &dtxl->depth, 1);
DRW_shgroup_call_add(grp, quad, NULL);
}
{
/* Final pass : Map HDR color to LDR color.
* Write result to the default color buffer */
psl->tonemap = DRW_pass_create("Tone Mapping", DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND);
DRWShadingGroup *grp = DRW_shgroup_create(e_data.tonemap_sh, psl->tonemap);
DRW_shgroup_uniform_buffer(grp, "hdrColorBuf", &effects->final_color, 0);
DRW_shgroup_call_add(grp, quad, NULL);
}
}
void EEVEE_draw_effects(EEVEE_Data *vedata)
{
EEVEE_PassList *psl = vedata->psl;
EEVEE_FramebufferList *fbl = vedata->fbl;
EEVEE_StorageList *stl = vedata->stl;
EEVEE_EffectsInfo *effects = stl->effects;
/* Default framebuffer and texture */
DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
if ((effects->enabled_effects & EFFECT_MOTION_BLUR) != 0) {
/* Motion Blur */
DRW_framebuffer_bind(fbl->effect_fb);
DRW_draw_pass(psl->motion_blur);
}
/* Restore default framebuffer */
DRW_framebuffer_texture_detach(dtxl->depth);
DRW_framebuffer_texture_attach(dfbl->default_fb, dtxl->depth, 0, 0);
DRW_framebuffer_bind(dfbl->default_fb);
/* Tonemapping */
DRW_draw_pass(psl->tonemap);
}
void EEVEE_effects_free(void)
{
DRW_SHADER_FREE_SAFE(e_data.tonemap_sh);
DRW_SHADER_FREE_SAFE(e_data.motion_blur_sh);
}