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