Rename any instance of scene layer or render layer in code with view layer
[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_volume.c
23  *  \ingroup draw_engine
24  *
25  * Volumetric effects rendering using frostbite approach.
26  */
27
28 #include "DRW_render.h"
29
30 #include "BLI_dynstr.h"
31 #include "BLI_rand.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_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_bsdf_direct_lib_glsl[];
66 extern char datatoc_octahedron_lib_glsl[];
67 extern char datatoc_irradiance_lib_glsl[];
68 extern char datatoc_lamps_lib_glsl[];
69 extern char datatoc_volumetric_frag_glsl[];
70 extern char datatoc_volumetric_geom_glsl[];
71 extern char datatoc_volumetric_vert_glsl[];
72 extern char datatoc_volumetric_resolve_frag_glsl[];
73 extern char datatoc_volumetric_scatter_frag_glsl[];
74 extern char datatoc_volumetric_integration_frag_glsl[];
75 extern char datatoc_volumetric_lib_glsl[];
76 extern char datatoc_gpu_shader_fullscreen_vert_glsl[];
77
78 static void eevee_create_shader_volumes(void)
79 {
80         DynStr *ds_frag = BLI_dynstr_new();
81         BLI_dynstr_append(ds_frag, datatoc_bsdf_common_lib_glsl);
82         BLI_dynstr_append(ds_frag, datatoc_volumetric_lib_glsl);
83         e_data.volumetric_common_lib = BLI_dynstr_get_cstring(ds_frag);
84         BLI_dynstr_free(ds_frag);
85
86         ds_frag = BLI_dynstr_new();
87         BLI_dynstr_append(ds_frag, datatoc_bsdf_common_lib_glsl);
88         BLI_dynstr_append(ds_frag, datatoc_bsdf_direct_lib_glsl);
89         BLI_dynstr_append(ds_frag, datatoc_irradiance_lib_glsl);
90         BLI_dynstr_append(ds_frag, datatoc_octahedron_lib_glsl);
91         BLI_dynstr_append(ds_frag, datatoc_lamps_lib_glsl);
92         BLI_dynstr_append(ds_frag, datatoc_volumetric_lib_glsl);
93         e_data.volumetric_common_lamps_lib = BLI_dynstr_get_cstring(ds_frag);
94         BLI_dynstr_free(ds_frag);
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_integration_sh = DRW_shader_create_with_lib(
112                 datatoc_volumetric_vert_glsl,
113                 datatoc_volumetric_geom_glsl,
114                 datatoc_volumetric_integration_frag_glsl,
115                 e_data.volumetric_common_lib, NULL);
116         e_data.volumetric_resolve_sh = DRW_shader_create_with_lib(
117                 datatoc_gpu_shader_fullscreen_vert_glsl, NULL,
118                 datatoc_volumetric_resolve_frag_glsl,
119                 e_data.volumetric_common_lib, NULL);
120 }
121
122 int EEVEE_volumes_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
123 {
124         EEVEE_StorageList *stl = vedata->stl;
125         EEVEE_FramebufferList *fbl = vedata->fbl;
126         EEVEE_TextureList *txl = vedata->txl;
127         EEVEE_EffectsInfo *effects = stl->effects;
128
129         const DRWContextState *draw_ctx = DRW_context_state_get();
130         ViewLayer *view_layer = draw_ctx->view_layer;
131         IDProperty *props = BKE_view_layer_engine_evaluated_get(view_layer, COLLECTION_MODE_NONE, RE_engine_id_BLENDER_EEVEE);
132
133         const float *viewport_size = DRW_viewport_size_get();
134
135         BLI_listbase_clear(&e_data.smoke_domains);
136
137         if (BKE_collection_engine_property_value_get_bool(props, "volumetric_enable")) {
138
139                 /* Shaders */
140                 if (!e_data.volumetric_scatter_sh) {
141                         eevee_create_shader_volumes();
142                 }
143
144                 if (sldata->volumetrics == NULL) {
145                         sldata->volumetrics = MEM_callocN(sizeof(EEVEE_VolumetricsInfo), "EEVEE_VolumetricsInfo");
146                 }
147
148                 EEVEE_VolumetricsInfo *volumetrics = sldata->volumetrics;
149
150                 int tile_size = BKE_collection_engine_property_value_get_int(props, "volumetric_tile_size");
151
152                 /* Find Froxel Texture resolution. */
153                 int froxel_tex_size[3];
154
155                 froxel_tex_size[0] = (int)ceilf(fmaxf(1.0f, viewport_size[0] / (float)tile_size));
156                 froxel_tex_size[1] = (int)ceilf(fmaxf(1.0f, viewport_size[1] / (float)tile_size));
157                 froxel_tex_size[2] = max_ii(BKE_collection_engine_property_value_get_int(props, "volumetric_samples"), 1);
158
159                 volumetrics->volume_coord_scale[0] = viewport_size[0] / (float)(tile_size * froxel_tex_size[0]);
160                 volumetrics->volume_coord_scale[1] = viewport_size[1] / (float)(tile_size * froxel_tex_size[1]);
161
162                 /* TODO compute snap to maxZBuffer for clustered rendering */
163
164                 if ((volumetrics->froxel_tex_size[0] != froxel_tex_size[0]) ||
165                     (volumetrics->froxel_tex_size[1] != froxel_tex_size[1]) ||
166                     (volumetrics->froxel_tex_size[2] != froxel_tex_size[2]))
167                 {
168                         DRW_TEXTURE_FREE_SAFE(txl->volume_prop_scattering);
169                         DRW_TEXTURE_FREE_SAFE(txl->volume_prop_extinction);
170                         DRW_TEXTURE_FREE_SAFE(txl->volume_prop_emission);
171                         DRW_TEXTURE_FREE_SAFE(txl->volume_prop_phase);
172                         DRW_TEXTURE_FREE_SAFE(txl->volume_scatter);
173                         DRW_TEXTURE_FREE_SAFE(txl->volume_transmittance);
174                         DRW_TEXTURE_FREE_SAFE(txl->volume_scatter_history);
175                         DRW_TEXTURE_FREE_SAFE(txl->volume_transmittance_history);
176                         DRW_FRAMEBUFFER_FREE_SAFE(fbl->volumetric_fb);
177                         DRW_FRAMEBUFFER_FREE_SAFE(fbl->volumetric_scat_fb);
178                         DRW_FRAMEBUFFER_FREE_SAFE(fbl->volumetric_integ_fb);
179                         volumetrics->froxel_tex_size[0] = froxel_tex_size[0];
180                         volumetrics->froxel_tex_size[1] = froxel_tex_size[1];
181                         volumetrics->froxel_tex_size[2] = froxel_tex_size[2];
182
183                         volumetrics->inv_tex_size[0] = 1.0f / (float)(volumetrics->froxel_tex_size[0]);
184                         volumetrics->inv_tex_size[1] = 1.0f / (float)(volumetrics->froxel_tex_size[1]);
185                         volumetrics->inv_tex_size[2] = 1.0f / (float)(volumetrics->froxel_tex_size[2]);
186                 }
187
188                 /* Like frostbite's paper, 5% blend of the new frame. */
189                 volumetrics->history_alpha = (txl->volume_prop_scattering == NULL) ? 0.0f : 0.95f;
190
191                 if (txl->volume_prop_scattering == NULL) {
192                         /* Volume properties: We evaluate all volumetric objects
193                          * and store their final properties into each froxel */
194                         txl->volume_prop_scattering = DRW_texture_create_3D(froxel_tex_size[0], froxel_tex_size[1], froxel_tex_size[2], DRW_TEX_RGB_11_11_10, DRW_TEX_FILTER, NULL);
195                         txl->volume_prop_extinction = DRW_texture_create_3D(froxel_tex_size[0], froxel_tex_size[1], froxel_tex_size[2], DRW_TEX_RGB_11_11_10, DRW_TEX_FILTER, NULL);
196                         txl->volume_prop_emission = DRW_texture_create_3D(froxel_tex_size[0], froxel_tex_size[1], froxel_tex_size[2], DRW_TEX_RGB_11_11_10, DRW_TEX_FILTER, NULL);
197                         txl->volume_prop_phase = DRW_texture_create_3D(froxel_tex_size[0], froxel_tex_size[1], froxel_tex_size[2], DRW_TEX_RG_16, DRW_TEX_FILTER, NULL);
198
199                         /* Volume scattering: We compute for each froxel the
200                          * Scattered light towards the view. We also resolve temporal
201                          * super sampling during this stage. */
202                         txl->volume_scatter = DRW_texture_create_3D(froxel_tex_size[0], froxel_tex_size[1], froxel_tex_size[2], DRW_TEX_RGB_11_11_10, DRW_TEX_FILTER, NULL);
203                         txl->volume_transmittance = DRW_texture_create_3D(froxel_tex_size[0], froxel_tex_size[1], froxel_tex_size[2], DRW_TEX_RGB_11_11_10, DRW_TEX_FILTER, NULL);
204
205                         /* Final integration: We compute for each froxel the
206                          * amount of scattered light and extinction coef at this
207                          * given depth. We use theses textures as double buffer
208                          * for the volumetric history. */
209                         txl->volume_scatter_history = DRW_texture_create_3D(froxel_tex_size[0], froxel_tex_size[1], froxel_tex_size[2], DRW_TEX_RGB_11_11_10, DRW_TEX_FILTER, NULL);
210                         txl->volume_transmittance_history = DRW_texture_create_3D(froxel_tex_size[0], froxel_tex_size[1], froxel_tex_size[2], DRW_TEX_RGB_11_11_10, DRW_TEX_FILTER, NULL);
211                 }
212
213                 /* Temporal Super sampling jitter */
214                 double ht_point[3];
215                 double ht_offset[3] = {0.0, 0.0};
216                 unsigned int ht_primes[3] = {3, 7, 2};
217                 unsigned int current_sample = 0;
218
219                 /* If TAA is in use do not use the history buffer. */
220                 bool do_taa = ((effects->enabled_effects & EFFECT_TAA) != 0);
221
222                 if (draw_ctx->evil_C != NULL) {
223                         struct wmWindowManager *wm = CTX_wm_manager(draw_ctx->evil_C);
224                         do_taa = do_taa && (ED_screen_animation_no_scrub(wm) == NULL);
225                 }
226
227                 if (do_taa) {
228                         volumetrics->history_alpha = 0.0f;
229                         current_sample = effects->taa_current_sample - 1;
230                         effects->volume_current_sample = -1;
231                 }
232                 else {
233                         const unsigned int max_sample = (ht_primes[0] * ht_primes[1] * ht_primes[2]);
234                         current_sample = effects->volume_current_sample = (effects->volume_current_sample + 1) % max_sample;
235                         if (current_sample != max_sample - 1) {
236                                 DRW_viewport_request_redraw();
237                         }
238                 }
239                 BLI_halton_3D(ht_primes, ht_offset, current_sample, ht_point);
240
241                 volumetrics->jitter[0] = (float)ht_point[0];
242                 volumetrics->jitter[1] = (float)ht_point[1];
243                 volumetrics->jitter[2] = (float)ht_point[2];
244
245                 /* Framebuffer setup */
246                 DRWFboTexture tex_vol[4] = {{&txl->volume_prop_scattering, DRW_TEX_RGB_11_11_10, DRW_TEX_FILTER},
247                                             {&txl->volume_prop_extinction, DRW_TEX_RGB_11_11_10, DRW_TEX_FILTER},
248                                             {&txl->volume_prop_emission, DRW_TEX_RGB_11_11_10, DRW_TEX_FILTER},
249                                             {&txl->volume_prop_phase, DRW_TEX_RG_16, DRW_TEX_FILTER}};
250
251                 DRW_framebuffer_init(&fbl->volumetric_fb, &draw_engine_eevee_type,
252                                      (int)froxel_tex_size[0], (int)froxel_tex_size[1],
253                                      tex_vol, 4);
254
255                 DRWFboTexture tex_vol_scat[2] = {{&txl->volume_scatter, DRW_TEX_RGB_11_11_10, DRW_TEX_FILTER},
256                                                  {&txl->volume_transmittance, DRW_TEX_RGB_11_11_10, DRW_TEX_FILTER}};
257
258                 DRW_framebuffer_init(&fbl->volumetric_scat_fb, &draw_engine_eevee_type,
259                                      (int)froxel_tex_size[0], (int)froxel_tex_size[1],
260                                      tex_vol_scat, 2);
261
262                 DRWFboTexture tex_vol_integ[2] = {{&txl->volume_scatter_history, DRW_TEX_RGB_11_11_10, DRW_TEX_FILTER},
263                                                   {&txl->volume_transmittance_history, DRW_TEX_RGB_11_11_10, DRW_TEX_FILTER}};
264
265                 DRW_framebuffer_init(&fbl->volumetric_integ_fb, &draw_engine_eevee_type,
266                                      (int)froxel_tex_size[0], (int)froxel_tex_size[1],
267                                      tex_vol_integ, 2);
268
269                 volumetrics->integration_start = BKE_collection_engine_property_value_get_float(props, "volumetric_start");
270                 volumetrics->integration_end = BKE_collection_engine_property_value_get_float(props, "volumetric_end");
271                 volumetrics->sample_distribution = 4.0f * (1.00001f - BKE_collection_engine_property_value_get_float(props, "volumetric_sample_distribution"));
272                 volumetrics->use_volume_shadows = BKE_collection_engine_property_value_get_bool(props, "volumetric_shadows");
273                 volumetrics->light_clamp = BKE_collection_engine_property_value_get_float(props, "volumetric_light_clamp");
274
275                 if (volumetrics->use_volume_shadows) {
276                         volumetrics->shadow_step_count = (float)BKE_collection_engine_property_value_get_int(props, "volumetric_shadow_samples");
277                 }
278                 else {
279                         volumetrics->shadow_step_count = 0;
280                 }
281
282                 if (DRW_viewport_is_persp_get()) {
283                         const float clip_start = stl->g_data->viewvecs[0][2];
284                         /* Negate */
285                         float near = volumetrics->integration_start = min_ff(-volumetrics->integration_start, clip_start - 1e-4f);
286                         float far = volumetrics->integration_end = min_ff(-volumetrics->integration_end, near - 1e-4f);
287
288                         volumetrics->depth_param[0] = (far - near * exp2(1.0f / volumetrics->sample_distribution)) / (far - near);
289                         volumetrics->depth_param[1] = (1.0f - volumetrics->depth_param[0]) / near;
290                         volumetrics->depth_param[2] = volumetrics->sample_distribution;
291                 }
292                 else {
293                         const float clip_start = stl->g_data->viewvecs[0][2];
294                         const float clip_end = stl->g_data->viewvecs[1][2];
295                         volumetrics->integration_start = min_ff(volumetrics->integration_end, clip_start);
296                         volumetrics->integration_end = max_ff(-volumetrics->integration_end, clip_end);
297
298                         volumetrics->depth_param[0] = volumetrics->integration_start;
299                         volumetrics->depth_param[1] = volumetrics->integration_end;
300                         volumetrics->depth_param[2] = 1.0f / (volumetrics->integration_end - volumetrics->integration_start);
301                 }
302
303                 /* Disable clamp if equal to 0. */
304                 if (volumetrics->light_clamp == 0.0) {
305                         volumetrics->light_clamp = FLT_MAX;
306                 }
307
308                 volumetrics->use_lights = BKE_collection_engine_property_value_get_bool(props, "volumetric_lights");
309
310                 return EFFECT_VOLUMETRIC | EFFECT_POST_BUFFER;
311         }
312
313         /* Cleanup to release memory */
314         DRW_TEXTURE_FREE_SAFE(txl->volume_prop_scattering);
315         DRW_TEXTURE_FREE_SAFE(txl->volume_prop_extinction);
316         DRW_TEXTURE_FREE_SAFE(txl->volume_prop_emission);
317         DRW_TEXTURE_FREE_SAFE(txl->volume_prop_phase);
318         DRW_TEXTURE_FREE_SAFE(txl->volume_scatter);
319         DRW_TEXTURE_FREE_SAFE(txl->volume_transmittance);
320         DRW_TEXTURE_FREE_SAFE(txl->volume_scatter_history);
321         DRW_TEXTURE_FREE_SAFE(txl->volume_transmittance_history);
322         DRW_FRAMEBUFFER_FREE_SAFE(fbl->volumetric_fb);
323         DRW_FRAMEBUFFER_FREE_SAFE(fbl->volumetric_scat_fb);
324         DRW_FRAMEBUFFER_FREE_SAFE(fbl->volumetric_integ_fb);
325
326         return 0;
327 }
328
329 void EEVEE_volumes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
330 {
331         EEVEE_PassList *psl = vedata->psl;
332         EEVEE_StorageList *stl = vedata->stl;
333         EEVEE_TextureList *txl = vedata->txl;
334         EEVEE_EffectsInfo *effects = stl->effects;
335
336         if ((effects->enabled_effects & EFFECT_VOLUMETRIC) != 0) {
337                 const DRWContextState *draw_ctx = DRW_context_state_get();
338                 Scene *scene = draw_ctx->scene;
339                 EEVEE_VolumetricsInfo *volumetrics = sldata->volumetrics;
340                 static int zero = 0;
341                 DRWShadingGroup *grp;
342
343                 /* Quick breakdown of the Volumetric rendering:
344                  *
345                  * The rendering is separated in 4 stages:
346                  *
347                  * - Material Parameters : we collect volume properties of
348                  *   all participating media in the scene and store them in
349                  *   a 3D texture aligned with the 3D frustum.
350                  *   This is done in 2 passes, one that clear the texture
351                  *   and/or evaluate the world volumes, and the 2nd one that
352                  *   additively render object volumes.
353                  *
354                  * - Light Scattering : the volume properties then are sampled
355                  *   and light scattering is evaluated for each cell of the
356                  *   volume texture. Temporal supersampling (if enabled) occurs here.
357                  *
358                  * - Volume Integration : the scattered light and extinction is
359                  *   integrated (accumulated) along the viewrays. The result is stored
360                  *   for every cell in another texture.
361                  *
362                  * - Fullscreen Resolve : From the previous stage, we get two
363                  *   3D textures that contains integrated scatered light and extinction
364                  *   for "every" positions in the frustum. We only need to sample
365                  *   them and blend the scene color with thoses factors. This also
366                  *   work for alpha blended materials.
367                  **/
368
369                 /* World pass is not additive as it also clear the buffer. */
370                 psl->volumetric_world_ps = DRW_pass_create("Volumetric World", DRW_STATE_WRITE_COLOR);
371
372                 /* World Volumetric */
373                 struct World *wo = scene->world;
374                 if (wo != NULL && wo->use_nodes && wo->nodetree) {
375                         struct GPUMaterial *mat = EEVEE_material_world_volume_get(scene, wo);
376
377                         grp = DRW_shgroup_material_empty_tri_batch_create(mat, psl->volumetric_world_ps, volumetrics->froxel_tex_size[2]);
378
379                         if (grp) {
380                                 DRW_shgroup_uniform_vec4(grp, "viewvecs[0]", (float *)stl->g_data->viewvecs, 2);
381                                 DRW_shgroup_uniform_ivec3(grp, "volumeTextureSize", (int *)volumetrics->froxel_tex_size, 1);
382                                 DRW_shgroup_uniform_vec2(grp, "volume_uv_ratio", (float *)volumetrics->volume_coord_scale, 1);
383                                 DRW_shgroup_uniform_vec3(grp, "volume_param", (float *)volumetrics->depth_param, 1);
384                                 DRW_shgroup_uniform_vec3(grp, "volume_jitter", (float *)volumetrics->jitter, 1);
385                         }
386                 }
387                 else {
388                         /* If no world or volume material is present just clear the buffer with this drawcall */
389                         grp = DRW_shgroup_empty_tri_batch_create(e_data.volumetric_clear_sh, psl->volumetric_world_ps, volumetrics->froxel_tex_size[2]);
390
391                         DRW_shgroup_uniform_ivec3(grp, "volumeTextureSize", (int *)volumetrics->froxel_tex_size, 1);
392                 }
393
394                 /* Volumetric Objects */
395                 psl->volumetric_objects_ps = DRW_pass_create("Volumetric Properties", DRW_STATE_WRITE_COLOR | DRW_STATE_ADDITIVE);
396
397                 psl->volumetric_scatter_ps = DRW_pass_create("Volumetric Scattering", DRW_STATE_WRITE_COLOR);
398                 grp = DRW_shgroup_empty_tri_batch_create(e_data.volumetric_scatter_sh, psl->volumetric_scatter_ps, volumetrics->froxel_tex_size[2]);
399                 DRW_shgroup_uniform_vec4(grp, "viewvecs[0]", (float *)stl->g_data->viewvecs, 2);
400                 DRW_shgroup_uniform_vec2(grp, "volume_uv_ratio", (float *)volumetrics->volume_coord_scale, 1);
401                 DRW_shgroup_uniform_vec3(grp, "volume_param", (float *)volumetrics->depth_param, 1);
402                 DRW_shgroup_uniform_vec3(grp, "volume_jitter", (float *)volumetrics->jitter, 1);
403                 DRW_shgroup_uniform_mat4(grp, "PastViewProjectionMatrix", (float *)stl->g_data->prev_persmat);
404                 DRW_shgroup_uniform_block(grp, "light_block", sldata->light_ubo);
405                 DRW_shgroup_uniform_block(grp, "shadow_block", sldata->shadow_ubo);
406                 DRW_shgroup_uniform_int(grp, "light_count", (volumetrics->use_lights) ? &sldata->lamps->num_light : &zero, 1);
407                 DRW_shgroup_uniform_buffer(grp, "irradianceGrid", &sldata->irradiance_pool);
408                 DRW_shgroup_uniform_buffer(grp, "shadowTexture", &sldata->shadow_pool);
409                 DRW_shgroup_uniform_float(grp, "volume_light_clamp", &volumetrics->light_clamp, 1);
410                 DRW_shgroup_uniform_float(grp, "volume_shadows_steps", &volumetrics->shadow_step_count, 1);
411                 DRW_shgroup_uniform_float(grp, "volume_history_alpha", &volumetrics->history_alpha, 1);
412                 DRW_shgroup_uniform_buffer(grp, "volumeScattering", &txl->volume_prop_scattering);
413                 DRW_shgroup_uniform_buffer(grp, "volumeExtinction", &txl->volume_prop_extinction);
414                 DRW_shgroup_uniform_buffer(grp, "volumeEmission", &txl->volume_prop_emission);
415                 DRW_shgroup_uniform_buffer(grp, "volumePhase", &txl->volume_prop_phase);
416                 DRW_shgroup_uniform_buffer(grp, "historyScattering", &txl->volume_scatter_history);
417                 DRW_shgroup_uniform_buffer(grp, "historyTransmittance", &txl->volume_transmittance_history);
418
419                 psl->volumetric_integration_ps = DRW_pass_create("Volumetric Integration", DRW_STATE_WRITE_COLOR);
420                 grp = DRW_shgroup_empty_tri_batch_create(e_data.volumetric_integration_sh, psl->volumetric_integration_ps, volumetrics->froxel_tex_size[2]);
421                 DRW_shgroup_uniform_vec4(grp, "viewvecs[0]", (float *)stl->g_data->viewvecs, 2);
422                 DRW_shgroup_uniform_vec2(grp, "volume_uv_ratio", (float *)volumetrics->volume_coord_scale, 1);
423                 DRW_shgroup_uniform_vec3(grp, "volume_param", (float *)volumetrics->depth_param, 1);
424                 DRW_shgroup_uniform_buffer(grp, "volumeScattering", &txl->volume_scatter);
425                 DRW_shgroup_uniform_buffer(grp, "volumeExtinction", &txl->volume_transmittance);
426
427                 psl->volumetric_resolve_ps = DRW_pass_create("Volumetric Resolve", DRW_STATE_WRITE_COLOR);
428                 grp = DRW_shgroup_create(e_data.volumetric_resolve_sh, psl->volumetric_resolve_ps);
429                 DRW_shgroup_uniform_vec4(grp, "viewvecs[0]", (float *)stl->g_data->viewvecs, 2);
430                 DRW_shgroup_uniform_vec2(grp, "volume_uv_ratio", (float *)volumetrics->volume_coord_scale, 1);
431                 DRW_shgroup_uniform_vec3(grp, "volume_param", (float *)volumetrics->depth_param, 1);
432                 DRW_shgroup_uniform_buffer(grp, "inScattering", &txl->volume_scatter);
433                 DRW_shgroup_uniform_buffer(grp, "inTransmittance", &txl->volume_transmittance);
434                 DRW_shgroup_uniform_buffer(grp, "inSceneColor", &e_data.color_src);
435                 DRW_shgroup_uniform_buffer(grp, "inSceneDepth", &e_data.depth_src);
436                 DRW_shgroup_call_add(grp, DRW_cache_fullscreen_quad_get(), NULL);
437         }
438 }
439
440 void EEVEE_volumes_cache_object_add(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, Scene *scene, Object *ob)
441 {
442         float *texcoloc = NULL;
443         float *texcosize = NULL;
444         struct ModifierData *md = NULL;
445         EEVEE_VolumetricsInfo *volumetrics = sldata->volumetrics;
446         Material *ma = give_current_material(ob, 1);
447
448         if (ma == NULL) {
449                 return;
450         }
451
452         struct GPUMaterial *mat = EEVEE_material_mesh_volume_get(scene, ma);
453
454         DRWShadingGroup *grp = DRW_shgroup_material_empty_tri_batch_create(mat, vedata->psl->volumetric_objects_ps, volumetrics->froxel_tex_size[2]);
455
456         /* Making sure it's updated. */
457         invert_m4_m4(ob->imat, ob->obmat);
458
459         BKE_mesh_texspace_get_reference((struct Mesh *)ob->data, NULL, &texcoloc, NULL, &texcosize);
460
461         if (grp) {
462                 DRW_shgroup_uniform_mat4(grp, "volumeObjectMatrix", (float *)ob->imat);
463                 DRW_shgroup_uniform_vec3(grp, "volumeOrcoLoc", texcoloc, 1);
464                 DRW_shgroup_uniform_vec3(grp, "volumeOrcoSize", texcosize, 1);
465                 DRW_shgroup_uniform_vec4(grp, "viewvecs[0]", (float *)vedata->stl->g_data->viewvecs, 2);
466                 DRW_shgroup_uniform_ivec3(grp, "volumeTextureSize", (int *)volumetrics->froxel_tex_size, 1);
467                 DRW_shgroup_uniform_vec2(grp, "volume_uv_ratio", (float *)volumetrics->volume_coord_scale, 1);
468                 DRW_shgroup_uniform_vec3(grp, "volume_param", (float *)volumetrics->depth_param, 1);
469                 DRW_shgroup_uniform_vec3(grp, "volume_jitter", (float *)volumetrics->jitter, 1);
470         }
471
472         /* Smoke Simulation */
473         if (((ob->base_flag & BASE_FROMDUPLI) == 0) &&
474             (md = modifiers_findByType(ob, eModifierType_Smoke)) &&
475             (modifier_isEnabled(scene, md, eModifierMode_Realtime)))
476         {
477                 SmokeModifierData *smd = (SmokeModifierData *)md;
478                 SmokeDomainSettings *sds = smd->domain;
479                 /* Don't show smoke before simulation starts, this could be made an option in the future. */
480                 const bool show_smoke = (CFRA >= sds->point_cache[0]->startframe);
481
482                 if (sds->fluid && show_smoke) {
483                         if (!sds->wt || !(sds->viewsettings & MOD_SMOKE_VIEW_SHOWBIG)) {
484                                 GPU_create_smoke(smd, 0);
485                         }
486                         else if (sds->wt && (sds->viewsettings & MOD_SMOKE_VIEW_SHOWBIG)) {
487                                 GPU_create_smoke(smd, 1);
488                         }
489                         BLI_addtail(&e_data.smoke_domains, BLI_genericNodeN(smd));
490                 }
491
492                 if (sds->tex != NULL) {
493                         DRW_shgroup_uniform_buffer(grp, "sampdensity", &sds->tex);
494                 }
495                 if (sds->tex_flame != NULL) {
496                         DRW_shgroup_uniform_buffer(grp, "sampflame", &sds->tex_flame);
497                 }
498         }
499 }
500
501 void EEVEE_volumes_compute(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
502 {
503         EEVEE_PassList *psl = vedata->psl;
504         EEVEE_TextureList *txl = vedata->txl;
505         EEVEE_FramebufferList *fbl = vedata->fbl;
506         EEVEE_StorageList *stl = vedata->stl;
507         EEVEE_EffectsInfo *effects = stl->effects;
508         if ((effects->enabled_effects & EFFECT_VOLUMETRIC) != 0) {
509                 DRW_stats_group_start("Volumetrics");
510
511                 /* Step 1: Participating Media Properties */
512                 DRW_framebuffer_bind(fbl->volumetric_fb);
513                 DRW_draw_pass(psl->volumetric_world_ps);
514                 DRW_draw_pass(psl->volumetric_objects_ps);
515
516                 /* Step 2: Scatter Light */
517                 DRW_framebuffer_bind(fbl->volumetric_scat_fb);
518                 DRW_draw_pass(psl->volumetric_scatter_ps);
519
520                 /* Step 3: Integration */
521                 DRW_framebuffer_bind(fbl->volumetric_integ_fb);
522                 DRW_draw_pass(psl->volumetric_integration_ps);
523
524                 /* Swap volume history buffers */
525                 SWAP(struct GPUFrameBuffer *, fbl->volumetric_scat_fb, fbl->volumetric_integ_fb);
526                 SWAP(GPUTexture *, txl->volume_scatter, txl->volume_scatter_history);
527                 SWAP(GPUTexture *, txl->volume_transmittance, txl->volume_transmittance_history);
528
529                 /* Restore */
530                 DRW_framebuffer_bind(fbl->main);
531
532                 DRW_stats_group_end();
533         }
534 }
535
536 void EEVEE_volumes_resolve(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
537 {
538         EEVEE_PassList *psl = vedata->psl;
539         EEVEE_TextureList *txl = vedata->txl;
540         EEVEE_FramebufferList *fbl = vedata->fbl;
541         EEVEE_StorageList *stl = vedata->stl;
542         EEVEE_EffectsInfo *effects = stl->effects;
543
544         if ((effects->enabled_effects & EFFECT_VOLUMETRIC) != 0) {
545                 DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
546
547                 e_data.color_src = txl->color;
548                 e_data.depth_src = dtxl->depth;
549
550                 /* Step 4: Apply for opaque */
551                 DRW_framebuffer_bind(fbl->effect_fb);
552                 DRW_draw_pass(psl->volumetric_resolve_ps);
553
554                 /* Swap the buffers and rebind depth to the current buffer */
555                 DRW_framebuffer_texture_detach(dtxl->depth);
556                 SWAP(struct GPUFrameBuffer *, fbl->main, fbl->effect_fb);
557                 SWAP(GPUTexture *, txl->color, txl->color_post);
558                 DRW_framebuffer_texture_attach(fbl->main, dtxl->depth, 0, 0);
559         }
560 }
561
562 void EEVEE_volumes_free_smoke_textures(void)
563 {
564         /* Free Smoke Textures after rendering */
565         for (LinkData *link = e_data.smoke_domains.first; link; link = link->next) {
566                 SmokeModifierData *smd = (SmokeModifierData *)link->data;
567                 GPU_free_smoke(smd);
568         }
569         BLI_freelistN(&e_data.smoke_domains);
570 }
571
572 void EEVEE_volumes_free(void)
573 {
574         MEM_SAFE_FREE(e_data.volumetric_common_lib);
575         MEM_SAFE_FREE(e_data.volumetric_common_lamps_lib);
576
577         DRW_SHADER_FREE_SAFE(e_data.volumetric_clear_sh);
578         DRW_SHADER_FREE_SAFE(e_data.volumetric_scatter_sh);
579         DRW_SHADER_FREE_SAFE(e_data.volumetric_integration_sh);
580         DRW_SHADER_FREE_SAFE(e_data.volumetric_resolve_sh);
581 }