Outliner: Add object(s) to new collection
[blender.git] / source / blender / draw / engines / eevee / eevee_volumes.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_volumes.c
23  *  \ingroup draw_engine
24  *
25  * Volumetric effects rendering using frostbite approach.
26  */
27
28 #include "DRW_render.h"
29
30 #include "BLI_rand.h"
31 #include "BLI_string_utils.h"
32
33 #include "DNA_object_force.h"
34 #include "DNA_smoke_types.h"
35 #include "DNA_world_types.h"
36
37 #include "BKE_global.h" /* for G.debug_value */
38 #include "BKE_modifier.h"
39 #include "BKE_mesh.h"
40 #include "BKE_object.h"
41
42 #include "ED_screen.h"
43
44 #include "eevee_private.h"
45 #include "GPU_draw.h"
46 #include "GPU_texture.h"
47
48 static struct {
49         char *volumetric_common_lib;
50         char *volumetric_common_lamps_lib;
51
52         struct GPUShader *volumetric_clear_sh;
53         struct GPUShader *volumetric_scatter_sh;
54         struct GPUShader *volumetric_scatter_with_lamps_sh;
55         struct GPUShader *volumetric_integration_sh;
56         struct GPUShader *volumetric_resolve_sh;
57
58         GPUTexture *color_src;
59         GPUTexture *depth_src;
60
61         /* List of all smoke domains rendered within this frame. */
62         ListBase smoke_domains;
63 } e_data = {NULL}; /* Engine data */
64
65 extern char datatoc_bsdf_common_lib_glsl[];
66 extern char datatoc_bsdf_direct_lib_glsl[];
67 extern char datatoc_common_uniforms_lib_glsl[];
68 extern char datatoc_octahedron_lib_glsl[];
69 extern char datatoc_irradiance_lib_glsl[];
70 extern char datatoc_lamps_lib_glsl[];
71 extern char datatoc_volumetric_frag_glsl[];
72 extern char datatoc_volumetric_geom_glsl[];
73 extern char datatoc_volumetric_vert_glsl[];
74 extern char datatoc_volumetric_resolve_frag_glsl[];
75 extern char datatoc_volumetric_scatter_frag_glsl[];
76 extern char datatoc_volumetric_integration_frag_glsl[];
77 extern char datatoc_volumetric_lib_glsl[];
78 extern char datatoc_gpu_shader_fullscreen_vert_glsl[];
79
80 static void eevee_create_shader_volumes(void)
81 {
82         e_data.volumetric_common_lib = BLI_string_joinN(
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_uniforms_lib_glsl,
89                 datatoc_bsdf_common_lib_glsl,
90                 datatoc_bsdf_direct_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_gpu_shader_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, unsigned int 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         unsigned int 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         ViewLayer *view_layer = draw_ctx->view_layer;
156         IDProperty *props = BKE_view_layer_engine_evaluated_get(view_layer, COLLECTION_MODE_NONE, RE_engine_id_BLENDER_EEVEE);
157
158         const float *viewport_size = DRW_viewport_size_get();
159
160         BLI_listbase_clear(&e_data.smoke_domains);
161
162         if (BKE_collection_engine_property_value_get_bool(props, "volumetric_enable")) {
163
164                 /* Shaders */
165                 if (!e_data.volumetric_scatter_sh) {
166                         eevee_create_shader_volumes();
167                 }
168
169                 int tile_size = BKE_collection_engine_property_value_get_int(props, "volumetric_tile_size");
170
171                 /* Find Froxel Texture resolution. */
172                 int tex_size[3];
173
174                 tex_size[0] = (int)ceilf(fmaxf(1.0f, viewport_size[0] / (float)tile_size));
175                 tex_size[1] = (int)ceilf(fmaxf(1.0f, viewport_size[1] / (float)tile_size));
176                 tex_size[2] = max_ii(BKE_collection_engine_property_value_get_int(props, "volumetric_samples"), 1);
177
178                 common_data->vol_coord_scale[0] = viewport_size[0] / (float)(tile_size * tex_size[0]);
179                 common_data->vol_coord_scale[1] = viewport_size[1] / (float)(tile_size * tex_size[1]);
180
181                 /* TODO compute snap to maxZBuffer for clustered rendering */
182
183                 if ((common_data->vol_tex_size[0] != tex_size[0]) ||
184                     (common_data->vol_tex_size[1] != tex_size[1]) ||
185                     (common_data->vol_tex_size[2] != tex_size[2]))
186                 {
187                         DRW_TEXTURE_FREE_SAFE(txl->volume_prop_scattering);
188                         DRW_TEXTURE_FREE_SAFE(txl->volume_prop_extinction);
189                         DRW_TEXTURE_FREE_SAFE(txl->volume_prop_emission);
190                         DRW_TEXTURE_FREE_SAFE(txl->volume_prop_phase);
191                         DRW_TEXTURE_FREE_SAFE(txl->volume_scatter);
192                         DRW_TEXTURE_FREE_SAFE(txl->volume_transmittance);
193                         DRW_TEXTURE_FREE_SAFE(txl->volume_scatter_history);
194                         DRW_TEXTURE_FREE_SAFE(txl->volume_transmittance_history);
195                         DRW_FRAMEBUFFER_FREE_SAFE(fbl->volumetric_fb);
196                         DRW_FRAMEBUFFER_FREE_SAFE(fbl->volumetric_scat_fb);
197                         DRW_FRAMEBUFFER_FREE_SAFE(fbl->volumetric_integ_fb);
198                         common_data->vol_tex_size[0] = tex_size[0];
199                         common_data->vol_tex_size[1] = tex_size[1];
200                         common_data->vol_tex_size[2] = tex_size[2];
201
202                         common_data->vol_inv_tex_size[0] = 1.0f / (float)(tex_size[0]);
203                         common_data->vol_inv_tex_size[1] = 1.0f / (float)(tex_size[1]);
204                         common_data->vol_inv_tex_size[2] = 1.0f / (float)(tex_size[2]);
205                 }
206
207                 /* Like frostbite's paper, 5% blend of the new frame. */
208                 common_data->vol_history_alpha = (txl->volume_prop_scattering == NULL) ? 0.0f : 0.95f;
209
210                 if (txl->volume_prop_scattering == NULL) {
211                         /* Volume properties: We evaluate all volumetric objects
212                          * and store their final properties into each froxel */
213                         txl->volume_prop_scattering = DRW_texture_create_3D(tex_size[0], tex_size[1], tex_size[2],
214                                                                             DRW_TEX_RGB_11_11_10, DRW_TEX_FILTER, NULL);
215                         txl->volume_prop_extinction = DRW_texture_create_3D(tex_size[0], tex_size[1], tex_size[2],
216                                                                             DRW_TEX_RGB_11_11_10, DRW_TEX_FILTER, NULL);
217                         txl->volume_prop_emission = DRW_texture_create_3D(tex_size[0], tex_size[1], tex_size[2],
218                                                                           DRW_TEX_RGB_11_11_10, DRW_TEX_FILTER, NULL);
219                         txl->volume_prop_phase = DRW_texture_create_3D(tex_size[0], tex_size[1], tex_size[2],
220                                                                        DRW_TEX_RG_16, DRW_TEX_FILTER, NULL);
221
222                         /* Volume scattering: We compute for each froxel the
223                          * Scattered light towards the view. We also resolve temporal
224                          * super sampling during this stage. */
225                         txl->volume_scatter = DRW_texture_create_3D(tex_size[0], tex_size[1], tex_size[2],
226                                                                     DRW_TEX_RGB_11_11_10, DRW_TEX_FILTER, NULL);
227                         txl->volume_transmittance = DRW_texture_create_3D(tex_size[0], tex_size[1], tex_size[2],
228                                                                           DRW_TEX_RGB_11_11_10, DRW_TEX_FILTER, NULL);
229
230                         /* Final integration: We compute for each froxel the
231                          * amount of scattered light and extinction coef at this
232                          * given depth. We use theses textures as double buffer
233                          * for the volumetric history. */
234                         txl->volume_scatter_history = DRW_texture_create_3D(tex_size[0], tex_size[1], tex_size[2],
235                                                                             DRW_TEX_RGB_11_11_10, DRW_TEX_FILTER, NULL);
236                         txl->volume_transmittance_history = DRW_texture_create_3D(tex_size[0], tex_size[1], tex_size[2],
237                                                                                   DRW_TEX_RGB_11_11_10, DRW_TEX_FILTER, NULL);
238                 }
239
240                 /* Temporal Super sampling jitter */
241                 unsigned int ht_primes[3] = {3, 7, 2};
242                 unsigned int current_sample = 0;
243
244                 /* If TAA is in use do not use the history buffer. */
245                 bool do_taa = ((effects->enabled_effects & EFFECT_TAA) != 0);
246
247                 if (draw_ctx->evil_C != NULL) {
248                         struct wmWindowManager *wm = CTX_wm_manager(draw_ctx->evil_C);
249                         do_taa = do_taa && (ED_screen_animation_no_scrub(wm) == NULL);
250                 }
251
252                 if (do_taa) {
253                         common_data->vol_history_alpha = 0.0f;
254                         current_sample = effects->taa_current_sample - 1;
255                         effects->volume_current_sample = -1;
256                 }
257                 else {
258                         const unsigned int max_sample = (ht_primes[0] * ht_primes[1] * ht_primes[2]);
259                         current_sample = effects->volume_current_sample = (effects->volume_current_sample + 1) % max_sample;
260                         if (current_sample != max_sample - 1) {
261                                 DRW_viewport_request_redraw();
262                         }
263                 }
264
265                 EEVEE_volumes_set_jitter(sldata, current_sample);
266
267                 /* Framebuffer setup */
268                 DRWFboTexture tex_vol[4] = {{&txl->volume_prop_scattering, DRW_TEX_RGB_11_11_10, DRW_TEX_FILTER},
269                                             {&txl->volume_prop_extinction, DRW_TEX_RGB_11_11_10, DRW_TEX_FILTER},
270                                             {&txl->volume_prop_emission, DRW_TEX_RGB_11_11_10, DRW_TEX_FILTER},
271                                             {&txl->volume_prop_phase, DRW_TEX_RG_16, DRW_TEX_FILTER}};
272
273                 DRW_framebuffer_init(&fbl->volumetric_fb, &draw_engine_eevee_type,
274                                      (int)tex_size[0], (int)tex_size[1],
275                                      tex_vol, 4);
276
277                 DRWFboTexture tex_vol_scat[2] = {{&txl->volume_scatter, DRW_TEX_RGB_11_11_10, DRW_TEX_FILTER},
278                                                  {&txl->volume_transmittance, DRW_TEX_RGB_11_11_10, DRW_TEX_FILTER}};
279
280                 DRW_framebuffer_init(&fbl->volumetric_scat_fb, &draw_engine_eevee_type,
281                                      (int)tex_size[0], (int)tex_size[1],
282                                      tex_vol_scat, 2);
283
284                 DRWFboTexture tex_vol_integ[2] = {{&txl->volume_scatter_history, DRW_TEX_RGB_11_11_10, DRW_TEX_FILTER},
285                                                   {&txl->volume_transmittance_history, DRW_TEX_RGB_11_11_10, DRW_TEX_FILTER}};
286
287                 DRW_framebuffer_init(&fbl->volumetric_integ_fb, &draw_engine_eevee_type,
288                                      (int)tex_size[0], (int)tex_size[1],
289                                      tex_vol_integ, 2);
290
291                 float integration_start = BKE_collection_engine_property_value_get_float(props, "volumetric_start");
292                 float integration_end = BKE_collection_engine_property_value_get_float(props, "volumetric_end");
293                 common_data->vol_light_clamp = BKE_collection_engine_property_value_get_float(props, "volumetric_light_clamp");
294
295                 common_data->vol_shadow_steps = (float)BKE_collection_engine_property_value_get_int(props, "volumetric_shadow_samples");
296                 if (BKE_collection_engine_property_value_get_bool(props, "volumetric_shadows")) {
297                 }
298                 else {
299                         common_data->vol_shadow_steps = 0;
300                 }
301
302                 if (DRW_viewport_is_persp_get()) {
303                         float sample_distribution = BKE_collection_engine_property_value_get_float(props, "volumetric_sample_distribution");
304                         sample_distribution = 4.0f * (1.00001f - sample_distribution);
305
306                         const float clip_start = common_data->view_vecs[0][2];
307                         /* Negate */
308                         float near = integration_start = min_ff(-integration_start, clip_start - 1e-4f);
309                         float far = integration_end = min_ff(-integration_end, near - 1e-4f);
310
311                         common_data->vol_depth_param[0] = (far - near * exp2(1.0f / sample_distribution)) / (far - near);
312                         common_data->vol_depth_param[1] = (1.0f - common_data->vol_depth_param[0]) / near;
313                         common_data->vol_depth_param[2] = sample_distribution;
314                 }
315                 else {
316                         const float clip_start = common_data->view_vecs[0][2];
317                         const float clip_end = clip_start + common_data->view_vecs[1][2];
318                         integration_start = min_ff(integration_end, clip_start);
319                         integration_end = max_ff(-integration_end, clip_end);
320
321                         common_data->vol_depth_param[0] = integration_start;
322                         common_data->vol_depth_param[1] = integration_end;
323                         common_data->vol_depth_param[2] = 1.0f / (integration_end - integration_start);
324                 }
325
326                 /* Disable clamp if equal to 0. */
327                 if (common_data->vol_light_clamp == 0.0) {
328                         common_data->vol_light_clamp = FLT_MAX;
329                 }
330
331                 common_data->vol_use_lights = BKE_collection_engine_property_value_get_bool(props, "volumetric_lights");
332
333                 return EFFECT_VOLUMETRIC | EFFECT_POST_BUFFER;
334         }
335
336         /* Cleanup to release memory */
337         DRW_TEXTURE_FREE_SAFE(txl->volume_prop_scattering);
338         DRW_TEXTURE_FREE_SAFE(txl->volume_prop_extinction);
339         DRW_TEXTURE_FREE_SAFE(txl->volume_prop_emission);
340         DRW_TEXTURE_FREE_SAFE(txl->volume_prop_phase);
341         DRW_TEXTURE_FREE_SAFE(txl->volume_scatter);
342         DRW_TEXTURE_FREE_SAFE(txl->volume_transmittance);
343         DRW_TEXTURE_FREE_SAFE(txl->volume_scatter_history);
344         DRW_TEXTURE_FREE_SAFE(txl->volume_transmittance_history);
345         DRW_FRAMEBUFFER_FREE_SAFE(fbl->volumetric_fb);
346         DRW_FRAMEBUFFER_FREE_SAFE(fbl->volumetric_scat_fb);
347         DRW_FRAMEBUFFER_FREE_SAFE(fbl->volumetric_integ_fb);
348
349         return 0;
350 }
351
352 void EEVEE_volumes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
353 {
354         EEVEE_PassList *psl = vedata->psl;
355         EEVEE_StorageList *stl = vedata->stl;
356         EEVEE_TextureList *txl = vedata->txl;
357         EEVEE_EffectsInfo *effects = stl->effects;
358         EEVEE_CommonUniformBuffer *common_data = &sldata->common_data;
359
360         if ((effects->enabled_effects & EFFECT_VOLUMETRIC) != 0) {
361                 const DRWContextState *draw_ctx = DRW_context_state_get();
362                 Scene *scene = draw_ctx->scene;
363                 DRWShadingGroup *grp;
364
365                 /* Quick breakdown of the Volumetric rendering:
366                  *
367                  * The rendering is separated in 4 stages:
368                  *
369                  * - Material Parameters : we collect volume properties of
370                  *   all participating media in the scene and store them in
371                  *   a 3D texture aligned with the 3D frustum.
372                  *   This is done in 2 passes, one that clear the texture
373                  *   and/or evaluate the world volumes, and the 2nd one that
374                  *   additively render object volumes.
375                  *
376                  * - Light Scattering : the volume properties then are sampled
377                  *   and light scattering is evaluated for each cell of the
378                  *   volume texture. Temporal supersampling (if enabled) occurs here.
379                  *
380                  * - Volume Integration : the scattered light and extinction is
381                  *   integrated (accumulated) along the viewrays. The result is stored
382                  *   for every cell in another texture.
383                  *
384                  * - Fullscreen Resolve : From the previous stage, we get two
385                  *   3D textures that contains integrated scatered light and extinction
386                  *   for "every" positions in the frustum. We only need to sample
387                  *   them and blend the scene color with thoses factors. This also
388                  *   work for alpha blended materials.
389                  **/
390
391                 /* World pass is not additive as it also clear the buffer. */
392                 psl->volumetric_world_ps = DRW_pass_create("Volumetric World", DRW_STATE_WRITE_COLOR);
393
394                 /* World Volumetric */
395                 struct World *wo = scene->world;
396                 if (wo != NULL && wo->use_nodes && wo->nodetree) {
397                         struct GPUMaterial *mat = EEVEE_material_world_volume_get(scene, wo);
398
399                         grp = DRW_shgroup_material_empty_tri_batch_create(mat,
400                                                                           psl->volumetric_world_ps,
401                                                                           common_data->vol_tex_size[2]);
402
403                         if (grp) {
404                                 DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
405                         }
406                 }
407                 else {
408                         /* If no world or volume material is present just clear the buffer with this drawcall */
409                         grp = DRW_shgroup_empty_tri_batch_create(e_data.volumetric_clear_sh,
410                                                                      psl->volumetric_world_ps,
411                                                                      common_data->vol_tex_size[2]);
412
413                         DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
414                 }
415
416                 /* Volumetric Objects */
417                 psl->volumetric_objects_ps = DRW_pass_create("Volumetric Properties", DRW_STATE_WRITE_COLOR |
418                                                                                       DRW_STATE_ADDITIVE);
419
420                 struct GPUShader *scatter_sh = (common_data->vol_use_lights) ? e_data.volumetric_scatter_with_lamps_sh
421                                                                       : e_data.volumetric_scatter_sh;
422                 psl->volumetric_scatter_ps = DRW_pass_create("Volumetric Scattering", DRW_STATE_WRITE_COLOR);
423                 grp = DRW_shgroup_empty_tri_batch_create(scatter_sh, psl->volumetric_scatter_ps,
424                                                          common_data->vol_tex_size[2]);
425                 DRW_shgroup_uniform_buffer(grp, "irradianceGrid", &sldata->irradiance_pool);
426                 DRW_shgroup_uniform_buffer(grp, "shadowTexture", &sldata->shadow_pool);
427                 DRW_shgroup_uniform_buffer(grp, "volumeScattering", &txl->volume_prop_scattering);
428                 DRW_shgroup_uniform_buffer(grp, "volumeExtinction", &txl->volume_prop_extinction);
429                 DRW_shgroup_uniform_buffer(grp, "volumeEmission", &txl->volume_prop_emission);
430                 DRW_shgroup_uniform_buffer(grp, "volumePhase", &txl->volume_prop_phase);
431                 DRW_shgroup_uniform_buffer(grp, "historyScattering", &txl->volume_scatter_history);
432                 DRW_shgroup_uniform_buffer(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_buffer(grp, "volumeScattering", &txl->volume_scatter);
442                 DRW_shgroup_uniform_buffer(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_buffer(grp, "inScattering", &txl->volume_scatter);
448                 DRW_shgroup_uniform_buffer(grp, "inTransmittance", &txl->volume_transmittance);
449                 DRW_shgroup_uniform_buffer(grp, "inSceneColor", &e_data.color_src);
450                 DRW_shgroup_uniform_buffer(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         float *texcoloc = NULL;
459         float *texcosize = NULL;
460         struct ModifierData *md = NULL;
461         Material *ma = give_current_material(ob, 1);
462
463         if (ma == NULL) {
464                 return;
465         }
466
467         struct GPUMaterial *mat = EEVEE_material_mesh_volume_get(scene, ma);
468
469         DRWShadingGroup *grp = DRW_shgroup_material_empty_tri_batch_create(mat, vedata->psl->volumetric_objects_ps, sldata->common_data.vol_tex_size[2]);
470
471         /* Making sure it's updated. */
472         invert_m4_m4(ob->imat, ob->obmat);
473
474         BKE_mesh_texspace_get_reference((struct Mesh *)ob->data, NULL, &texcoloc, NULL, &texcosize);
475
476         if (grp) {
477                 DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
478                 DRW_shgroup_uniform_mat4(grp, "volumeObjectMatrix", (float *)ob->imat);
479                 DRW_shgroup_uniform_vec3(grp, "volumeOrcoLoc", texcoloc, 1);
480                 DRW_shgroup_uniform_vec3(grp, "volumeOrcoSize", texcosize, 1);
481         }
482
483         /* Smoke Simulation */
484         if (((ob->base_flag & BASE_FROMDUPLI) == 0) &&
485             (md = modifiers_findByType(ob, eModifierType_Smoke)) &&
486             (modifier_isEnabled(scene, md, eModifierMode_Realtime)))
487         {
488                 SmokeModifierData *smd = (SmokeModifierData *)md;
489                 SmokeDomainSettings *sds = smd->domain;
490                 /* Don't show smoke before simulation starts, this could be made an option in the future. */
491                 const bool show_smoke = (CFRA >= sds->point_cache[0]->startframe);
492
493                 if (sds->fluid && show_smoke) {
494                         if (!sds->wt || !(sds->viewsettings & MOD_SMOKE_VIEW_SHOWBIG)) {
495                                 GPU_create_smoke(smd, 0);
496                         }
497                         else if (sds->wt && (sds->viewsettings & MOD_SMOKE_VIEW_SHOWBIG)) {
498                                 GPU_create_smoke(smd, 1);
499                         }
500                         BLI_addtail(&e_data.smoke_domains, BLI_genericNodeN(smd));
501                 }
502
503                 if (sds->tex != NULL) {
504                         DRW_shgroup_uniform_buffer(grp, "sampdensity", &sds->tex);
505                 }
506                 if (sds->tex_flame != NULL) {
507                         DRW_shgroup_uniform_buffer(grp, "sampflame", &sds->tex_flame);
508                 }
509         }
510 }
511
512 void EEVEE_volumes_compute(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
513 {
514         EEVEE_PassList *psl = vedata->psl;
515         EEVEE_TextureList *txl = vedata->txl;
516         EEVEE_FramebufferList *fbl = vedata->fbl;
517         EEVEE_StorageList *stl = vedata->stl;
518         EEVEE_EffectsInfo *effects = stl->effects;
519         if ((effects->enabled_effects & EFFECT_VOLUMETRIC) != 0) {
520                 DRW_stats_group_start("Volumetrics");
521
522                 /* Step 1: Participating Media Properties */
523                 DRW_framebuffer_bind(fbl->volumetric_fb);
524                 DRW_draw_pass(psl->volumetric_world_ps);
525                 DRW_draw_pass(psl->volumetric_objects_ps);
526
527                 /* Step 2: Scatter Light */
528                 DRW_framebuffer_bind(fbl->volumetric_scat_fb);
529                 DRW_draw_pass(psl->volumetric_scatter_ps);
530
531                 /* Step 3: Integration */
532                 DRW_framebuffer_bind(fbl->volumetric_integ_fb);
533                 DRW_draw_pass(psl->volumetric_integration_ps);
534
535                 /* Swap volume history buffers */
536                 SWAP(struct GPUFrameBuffer *, fbl->volumetric_scat_fb, fbl->volumetric_integ_fb);
537                 SWAP(GPUTexture *, txl->volume_scatter, txl->volume_scatter_history);
538                 SWAP(GPUTexture *, txl->volume_transmittance, txl->volume_transmittance_history);
539
540                 /* Restore */
541                 DRW_framebuffer_bind(fbl->main);
542
543                 DRW_stats_group_end();
544         }
545 }
546
547 void EEVEE_volumes_resolve(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
548 {
549         EEVEE_PassList *psl = vedata->psl;
550         EEVEE_TextureList *txl = vedata->txl;
551         EEVEE_FramebufferList *fbl = vedata->fbl;
552         EEVEE_StorageList *stl = vedata->stl;
553         EEVEE_EffectsInfo *effects = stl->effects;
554
555         if ((effects->enabled_effects & EFFECT_VOLUMETRIC) != 0) {
556                 DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
557
558                 e_data.color_src = txl->color;
559                 e_data.depth_src = dtxl->depth;
560
561                 /* Step 4: Apply for opaque */
562                 DRW_framebuffer_bind(fbl->effect_fb);
563                 DRW_draw_pass(psl->volumetric_resolve_ps);
564
565                 /* Swap the buffers and rebind depth to the current buffer */
566                 DRW_framebuffer_texture_detach(dtxl->depth);
567                 SWAP(struct GPUFrameBuffer *, fbl->main, fbl->effect_fb);
568                 SWAP(GPUTexture *, txl->color, txl->color_post);
569                 DRW_framebuffer_texture_attach(fbl->main, dtxl->depth, 0, 0);
570         }
571 }
572
573 void EEVEE_volumes_free_smoke_textures(void)
574 {
575         /* Free Smoke Textures after rendering */
576         for (LinkData *link = e_data.smoke_domains.first; link; link = link->next) {
577                 SmokeModifierData *smd = (SmokeModifierData *)link->data;
578                 GPU_free_smoke(smd);
579         }
580         BLI_freelistN(&e_data.smoke_domains);
581 }
582
583 void EEVEE_volumes_free(void)
584 {
585         MEM_SAFE_FREE(e_data.volumetric_common_lib);
586         MEM_SAFE_FREE(e_data.volumetric_common_lamps_lib);
587
588         DRW_SHADER_FREE_SAFE(e_data.volumetric_clear_sh);
589         DRW_SHADER_FREE_SAFE(e_data.volumetric_scatter_sh);
590         DRW_SHADER_FREE_SAFE(e_data.volumetric_scatter_with_lamps_sh);
591         DRW_SHADER_FREE_SAFE(e_data.volumetric_integration_sh);
592         DRW_SHADER_FREE_SAFE(e_data.volumetric_resolve_sh);
593 }