d53ed239f4e10ede7c9927cecd70869e54933b82
[blender.git] / source / blender / draw / engines / eevee / eevee_screen_raytrace.c
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * Copyright 2016, Blender Foundation.
17  */
18
19 /** \file
20  * \ingroup draw_engine
21  *
22  * Screen space reflections and refractions techniques.
23  */
24
25 #include "DRW_render.h"
26
27 #include "BLI_dynstr.h"
28 #include "BLI_string_utils.h"
29
30 #include "DEG_depsgraph_query.h"
31
32 #include "eevee_private.h"
33 #include "GPU_texture.h"
34
35 /* SSR shader variations */
36 enum {
37   SSR_RESOLVE = (1 << 0),
38   SSR_FULL_TRACE = (1 << 1),
39   SSR_AO = (1 << 3),
40   SSR_MAX_SHADER = (1 << 4),
41 };
42
43 static struct {
44   /* Screen Space Reflection */
45   struct GPUShader *ssr_sh[SSR_MAX_SHADER];
46
47   /* Theses are just references, not actually allocated */
48   struct GPUTexture *depth_src;
49   struct GPUTexture *color_src;
50 } e_data = {{NULL}}; /* Engine data */
51
52 extern char datatoc_ambient_occlusion_lib_glsl[];
53 extern char datatoc_common_view_lib_glsl[];
54 extern char datatoc_common_uniforms_lib_glsl[];
55 extern char datatoc_bsdf_common_lib_glsl[];
56 extern char datatoc_bsdf_sampling_lib_glsl[];
57 extern char datatoc_octahedron_lib_glsl[];
58 extern char datatoc_effect_ssr_frag_glsl[];
59 extern char datatoc_lightprobe_lib_glsl[];
60 extern char datatoc_raytrace_lib_glsl[];
61
62 static struct GPUShader *eevee_effects_screen_raytrace_shader_get(int options)
63 {
64   if (e_data.ssr_sh[options] == NULL) {
65     char *ssr_shader_str = BLI_string_joinN(datatoc_common_view_lib_glsl,
66                                             datatoc_common_uniforms_lib_glsl,
67                                             datatoc_bsdf_common_lib_glsl,
68                                             datatoc_bsdf_sampling_lib_glsl,
69                                             datatoc_ambient_occlusion_lib_glsl,
70                                             datatoc_octahedron_lib_glsl,
71                                             datatoc_lightprobe_lib_glsl,
72                                             datatoc_raytrace_lib_glsl,
73                                             datatoc_effect_ssr_frag_glsl);
74
75     DynStr *ds_defines = BLI_dynstr_new();
76     BLI_dynstr_append(ds_defines, SHADER_DEFINES);
77     if (options & SSR_RESOLVE) {
78       BLI_dynstr_append(ds_defines, "#define STEP_RESOLVE\n");
79     }
80     else {
81       BLI_dynstr_append(ds_defines, "#define STEP_RAYTRACE\n");
82       BLI_dynstr_append(ds_defines, "#define PLANAR_PROBE_RAYTRACE\n");
83     }
84     if (options & SSR_FULL_TRACE) {
85       BLI_dynstr_append(ds_defines, "#define FULLRES\n");
86     }
87     if (options & SSR_AO) {
88       BLI_dynstr_append(ds_defines, "#define SSR_AO\n");
89     }
90     char *ssr_define_str = BLI_dynstr_get_cstring(ds_defines);
91     BLI_dynstr_free(ds_defines);
92
93     e_data.ssr_sh[options] = DRW_shader_create_fullscreen(ssr_shader_str, ssr_define_str);
94
95     MEM_freeN(ssr_shader_str);
96     MEM_freeN(ssr_define_str);
97   }
98
99   return e_data.ssr_sh[options];
100 }
101
102 int EEVEE_screen_raytrace_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
103 {
104   EEVEE_CommonUniformBuffer *common_data = &sldata->common_data;
105   EEVEE_StorageList *stl = vedata->stl;
106   EEVEE_FramebufferList *fbl = vedata->fbl;
107   EEVEE_TextureList *txl = vedata->txl;
108   EEVEE_EffectsInfo *effects = stl->effects;
109   const float *viewport_size = DRW_viewport_size_get();
110
111   const DRWContextState *draw_ctx = DRW_context_state_get();
112   const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph);
113
114   /* Compute pixel size, (shared with contact shadows) */
115   copy_v2_v2(common_data->ssr_pixelsize, viewport_size);
116   invert_v2(common_data->ssr_pixelsize);
117
118   if (scene_eval->eevee.flag & SCE_EEVEE_SSR_ENABLED) {
119     const bool use_refraction = (scene_eval->eevee.flag & SCE_EEVEE_SSR_REFRACTION) != 0;
120
121     if (use_refraction) {
122       /* TODO: Opti: Could be shared. */
123       DRW_texture_ensure_fullscreen_2d(
124           &txl->refract_color, GPU_R11F_G11F_B10F, DRW_TEX_FILTER | DRW_TEX_MIPMAP);
125
126       GPU_framebuffer_ensure_config(
127           &fbl->refract_fb, {GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(txl->refract_color)});
128     }
129
130     const bool is_persp = DRW_view_is_persp_get(NULL);
131     if (effects->ssr_was_persp != is_persp) {
132       effects->ssr_was_persp = is_persp;
133       DRW_viewport_request_redraw();
134       EEVEE_temporal_sampling_reset(vedata);
135       stl->g_data->valid_double_buffer = false;
136     }
137
138     if (!effects->ssr_was_valid_double_buffer) {
139       DRW_viewport_request_redraw();
140       EEVEE_temporal_sampling_reset(vedata);
141     }
142     effects->ssr_was_valid_double_buffer = stl->g_data->valid_double_buffer;
143
144     effects->reflection_trace_full = (scene_eval->eevee.flag & SCE_EEVEE_SSR_HALF_RESOLUTION) == 0;
145     common_data->ssr_thickness = scene_eval->eevee.ssr_thickness;
146     common_data->ssr_border_fac = scene_eval->eevee.ssr_border_fade;
147     common_data->ssr_firefly_fac = scene_eval->eevee.ssr_firefly_fac;
148     common_data->ssr_max_roughness = scene_eval->eevee.ssr_max_roughness;
149     common_data->ssr_quality = 1.0f - 0.95f * scene_eval->eevee.ssr_quality;
150     common_data->ssr_brdf_bias = 0.1f + common_data->ssr_quality * 0.6f; /* Range [0.1, 0.7]. */
151
152     if (common_data->ssr_firefly_fac < 1e-8f) {
153       common_data->ssr_firefly_fac = FLT_MAX;
154     }
155
156     const int divisor = (effects->reflection_trace_full) ? 1 : 2;
157     int tracing_res[2] = {(int)viewport_size[0] / divisor, (int)viewport_size[1] / divisor};
158     int size_fs[2] = {(int)viewport_size[0], (int)viewport_size[1]};
159     const bool high_qual_input = true; /* TODO dither low quality input */
160     const eGPUTextureFormat format = (high_qual_input) ? GPU_RGBA16F : GPU_RGBA8;
161
162     tracing_res[0] = max_ii(1, tracing_res[0]);
163     tracing_res[1] = max_ii(1, tracing_res[1]);
164
165     /* MRT for the shading pass in order to output needed data for the SSR pass. */
166     effects->ssr_specrough_input = DRW_texture_pool_query_2d(
167         size_fs[0], size_fs[1], format, &draw_engine_eevee_type);
168
169     GPU_framebuffer_texture_attach(fbl->main_fb, effects->ssr_specrough_input, 2, 0);
170
171     /* Raytracing output */
172     effects->ssr_hit_output = DRW_texture_pool_query_2d(
173         tracing_res[0], tracing_res[1], GPU_RG16I, &draw_engine_eevee_type);
174     effects->ssr_pdf_output = DRW_texture_pool_query_2d(
175         tracing_res[0], tracing_res[1], GPU_R16F, &draw_engine_eevee_type);
176
177     GPU_framebuffer_ensure_config(&fbl->screen_tracing_fb,
178                                   {GPU_ATTACHMENT_NONE,
179                                    GPU_ATTACHMENT_TEXTURE(effects->ssr_hit_output),
180                                    GPU_ATTACHMENT_TEXTURE(effects->ssr_pdf_output)});
181
182     /* Enable double buffering to be able to read previous frame color */
183     return EFFECT_SSR | EFFECT_NORMAL_BUFFER | EFFECT_DOUBLE_BUFFER |
184            ((use_refraction) ? EFFECT_REFRACT : 0);
185   }
186
187   /* Cleanup to release memory */
188   GPU_FRAMEBUFFER_FREE_SAFE(fbl->screen_tracing_fb);
189   effects->ssr_specrough_input = NULL;
190   effects->ssr_hit_output = NULL;
191   effects->ssr_pdf_output = NULL;
192
193   return 0;
194 }
195
196 void EEVEE_screen_raytrace_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
197 {
198   EEVEE_PassList *psl = vedata->psl;
199   EEVEE_StorageList *stl = vedata->stl;
200   EEVEE_TextureList *txl = vedata->txl;
201   EEVEE_EffectsInfo *effects = stl->effects;
202   LightCache *lcache = stl->g_data->light_cache;
203
204   struct GPUBatch *quad = DRW_cache_fullscreen_quad_get();
205
206   if ((effects->enabled_effects & EFFECT_SSR) != 0) {
207     int options = (effects->reflection_trace_full) ? SSR_FULL_TRACE : 0;
208     options |= ((effects->enabled_effects & EFFECT_GTAO) != 0) ? SSR_AO : 0;
209
210     struct GPUShader *trace_shader = eevee_effects_screen_raytrace_shader_get(options);
211     struct GPUShader *resolve_shader = eevee_effects_screen_raytrace_shader_get(SSR_RESOLVE |
212                                                                                 options);
213
214     /** Screen space raytracing overview
215      *
216      * Following Frostbite stochastic SSR.
217      *
218      * - First pass Trace rays across the depth buffer. The hit position and pdf are
219      *   recorded in a RGBA16F render target for each ray (sample).
220      *
221      * - We down-sample the previous frame color buffer.
222      *
223      * - For each final pixel, we gather neighbors rays and choose a color buffer
224      *   mipmap for each ray using its pdf. (filtered importance sampling)
225      *   We then evaluate the lighting from the probes and mix the results together.
226      */
227     DRW_PASS_CREATE(psl->ssr_raytrace, DRW_STATE_WRITE_COLOR);
228     DRWShadingGroup *grp = DRW_shgroup_create(trace_shader, psl->ssr_raytrace);
229     DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &e_data.depth_src);
230     DRW_shgroup_uniform_texture_ref(grp, "normalBuffer", &effects->ssr_normal_input);
231     DRW_shgroup_uniform_texture_ref(grp, "specroughBuffer", &effects->ssr_specrough_input);
232     DRW_shgroup_uniform_texture_ref(grp, "maxzBuffer", &txl->maxzbuffer);
233     DRW_shgroup_uniform_texture_ref(grp, "planarDepth", &vedata->txl->planar_depth);
234     DRW_shgroup_uniform_texture(grp, "utilTex", EEVEE_materials_get_util_tex());
235     DRW_shgroup_uniform_block(grp, "grid_block", sldata->grid_ubo);
236     DRW_shgroup_uniform_block(grp, "probe_block", sldata->probe_ubo);
237     DRW_shgroup_uniform_block(grp, "planar_block", sldata->planar_ubo);
238     DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
239     if (!effects->reflection_trace_full) {
240       DRW_shgroup_uniform_ivec2(grp, "halfresOffset", effects->ssr_halfres_ofs, 1);
241     }
242     DRW_shgroup_call(grp, quad, NULL);
243
244     DRW_PASS_CREATE(psl->ssr_resolve, DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ADD);
245     grp = DRW_shgroup_create(resolve_shader, psl->ssr_resolve);
246     DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &e_data.depth_src);
247     DRW_shgroup_uniform_texture_ref(grp, "normalBuffer", &effects->ssr_normal_input);
248     DRW_shgroup_uniform_texture_ref(grp, "specroughBuffer", &effects->ssr_specrough_input);
249     DRW_shgroup_uniform_texture_ref(grp, "probeCubes", &lcache->cube_tx.tex);
250     DRW_shgroup_uniform_texture_ref(grp, "probePlanars", &vedata->txl->planar_pool);
251     DRW_shgroup_uniform_texture_ref(grp, "planarDepth", &vedata->txl->planar_depth);
252     DRW_shgroup_uniform_texture_ref(grp, "hitBuffer", &effects->ssr_hit_output);
253     DRW_shgroup_uniform_texture_ref(grp, "pdfBuffer", &effects->ssr_pdf_output);
254     DRW_shgroup_uniform_texture_ref(grp, "prevColorBuffer", &txl->color_double_buffer);
255     DRW_shgroup_uniform_block(grp, "grid_block", sldata->grid_ubo);
256     DRW_shgroup_uniform_block(grp, "probe_block", sldata->probe_ubo);
257     DRW_shgroup_uniform_block(grp, "planar_block", sldata->planar_ubo);
258     DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
259     DRW_shgroup_uniform_int(grp, "neighborOffset", &effects->ssr_neighbor_ofs, 1);
260     if ((effects->enabled_effects & EFFECT_GTAO) != 0) {
261       DRW_shgroup_uniform_texture(grp, "utilTex", EEVEE_materials_get_util_tex());
262       DRW_shgroup_uniform_texture_ref(grp, "horizonBuffer", &effects->gtao_horizons);
263     }
264
265     DRW_shgroup_call(grp, quad, NULL);
266   }
267 }
268
269 void EEVEE_refraction_compute(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
270 {
271   EEVEE_FramebufferList *fbl = vedata->fbl;
272   EEVEE_TextureList *txl = vedata->txl;
273   EEVEE_StorageList *stl = vedata->stl;
274   EEVEE_EffectsInfo *effects = stl->effects;
275
276   if ((effects->enabled_effects & EFFECT_REFRACT) != 0) {
277     GPU_framebuffer_blit(fbl->main_fb, 0, fbl->refract_fb, 0, GPU_COLOR_BIT);
278     EEVEE_downsample_buffer(vedata, txl->refract_color, 9);
279
280     /* Restore */
281     GPU_framebuffer_bind(fbl->main_fb);
282   }
283 }
284
285 void EEVEE_reflection_compute(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
286 {
287   EEVEE_PassList *psl = vedata->psl;
288   EEVEE_FramebufferList *fbl = vedata->fbl;
289   EEVEE_StorageList *stl = vedata->stl;
290   EEVEE_TextureList *txl = vedata->txl;
291   EEVEE_EffectsInfo *effects = stl->effects;
292
293   if (((effects->enabled_effects & EFFECT_SSR) != 0) && stl->g_data->valid_double_buffer) {
294     DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
295     e_data.depth_src = dtxl->depth;
296
297     DRW_stats_group_start("SSR");
298
299     /* Raytrace. */
300     GPU_framebuffer_bind(fbl->screen_tracing_fb);
301     DRW_draw_pass(psl->ssr_raytrace);
302
303     EEVEE_downsample_buffer(vedata, txl->color_double_buffer, 9);
304
305     /* Resolve at fullres */
306     int sample = (DRW_state_is_image_render()) ? effects->taa_render_sample :
307                                                  effects->taa_current_sample;
308     /* Doing a neighbor shift only after a few iteration.
309      * We wait for a prime number of cycles to avoid noise correlation.
310      * This reduces variance faster. */
311     effects->ssr_neighbor_ofs = ((sample / 5) % 8) * 4;
312     switch ((sample / 11) % 4) {
313       case 0:
314         effects->ssr_halfres_ofs[0] = 0;
315         effects->ssr_halfres_ofs[1] = 0;
316         break;
317       case 1:
318         effects->ssr_halfres_ofs[0] = 0;
319         effects->ssr_halfres_ofs[1] = 1;
320         break;
321       case 2:
322         effects->ssr_halfres_ofs[0] = 1;
323         effects->ssr_halfres_ofs[1] = 0;
324         break;
325       case 4:
326         effects->ssr_halfres_ofs[0] = 1;
327         effects->ssr_halfres_ofs[1] = 1;
328         break;
329     }
330     GPU_framebuffer_bind(fbl->main_color_fb);
331     DRW_draw_pass(psl->ssr_resolve);
332
333     /* Restore */
334     GPU_framebuffer_bind(fbl->main_fb);
335     DRW_stats_group_end();
336   }
337 }
338
339 void EEVEE_screen_raytrace_free(void)
340 {
341   for (int i = 0; i < SSR_MAX_SHADER; ++i) {
342     DRW_SHADER_FREE_SAFE(e_data.ssr_sh[i]);
343   }
344 }