Move EEVEE properties into scene
[blender.git] / source / blender / draw / engines / eevee / eevee_temporal_sampling.c
1 /*
2  * Copyright 2016, Blender Foundation.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * Contributor(s): Blender Institute
19  *
20  */
21
22 /** \file eevee_temporal_sampling.c
23  *  \ingroup draw_engine
24  *
25  * Temporal super sampling technique
26  */
27
28 #include "DRW_render.h"
29
30 #include "ED_screen.h"
31
32 #include "BLI_rand.h"
33 #include "BLI_string_utils.h"
34
35 #include "DEG_depsgraph_query.h"
36
37 #include "eevee_private.h"
38 #include "GPU_texture.h"
39
40 #define FILTER_CDF_TABLE_SIZE 512
41
42 static struct {
43         /* Temporal Anti Aliasing */
44         struct GPUShader *taa_resolve_sh;
45         struct GPUShader *taa_resolve_reproject_sh;
46
47         /* Pixel filter table: Only blackman-harris for now. */
48         float inverted_cdf[FILTER_CDF_TABLE_SIZE];
49 } e_data = {NULL}; /* Engine data */
50
51 extern char datatoc_common_uniforms_lib_glsl[];
52 extern char datatoc_common_view_lib_glsl[];
53 extern char datatoc_bsdf_common_lib_glsl[];
54 extern char datatoc_effect_temporal_aa_glsl[];
55
56 static void eevee_create_shader_temporal_sampling(void)
57 {
58         char *frag_str = BLI_string_joinN(
59                 datatoc_common_uniforms_lib_glsl,
60                 datatoc_common_view_lib_glsl,
61                 datatoc_bsdf_common_lib_glsl,
62                 datatoc_effect_temporal_aa_glsl);
63
64         e_data.taa_resolve_sh = DRW_shader_create_fullscreen(frag_str, NULL);
65         e_data.taa_resolve_reproject_sh = DRW_shader_create_fullscreen(frag_str, "#define USE_REPROJECTION\n");
66
67         MEM_freeN(frag_str);
68 }
69
70 static float UNUSED_FUNCTION(filter_box)(float UNUSED(x))
71 {
72         return 1.0f;
73 }
74
75 static float filter_blackman_harris(float x)
76 {
77         /* Hardcoded 1px footprint [-0.5..0.5]. We resize later. */
78         const float width = 1.0f;
79         x = 2.0f * M_PI * (x / width + 0.5f);
80         return 0.35875f - 0.48829f * cosf(x) + 0.14128f * cosf(2.0f * x) - 0.01168f * cosf(3.0f * x);
81 }
82
83 /* Compute cumulative distribution function of a discrete function. */
84 static void compute_cdf(float (*func)(float x), float cdf[FILTER_CDF_TABLE_SIZE])
85 {
86         cdf[0] = 0.0f;
87         /* Actual CDF evaluation. */
88         for (int u = 0; u < FILTER_CDF_TABLE_SIZE - 1; ++u) {
89                 float x = (float)(u + 1) / (float)(FILTER_CDF_TABLE_SIZE - 1);
90                 cdf[u + 1] = cdf[u] + func(x - 0.5f); /* [-0.5..0.5]. We resize later. */
91         }
92         /* Normalize the CDF. */
93         for (int u = 0; u < FILTER_CDF_TABLE_SIZE - 1; u++) {
94                 cdf[u] /= cdf[FILTER_CDF_TABLE_SIZE - 1];
95         }
96         /* Just to make sure. */
97         cdf[FILTER_CDF_TABLE_SIZE - 1] = 1.0f;
98 }
99
100 static void invert_cdf(const float cdf[FILTER_CDF_TABLE_SIZE], float invert_cdf[FILTER_CDF_TABLE_SIZE])
101 {
102         for (int u = 0; u < FILTER_CDF_TABLE_SIZE; u++) {
103                 float x = (float)u / (float)(FILTER_CDF_TABLE_SIZE - 1);
104                 for (int i = 0; i < FILTER_CDF_TABLE_SIZE; ++i) {
105                         if (cdf[i] >= x) {
106                                 if (i == FILTER_CDF_TABLE_SIZE - 1) {
107                                         invert_cdf[u] = 1.0f;
108                                 }
109                                 else {
110                                         float t = (x - cdf[i]) / (cdf[i + 1] - cdf[i]);
111                                         invert_cdf[u] = ((float)i + t) / (float)(FILTER_CDF_TABLE_SIZE - 1);
112                                 }
113                                 break;
114                         }
115                 }
116         }
117 }
118
119 /* Evaluate a discrete function table with linear interpolation. */
120 static float eval_table(float *table, float x)
121 {
122         CLAMP(x, 0.0f, 1.0f);
123         x = x * (FILTER_CDF_TABLE_SIZE - 1);
124
125         int index = min_ii((int)(x), FILTER_CDF_TABLE_SIZE - 1);
126         int nindex = min_ii(index + 1, FILTER_CDF_TABLE_SIZE - 1);
127         float t = x - index;
128
129         return (1.0f - t) * table[index] + t * table[nindex];
130 }
131
132 static void eevee_create_cdf_table_temporal_sampling(void)
133 {
134         float *cdf_table = MEM_mallocN(sizeof(float) * FILTER_CDF_TABLE_SIZE, "Eevee Filter CDF table");
135
136         float filter_width = 2.0f; /* Use a 2 pixel footprint by default. */
137
138         {
139                 /* Use blackman-harris filter. */
140                 filter_width *= 2.0f;
141                 compute_cdf(filter_blackman_harris, cdf_table);
142         }
143
144         invert_cdf(cdf_table, e_data.inverted_cdf);
145
146         /* Scale and offset table. */
147         for (int i = 0; i < FILTER_CDF_TABLE_SIZE; ++i) {
148                 e_data.inverted_cdf[i] = (e_data.inverted_cdf[i] - 0.5f) * filter_width;
149         }
150
151         MEM_freeN(cdf_table);
152 }
153
154 void EEVEE_temporal_sampling_matrices_calc(
155         EEVEE_EffectsInfo *effects, float viewmat[4][4], float persmat[4][4], const double ht_point[2])
156 {
157         const float *viewport_size = DRW_viewport_size_get();
158         const DRWContextState *draw_ctx = DRW_context_state_get();
159         Scene *scene = draw_ctx->scene;
160         RenderData *rd = &scene->r;
161
162         float filter_size = rd->gauss; /* Sigh.. Stupid legacy naming. */
163
164         float ofs_x = eval_table(e_data.inverted_cdf, (float)(ht_point[0])) * filter_size;
165         float ofs_y = eval_table(e_data.inverted_cdf, (float)(ht_point[1])) * filter_size;
166
167         window_translate_m4(
168                 effects->overide_winmat, persmat,
169                 ofs_x / viewport_size[0],
170                 ofs_y / viewport_size[1]);
171
172         mul_m4_m4m4(effects->overide_persmat, effects->overide_winmat, viewmat);
173         invert_m4_m4(effects->overide_persinv, effects->overide_persmat);
174         invert_m4_m4(effects->overide_wininv, effects->overide_winmat);
175 }
176
177 int EEVEE_temporal_sampling_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
178 {
179         EEVEE_StorageList *stl = vedata->stl;
180         // EEVEE_FramebufferList *fbl = vedata->fbl;
181         // EEVEE_TextureList *txl = vedata->txl;
182         EEVEE_EffectsInfo *effects = stl->effects;
183         int repro_flag = 0;
184
185         if (!e_data.taa_resolve_sh) {
186                 eevee_create_shader_temporal_sampling();
187                 eevee_create_cdf_table_temporal_sampling();
188         }
189
190         /* Reset for each "redraw". When rendering using ogl render,
191          * we accumulate the redraw inside the drawing loop in eevee_draw_background().
192          * But we do NOT accumulate between "redraw" (as in full draw manager drawloop)
193          * because the opengl render already does that. */
194         effects->taa_render_sample = 1;
195
196         const DRWContextState *draw_ctx = DRW_context_state_get();
197         const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph);
198
199         if (((scene_eval->eevee.taa_samples != 1) &&
200             /* FIXME the motion blur camera evaluation is tagging view_updated
201              * thus making the TAA always reset and never stopping rendering. */
202             (effects->enabled_effects & EFFECT_MOTION_BLUR) == 0) ||
203             DRW_state_is_image_render())
204         {
205                 float persmat[4][4], viewmat[4][4];
206
207                 if (!DRW_state_is_image_render() &&
208                     (scene_eval->eevee.flag & SCE_EEVEE_TAA_REPROJECTION))
209                 {
210                         repro_flag = EFFECT_TAA_REPROJECT | EFFECT_VELOCITY_BUFFER | EFFECT_DEPTH_DOUBLE_BUFFER | EFFECT_DOUBLE_BUFFER | EFFECT_POST_BUFFER;
211                         effects->taa_reproject_sample = ((effects->taa_reproject_sample + 1) % 16);
212                 }
213
214                 /* Until we support reprojection, we need to make sure
215                  * that the history buffer contains correct information. */
216                 bool view_is_valid = stl->g_data->valid_double_buffer;
217
218                 view_is_valid = view_is_valid && (stl->g_data->view_updated == false);
219
220                 if (draw_ctx->evil_C != NULL) {
221                         struct wmWindowManager *wm = CTX_wm_manager(draw_ctx->evil_C);
222                         view_is_valid = view_is_valid && (ED_screen_animation_no_scrub(wm) == NULL);
223                 }
224
225                 effects->taa_total_sample = scene_eval->eevee.taa_samples;
226                 MAX2(effects->taa_total_sample, 0);
227
228                 DRW_viewport_matrix_get(persmat, DRW_MAT_PERS);
229                 DRW_viewport_matrix_get(viewmat, DRW_MAT_VIEW);
230                 DRW_viewport_matrix_get(effects->overide_winmat, DRW_MAT_WIN);
231                 /* The view is jittered by the oglrenderer. So avoid testing in this case. */
232                 if (!DRW_state_is_image_render()) {
233                         view_is_valid = view_is_valid && compare_m4m4(persmat, effects->prev_drw_persmat, FLT_MIN);
234                         copy_m4_m4(effects->prev_drw_persmat, persmat);
235                 }
236
237                 /* Prevent ghosting from probe data. */
238                 view_is_valid = view_is_valid && (effects->prev_drw_support == DRW_state_draw_support());
239                 effects->prev_drw_support = DRW_state_draw_support();
240
241                 if (((effects->taa_total_sample == 0) || (effects->taa_current_sample < effects->taa_total_sample)) ||
242                     DRW_state_is_image_render())
243                 {
244                         if (view_is_valid) {
245                                 /* OGL render already jitter the camera. */
246                                 if (!DRW_state_is_image_render()) {
247                                         effects->taa_current_sample += 1;
248                                         repro_flag = 0;
249
250                                         double ht_point[2];
251                                         double ht_offset[2] = {0.0, 0.0};
252                                         uint ht_primes[2] = {2, 3};
253
254                                         BLI_halton_2D(ht_primes, ht_offset, effects->taa_current_sample - 1, ht_point);
255
256                                         EEVEE_temporal_sampling_matrices_calc(effects, viewmat, persmat, ht_point);
257
258                                         DRW_viewport_matrix_override_set(effects->overide_persmat, DRW_MAT_PERS);
259                                         DRW_viewport_matrix_override_set(effects->overide_persinv, DRW_MAT_PERSINV);
260                                         DRW_viewport_matrix_override_set(effects->overide_winmat, DRW_MAT_WIN);
261                                         DRW_viewport_matrix_override_set(effects->overide_wininv, DRW_MAT_WININV);
262                                 }
263                         }
264                         else {
265                                 effects->taa_current_sample = 1;
266                         }
267                 }
268                 else {
269                         effects->taa_current_sample = 1;
270                 }
271
272                 return repro_flag | EFFECT_TAA | EFFECT_DOUBLE_BUFFER | EFFECT_DEPTH_DOUBLE_BUFFER | EFFECT_POST_BUFFER;
273         }
274
275         effects->taa_current_sample = 1;
276
277         return repro_flag;
278 }
279
280 void EEVEE_temporal_sampling_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
281 {
282         EEVEE_PassList *psl = vedata->psl;
283         EEVEE_StorageList *stl = vedata->stl;
284         EEVEE_TextureList *txl = vedata->txl;
285         EEVEE_EffectsInfo *effects = stl->effects;
286
287         if ((effects->enabled_effects & (EFFECT_TAA | EFFECT_TAA_REPROJECT)) != 0) {
288                 struct GPUShader *sh = (effects->enabled_effects & EFFECT_TAA_REPROJECT)
289                                         ? e_data.taa_resolve_reproject_sh
290                                         : e_data.taa_resolve_sh;
291
292                 psl->taa_resolve = DRW_pass_create("Temporal AA Resolve", DRW_STATE_WRITE_COLOR);
293                 DRWShadingGroup *grp = DRW_shgroup_create(sh, psl->taa_resolve);
294
295                 DRW_shgroup_uniform_texture_ref(grp, "colorHistoryBuffer", &txl->color_double_buffer);
296                 DRW_shgroup_uniform_texture_ref(grp, "colorBuffer", &txl->color);
297
298                 if (effects->enabled_effects & EFFECT_TAA_REPROJECT) {
299                         // DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
300                         DRW_shgroup_uniform_texture_ref(grp, "velocityBuffer", &effects->velocity_tx);
301                         DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
302                 }
303                 else {
304                         DRW_shgroup_uniform_float(grp, "alpha", &effects->taa_alpha, 1);
305                 }
306                 DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
307         }
308 }
309
310 /* Special Swap */
311 #define SWAP_BUFFER_TAA() do { \
312         SWAP(struct GPUFrameBuffer *, fbl->effect_fb, fbl->double_buffer_fb); \
313         SWAP(struct GPUFrameBuffer *, fbl->effect_color_fb, fbl->double_buffer_color_fb); \
314         SWAP(GPUTexture *, txl->color_post, txl->color_double_buffer); \
315         effects->swap_double_buffer = false; \
316         effects->source_buffer = txl->color_double_buffer; \
317         effects->target_buffer = fbl->main_color_fb; \
318 } while (0);
319
320 void EEVEE_temporal_sampling_draw(EEVEE_Data *vedata)
321 {
322         EEVEE_PassList *psl = vedata->psl;
323         EEVEE_TextureList *txl = vedata->txl;
324         EEVEE_FramebufferList *fbl = vedata->fbl;
325         EEVEE_StorageList *stl = vedata->stl;
326         EEVEE_EffectsInfo *effects = stl->effects;
327
328         if ((effects->enabled_effects & (EFFECT_TAA | EFFECT_TAA_REPROJECT)) != 0) {
329                 if ((effects->enabled_effects & EFFECT_TAA) != 0 && effects->taa_current_sample != 1) {
330                         if (DRW_state_is_image_render()) {
331                                 /* See EEVEE_temporal_sampling_init() for more details. */
332                                 effects->taa_alpha = 1.0f / (float)(effects->taa_render_sample);
333                         }
334                         else {
335                                 effects->taa_alpha = 1.0f / (float)(effects->taa_current_sample);
336                         }
337
338                         GPU_framebuffer_bind(fbl->effect_color_fb);
339                         DRW_draw_pass(psl->taa_resolve);
340
341                         /* Restore the depth from sample 1. */
342                         if (!DRW_state_is_image_render()) {
343                                 GPU_framebuffer_blit(fbl->double_buffer_depth_fb, 0, fbl->main_fb, 0, GPU_DEPTH_BIT);
344                         }
345
346                         SWAP_BUFFER_TAA();
347                 }
348                 else {
349                         if (!DRW_state_is_image_render()) {
350                                 /* Do reprojection for noise reduction */
351                                 /* TODO : do AA jitter if in only render view. */
352                                 if ((effects->enabled_effects & EFFECT_TAA_REPROJECT) != 0 &&
353                                     stl->g_data->valid_double_buffer)
354                                 {
355                                         GPU_framebuffer_bind(fbl->effect_color_fb);
356                                         DRW_draw_pass(psl->taa_resolve);
357
358                                         SWAP_BUFFER_TAA();
359                                 }
360
361                                 /* Save the depth buffer for the next frame.
362                                  * This saves us from doing anything special
363                                  * in the other mode engines. */
364                                 GPU_framebuffer_blit(fbl->main_fb, 0, fbl->double_buffer_depth_fb, 0, GPU_DEPTH_BIT);
365                         }
366                 }
367
368                 /* Make each loop count when doing a render. */
369                 if (DRW_state_is_image_render()) {
370                         effects->taa_render_sample += 1;
371                         effects->taa_current_sample += 1;
372                 }
373                 else {
374                         if ((effects->taa_total_sample == 0) ||
375                             (effects->taa_current_sample < effects->taa_total_sample))
376                         {
377                                 DRW_viewport_request_redraw();
378                         }
379                 }
380         }
381 }
382
383 void EEVEE_temporal_sampling_free(void)
384 {
385         DRW_SHADER_FREE_SAFE(e_data.taa_resolve_sh);
386         DRW_SHADER_FREE_SAFE(e_data.taa_resolve_reproject_sh);
387 }