2017-11-01 01:03:36 +01:00
|
|
|
/*
|
|
|
|
|
* 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.
|
|
|
|
|
*
|
2019-01-23 11:29:18 +11:00
|
|
|
* Copyright 2016, Blender Foundation.
|
2017-11-01 01:03:36 +01:00
|
|
|
*/
|
|
|
|
|
|
2019-02-18 08:08:12 +11:00
|
|
|
/** \file
|
|
|
|
|
* \ingroup draw_engine
|
2017-11-20 14:11:45 +11:00
|
|
|
*
|
|
|
|
|
* Temporal super sampling technique
|
2017-11-01 01:03:36 +01:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include "DRW_render.h"
|
|
|
|
|
|
2018-04-20 18:24:14 +02:00
|
|
|
#include "ED_screen.h"
|
|
|
|
|
|
2017-11-01 01:03:36 +01:00
|
|
|
#include "BLI_rand.h"
|
|
|
|
|
|
2018-05-16 19:34:24 +02:00
|
|
|
#include "DEG_depsgraph_query.h"
|
|
|
|
|
|
2017-11-01 01:03:36 +01:00
|
|
|
#include "eevee_private.h"
|
|
|
|
|
#include "GPU_texture.h"
|
|
|
|
|
|
2018-02-03 23:48:00 +01:00
|
|
|
#define FILTER_CDF_TABLE_SIZE 512
|
|
|
|
|
|
2017-11-01 01:03:36 +01:00
|
|
|
static struct {
|
2019-04-17 06:17:24 +02:00
|
|
|
/* Pixel filter table: Only blackman-harris for now. */
|
|
|
|
|
bool inited;
|
|
|
|
|
float inverted_cdf[FILTER_CDF_TABLE_SIZE];
|
2018-11-16 13:46:13 -02:00
|
|
|
} e_data = {false}; /* Engine data */
|
2017-11-01 01:03:36 +01:00
|
|
|
|
2018-04-20 18:24:14 +02:00
|
|
|
extern char datatoc_common_uniforms_lib_glsl[];
|
|
|
|
|
extern char datatoc_common_view_lib_glsl[];
|
|
|
|
|
extern char datatoc_bsdf_common_lib_glsl[];
|
2017-11-01 01:03:36 +01:00
|
|
|
|
2018-02-05 01:49:19 +01:00
|
|
|
static float UNUSED_FUNCTION(filter_box)(float UNUSED(x))
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
return 1.0f;
|
2018-02-05 01:49:19 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static float filter_blackman_harris(float x)
|
2018-02-03 23:48:00 +01:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
/* Hardcoded 1px footprint [-0.5..0.5]. We resize later. */
|
|
|
|
|
const float width = 1.0f;
|
|
|
|
|
x = 2.0f * M_PI * (x / width + 0.5f);
|
|
|
|
|
return 0.35875f - 0.48829f * cosf(x) + 0.14128f * cosf(2.0f * x) - 0.01168f * cosf(3.0f * x);
|
2018-02-03 23:48:00 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Compute cumulative distribution function of a discrete function. */
|
|
|
|
|
static void compute_cdf(float (*func)(float x), float cdf[FILTER_CDF_TABLE_SIZE])
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
cdf[0] = 0.0f;
|
|
|
|
|
/* Actual CDF evaluation. */
|
2019-09-08 00:12:26 +10:00
|
|
|
for (int u = 0; u < FILTER_CDF_TABLE_SIZE - 1; u++) {
|
2019-04-17 06:17:24 +02:00
|
|
|
float x = (float)(u + 1) / (float)(FILTER_CDF_TABLE_SIZE - 1);
|
|
|
|
|
cdf[u + 1] = cdf[u] + func(x - 0.5f); /* [-0.5..0.5]. We resize later. */
|
|
|
|
|
}
|
|
|
|
|
/* Normalize the CDF. */
|
|
|
|
|
for (int u = 0; u < FILTER_CDF_TABLE_SIZE - 1; u++) {
|
|
|
|
|
cdf[u] /= cdf[FILTER_CDF_TABLE_SIZE - 1];
|
|
|
|
|
}
|
|
|
|
|
/* Just to make sure. */
|
|
|
|
|
cdf[FILTER_CDF_TABLE_SIZE - 1] = 1.0f;
|
2018-02-03 23:48:00 +01:00
|
|
|
}
|
|
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
static void invert_cdf(const float cdf[FILTER_CDF_TABLE_SIZE],
|
|
|
|
|
float invert_cdf[FILTER_CDF_TABLE_SIZE])
|
2018-02-03 23:48:00 +01:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
for (int u = 0; u < FILTER_CDF_TABLE_SIZE; u++) {
|
|
|
|
|
float x = (float)u / (float)(FILTER_CDF_TABLE_SIZE - 1);
|
2019-09-08 00:12:26 +10:00
|
|
|
for (int i = 0; i < FILTER_CDF_TABLE_SIZE; i++) {
|
2019-04-17 06:17:24 +02:00
|
|
|
if (cdf[i] >= x) {
|
|
|
|
|
if (i == FILTER_CDF_TABLE_SIZE - 1) {
|
|
|
|
|
invert_cdf[u] = 1.0f;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
float t = (x - cdf[i]) / (cdf[i + 1] - cdf[i]);
|
|
|
|
|
invert_cdf[u] = ((float)i + t) / (float)(FILTER_CDF_TABLE_SIZE - 1);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-02-03 23:48:00 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Evaluate a discrete function table with linear interpolation. */
|
|
|
|
|
static float eval_table(float *table, float x)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
CLAMP(x, 0.0f, 1.0f);
|
|
|
|
|
x = x * (FILTER_CDF_TABLE_SIZE - 1);
|
2018-02-03 23:48:00 +01:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
int index = min_ii((int)(x), FILTER_CDF_TABLE_SIZE - 1);
|
|
|
|
|
int nindex = min_ii(index + 1, FILTER_CDF_TABLE_SIZE - 1);
|
|
|
|
|
float t = x - index;
|
2018-02-03 23:48:00 +01:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
return (1.0f - t) * table[index] + t * table[nindex];
|
2018-02-03 23:48:00 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void eevee_create_cdf_table_temporal_sampling(void)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
float *cdf_table = MEM_mallocN(sizeof(float) * FILTER_CDF_TABLE_SIZE, "Eevee Filter CDF table");
|
2018-02-03 23:48:00 +01:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
float filter_width = 2.0f; /* Use a 2 pixel footprint by default. */
|
2018-02-05 01:49:19 +01:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
{
|
|
|
|
|
/* Use blackman-harris filter. */
|
|
|
|
|
filter_width *= 2.0f;
|
|
|
|
|
compute_cdf(filter_blackman_harris, cdf_table);
|
|
|
|
|
}
|
2018-02-05 01:49:19 +01:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
invert_cdf(cdf_table, e_data.inverted_cdf);
|
2018-02-03 23:48:00 +01:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
/* Scale and offset table. */
|
2019-09-08 00:12:26 +10:00
|
|
|
for (int i = 0; i < FILTER_CDF_TABLE_SIZE; i++) {
|
2019-04-17 06:17:24 +02:00
|
|
|
e_data.inverted_cdf[i] = (e_data.inverted_cdf[i] - 0.5f) * filter_width;
|
|
|
|
|
}
|
2018-02-05 01:49:19 +01:00
|
|
|
|
2019-04-17 06:17:24 +02:00
|
|
|
MEM_freeN(cdf_table);
|
|
|
|
|
e_data.inited = true;
|
2018-02-03 23:48:00 +01:00
|
|
|
}
|
|
|
|
|
|
2019-04-30 22:23:54 +02:00
|
|
|
void EEVEE_temporal_sampling_offset_calc(const double ht_point[2],
|
|
|
|
|
const float filter_size,
|
|
|
|
|
float r_offset[2])
|
|
|
|
|
{
|
|
|
|
|
r_offset[0] = eval_table(e_data.inverted_cdf, (float)(ht_point[0])) * filter_size;
|
|
|
|
|
r_offset[1] = eval_table(e_data.inverted_cdf, (float)(ht_point[1])) * filter_size;
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-21 12:34:48 +02:00
|
|
|
void EEVEE_temporal_sampling_matrices_calc(EEVEE_EffectsInfo *effects, const double ht_point[2])
|
2018-01-29 19:39:53 +01:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
const float *viewport_size = DRW_viewport_size_get();
|
|
|
|
|
const DRWContextState *draw_ctx = DRW_context_state_get();
|
|
|
|
|
Scene *scene = draw_ctx->scene;
|
|
|
|
|
RenderData *rd = &scene->r;
|
2018-02-05 01:49:19 +01:00
|
|
|
|
2019-05-21 12:34:48 +02:00
|
|
|
float persmat[4][4], viewmat[4][4], winmat[4][4];
|
|
|
|
|
DRW_view_persmat_get(NULL, persmat, false);
|
|
|
|
|
DRW_view_viewmat_get(NULL, viewmat, false);
|
|
|
|
|
DRW_view_winmat_get(NULL, winmat, false);
|
|
|
|
|
|
2019-04-30 22:23:54 +02:00
|
|
|
float ofs[2];
|
|
|
|
|
EEVEE_temporal_sampling_offset_calc(ht_point, rd->gauss, ofs);
|
2018-01-29 19:39:53 +01:00
|
|
|
|
2019-05-21 12:34:48 +02:00
|
|
|
window_translate_m4(winmat, persmat, ofs[0] / viewport_size[0], ofs[1] / viewport_size[1]);
|
|
|
|
|
|
|
|
|
|
BLI_assert(effects->taa_view != NULL);
|
2018-01-29 19:39:53 +01:00
|
|
|
|
2019-05-21 12:34:48 +02:00
|
|
|
/* When rendering just update the view. This avoids recomputing the culling. */
|
|
|
|
|
DRW_view_update_sub(effects->taa_view, viewmat, winmat);
|
2018-01-29 19:39:53 +01:00
|
|
|
}
|
|
|
|
|
|
2019-05-16 11:40:07 +02:00
|
|
|
/* Update the matrices based on the current sample.
|
|
|
|
|
* Note: `DRW_MAT_PERS` and `DRW_MAT_VIEW` needs to read the original matrices. */
|
|
|
|
|
void EEVEE_temporal_sampling_update_matrices(EEVEE_Data *vedata)
|
|
|
|
|
{
|
|
|
|
|
EEVEE_StorageList *stl = ((EEVEE_Data *)vedata)->stl;
|
|
|
|
|
EEVEE_EffectsInfo *effects = stl->effects;
|
|
|
|
|
|
|
|
|
|
double ht_point[2];
|
|
|
|
|
double ht_offset[2] = {0.0, 0.0};
|
|
|
|
|
uint ht_primes[2] = {2, 3};
|
|
|
|
|
|
|
|
|
|
BLI_halton_2d(ht_primes, ht_offset, effects->taa_current_sample - 1, ht_point);
|
|
|
|
|
|
2019-05-21 12:34:48 +02:00
|
|
|
EEVEE_temporal_sampling_matrices_calc(effects, ht_point);
|
2019-05-16 11:40:07 +02:00
|
|
|
|
2019-05-21 12:34:48 +02:00
|
|
|
DRW_view_set_active(effects->taa_view);
|
2019-05-16 11:40:07 +02:00
|
|
|
}
|
|
|
|
|
|
2018-07-20 22:43:30 +02:00
|
|
|
void EEVEE_temporal_sampling_reset(EEVEE_Data *vedata)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
vedata->stl->effects->taa_render_sample = 1;
|
2019-04-30 22:23:54 +02:00
|
|
|
vedata->stl->effects->taa_current_sample = 1;
|
2018-07-20 22:43:30 +02:00
|
|
|
}
|
|
|
|
|
|
2017-11-22 10:52:39 -02:00
|
|
|
int EEVEE_temporal_sampling_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
|
2017-11-01 01:03:36 +01:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
EEVEE_StorageList *stl = vedata->stl;
|
|
|
|
|
EEVEE_EffectsInfo *effects = stl->effects;
|
|
|
|
|
int repro_flag = 0;
|
|
|
|
|
|
|
|
|
|
if (!e_data.inited) {
|
|
|
|
|
eevee_create_cdf_table_temporal_sampling();
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-21 12:34:48 +02:00
|
|
|
/**
|
|
|
|
|
* Reset for each "redraw". When rendering using ogl render,
|
2020-02-11 15:18:55 +01:00
|
|
|
* we accumulate the redraw inside the drawing loop in eevee_draw_scene().
|
2019-05-21 12:34:48 +02:00
|
|
|
**/
|
2019-04-17 06:17:24 +02:00
|
|
|
effects->taa_render_sample = 1;
|
2019-05-21 12:34:48 +02:00
|
|
|
effects->taa_view = NULL;
|
|
|
|
|
|
|
|
|
|
/* Create a sub view to disable clipping planes (if any). */
|
|
|
|
|
const DRWView *default_view = DRW_view_default_get();
|
|
|
|
|
float viewmat[4][4], winmat[4][4];
|
|
|
|
|
DRW_view_viewmat_get(default_view, viewmat, false);
|
|
|
|
|
DRW_view_winmat_get(default_view, winmat, false);
|
|
|
|
|
effects->taa_view = DRW_view_create_sub(default_view, viewmat, winmat);
|
|
|
|
|
DRW_view_clip_planes_set(effects->taa_view, NULL, 0);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
|
|
|
|
const DRWContextState *draw_ctx = DRW_context_state_get();
|
|
|
|
|
const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph);
|
|
|
|
|
|
|
|
|
|
if ((scene_eval->eevee.taa_samples != 1) || DRW_state_is_image_render()) {
|
2019-05-21 12:34:48 +02:00
|
|
|
float persmat[4][4];
|
2019-04-17 06:17:24 +02:00
|
|
|
|
|
|
|
|
if (!DRW_state_is_image_render() && (scene_eval->eevee.flag & SCE_EEVEE_TAA_REPROJECTION)) {
|
|
|
|
|
repro_flag = EFFECT_TAA_REPROJECT | EFFECT_VELOCITY_BUFFER | EFFECT_DEPTH_DOUBLE_BUFFER |
|
|
|
|
|
EFFECT_DOUBLE_BUFFER | EFFECT_POST_BUFFER;
|
|
|
|
|
effects->taa_reproject_sample = ((effects->taa_reproject_sample + 1) % 16);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Until we support reprojection, we need to make sure
|
|
|
|
|
* that the history buffer contains correct information. */
|
|
|
|
|
bool view_is_valid = stl->g_data->valid_double_buffer;
|
|
|
|
|
|
|
|
|
|
view_is_valid = view_is_valid && (stl->g_data->view_updated == false);
|
|
|
|
|
|
|
|
|
|
if (draw_ctx->evil_C != NULL) {
|
|
|
|
|
struct wmWindowManager *wm = CTX_wm_manager(draw_ctx->evil_C);
|
|
|
|
|
view_is_valid = view_is_valid && (ED_screen_animation_no_scrub(wm) == NULL);
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-08 16:47:33 +01:00
|
|
|
effects->taa_total_sample = EEVEE_renderpasses_only_first_sample_pass_active(vedata) ?
|
|
|
|
|
1 :
|
|
|
|
|
scene_eval->eevee.taa_samples;
|
2019-04-17 06:17:24 +02:00
|
|
|
MAX2(effects->taa_total_sample, 0);
|
|
|
|
|
|
2019-05-21 12:34:48 +02:00
|
|
|
DRW_view_persmat_get(NULL, persmat, false);
|
2019-05-16 11:40:07 +02:00
|
|
|
view_is_valid = view_is_valid && compare_m4m4(persmat, effects->prev_drw_persmat, FLT_MIN);
|
|
|
|
|
copy_m4_m4(effects->prev_drw_persmat, persmat);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
|
|
|
|
/* Prevent ghosting from probe data. */
|
|
|
|
|
view_is_valid = view_is_valid && (effects->prev_drw_support == DRW_state_draw_support());
|
|
|
|
|
effects->prev_drw_support = DRW_state_draw_support();
|
|
|
|
|
|
|
|
|
|
if (((effects->taa_total_sample == 0) ||
|
|
|
|
|
(effects->taa_current_sample < effects->taa_total_sample)) ||
|
|
|
|
|
DRW_state_is_image_render()) {
|
|
|
|
|
if (view_is_valid) {
|
2020-02-11 15:18:55 +01:00
|
|
|
/* Viewport rendering updates the matrices in `eevee_draw_scene` */
|
2019-04-17 06:17:24 +02:00
|
|
|
if (!DRW_state_is_image_render()) {
|
|
|
|
|
effects->taa_current_sample += 1;
|
|
|
|
|
repro_flag = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
effects->taa_current_sample = 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
effects->taa_current_sample = 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return repro_flag | EFFECT_TAA | EFFECT_DOUBLE_BUFFER | EFFECT_DEPTH_DOUBLE_BUFFER |
|
|
|
|
|
EFFECT_POST_BUFFER;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
effects->taa_current_sample = 1;
|
|
|
|
|
|
|
|
|
|
return repro_flag;
|
2017-11-01 01:03:36 +01:00
|
|
|
}
|
|
|
|
|
|
2018-04-20 18:24:14 +02:00
|
|
|
void EEVEE_temporal_sampling_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
|
2017-11-01 01:03:36 +01:00
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
EEVEE_PassList *psl = vedata->psl;
|
|
|
|
|
EEVEE_StorageList *stl = vedata->stl;
|
|
|
|
|
EEVEE_TextureList *txl = vedata->txl;
|
|
|
|
|
EEVEE_EffectsInfo *effects = stl->effects;
|
|
|
|
|
|
|
|
|
|
if ((effects->enabled_effects & (EFFECT_TAA | EFFECT_TAA_REPROJECT)) != 0) {
|
|
|
|
|
struct GPUShader *sh = EEVEE_shaders_taa_resolve_sh_get(effects->enabled_effects);
|
|
|
|
|
|
2019-05-17 15:02:47 +02:00
|
|
|
DRW_PASS_CREATE(psl->taa_resolve, DRW_STATE_WRITE_COLOR);
|
2019-04-17 06:17:24 +02:00
|
|
|
DRWShadingGroup *grp = DRW_shgroup_create(sh, psl->taa_resolve);
|
|
|
|
|
|
|
|
|
|
DRW_shgroup_uniform_texture_ref(grp, "colorHistoryBuffer", &txl->taa_history);
|
|
|
|
|
DRW_shgroup_uniform_texture_ref(grp, "colorBuffer", &effects->source_buffer);
|
|
|
|
|
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
|
2020-02-20 14:53:53 +01:00
|
|
|
DRW_shgroup_uniform_block(
|
|
|
|
|
grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
|
2019-04-17 06:17:24 +02:00
|
|
|
|
|
|
|
|
if (effects->enabled_effects & EFFECT_TAA_REPROJECT) {
|
|
|
|
|
// DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
|
|
|
|
|
DRW_shgroup_uniform_texture_ref(grp, "velocityBuffer", &effects->velocity_tx);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
DRW_shgroup_uniform_float(grp, "alpha", &effects->taa_alpha, 1);
|
|
|
|
|
}
|
2019-05-13 18:28:36 +02:00
|
|
|
DRW_shgroup_call(grp, DRW_cache_fullscreen_quad_get(), NULL);
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2017-11-01 01:03:36 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void EEVEE_temporal_sampling_draw(EEVEE_Data *vedata)
|
|
|
|
|
{
|
2019-04-17 06:17:24 +02:00
|
|
|
EEVEE_PassList *psl = vedata->psl;
|
|
|
|
|
EEVEE_TextureList *txl = vedata->txl;
|
|
|
|
|
EEVEE_FramebufferList *fbl = vedata->fbl;
|
|
|
|
|
EEVEE_StorageList *stl = vedata->stl;
|
|
|
|
|
EEVEE_EffectsInfo *effects = stl->effects;
|
|
|
|
|
|
|
|
|
|
if ((effects->enabled_effects & (EFFECT_TAA | EFFECT_TAA_REPROJECT)) != 0) {
|
|
|
|
|
if ((effects->enabled_effects & EFFECT_TAA) != 0 && effects->taa_current_sample != 1) {
|
|
|
|
|
if (DRW_state_is_image_render()) {
|
|
|
|
|
/* See EEVEE_temporal_sampling_init() for more details. */
|
|
|
|
|
effects->taa_alpha = 1.0f / (float)(effects->taa_render_sample);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
effects->taa_alpha = 1.0f / (float)(effects->taa_current_sample);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
GPU_framebuffer_bind(effects->target_buffer);
|
|
|
|
|
DRW_draw_pass(psl->taa_resolve);
|
|
|
|
|
|
|
|
|
|
/* Restore the depth from sample 1. */
|
2019-05-16 11:40:07 +02:00
|
|
|
GPU_framebuffer_blit(fbl->double_buffer_depth_fb, 0, fbl->main_fb, 0, GPU_DEPTH_BIT);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
|
|
|
|
SWAP_BUFFERS_TAA();
|
|
|
|
|
}
|
|
|
|
|
else {
|
2019-05-16 11:40:07 +02:00
|
|
|
/* Save the depth buffer for the next frame.
|
|
|
|
|
* This saves us from doing anything special
|
|
|
|
|
* in the other mode engines. */
|
|
|
|
|
GPU_framebuffer_blit(fbl->main_fb, 0, fbl->double_buffer_depth_fb, 0, GPU_DEPTH_BIT);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
|
|
|
|
/* Do reprojection for noise reduction */
|
|
|
|
|
/* TODO : do AA jitter if in only render view. */
|
|
|
|
|
if (!DRW_state_is_image_render() && (effects->enabled_effects & EFFECT_TAA_REPROJECT) != 0 &&
|
|
|
|
|
stl->g_data->valid_taa_history) {
|
|
|
|
|
GPU_framebuffer_bind(effects->target_buffer);
|
|
|
|
|
DRW_draw_pass(psl->taa_resolve);
|
|
|
|
|
SWAP_BUFFERS_TAA();
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
struct GPUFrameBuffer *source_fb = (effects->target_buffer == fbl->main_color_fb) ?
|
|
|
|
|
fbl->effect_color_fb :
|
|
|
|
|
fbl->main_color_fb;
|
|
|
|
|
GPU_framebuffer_blit(source_fb, 0, fbl->taa_history_color_fb, 0, GPU_COLOR_BIT);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Make each loop count when doing a render. */
|
|
|
|
|
if (DRW_state_is_image_render()) {
|
|
|
|
|
effects->taa_render_sample += 1;
|
|
|
|
|
effects->taa_current_sample += 1;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
if ((effects->taa_total_sample == 0) ||
|
|
|
|
|
(effects->taa_current_sample < effects->taa_total_sample)) {
|
|
|
|
|
DRW_viewport_request_redraw();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2017-11-01 01:03:36 +01:00
|
|
|
}
|