doxygen: add newline after \file
[blender.git] / source / blender / draw / engines / eevee / eevee_volumes.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  * Volumetric effects rendering using frostbite approach.
23  */
24
25 #include "DRW_render.h"
26
27 #include "BLI_rand.h"
28 #include "BLI_string_utils.h"
29
30 #include "DNA_object_force_types.h"
31 #include "DNA_smoke_types.h"
32 #include "DNA_world_types.h"
33
34 #include "BKE_modifier.h"
35 #include "BKE_mesh.h"
36 #include "BKE_smoke.h"
37
38 #include "ED_screen.h"
39
40 #include "DEG_depsgraph_query.h"
41
42 #include "eevee_private.h"
43 #include "GPU_draw.h"
44 #include "GPU_texture.h"
45 #include "GPU_material.h"
46
47 static struct {
48         char *volumetric_common_lib;
49         char *volumetric_common_lamps_lib;
50
51         struct GPUShader *volumetric_clear_sh;
52         struct GPUShader *volumetric_scatter_sh;
53         struct GPUShader *volumetric_scatter_with_lamps_sh;
54         struct GPUShader *volumetric_integration_sh;
55         struct GPUShader *volumetric_resolve_sh;
56
57         GPUTexture *color_src;
58         GPUTexture *depth_src;
59
60         /* List of all smoke domains rendered within this frame. */
61         ListBase smoke_domains;
62 } e_data = {NULL}; /* Engine data */
63
64 extern char datatoc_bsdf_common_lib_glsl[];
65 extern char datatoc_common_uniforms_lib_glsl[];
66 extern char datatoc_common_view_lib_glsl[];
67 extern char datatoc_octahedron_lib_glsl[];
68 extern char datatoc_irradiance_lib_glsl[];
69 extern char datatoc_lamps_lib_glsl[];
70 extern char datatoc_volumetric_frag_glsl[];
71 extern char datatoc_volumetric_geom_glsl[];
72 extern char datatoc_volumetric_vert_glsl[];
73 extern char datatoc_volumetric_resolve_frag_glsl[];
74 extern char datatoc_volumetric_scatter_frag_glsl[];
75 extern char datatoc_volumetric_integration_frag_glsl[];
76 extern char datatoc_volumetric_lib_glsl[];
77 extern char datatoc_common_fullscreen_vert_glsl[];
78
79 static void eevee_create_shader_volumes(void)
80 {
81         e_data.volumetric_common_lib = BLI_string_joinN(
82                 datatoc_common_view_lib_glsl,
83                 datatoc_common_uniforms_lib_glsl,
84                 datatoc_bsdf_common_lib_glsl,
85                 datatoc_volumetric_lib_glsl);
86
87         e_data.volumetric_common_lamps_lib = BLI_string_joinN(
88                 datatoc_common_view_lib_glsl,
89                 datatoc_common_uniforms_lib_glsl,
90                 datatoc_bsdf_common_lib_glsl,
91                 datatoc_octahedron_lib_glsl,
92                 datatoc_irradiance_lib_glsl,
93                 datatoc_lamps_lib_glsl,
94                 datatoc_volumetric_lib_glsl);
95
96         e_data.volumetric_clear_sh = DRW_shader_create_with_lib(
97                 datatoc_volumetric_vert_glsl,
98                 datatoc_volumetric_geom_glsl,
99                 datatoc_volumetric_frag_glsl,
100                 e_data.volumetric_common_lib,
101                 "#define VOLUMETRICS\n"
102                 "#define CLEAR\n");
103         e_data.volumetric_scatter_sh = DRW_shader_create_with_lib(
104                 datatoc_volumetric_vert_glsl,
105                 datatoc_volumetric_geom_glsl,
106                 datatoc_volumetric_scatter_frag_glsl,
107                 e_data.volumetric_common_lamps_lib,
108                 SHADER_DEFINES
109                 "#define VOLUMETRICS\n"
110                 "#define VOLUME_SHADOW\n");
111         e_data.volumetric_scatter_with_lamps_sh = DRW_shader_create_with_lib(
112                 datatoc_volumetric_vert_glsl,
113                 datatoc_volumetric_geom_glsl,
114                 datatoc_volumetric_scatter_frag_glsl,
115                 e_data.volumetric_common_lamps_lib,
116                 SHADER_DEFINES
117                 "#define VOLUMETRICS\n"
118                 "#define VOLUME_LIGHTING\n"
119                 "#define VOLUME_SHADOW\n");
120         e_data.volumetric_integration_sh = DRW_shader_create_with_lib(
121                 datatoc_volumetric_vert_glsl,
122                 datatoc_volumetric_geom_glsl,
123                 datatoc_volumetric_integration_frag_glsl,
124                 e_data.volumetric_common_lib, NULL);
125         e_data.volumetric_resolve_sh = DRW_shader_create_with_lib(
126                 datatoc_common_fullscreen_vert_glsl, NULL,
127                 datatoc_volumetric_resolve_frag_glsl,
128                 e_data.volumetric_common_lib, NULL);
129 }
130
131 void EEVEE_volumes_set_jitter(EEVEE_ViewLayerData *sldata, uint current_sample)
132 {
133         EEVEE_CommonUniformBuffer *common_data = &sldata->common_data;
134
135         double ht_point[3];
136         double ht_offset[3] = {0.0, 0.0};
137         uint ht_primes[3] = {3, 7, 2};
138
139         BLI_halton_3D(ht_primes, ht_offset, current_sample, ht_point);
140
141         common_data->vol_jitter[0] = (float)ht_point[0];
142         common_data->vol_jitter[1] = (float)ht_point[1];
143         common_data->vol_jitter[2] = (float)ht_point[2];
144 }
145
146 int EEVEE_volumes_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
147 {
148         EEVEE_StorageList *stl = vedata->stl;
149         EEVEE_FramebufferList *fbl = vedata->fbl;
150         EEVEE_TextureList *txl = vedata->txl;
151         EEVEE_EffectsInfo *effects = stl->effects;
152         EEVEE_CommonUniformBuffer *common_data = &sldata->common_data;
153
154         const DRWContextState *draw_ctx = DRW_context_state_get();
155         const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph);
156
157         const float *viewport_size = DRW_viewport_size_get();
158
159         BLI_listbase_clear(&e_data.smoke_domains);
160
161         if (scene_eval->eevee.flag & SCE_EEVEE_VOLUMETRIC_ENABLED) {
162
163                 /* Shaders */
164                 if (!e_data.volumetric_scatter_sh) {
165                         eevee_create_shader_volumes();
166                 }
167
168                 const int tile_size = scene_eval->eevee.volumetric_tile_size;
169
170                 /* Find Froxel Texture resolution. */
171                 int tex_size[3];
172
173                 tex_size[0] = (int)ceilf(fmaxf(1.0f, viewport_size[0] / (float)tile_size));
174                 tex_size[1] = (int)ceilf(fmaxf(1.0f, viewport_size[1] / (float)tile_size));
175                 tex_size[2] = max_ii(scene_eval->eevee.volumetric_samples, 1);
176
177                 common_data->vol_coord_scale[0] = viewport_size[0] / (float)(tile_size * tex_size[0]);
178                 common_data->vol_coord_scale[1] = viewport_size[1] / (float)(tile_size * tex_size[1]);
179
180                 /* TODO compute snap to maxZBuffer for clustered rendering */
181
182                 if ((common_data->vol_tex_size[0] != tex_size[0]) ||
183                     (common_data->vol_tex_size[1] != tex_size[1]) ||
184                     (common_data->vol_tex_size[2] != tex_size[2]))
185                 {
186                         DRW_TEXTURE_FREE_SAFE(txl->volume_prop_scattering);
187                         DRW_TEXTURE_FREE_SAFE(txl->volume_prop_extinction);
188                         DRW_TEXTURE_FREE_SAFE(txl->volume_prop_emission);
189                         DRW_TEXTURE_FREE_SAFE(txl->volume_prop_phase);
190                         DRW_TEXTURE_FREE_SAFE(txl->volume_scatter);
191                         DRW_TEXTURE_FREE_SAFE(txl->volume_transmittance);
192                         DRW_TEXTURE_FREE_SAFE(txl->volume_scatter_history);
193                         DRW_TEXTURE_FREE_SAFE(txl->volume_transmittance_history);
194                         GPU_FRAMEBUFFER_FREE_SAFE(fbl->volumetric_fb);
195                         GPU_FRAMEBUFFER_FREE_SAFE(fbl->volumetric_scat_fb);
196                         GPU_FRAMEBUFFER_FREE_SAFE(fbl->volumetric_integ_fb);
197                         common_data->vol_tex_size[0] = tex_size[0];
198                         common_data->vol_tex_size[1] = tex_size[1];
199                         common_data->vol_tex_size[2] = tex_size[2];
200
201                         common_data->vol_inv_tex_size[0] = 1.0f / (float)(tex_size[0]);
202                         common_data->vol_inv_tex_size[1] = 1.0f / (float)(tex_size[1]);
203                         common_data->vol_inv_tex_size[2] = 1.0f / (float)(tex_size[2]);
204                 }
205
206                 /* Like frostbite's paper, 5% blend of the new frame. */
207                 common_data->vol_history_alpha = (txl->volume_prop_scattering == NULL) ? 0.0f : 0.95f;
208
209                 if (txl->volume_prop_scattering == NULL) {
210                         /* Volume properties: We evaluate all volumetric objects
211                          * and store their final properties into each froxel */
212                         txl->volume_prop_scattering = DRW_texture_create_3D(tex_size[0], tex_size[1], tex_size[2],
213                                                                             GPU_R11F_G11F_B10F, DRW_TEX_FILTER, NULL);
214                         txl->volume_prop_extinction = DRW_texture_create_3D(tex_size[0], tex_size[1], tex_size[2],
215                                                                             GPU_R11F_G11F_B10F, DRW_TEX_FILTER, NULL);
216                         txl->volume_prop_emission = DRW_texture_create_3D(tex_size[0], tex_size[1], tex_size[2],
217                                                                           GPU_R11F_G11F_B10F, DRW_TEX_FILTER, NULL);
218                         txl->volume_prop_phase = DRW_texture_create_3D(tex_size[0], tex_size[1], tex_size[2],
219                                                                        GPU_RG16F, DRW_TEX_FILTER, NULL);
220
221                         /* Volume scattering: We compute for each froxel the
222                          * Scattered light towards the view. We also resolve temporal
223                          * super sampling during this stage. */
224                         txl->volume_scatter = DRW_texture_create_3D(tex_size[0], tex_size[1], tex_size[2],
225                                                                     GPU_R11F_G11F_B10F, DRW_TEX_FILTER, NULL);
226                         txl->volume_transmittance = DRW_texture_create_3D(tex_size[0], tex_size[1], tex_size[2],
227                                                                           GPU_R11F_G11F_B10F, DRW_TEX_FILTER, NULL);
228
229                         /* Final integration: We compute for each froxel the
230                          * amount of scattered light and extinction coef at this
231                          * given depth. We use theses textures as double buffer
232                          * for the volumetric history. */
233                         txl->volume_scatter_history = DRW_texture_create_3D(tex_size[0], tex_size[1], tex_size[2],
234                                                                             GPU_R11F_G11F_B10F, DRW_TEX_FILTER, NULL);
235                         txl->volume_transmittance_history = DRW_texture_create_3D(tex_size[0], tex_size[1], tex_size[2],
236                                                                                   GPU_R11F_G11F_B10F, DRW_TEX_FILTER, NULL);
237                 }
238
239                 /* Temporal Super sampling jitter */
240                 uint ht_primes[3] = {3, 7, 2};
241                 uint current_sample = 0;
242
243                 /* If TAA is in use do not use the history buffer. */
244                 bool do_taa = ((effects->enabled_effects & EFFECT_TAA) != 0);
245
246                 if (draw_ctx->evil_C != NULL) {
247                         struct wmWindowManager *wm = CTX_wm_manager(draw_ctx->evil_C);
248                         do_taa = do_taa && (ED_screen_animation_no_scrub(wm) == NULL);
249                 }
250
251                 if (do_taa) {
252                         common_data->vol_history_alpha = 0.0f;
253                         current_sample = effects->taa_current_sample - 1;
254                         effects->volume_current_sample = -1;
255                 }
256                 else {
257                         const uint max_sample = (ht_primes[0] * ht_primes[1] * ht_primes[2]);
258                         current_sample = effects->volume_current_sample = (effects->volume_current_sample + 1) % max_sample;
259                         if (current_sample != max_sample - 1) {
260                                 DRW_viewport_request_redraw();
261                         }
262                 }
263
264                 EEVEE_volumes_set_jitter(sldata, current_sample);
265
266                 /* Framebuffer setup */
267                 GPU_framebuffer_ensure_config(&fbl->volumetric_fb, {
268                         GPU_ATTACHMENT_NONE,
269                         GPU_ATTACHMENT_TEXTURE(txl->volume_prop_scattering),
270                         GPU_ATTACHMENT_TEXTURE(txl->volume_prop_extinction),
271                         GPU_ATTACHMENT_TEXTURE(txl->volume_prop_emission),
272                         GPU_ATTACHMENT_TEXTURE(txl->volume_prop_phase)
273                 });
274                 GPU_framebuffer_ensure_config(&fbl->volumetric_scat_fb, {
275                         GPU_ATTACHMENT_NONE,
276                         GPU_ATTACHMENT_TEXTURE(txl->volume_scatter),
277                         GPU_ATTACHMENT_TEXTURE(txl->volume_transmittance)
278                 });
279                 GPU_framebuffer_ensure_config(&fbl->volumetric_integ_fb, {
280                         GPU_ATTACHMENT_NONE,
281                         GPU_ATTACHMENT_TEXTURE(txl->volume_scatter_history),
282                         GPU_ATTACHMENT_TEXTURE(txl->volume_transmittance_history)
283                 });
284
285                 float integration_start = scene_eval->eevee.volumetric_start;
286                 float integration_end = scene_eval->eevee.volumetric_end;
287                 common_data->vol_light_clamp = scene_eval->eevee.volumetric_light_clamp;
288                 common_data->vol_shadow_steps = (float)scene_eval->eevee.volumetric_shadow_samples;
289                 if ((scene_eval->eevee.flag & SCE_EEVEE_VOLUMETRIC_SHADOWS) == 0) {
290                         common_data->vol_shadow_steps = 0;
291                 }
292
293                 if (DRW_viewport_is_persp_get()) {
294                         float sample_distribution = scene_eval->eevee.volumetric_sample_distribution;
295                         sample_distribution = 4.0f * (1.00001f - sample_distribution);
296
297                         const float clip_start = common_data->view_vecs[0][2];
298                         /* Negate */
299                         float near = integration_start = min_ff(-integration_start, clip_start - 1e-4f);
300                         float far = integration_end = min_ff(-integration_end, near - 1e-4f);
301
302                         common_data->vol_depth_param[0] = (far - near * exp2(1.0f / sample_distribution)) / (far - near);
303                         common_data->vol_depth_param[1] = (1.0f - common_data->vol_depth_param[0]) / near;
304                         common_data->vol_depth_param[2] = sample_distribution;
305                 }
306                 else {
307                         const float clip_start = common_data->view_vecs[0][2];
308                         const float clip_end = clip_start + common_data->view_vecs[1][2];
309                         integration_start = min_ff(integration_end, clip_start);
310                         integration_end = max_ff(-integration_end, clip_end);
311
312                         common_data->vol_depth_param[0] = integration_start;
313                         common_data->vol_depth_param[1] = integration_end;
314                         common_data->vol_depth_param[2] = 1.0f / (integration_end - integration_start);
315                 }
316
317                 /* Disable clamp if equal to 0. */
318                 if (common_data->vol_light_clamp == 0.0) {
319                         common_data->vol_light_clamp = FLT_MAX;
320                 }
321
322                 common_data->vol_use_lights = (scene_eval->eevee.flag & SCE_EEVEE_VOLUMETRIC_LIGHTS) != 0;
323
324                 return EFFECT_VOLUMETRIC | EFFECT_POST_BUFFER;
325         }
326
327         /* Cleanup to release memory */
328         DRW_TEXTURE_FREE_SAFE(txl->volume_prop_scattering);
329         DRW_TEXTURE_FREE_SAFE(txl->volume_prop_extinction);
330         DRW_TEXTURE_FREE_SAFE(txl->volume_prop_emission);
331         DRW_TEXTURE_FREE_SAFE(txl->volume_prop_phase);
332         DRW_TEXTURE_FREE_SAFE(txl->volume_scatter);
333         DRW_TEXTURE_FREE_SAFE(txl->volume_transmittance);
334         DRW_TEXTURE_FREE_SAFE(txl->volume_scatter_history);
335         DRW_TEXTURE_FREE_SAFE(txl->volume_transmittance_history);
336         GPU_FRAMEBUFFER_FREE_SAFE(fbl->volumetric_fb);
337         GPU_FRAMEBUFFER_FREE_SAFE(fbl->volumetric_scat_fb);
338         GPU_FRAMEBUFFER_FREE_SAFE(fbl->volumetric_integ_fb);
339
340         return 0;
341 }
342
343 void EEVEE_volumes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
344 {
345         EEVEE_PassList *psl = vedata->psl;
346         EEVEE_StorageList *stl = vedata->stl;
347         EEVEE_TextureList *txl = vedata->txl;
348         EEVEE_EffectsInfo *effects = stl->effects;
349         LightCache *lcache = stl->g_data->light_cache;
350         EEVEE_CommonUniformBuffer *common_data = &sldata->common_data;
351
352         if ((effects->enabled_effects & EFFECT_VOLUMETRIC) != 0) {
353                 const DRWContextState *draw_ctx = DRW_context_state_get();
354                 Scene *scene = draw_ctx->scene;
355                 DRWShadingGroup *grp = NULL;
356
357                 /* Quick breakdown of the Volumetric rendering:
358                  *
359                  * The rendering is separated in 4 stages:
360                  *
361                  * - Material Parameters : we collect volume properties of
362                  *   all participating media in the scene and store them in
363                  *   a 3D texture aligned with the 3D frustum.
364                  *   This is done in 2 passes, one that clear the texture
365                  *   and/or evaluate the world volumes, and the 2nd one that
366                  *   additively render object volumes.
367                  *
368                  * - Light Scattering : the volume properties then are sampled
369                  *   and light scattering is evaluated for each cell of the
370                  *   volume texture. Temporal super-sampling (if enabled) occurs here.
371                  *
372                  * - Volume Integration : the scattered light and extinction is
373                  *   integrated (accumulated) along the view-rays. The result is stored
374                  *   for every cell in another texture.
375                  *
376                  * - Full-screen Resolve : From the previous stage, we get two
377                  *   3D textures that contains integrated scattered light and extinction
378                  *   for "every" positions in the frustum. We only need to sample
379                  *   them and blend the scene color with those factors. This also
380                  *   work for alpha blended materials.
381                  **/
382
383                 /* World pass is not additive as it also clear the buffer. */
384                 psl->volumetric_world_ps = DRW_pass_create("Volumetric World", DRW_STATE_WRITE_COLOR);
385
386                 /* World Volumetric */
387                 struct World *wo = scene->world;
388                 if (wo != NULL && wo->use_nodes && wo->nodetree) {
389                         struct GPUMaterial *mat = EEVEE_material_world_volume_get(scene, wo);
390
391                         grp = DRW_shgroup_material_empty_tri_batch_create(mat,
392                                                                           psl->volumetric_world_ps,
393                                                                           common_data->vol_tex_size[2]);
394
395                         if (grp) {
396                                 DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
397                                 /* TODO (fclem): remove those (need to clean the GLSL files). */
398                                 DRW_shgroup_uniform_block(grp, "grid_block", sldata->grid_ubo);
399                                 DRW_shgroup_uniform_block(grp, "probe_block", sldata->probe_ubo);
400                                 DRW_shgroup_uniform_block(grp, "planar_block", sldata->planar_ubo);
401                                 DRW_shgroup_uniform_block(grp, "light_block", sldata->light_ubo);
402                                 DRW_shgroup_uniform_block(grp, "shadow_block", sldata->shadow_ubo);
403                         }
404                 }
405
406                 if (grp == NULL) {
407                         /* If no world or volume material is present just clear the buffer with this drawcall */
408                         grp = DRW_shgroup_empty_tri_batch_create(e_data.volumetric_clear_sh,
409                                                                      psl->volumetric_world_ps,
410                                                                      common_data->vol_tex_size[2]);
411
412                         DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
413                 }
414
415                 /* Volumetric Objects */
416                 psl->volumetric_objects_ps = DRW_pass_create("Volumetric Properties", DRW_STATE_WRITE_COLOR |
417                                                                                       DRW_STATE_ADDITIVE);
418
419                 struct GPUShader *scatter_sh = (common_data->vol_use_lights) ? e_data.volumetric_scatter_with_lamps_sh
420                                                                       : e_data.volumetric_scatter_sh;
421                 psl->volumetric_scatter_ps = DRW_pass_create("Volumetric Scattering", DRW_STATE_WRITE_COLOR);
422                 grp = DRW_shgroup_empty_tri_batch_create(scatter_sh, psl->volumetric_scatter_ps,
423                                                          common_data->vol_tex_size[2]);
424                 DRW_shgroup_uniform_texture_ref(grp, "irradianceGrid", &lcache->grid_tx.tex);
425                 DRW_shgroup_uniform_texture_ref(grp, "shadowCubeTexture", &sldata->shadow_cube_pool);
426                 DRW_shgroup_uniform_texture_ref(grp, "shadowCascadeTexture", &sldata->shadow_cascade_pool);
427                 DRW_shgroup_uniform_texture_ref(grp, "volumeScattering", &txl->volume_prop_scattering);
428                 DRW_shgroup_uniform_texture_ref(grp, "volumeExtinction", &txl->volume_prop_extinction);
429                 DRW_shgroup_uniform_texture_ref(grp, "volumeEmission", &txl->volume_prop_emission);
430                 DRW_shgroup_uniform_texture_ref(grp, "volumePhase", &txl->volume_prop_phase);
431                 DRW_shgroup_uniform_texture_ref(grp, "historyScattering", &txl->volume_scatter_history);
432                 DRW_shgroup_uniform_texture_ref(grp, "historyTransmittance", &txl->volume_transmittance_history);
433                 DRW_shgroup_uniform_block(grp, "light_block", sldata->light_ubo);
434                 DRW_shgroup_uniform_block(grp, "shadow_block", sldata->shadow_ubo);
435                 DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
436
437                 psl->volumetric_integration_ps = DRW_pass_create("Volumetric Integration", DRW_STATE_WRITE_COLOR);
438                 grp = DRW_shgroup_empty_tri_batch_create(e_data.volumetric_integration_sh,
439                                                          psl->volumetric_integration_ps,
440                                                          common_data->vol_tex_size[2]);
441                 DRW_shgroup_uniform_texture_ref(grp, "volumeScattering", &txl->volume_scatter);
442                 DRW_shgroup_uniform_texture_ref(grp, "volumeExtinction", &txl->volume_transmittance);
443                 DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
444
445                 psl->volumetric_resolve_ps = DRW_pass_create("Volumetric Resolve", DRW_STATE_WRITE_COLOR);
446                 grp = DRW_shgroup_create(e_data.volumetric_resolve_sh, psl->volumetric_resolve_ps);
447                 DRW_shgroup_uniform_texture_ref(grp, "inScattering", &txl->volume_scatter);
448                 DRW_shgroup_uniform_texture_ref(grp, "inTransmittance", &txl->volume_transmittance);
449                 DRW_shgroup_uniform_texture_ref(grp, "inSceneColor", &e_data.color_src);
450                 DRW_shgroup_uniform_texture_ref(grp, "inSceneDepth", &e_data.depth_src);
451                 DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
452                 DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
453         }
454 }
455
456 void EEVEE_volumes_cache_object_add(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, Scene *scene, Object *ob)
457 {
458         const DRWContextState *draw_ctx = DRW_context_state_get();
459
460         float *texcoloc = NULL;
461         float *texcosize = NULL;
462         struct ModifierData *md = NULL;
463         Material *ma = give_current_material(ob, 1);
464
465         if (ma == NULL) {
466                 return;
467         }
468
469         struct GPUMaterial *mat = EEVEE_material_mesh_volume_get(scene, ma);
470
471         /* If shader failed to compile or is currently compiling. */
472         if (GPU_material_status(mat) != GPU_MAT_SUCCESS) {
473                 return;
474         }
475
476         DRWShadingGroup *grp = DRW_shgroup_material_empty_tri_batch_create(mat, vedata->psl->volumetric_objects_ps, sldata->common_data.vol_tex_size[2]);
477
478         /* Making sure it's updated. */
479         invert_m4_m4(ob->imat, ob->obmat);
480
481         BKE_mesh_texspace_get_reference((struct Mesh *)ob->data, NULL, &texcoloc, NULL, &texcosize);
482
483         /* TODO(fclem) remove those "unnecessary" UBOs */
484         DRW_shgroup_uniform_block(grp, "planar_block", sldata->planar_ubo);
485         DRW_shgroup_uniform_block(grp, "probe_block", sldata->probe_ubo);
486         DRW_shgroup_uniform_block(grp, "shadow_block", sldata->shadow_ubo);
487         DRW_shgroup_uniform_block(grp, "light_block", sldata->light_ubo);
488         DRW_shgroup_uniform_block(grp, "grid_block", sldata->grid_ubo);
489
490         DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
491         DRW_shgroup_uniform_mat4(grp, "volumeObjectMatrix", ob->imat);
492         DRW_shgroup_uniform_vec3(grp, "volumeOrcoLoc", texcoloc, 1);
493         DRW_shgroup_uniform_vec3(grp, "volumeOrcoSize", texcosize, 1);
494
495         /* Smoke Simulation */
496         if (((ob->base_flag & BASE_FROM_DUPLI) == 0) &&
497             (md = modifiers_findByType(ob, eModifierType_Smoke)) &&
498             (modifier_isEnabled(scene, md, eModifierMode_Realtime)))
499         {
500                 SmokeModifierData *smd = (SmokeModifierData *)md;
501                 SmokeDomainSettings *sds = smd->domain;
502
503                 if (sds == NULL) {
504                         return;
505                 }
506
507                 /* Don't show smoke before simulation starts, this could be made an option in the future. */
508                 const bool show_smoke = ((int)DEG_get_ctime(draw_ctx->depsgraph) >= sds->point_cache[0]->startframe);
509
510                 if (sds->fluid && show_smoke) {
511                         const bool show_highres = BKE_smoke_show_highres(scene, sds);
512                         if (!sds->wt || !show_highres) {
513                                 GPU_create_smoke(smd, 0);
514                         }
515                         else if (sds->wt && show_highres) {
516                                 GPU_create_smoke(smd, 1);
517                         }
518                         BLI_addtail(&e_data.smoke_domains, BLI_genericNodeN(smd));
519                 }
520
521                 if (sds->tex != NULL) {
522                         DRW_shgroup_uniform_texture_ref(grp, "sampdensity", &sds->tex);
523                 }
524                 if (sds->tex_flame != NULL) {
525                         DRW_shgroup_uniform_texture_ref(grp, "sampflame", &sds->tex_flame);
526                 }
527
528                 /* Output is such that 0..1 maps to 0..1000K */
529                 DRW_shgroup_uniform_vec2(grp, "unftemperature", &sds->flame_ignition, 1);
530         }
531 }
532
533 void EEVEE_volumes_compute(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
534 {
535         EEVEE_PassList *psl = vedata->psl;
536         EEVEE_TextureList *txl = vedata->txl;
537         EEVEE_FramebufferList *fbl = vedata->fbl;
538         EEVEE_StorageList *stl = vedata->stl;
539         EEVEE_EffectsInfo *effects = stl->effects;
540         if ((effects->enabled_effects & EFFECT_VOLUMETRIC) != 0) {
541                 DRW_stats_group_start("Volumetrics");
542
543                 /* Step 1: Participating Media Properties */
544                 GPU_framebuffer_bind(fbl->volumetric_fb);
545                 DRW_draw_pass(psl->volumetric_world_ps);
546                 DRW_draw_pass(psl->volumetric_objects_ps);
547
548                 /* Step 2: Scatter Light */
549                 GPU_framebuffer_bind(fbl->volumetric_scat_fb);
550                 DRW_draw_pass(psl->volumetric_scatter_ps);
551
552                 /* Step 3: Integration */
553                 GPU_framebuffer_bind(fbl->volumetric_integ_fb);
554                 DRW_draw_pass(psl->volumetric_integration_ps);
555
556                 /* Swap volume history buffers */
557                 SWAP(struct GPUFrameBuffer *, fbl->volumetric_scat_fb, fbl->volumetric_integ_fb);
558                 SWAP(GPUTexture *, txl->volume_scatter, txl->volume_scatter_history);
559                 SWAP(GPUTexture *, txl->volume_transmittance, txl->volume_transmittance_history);
560
561                 /* Restore */
562                 GPU_framebuffer_bind(fbl->main_fb);
563
564                 DRW_stats_group_end();
565         }
566 }
567
568 void EEVEE_volumes_resolve(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
569 {
570         EEVEE_PassList *psl = vedata->psl;
571         EEVEE_TextureList *txl = vedata->txl;
572         EEVEE_FramebufferList *fbl = vedata->fbl;
573         EEVEE_StorageList *stl = vedata->stl;
574         EEVEE_EffectsInfo *effects = stl->effects;
575
576         if ((effects->enabled_effects & EFFECT_VOLUMETRIC) != 0) {
577                 DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
578
579                 e_data.color_src = txl->color;
580                 e_data.depth_src = dtxl->depth;
581
582                 /* Step 4: Apply for opaque */
583                 GPU_framebuffer_bind(fbl->effect_color_fb);
584                 DRW_draw_pass(psl->volumetric_resolve_ps);
585
586                 /* Swap the buffers and rebind depth to the current buffer */
587                 SWAP(GPUFrameBuffer *, fbl->main_fb, fbl->effect_fb);
588                 SWAP(GPUFrameBuffer *, fbl->main_color_fb, fbl->effect_color_fb);
589                 SWAP(GPUTexture *, txl->color, txl->color_post);
590
591                 /* Restore */
592                 GPU_framebuffer_texture_detach(fbl->effect_fb, dtxl->depth);
593                 GPU_framebuffer_texture_attach(fbl->main_fb, dtxl->depth, 0, 0);
594                 GPU_framebuffer_bind(fbl->main_fb);
595         }
596 }
597
598 void EEVEE_volumes_free_smoke_textures(void)
599 {
600         /* Free Smoke Textures after rendering */
601         for (LinkData *link = e_data.smoke_domains.first; link; link = link->next) {
602                 SmokeModifierData *smd = (SmokeModifierData *)link->data;
603                 GPU_free_smoke(smd);
604         }
605         BLI_freelistN(&e_data.smoke_domains);
606 }
607
608 void EEVEE_volumes_free(void)
609 {
610         MEM_SAFE_FREE(e_data.volumetric_common_lib);
611         MEM_SAFE_FREE(e_data.volumetric_common_lamps_lib);
612
613         DRW_SHADER_FREE_SAFE(e_data.volumetric_clear_sh);
614         DRW_SHADER_FREE_SAFE(e_data.volumetric_scatter_sh);
615         DRW_SHADER_FREE_SAFE(e_data.volumetric_scatter_with_lamps_sh);
616         DRW_SHADER_FREE_SAFE(e_data.volumetric_integration_sh);
617         DRW_SHADER_FREE_SAFE(e_data.volumetric_resolve_sh);
618 }