Rename any instance of scene layer or render layer in code with view layer
[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
32 #include "eevee_private.h"
33 #include "GPU_texture.h"
34
35 /* SSR shader variations */
36 enum {
37         SSR_SAMPLES      = (1 << 0) | (1 << 1),
38         SSR_RESOLVE      = (1 << 2),
39         SSR_FULL_TRACE   = (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_bsdf_common_lib_glsl[];
54 extern char datatoc_bsdf_sampling_lib_glsl[];
55 extern char datatoc_octahedron_lib_glsl[];
56 extern char datatoc_effect_ssr_frag_glsl[];
57 extern char datatoc_lightprobe_lib_glsl[];
58 extern char datatoc_raytrace_lib_glsl[];
59
60 static struct GPUShader *eevee_effects_screen_raytrace_shader_get(int options)
61 {
62         if (e_data.ssr_sh[options] == NULL) {
63                 DynStr *ds_frag = BLI_dynstr_new();
64                 BLI_dynstr_append(ds_frag, datatoc_bsdf_common_lib_glsl);
65                 BLI_dynstr_append(ds_frag, datatoc_bsdf_sampling_lib_glsl);
66                 BLI_dynstr_append(ds_frag, datatoc_octahedron_lib_glsl);
67                 BLI_dynstr_append(ds_frag, datatoc_lightprobe_lib_glsl);
68                 BLI_dynstr_append(ds_frag, datatoc_ambient_occlusion_lib_glsl);
69                 BLI_dynstr_append(ds_frag, datatoc_raytrace_lib_glsl);
70                 BLI_dynstr_append(ds_frag, datatoc_effect_ssr_frag_glsl);
71                 char *ssr_shader_str = BLI_dynstr_get_cstring(ds_frag);
72                 BLI_dynstr_free(ds_frag);
73
74                 int samples = (SSR_SAMPLES & options) + 1;
75
76                 DynStr *ds_defines = BLI_dynstr_new();
77                 BLI_dynstr_appendf(ds_defines, SHADER_DEFINES);
78                 BLI_dynstr_appendf(ds_defines, "#define RAY_COUNT %d\n", samples);
79                 if (options & SSR_RESOLVE) {
80                         BLI_dynstr_appendf(ds_defines, "#define STEP_RESOLVE\n");
81                 }
82                 else {
83                         BLI_dynstr_appendf(ds_defines, "#define STEP_RAYTRACE\n");
84                         BLI_dynstr_appendf(ds_defines, "#define PLANAR_PROBE_RAYTRACE\n");
85                 }
86                 if (options & SSR_FULL_TRACE) {
87                         BLI_dynstr_appendf(ds_defines, "#define FULLRES\n");
88                 }
89                 char *ssr_define_str = BLI_dynstr_get_cstring(ds_defines);
90                 BLI_dynstr_free(ds_defines);
91
92                 e_data.ssr_sh[options] = DRW_shader_create_fullscreen(ssr_shader_str, ssr_define_str);
93
94                 MEM_freeN(ssr_shader_str);
95                 MEM_freeN(ssr_define_str);
96         }
97
98         return e_data.ssr_sh[options];
99 }
100
101 int EEVEE_screen_raytrace_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
102 {
103         EEVEE_StorageList *stl = vedata->stl;
104         EEVEE_FramebufferList *fbl = vedata->fbl;
105         EEVEE_TextureList *txl = vedata->txl;
106         EEVEE_EffectsInfo *effects = stl->effects;
107         const float *viewport_size = DRW_viewport_size_get();
108
109         const DRWContextState *draw_ctx = DRW_context_state_get();
110         ViewLayer *view_layer = draw_ctx->view_layer;
111         IDProperty *props = BKE_view_layer_engine_evaluated_get(view_layer, COLLECTION_MODE_NONE, RE_engine_id_BLENDER_EEVEE);
112
113         /* Compute pixel size, (shared with contact shadows) */
114         copy_v2_v2(effects->ssr_pixelsize, viewport_size);
115         invert_v2(effects->ssr_pixelsize);
116
117         if (BKE_collection_engine_property_value_get_bool(props, "ssr_enable")) {
118                 const bool use_refraction = BKE_collection_engine_property_value_get_bool(props, "ssr_refraction");
119
120                 if (use_refraction) {
121                         DRWFboTexture tex = {&txl->refract_color, DRW_TEX_RGB_11_11_10, DRW_TEX_FILTER | DRW_TEX_MIPMAP};
122
123                         DRW_framebuffer_init(&fbl->refract_fb, &draw_engine_eevee_type, (int)viewport_size[0], (int)viewport_size[1], &tex, 1);
124                 }
125
126                 effects->ssr_ray_count = BKE_collection_engine_property_value_get_int(props, "ssr_ray_count");
127                 effects->reflection_trace_full = !BKE_collection_engine_property_value_get_bool(props, "ssr_halfres");
128                 effects->ssr_use_normalization = BKE_collection_engine_property_value_get_bool(props, "ssr_normalize_weight");
129                 effects->ssr_quality = 1.0f - BKE_collection_engine_property_value_get_float(props, "ssr_quality");
130                 effects->ssr_thickness = BKE_collection_engine_property_value_get_float(props, "ssr_thickness");
131                 effects->ssr_border_fac = BKE_collection_engine_property_value_get_float(props, "ssr_border_fade");
132                 effects->ssr_firefly_fac = BKE_collection_engine_property_value_get_float(props, "ssr_firefly_fac");
133                 effects->ssr_max_roughness = BKE_collection_engine_property_value_get_float(props, "ssr_max_roughness");
134
135                 if (effects->ssr_firefly_fac < 1e-8f) {
136                         effects->ssr_firefly_fac = FLT_MAX;
137                 }
138
139                 /* Important, can lead to breakage otherwise. */
140                 CLAMP(effects->ssr_ray_count, 1, 4);
141
142                 const int divisor = (effects->reflection_trace_full) ? 1 : 2;
143                 int tracing_res[2] = {(int)viewport_size[0] / divisor, (int)viewport_size[1] / divisor};
144                 const bool high_qual_input = true; /* TODO dither low quality input */
145
146                 /* MRT for the shading pass in order to output needed data for the SSR pass. */
147                 /* TODO create one texture layer per lobe */
148                 if (txl->ssr_specrough_input == NULL) {
149                         DRWTextureFormat specrough_format = (high_qual_input) ? DRW_TEX_RGBA_16 : DRW_TEX_RGBA_8;
150                         txl->ssr_specrough_input = DRW_texture_create_2D((int)viewport_size[0], (int)viewport_size[1], specrough_format, 0, NULL);
151                 }
152
153                 /* Reattach textures to the right buffer (because we are alternating between buffers) */
154                 /* TODO multiple FBO per texture!!!! */
155                 DRW_framebuffer_texture_detach(txl->ssr_specrough_input);
156                 DRW_framebuffer_texture_attach(fbl->main, txl->ssr_specrough_input, 2, 0);
157
158                 /* Raytracing output */
159                 /* TODO try integer format for hit coord to increase precision */
160                 DRWFboTexture tex_output[4] = {
161                         {&stl->g_data->ssr_hit_output[0], DRW_TEX_RGBA_16, DRW_TEX_TEMP},
162                         {&stl->g_data->ssr_hit_output[1], DRW_TEX_RGBA_16, DRW_TEX_TEMP},
163                         {&stl->g_data->ssr_hit_output[2], DRW_TEX_RGBA_16, DRW_TEX_TEMP},
164                         {&stl->g_data->ssr_hit_output[3], DRW_TEX_RGBA_16, DRW_TEX_TEMP},
165                 };
166
167                 DRW_framebuffer_init(&fbl->screen_tracing_fb, &draw_engine_eevee_type, tracing_res[0], tracing_res[1], tex_output, effects->ssr_ray_count);
168
169                 /* Enable double buffering to be able to read previous frame color */
170                 return EFFECT_SSR | EFFECT_NORMAL_BUFFER | EFFECT_DOUBLE_BUFFER | ((use_refraction) ? EFFECT_REFRACT : 0);
171         }
172
173         /* Cleanup to release memory */
174         DRW_TEXTURE_FREE_SAFE(txl->ssr_specrough_input);
175         DRW_FRAMEBUFFER_FREE_SAFE(fbl->screen_tracing_fb);
176         for (int i = 0; i < 4; ++i) {
177                 stl->g_data->ssr_hit_output[i] = NULL;
178         }
179
180         return 0;
181 }
182
183 void EEVEE_screen_raytrace_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
184 {
185         EEVEE_PassList *psl = vedata->psl;
186         EEVEE_StorageList *stl = vedata->stl;
187         EEVEE_TextureList *txl = vedata->txl;
188         EEVEE_EffectsInfo *effects = stl->effects;
189
190         struct Gwn_Batch *quad = DRW_cache_fullscreen_quad_get();
191
192         if ((effects->enabled_effects & EFFECT_SSR) != 0) {
193                 int options = (effects->reflection_trace_full) ? SSR_FULL_TRACE : 0;
194                 options |= (effects->ssr_ray_count - 1);
195
196                 struct GPUShader *trace_shader = eevee_effects_screen_raytrace_shader_get(options);
197                 struct GPUShader *resolve_shader = eevee_effects_screen_raytrace_shader_get(SSR_RESOLVE | options);
198
199                 /** Screen space raytracing overview
200                  *
201                  * Following Frostbite stochastic SSR.
202                  *
203                  * - First pass Trace rays accross the depth buffer. The hit position and pdf are
204                  *   recorded in a RGBA16F render target for each ray (sample).
205                  *
206                  * - We downsample the previous frame color buffer.
207                  *
208                  * - For each final pixel, we gather neighboors rays and choose a color buffer
209                  *   mipmap for each ray using its pdf. (filtered importance sampling)
210                  *   We then evaluate the lighting from the probes and mix the results together.
211                  */
212                 psl->ssr_raytrace = DRW_pass_create("SSR Raytrace", DRW_STATE_WRITE_COLOR);
213                 DRWShadingGroup *grp = DRW_shgroup_create(trace_shader, psl->ssr_raytrace);
214                 DRW_shgroup_uniform_buffer(grp, "depthBuffer", &e_data.depth_src);
215                 DRW_shgroup_uniform_buffer(grp, "normalBuffer", &txl->ssr_normal_input);
216                 DRW_shgroup_uniform_buffer(grp, "specroughBuffer", &txl->ssr_specrough_input);
217                 DRW_shgroup_uniform_texture(grp, "utilTex", EEVEE_materials_get_util_tex());
218                 DRW_shgroup_uniform_buffer(grp, "maxzBuffer", &txl->maxzbuffer);
219                 DRW_shgroup_uniform_vec4(grp, "viewvecs[0]", (float *)stl->g_data->viewvecs, 2);
220                 DRW_shgroup_uniform_vec2(grp, "mipRatio[0]", (float *)stl->g_data->mip_ratio, 10);
221                 DRW_shgroup_uniform_vec4(grp, "ssrParameters", &effects->ssr_quality, 1);
222                 DRW_shgroup_uniform_int(grp, "planar_count", &sldata->probes->num_planar, 1);
223                 DRW_shgroup_uniform_float(grp, "maxRoughness", &effects->ssr_max_roughness, 1);
224                 DRW_shgroup_uniform_buffer(grp, "planarDepth", &vedata->txl->planar_depth);
225                 DRW_shgroup_uniform_block(grp, "planar_block", sldata->planar_ubo);
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_buffer(grp, "depthBuffer", &e_data.depth_src);
231                 DRW_shgroup_uniform_buffer(grp, "normalBuffer", &txl->ssr_normal_input);
232                 DRW_shgroup_uniform_buffer(grp, "specroughBuffer", &txl->ssr_specrough_input);
233                 DRW_shgroup_uniform_texture(grp, "utilTex", EEVEE_materials_get_util_tex());
234                 DRW_shgroup_uniform_buffer(grp, "prevColorBuffer", &txl->color_double_buffer);
235                 DRW_shgroup_uniform_mat4(grp, "PastViewProjectionMatrix", (float *)stl->g_data->prev_persmat);
236                 DRW_shgroup_uniform_vec4(grp, "viewvecs[0]", (float *)stl->g_data->viewvecs, 2);
237                 DRW_shgroup_uniform_int(grp, "planar_count", &sldata->probes->num_planar, 1);
238                 DRW_shgroup_uniform_int(grp, "probe_count", &sldata->probes->num_render_cube, 1);
239                 DRW_shgroup_uniform_vec2(grp, "mipRatio[0]", (float *)stl->g_data->mip_ratio, 10);
240                 DRW_shgroup_uniform_float(grp, "borderFadeFactor", &effects->ssr_border_fac, 1);
241                 DRW_shgroup_uniform_float(grp, "maxRoughness", &effects->ssr_max_roughness, 1);
242                 DRW_shgroup_uniform_float(grp, "lodCubeMax", &sldata->probes->lod_cube_max, 1);
243                 DRW_shgroup_uniform_float(grp, "lodPlanarMax", &sldata->probes->lod_planar_max, 1);
244                 DRW_shgroup_uniform_float(grp, "fireflyFactor", &effects->ssr_firefly_fac, 1);
245                 DRW_shgroup_uniform_block(grp, "probe_block", sldata->probe_ubo);
246                 DRW_shgroup_uniform_block(grp, "planar_block", sldata->planar_ubo);
247                 DRW_shgroup_uniform_buffer(grp, "probeCubes", &sldata->probe_pool);
248                 DRW_shgroup_uniform_buffer(grp, "probePlanars", &vedata->txl->planar_pool);
249                 DRW_shgroup_uniform_buffer(grp, "hitBuffer0", &stl->g_data->ssr_hit_output[0]);
250                 if (effects->ssr_ray_count > 1) {
251                         DRW_shgroup_uniform_buffer(grp, "hitBuffer1", &stl->g_data->ssr_hit_output[1]);
252                 }
253                 if (effects->ssr_ray_count > 2) {
254                         DRW_shgroup_uniform_buffer(grp, "hitBuffer2", &stl->g_data->ssr_hit_output[2]);
255                 }
256                 if (effects->ssr_ray_count > 3) {
257                         DRW_shgroup_uniform_buffer(grp, "hitBuffer3", &stl->g_data->ssr_hit_output[3]);
258                 }
259
260                 DRW_shgroup_uniform_vec4(grp, "aoParameters[0]", &effects->ao_dist, 2);
261                 if (effects->use_ao) {
262                         DRW_shgroup_uniform_buffer(grp, "horizonBuffer", &vedata->txl->gtao_horizons);
263                         DRW_shgroup_uniform_ivec2(grp, "aoHorizonTexSize", (int *)vedata->stl->effects->ao_texsize, 1);
264                 }
265                 else {
266                         /* Use shadow_pool as fallback to avoid sampling problem on certain platform, see: T52593 */
267                         DRW_shgroup_uniform_buffer(grp, "horizonBuffer", &sldata->shadow_pool);
268                 }
269
270                 DRW_shgroup_call_add(grp, quad, NULL);
271         }
272 }
273
274 void EEVEE_refraction_compute(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
275 {
276         EEVEE_FramebufferList *fbl = vedata->fbl;
277         EEVEE_TextureList *txl = vedata->txl;
278         EEVEE_StorageList *stl = vedata->stl;
279         EEVEE_EffectsInfo *effects = stl->effects;
280
281         if ((effects->enabled_effects & EFFECT_REFRACT) != 0) {
282                 DRW_framebuffer_texture_attach(fbl->refract_fb, txl->refract_color, 0, 0);
283                 DRW_framebuffer_blit(fbl->main, fbl->refract_fb, false, false);
284                 EEVEE_downsample_buffer(vedata, fbl->downsample_fb, txl->refract_color, 9);
285
286                 /* Restore */
287                 DRW_framebuffer_bind(fbl->main);
288         }
289 }
290
291 void EEVEE_reflection_compute(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
292 {
293         EEVEE_PassList *psl = vedata->psl;
294         EEVEE_FramebufferList *fbl = vedata->fbl;
295         EEVEE_StorageList *stl = vedata->stl;
296         EEVEE_TextureList *txl = vedata->txl;
297         EEVEE_EffectsInfo *effects = stl->effects;
298
299         if (((effects->enabled_effects & EFFECT_SSR) != 0) && stl->g_data->valid_double_buffer) {
300                 DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
301                 e_data.depth_src = dtxl->depth;
302
303                 DRW_stats_group_start("SSR");
304
305                 for (int i = 0; i < effects->ssr_ray_count; ++i) {
306                         DRW_framebuffer_texture_attach(fbl->screen_tracing_fb, stl->g_data->ssr_hit_output[i], i, 0);
307                 }
308                 DRW_framebuffer_bind(fbl->screen_tracing_fb);
309
310                 /* Raytrace. */
311                 DRW_draw_pass(psl->ssr_raytrace);
312
313                 for (int i = 0; i < effects->ssr_ray_count; ++i) {
314                         DRW_framebuffer_texture_detach(stl->g_data->ssr_hit_output[i]);
315                 }
316
317                 EEVEE_downsample_buffer(vedata, fbl->downsample_fb, txl->color_double_buffer, 9);
318
319                 /* Resolve at fullres */
320                 DRW_framebuffer_texture_detach(dtxl->depth);
321                 DRW_framebuffer_texture_detach(txl->ssr_normal_input);
322                 DRW_framebuffer_texture_detach(txl->ssr_specrough_input);
323                 DRW_framebuffer_bind(fbl->main);
324                 DRW_draw_pass(psl->ssr_resolve);
325
326                 /* Restore */
327                 DRW_framebuffer_texture_attach(fbl->main, dtxl->depth, 0, 0);
328                 DRW_framebuffer_texture_attach(fbl->main, txl->ssr_normal_input, 1, 0);
329                 DRW_framebuffer_texture_attach(fbl->main, txl->ssr_specrough_input, 2, 0);
330                 DRW_framebuffer_bind(fbl->main);
331
332                 DRW_stats_group_end();
333         }
334 }
335
336 void EEVEE_screen_raytrace_free(void)
337 {
338         for (int i = 0; i < SSR_MAX_SHADER; ++i) {
339                 DRW_SHADER_FREE_SAFE(e_data.ssr_sh[i]);
340         }
341 }