Blender  V2.93
eevee_volumes.c
Go to the documentation of this file.
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 
25 #include "DRW_render.h"
26 
27 #include "BLI_listbase.h"
28 #include "BLI_rand.h"
29 #include "BLI_string_utils.h"
30 
31 #include "DNA_fluid_types.h"
32 #include "DNA_object_force_types.h"
33 #include "DNA_volume_types.h"
34 #include "DNA_world_types.h"
35 
36 #include "BKE_fluid.h"
37 #include "BKE_global.h"
38 #include "BKE_mesh.h"
39 #include "BKE_modifier.h"
40 #include "BKE_volume.h"
41 #include "BKE_volume_render.h"
42 
43 #include "ED_screen.h"
44 
45 #include "DEG_depsgraph_query.h"
46 
47 #include "GPU_capabilities.h"
48 #include "GPU_material.h"
49 #include "GPU_texture.h"
50 #include "eevee_private.h"
51 
52 static struct {
54 
58 
61 
62  /* List of all fluid simulation / smoke domains rendered within this frame. */
64 } e_data = {NULL}; /* Engine data */
65 
67 {
68  const float zero[4] = {0.0f, 0.0f, 0.0f, 0.0f};
69  e_data.dummy_zero = DRW_texture_create_3d(1, 1, 1, GPU_RGBA8, DRW_TEX_WRAP, zero);
70 
71  const float one[4] = {1.0f, 1.0f, 1.0f, 1.0f};
72  e_data.dummy_one = DRW_texture_create_3d(1, 1, 1, GPU_RGBA8, DRW_TEX_WRAP, one);
73 
74  const float flame = 0.0f;
75  e_data.dummy_flame = DRW_texture_create_3d(1, 1, 1, GPU_R8, DRW_TEX_WRAP, &flame);
76 }
77 
79 {
80  switch (default_value) {
82  return e_data.dummy_zero;
84  return e_data.dummy_one;
85  }
86 
87  return e_data.dummy_zero;
88 }
89 
90 void EEVEE_volumes_set_jitter(EEVEE_ViewLayerData *sldata, uint current_sample)
91 {
92  EEVEE_CommonUniformBuffer *common_data = &sldata->common_data;
93 
94  double ht_point[3];
95  double ht_offset[3] = {0.0, 0.0};
96  const uint ht_primes[3] = {3, 7, 2};
97 
98  BLI_halton_3d(ht_primes, ht_offset, current_sample, ht_point);
99 
100  common_data->vol_jitter[0] = (float)ht_point[0];
101  common_data->vol_jitter[1] = (float)ht_point[1];
102  common_data->vol_jitter[2] = (float)ht_point[2];
103 }
104 
106 {
107  EEVEE_StorageList *stl = vedata->stl;
108  EEVEE_FramebufferList *fbl = vedata->fbl;
109  EEVEE_TextureList *txl = vedata->txl;
110  EEVEE_EffectsInfo *effects = stl->effects;
111  EEVEE_CommonUniformBuffer *common_data = &sldata->common_data;
112 
113  const DRWContextState *draw_ctx = DRW_context_state_get();
114  const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph);
115 
116  const float *viewport_size = DRW_viewport_size_get();
117 
118  const int tile_size = scene_eval->eevee.volumetric_tile_size;
119 
120  /* Find Froxel Texture resolution. */
121  int tex_size[3];
122 
123  tex_size[0] = (int)ceilf(fmaxf(1.0f, viewport_size[0] / (float)tile_size));
124  tex_size[1] = (int)ceilf(fmaxf(1.0f, viewport_size[1] / (float)tile_size));
125  tex_size[2] = max_ii(scene_eval->eevee.volumetric_samples, 1);
126 
127  common_data->vol_coord_scale[0] = viewport_size[0] / (float)(tile_size * tex_size[0]);
128  common_data->vol_coord_scale[1] = viewport_size[1] / (float)(tile_size * tex_size[1]);
129  common_data->vol_coord_scale[2] = 1.0f / viewport_size[0];
130  common_data->vol_coord_scale[3] = 1.0f / viewport_size[1];
131 
132  /* TODO compute snap to maxZBuffer for clustered rendering */
133  if ((common_data->vol_tex_size[0] != tex_size[0]) ||
134  (common_data->vol_tex_size[1] != tex_size[1]) ||
135  (common_data->vol_tex_size[2] != tex_size[2])) {
147  copy_v3_v3_int(common_data->vol_tex_size, tex_size);
148 
149  common_data->vol_inv_tex_size[0] = 1.0f / (float)(tex_size[0]);
150  common_data->vol_inv_tex_size[1] = 1.0f / (float)(tex_size[1]);
151  common_data->vol_inv_tex_size[2] = 1.0f / (float)(tex_size[2]);
152  }
153 
154  /* Like frostbite's paper, 5% blend of the new frame. */
155  common_data->vol_history_alpha = (txl->volume_prop_scattering == NULL) ? 0.0f : 0.95f;
156 
157  /* Temporal Super sampling jitter */
158  uint ht_primes[3] = {3, 7, 2};
159  uint current_sample = 0;
160 
161  /* If TAA is in use do not use the history buffer. */
162  bool do_taa = ((effects->enabled_effects & EFFECT_TAA) != 0);
163 
164  if (draw_ctx->evil_C != NULL) {
165  struct wmWindowManager *wm = CTX_wm_manager(draw_ctx->evil_C);
166  do_taa = do_taa && (ED_screen_animation_no_scrub(wm) == NULL);
167  }
168 
169  if (do_taa) {
170  common_data->vol_history_alpha = 0.0f;
171  current_sample = effects->taa_current_sample - 1;
172  effects->volume_current_sample = -1;
173  }
174  else if (DRW_state_is_image_render()) {
175  const uint max_sample = (ht_primes[0] * ht_primes[1] * ht_primes[2]);
176  current_sample = effects->volume_current_sample = (effects->volume_current_sample + 1) %
177  max_sample;
178  if (current_sample != max_sample - 1) {
180  }
181  }
182 
183  EEVEE_volumes_set_jitter(sldata, current_sample);
184 
185  float integration_start = scene_eval->eevee.volumetric_start;
186  float integration_end = scene_eval->eevee.volumetric_end;
187  effects->volume_light_clamp = scene_eval->eevee.volumetric_light_clamp;
188  common_data->vol_shadow_steps = (float)scene_eval->eevee.volumetric_shadow_samples;
189  if ((scene_eval->eevee.flag & SCE_EEVEE_VOLUMETRIC_SHADOWS) == 0) {
190  common_data->vol_shadow_steps = 0;
191  }
192 
194  float sample_distribution = scene_eval->eevee.volumetric_sample_distribution;
195  sample_distribution = 4.0f * (max_ff(1.0f - sample_distribution, 1e-2f));
196 
197  const float clip_start = DRW_view_near_distance_get(NULL);
198  /* Negate */
199  float near = integration_start = min_ff(-integration_start, clip_start - 1e-4f);
200  float far = integration_end = min_ff(-integration_end, near - 1e-4f);
201 
202  common_data->vol_depth_param[0] = (far - near * exp2(1.0f / sample_distribution)) /
203  (far - near);
204  common_data->vol_depth_param[1] = (1.0f - common_data->vol_depth_param[0]) / near;
205  common_data->vol_depth_param[2] = sample_distribution;
206  }
207  else {
208  const float clip_start = DRW_view_near_distance_get(NULL);
209  const float clip_end = DRW_view_far_distance_get(NULL);
210  integration_start = min_ff(integration_end, clip_start);
211  integration_end = max_ff(-integration_end, clip_end);
212 
213  common_data->vol_depth_param[0] = integration_start;
214  common_data->vol_depth_param[1] = integration_end;
215  common_data->vol_depth_param[2] = 1.0f / (integration_end - integration_start);
216  }
217 
218  /* Disable clamp if equal to 0. */
219  if (effects->volume_light_clamp == 0.0) {
220  effects->volume_light_clamp = FLT_MAX;
221  }
222 
223  common_data->vol_use_lights = (scene_eval->eevee.flag & SCE_EEVEE_VOLUMETRIC_LIGHTS) != 0;
224  common_data->vol_use_soft_shadows = (scene_eval->eevee.flag & SCE_EEVEE_SHADOW_SOFT) != 0;
225 
226  if (!e_data.dummy_scatter) {
227  const float scatter[4] = {0.0f, 0.0f, 0.0f, 0.0f};
228  const float transmit[4] = {1.0f, 1.0f, 1.0f, 1.0f};
229  e_data.dummy_scatter = DRW_texture_create_3d(1, 1, 1, GPU_RGBA8, DRW_TEX_WRAP, scatter);
230  e_data.dummy_transmit = DRW_texture_create_3d(1, 1, 1, GPU_RGBA8, DRW_TEX_WRAP, transmit);
231  }
232 }
233 
235 {
236  EEVEE_PassList *psl = vedata->psl;
237  EEVEE_StorageList *stl = vedata->stl;
238  EEVEE_EffectsInfo *effects = stl->effects;
239  EEVEE_CommonUniformBuffer *common_data = &sldata->common_data;
240 
241  const DRWContextState *draw_ctx = DRW_context_state_get();
242  Scene *scene = draw_ctx->scene;
243  DRWShadingGroup *grp = NULL;
244 
245  /* Textures */
246  if (!e_data.dummy_zero) {
248  }
249 
250  /* Quick breakdown of the Volumetric rendering:
251  *
252  * The rendering is separated in 4 stages:
253  *
254  * - Material Parameters : we collect volume properties of
255  * all participating media in the scene and store them in
256  * a 3D texture aligned with the 3D frustum.
257  * This is done in 2 passes, one that clear the texture
258  * and/or evaluate the world volumes, and the 2nd one that
259  * additively render object volumes.
260  *
261  * - Light Scattering : the volume properties then are sampled
262  * and light scattering is evaluated for each cell of the
263  * volume texture. Temporal super-sampling (if enabled) occurs here.
264  *
265  * - Volume Integration : the scattered light and extinction is
266  * integrated (accumulated) along the view-rays. The result is stored
267  * for every cell in another texture.
268  *
269  * - Full-screen Resolve : From the previous stage, we get two
270  * 3D textures that contains integrated scattered light and extinction
271  * for "every" positions in the frustum. We only need to sample
272  * them and blend the scene color with those factors. This also
273  * work for alpha blended materials.
274  */
275 
276  /* World pass is not additive as it also clear the buffer. */
279 
280  /* World Volumetric */
281  struct World *wo = scene->world;
282  if (wo != NULL && wo->use_nodes && wo->nodetree &&
283  !LOOK_DEV_STUDIO_LIGHT_ENABLED(draw_ctx->v3d)) {
284  struct GPUMaterial *mat = EEVEE_material_get(vedata, scene, NULL, wo, VAR_MAT_VOLUME);
285 
288  }
289 
290  if (grp) {
291  DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
292  /* TODO(fclem): remove those (need to clean the GLSL files). */
293  DRW_shgroup_uniform_block(grp, "grid_block", sldata->grid_ubo);
294  DRW_shgroup_uniform_block(grp, "probe_block", sldata->probe_ubo);
295  DRW_shgroup_uniform_block(grp, "planar_block", sldata->planar_ubo);
296  DRW_shgroup_uniform_block(grp, "light_block", sldata->light_ubo);
297  DRW_shgroup_uniform_block(grp, "shadow_block", sldata->shadow_ubo);
298  DRW_shgroup_uniform_block(grp, "renderpass_block", sldata->renderpass_ubo.combined);
299 
300  /* Fix principle volumetric not working with world materials. */
301  ListBase gpu_grids = GPU_material_volume_grids(mat);
302  LISTBASE_FOREACH (GPUMaterialVolumeGrid *, gpu_grid, &gpu_grids) {
304  grp, gpu_grid->sampler_name, eevee_volume_default_texture(gpu_grid->default_value));
305  }
306 
308 
310  }
311  }
312 
313  if (grp == NULL) {
314  /* If no world or volume material is present just clear the buffer with this drawcall */
316  DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
317  DRW_shgroup_uniform_block(grp, "probe_block", sldata->probe_ubo);
318  DRW_shgroup_uniform_block(grp, "light_block", sldata->light_ubo);
319  DRW_shgroup_uniform_block(grp, "renderpass_block", sldata->renderpass_ubo.combined);
320 
322  }
323 }
324 
326 {
327  Volume *volume = ob->data;
328  BKE_volume_load(volume, G.main);
329 
330  /* Test if we need to use multiple transforms. */
331  DRWVolumeGrid *first_drw_grid = NULL;
332  bool multiple_transforms = true;
333 
334  LISTBASE_FOREACH (GPUMaterialVolumeGrid *, gpu_grid, gpu_grids) {
335  const VolumeGrid *volume_grid = BKE_volume_grid_find_for_read(volume, gpu_grid->name);
336  DRWVolumeGrid *drw_grid = (volume_grid) ?
337  DRW_volume_batch_cache_get_grid(volume, volume_grid) :
338  NULL;
339 
340  if (drw_grid) {
341  if (first_drw_grid == NULL) {
342  first_drw_grid = drw_grid;
343  }
344  else if (drw_grid &&
345  !equals_m4m4(drw_grid->object_to_texture, first_drw_grid->object_to_texture)) {
346  multiple_transforms = true;
347  break;
348  }
349  }
350  }
351 
352  /* Bail out of no grids to render. */
353  if (first_drw_grid == NULL) {
354  return false;
355  }
356 
357  /* Set transform matrix for the volume as a whole. This one is also used for
358  * clipping so must map the entire bounding box to 0..1. */
359  float bounds_to_object[4][4];
360 
361  if (multiple_transforms) {
362  /* For multiple grids with different transform, we first transform from object space
363  * to bounds, then for each individual grid from bounds to texture. */
365  float bb_size[3];
366  sub_v3_v3v3(bb_size, bb->vec[6], bb->vec[0]);
367  size_to_mat4(bounds_to_object, bb_size);
368  copy_v3_v3(bounds_to_object[3], bb->vec[0]);
369 
370  invert_m4_m4(first_drw_grid->object_to_bounds, bounds_to_object);
371  DRW_shgroup_uniform_mat4(grp, "volumeObjectToTexture", first_drw_grid->object_to_bounds);
372  }
373  else {
374  /* All grid transforms are equal, we can transform to texture space immediately. */
375  DRW_shgroup_uniform_mat4(grp, "volumeObjectToTexture", first_drw_grid->object_to_texture);
376  }
377 
378  /* Don't use orco transform here, only matrix. */
379  DRW_shgroup_uniform_vec3_copy(grp, "volumeOrcoLoc", (float[3]){0.5f, 0.5f, 0.5f});
380  DRW_shgroup_uniform_vec3_copy(grp, "volumeOrcoSize", (float[3]){0.5f, 0.5f, 0.5f});
381 
382  /* Set density scale. */
383  const float density_scale = BKE_volume_density_scale(volume, ob->obmat);
384  DRW_shgroup_uniform_float_copy(grp, "volumeDensityScale", density_scale);
385 
386  /* Bind volume grid textures. */
387  LISTBASE_FOREACH (GPUMaterialVolumeGrid *, gpu_grid, gpu_grids) {
388  const VolumeGrid *volume_grid = BKE_volume_grid_find_for_read(volume, gpu_grid->name);
389  DRWVolumeGrid *drw_grid = (volume_grid) ?
390  DRW_volume_batch_cache_get_grid(volume, volume_grid) :
391  NULL;
392 
393  /* Handle 3 cases here:
394  * - Grid exists and texture was loaded -> use texture.
395  * - Grid exists but has zero size or failed to load -> use zero.
396  * - Grid does not exist -> use default value. */
397  GPUTexture *grid_tex = (drw_grid) ? drw_grid->texture :
398  (volume_grid) ?
399  e_data.dummy_zero :
400  eevee_volume_default_texture(gpu_grid->default_value);
401 
402  DRW_shgroup_uniform_texture(grp, gpu_grid->sampler_name, grid_tex);
403 
404  if (drw_grid && multiple_transforms) {
405  /* Specify per-volume transform matrix that is applied after the
406  * transform from object to bounds. */
407  mul_m4_m4m4(drw_grid->bounds_to_texture, drw_grid->object_to_texture, bounds_to_object);
408  DRW_shgroup_uniform_mat4(grp, gpu_grid->transform_name, drw_grid->bounds_to_texture);
409  }
410  }
411 
412  return true;
413 }
414 
416  Object *ob,
417  ListBase *gpu_grids,
418  DRWShadingGroup *grp)
419 {
420  static const float white[3] = {1.0f, 1.0f, 1.0f};
421  ModifierData *md = NULL;
422 
423  /* Smoke Simulation */
426  ((FluidModifierData *)md)->domain != NULL) {
428  FluidDomainSettings *fds = fmd->domain;
429 
430  /* Don't try to show liquid domains here. */
431  if (!fds->fluid || !(fds->type == FLUID_DOMAIN_TYPE_GAS)) {
432  return false;
433  }
434 
435  /* Don't show smoke before simulation starts, this could be made an option in the future. */
436  /* (sebbas): Always show smoke for manta */
437 #if 0
438  const DRWContextState *draw_ctx = DRW_context_state_get();
439  const bool show_smoke = ((int)DEG_get_ctime(draw_ctx->depsgraph) >=
440  *fds->point_cache[0]->startframe);
441 #endif
442 
443  if (fds->fluid && (fds->type == FLUID_DOMAIN_TYPE_GAS) /* && show_smoke */) {
445  BLI_addtail(&e_data.smoke_domains, BLI_genericNodeN(fmd));
446  }
447 
448  LISTBASE_FOREACH (GPUMaterialVolumeGrid *, gpu_grid, gpu_grids) {
449  if (STREQ(gpu_grid->name, "density")) {
451  grp, gpu_grid->sampler_name, fds->tex_density ? &fds->tex_density : &e_data.dummy_one);
452  }
453  else if (STREQ(gpu_grid->name, "color")) {
455  grp, gpu_grid->sampler_name, fds->tex_color ? &fds->tex_color : &e_data.dummy_one);
456  }
457  else if (STR_ELEM(gpu_grid->name, "flame", "temperature")) {
459  grp, gpu_grid->sampler_name, fds->tex_flame ? &fds->tex_flame : &e_data.dummy_flame);
460  }
461  else {
463  grp, gpu_grid->sampler_name, eevee_volume_default_texture(gpu_grid->default_value));
464  }
465  }
466 
467  /* Constant Volume color. */
468  bool use_constant_color = ((fds->active_fields & FLUID_DOMAIN_ACTIVE_COLORS) == 0 &&
470 
472  grp, "volumeColor", (use_constant_color) ? fds->active_color : white, 1);
473 
474  /* Output is such that 0..1 maps to 0..1000K */
475  DRW_shgroup_uniform_vec2(grp, "volumeTemperature", &fds->flame_ignition, 1);
476  }
477  else {
478  LISTBASE_FOREACH (GPUMaterialVolumeGrid *, gpu_grid, gpu_grids) {
480  grp, gpu_grid->sampler_name, eevee_volume_default_texture(gpu_grid->default_value));
481  }
482  }
483 
484  /* Transform for mesh volumes. */
485  static const float unit_mat[4][4] = {{1.0f, 0.0f, 0.0f, 0.0f},
486  {0.0f, 1.0f, 0.0f, 0.0f},
487  {0.0f, 0.0f, 1.0f, 0.0f},
488  {0.0f, 0.0f, 0.0f, 1.0f}};
489  float *texco_loc, *texco_size;
490  BKE_mesh_texspace_get_reference((struct Mesh *)ob->data, NULL, &texco_loc, &texco_size);
491 
492  DRW_shgroup_uniform_mat4(grp, "volumeObjectToTexture", unit_mat);
493  DRW_shgroup_uniform_vec3(grp, "volumeOrcoLoc", texco_loc, 1);
494  DRW_shgroup_uniform_vec3(grp, "volumeOrcoSize", texco_size, 1);
495 
496  return true;
497 }
498 
500  EEVEE_Data *vedata,
501  Scene *scene,
502  Object *ob)
503 {
505 
506  if (ma == NULL) {
507  if (ob->type == OB_VOLUME) {
509  }
510  else {
511  return;
512  }
513  }
514 
515  float size[3];
516  mat4_to_size(size, ob->obmat);
517  /* Check if any of the axes have 0 length. (see T69070) */
518  const float epsilon = 1e-8f;
519  if ((size[0] < epsilon) || (size[1] < epsilon) || (size[2] < epsilon)) {
520  return;
521  }
522 
523  int mat_options = VAR_MAT_VOLUME | VAR_MAT_MESH;
524  struct GPUMaterial *mat = EEVEE_material_get(vedata, scene, ma, NULL, mat_options);
526 
527  /* If shader failed to compile or is currently compiling. */
528  if (status != GPU_MAT_SUCCESS) {
529  return;
530  }
531 
533 
534  /* TODO(fclem): remove those "unnecessary" UBOs */
535  DRW_shgroup_uniform_block(grp, "planar_block", sldata->planar_ubo);
536  DRW_shgroup_uniform_block(grp, "probe_block", sldata->probe_ubo);
537  DRW_shgroup_uniform_block(grp, "shadow_block", sldata->shadow_ubo);
538  DRW_shgroup_uniform_block(grp, "light_block", sldata->light_ubo);
539  DRW_shgroup_uniform_block(grp, "grid_block", sldata->grid_ubo);
540  DRW_shgroup_uniform_block(grp, "renderpass_block", sldata->renderpass_ubo.combined);
541 
542  DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
543 
544  ListBase gpu_grids = GPU_material_volume_grids(mat);
545 
546  if (ob->type == OB_VOLUME) {
547  if (!eevee_volume_object_grids_init(ob, &gpu_grids, grp)) {
548  return;
549  }
550  }
551  else {
552  if (!eevee_volume_object_mesh_init(scene, ob, &gpu_grids, grp)) {
553  return;
554  }
555  }
556 
557  /* TODO Reduce to number of slices intersecting. */
558  /* TODO Preemptive culling. */
560 
562 }
563 
565 {
566  EEVEE_PassList *psl = vedata->psl;
567  EEVEE_TextureList *txl = vedata->txl;
568  EEVEE_EffectsInfo *effects = vedata->stl->effects;
569  LightCache *lcache = vedata->stl->g_data->light_cache;
570  EEVEE_CommonUniformBuffer *common_data = &sldata->common_data;
571 
572  if ((effects->enabled_effects & EFFECT_VOLUMETRIC) != 0) {
573  DRWShadingGroup *grp;
574  struct GPUShader *sh;
575 
580  DRW_shgroup_uniform_texture_ref(grp, "irradianceGrid", &lcache->grid_tx.tex);
581  DRW_shgroup_uniform_texture_ref(grp, "shadowCubeTexture", &sldata->shadow_cube_pool);
582  DRW_shgroup_uniform_texture_ref(grp, "shadowCascadeTexture", &sldata->shadow_cascade_pool);
583  DRW_shgroup_uniform_texture_ref(grp, "volumeScattering", &txl->volume_prop_scattering);
584  DRW_shgroup_uniform_texture_ref(grp, "volumeExtinction", &txl->volume_prop_extinction);
585  DRW_shgroup_uniform_texture_ref(grp, "volumeEmission", &txl->volume_prop_emission);
586  DRW_shgroup_uniform_texture_ref(grp, "volumePhase", &txl->volume_prop_phase);
587  DRW_shgroup_uniform_texture_ref(grp, "historyScattering", &txl->volume_scatter_history);
588  DRW_shgroup_uniform_texture_ref(grp, "historyTransmittance", &txl->volume_transmit_history);
589  DRW_shgroup_uniform_block(grp, "light_block", sldata->light_ubo);
590  DRW_shgroup_uniform_block(grp, "shadow_block", sldata->shadow_ubo);
591  DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
592  DRW_shgroup_uniform_block(grp, "probe_block", sldata->probe_ubo);
593  DRW_shgroup_uniform_block(grp, "renderpass_block", sldata->renderpass_ubo.combined);
594 
596 
600  DRW_shgroup_uniform_texture_ref(grp, "volumeScattering", &txl->volume_scatter);
601  DRW_shgroup_uniform_texture_ref(grp, "volumeExtinction", &txl->volume_transmit);
602  DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
603  DRW_shgroup_uniform_block(grp, "probe_block", sldata->probe_ubo);
604  DRW_shgroup_uniform_block(grp, "renderpass_block", sldata->renderpass_ubo.combined);
605  if (USE_VOLUME_OPTI) {
606  DRW_shgroup_uniform_image_ref(grp, "finalScattering_img", &txl->volume_scatter_history);
607  DRW_shgroup_uniform_image_ref(grp, "finalTransmittance_img", &txl->volume_transmit_history);
608  }
609 
611  grp, NULL, USE_VOLUME_OPTI ? 1 : common_data->vol_tex_size[2]);
612 
615  psl->volumetric_resolve_ps);
616  DRW_shgroup_uniform_texture_ref(grp, "inScattering", &txl->volume_scatter);
617  DRW_shgroup_uniform_texture_ref(grp, "inTransmittance", &txl->volume_transmit);
618  DRW_shgroup_uniform_texture_ref(grp, "inSceneDepth", &e_data.depth_src);
619  DRW_shgroup_uniform_block(grp, "light_block", sldata->light_ubo);
620  DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
621  DRW_shgroup_uniform_block(grp, "probe_block", sldata->probe_ubo);
622  DRW_shgroup_uniform_block(grp, "renderpass_block", sldata->renderpass_ubo.combined);
623 
625  }
626 }
627 
629 {
630  EEVEE_FramebufferList *fbl = vedata->fbl;
631  EEVEE_TextureList *txl = vedata->txl;
632  EEVEE_EffectsInfo *effects = vedata->stl->effects;
633  EEVEE_CommonUniformBuffer *common_data = &sldata->common_data;
634 
635  if ((effects->enabled_effects & EFFECT_VOLUMETRIC) != 0) {
636  int *tex_size = common_data->vol_tex_size;
637 
638  if (txl->volume_prop_scattering == NULL) {
639  /* Volume properties: We evaluate all volumetric objects
640  * and store their final properties into each froxel */
642  tex_size[0], tex_size[1], tex_size[2], GPU_R11F_G11F_B10F, DRW_TEX_FILTER, NULL);
644  tex_size[0], tex_size[1], tex_size[2], GPU_R11F_G11F_B10F, DRW_TEX_FILTER, NULL);
646  tex_size[0], tex_size[1], tex_size[2], GPU_R11F_G11F_B10F, DRW_TEX_FILTER, NULL);
648  tex_size[0], tex_size[1], tex_size[2], GPU_RG16F, DRW_TEX_FILTER, NULL);
649 
650  /* Volume scattering: We compute for each froxel the
651  * Scattered light towards the view. We also resolve temporal
652  * super sampling during this stage. */
654  tex_size[0], tex_size[1], tex_size[2], GPU_R11F_G11F_B10F, DRW_TEX_FILTER, NULL);
656  tex_size[0], tex_size[1], tex_size[2], GPU_R11F_G11F_B10F, DRW_TEX_FILTER, NULL);
657 
658  /* Final integration: We compute for each froxel the
659  * amount of scattered light and extinction coef at this
660  * given depth. We use these textures as double buffer
661  * for the volumetric history. */
663  tex_size[0], tex_size[1], tex_size[2], GPU_R11F_G11F_B10F, DRW_TEX_FILTER, NULL);
665  tex_size[0], tex_size[1], tex_size[2], GPU_R11F_G11F_B10F, DRW_TEX_FILTER, NULL);
666  }
667 
668  GPU_framebuffer_ensure_config(&fbl->volumetric_fb,
669  {GPU_ATTACHMENT_NONE,
670  GPU_ATTACHMENT_TEXTURE(txl->volume_prop_scattering),
671  GPU_ATTACHMENT_TEXTURE(txl->volume_prop_extinction),
672  GPU_ATTACHMENT_TEXTURE(txl->volume_prop_emission),
673  GPU_ATTACHMENT_TEXTURE(txl->volume_prop_phase)});
674  GPU_framebuffer_ensure_config(&fbl->volumetric_scat_fb,
675  {GPU_ATTACHMENT_NONE,
676  GPU_ATTACHMENT_TEXTURE(txl->volume_scatter),
677  GPU_ATTACHMENT_TEXTURE(txl->volume_transmit)});
678  GPU_framebuffer_ensure_config(&fbl->volumetric_integ_fb,
679  {GPU_ATTACHMENT_NONE,
680  GPU_ATTACHMENT_TEXTURE(txl->volume_scatter_history),
681  GPU_ATTACHMENT_TEXTURE(txl->volume_transmit_history)});
682  }
683  else {
695  }
696 
697  effects->volume_scatter = e_data.dummy_scatter;
698  effects->volume_transmit = e_data.dummy_transmit;
699 }
700 
702 {
703  EEVEE_PassList *psl = vedata->psl;
704  EEVEE_TextureList *txl = vedata->txl;
705  EEVEE_FramebufferList *fbl = vedata->fbl;
706  EEVEE_StorageList *stl = vedata->stl;
707  EEVEE_EffectsInfo *effects = stl->effects;
708  if ((effects->enabled_effects & EFFECT_VOLUMETRIC) != 0) {
709  DRW_stats_group_start("Volumetrics");
710 
711  /* We sample the shadow-maps using shadow sampler. We need to enable Comparison mode.
712  * TODO(fclem): avoid this by using sampler objects.*/
715 
719 
722 
723  if (USE_VOLUME_OPTI) {
724  /* Avoid feedback loop assert. */
726  }
727  else {
729  }
730 
732 
736 
737  effects->volume_scatter = txl->volume_scatter;
738  effects->volume_transmit = txl->volume_transmit;
739 
740  /* Restore */
742 
744  }
745 }
746 
748 {
749  EEVEE_PassList *psl = vedata->psl;
750  EEVEE_FramebufferList *fbl = vedata->fbl;
751  EEVEE_StorageList *stl = vedata->stl;
752  EEVEE_EffectsInfo *effects = stl->effects;
753 
754  if ((effects->enabled_effects & EFFECT_VOLUMETRIC) != 0) {
756  e_data.depth_src = dtxl->depth;
757 
758  if (USE_VOLUME_OPTI) {
760  }
761 
762  /* Apply for opaque geometry. */
765 
766  /* Restore. */
768  }
769 }
770 
772 {
773  /* Free Smoke Textures after rendering */
774  LISTBASE_FOREACH (LinkData *, link, &e_data.smoke_domains) {
775  FluidModifierData *fmd = (FluidModifierData *)link->data;
776  DRW_smoke_free(fmd);
777  }
778  BLI_freelistN(&e_data.smoke_domains);
779 }
780 
782 {
783  DRW_TEXTURE_FREE_SAFE(e_data.dummy_scatter);
784  DRW_TEXTURE_FREE_SAFE(e_data.dummy_transmit);
785 
786  DRW_TEXTURE_FREE_SAFE(e_data.dummy_zero);
787  DRW_TEXTURE_FREE_SAFE(e_data.dummy_one);
788  DRW_TEXTURE_FREE_SAFE(e_data.dummy_flame);
789 }
790 
791 /* -------------------------------------------------------------------- */
796 {
797  EEVEE_FramebufferList *fbl = vedata->fbl;
798  EEVEE_TextureList *txl = vedata->txl;
799  EEVEE_StorageList *stl = vedata->stl;
800  EEVEE_PassList *psl = vedata->psl;
801  EEVEE_EffectsInfo *effects = stl->effects;
802 
803  /* Create FrameBuffer. */
804 
805  /* Should be enough precision for many samples. */
806  const eGPUTextureFormat texture_format_accum = (tot_samples > 128) ? GPU_RGBA32F : GPU_RGBA16F;
807  DRW_texture_ensure_fullscreen_2d(&txl->volume_scatter_accum, texture_format_accum, 0);
808  DRW_texture_ensure_fullscreen_2d(&txl->volume_transmittance_accum, texture_format_accum, 0);
809 
810  GPU_framebuffer_ensure_config(&fbl->volumetric_accum_fb,
811  {GPU_ATTACHMENT_NONE,
812  GPU_ATTACHMENT_TEXTURE(txl->volume_scatter_accum),
813  GPU_ATTACHMENT_TEXTURE(txl->volume_transmittance_accum)});
814 
815  /* Create Pass and shgroup. */
817  DRWShadingGroup *grp = NULL;
818  if ((effects->enabled_effects & EFFECT_VOLUMETRIC) != 0) {
820  DRW_shgroup_uniform_texture_ref(grp, "inScattering", &txl->volume_scatter);
821  DRW_shgroup_uniform_texture_ref(grp, "inTransmittance", &txl->volume_transmit);
822  DRW_shgroup_uniform_texture_ref(grp, "inSceneDepth", &e_data.depth_src);
823  DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
824  DRW_shgroup_uniform_block(grp, "renderpass_block", sldata->renderpass_ubo.combined);
825  }
826  else {
827  /* There is no volumetrics in the scene. Use a shader to fill the accum textures with a default
828  * value. */
830  }
832 }
833 
835 {
836  EEVEE_FramebufferList *fbl = vedata->fbl;
837  EEVEE_PassList *psl = vedata->psl;
838  EEVEE_EffectsInfo *effects = vedata->stl->effects;
839 
840  if (fbl->volumetric_accum_fb != NULL) {
841  /* Accum pass */
843 
844  /* Clear texture. */
845  if (effects->taa_current_sample == 1) {
846  const float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f};
847  GPU_framebuffer_clear_color(fbl->volumetric_accum_fb, clear);
848  }
849 
851 
852  /* Restore */
854  }
855 }
856 
typedef float(TangentPoint)[2]
struct wmWindowManager * CTX_wm_manager(const bContext *C)
Definition: context.c:689
struct Material * BKE_object_material_get(struct Object *ob, short act)
Definition: material.c:697
struct Material * BKE_material_default_volume(void)
Definition: material.c:1834
void BKE_mesh_texspace_get_reference(struct Mesh *me, short **r_texflag, float **r_loc, float **r_size)
Definition: mesh.c:1135
bool BKE_modifier_is_enabled(const struct Scene *scene, struct ModifierData *md, int required_mode)
struct ModifierData * BKE_modifiers_findby_type(const struct Object *ob, ModifierType type)
Volume datablock.
struct BoundBox * BKE_volume_boundbox_get(struct Object *ob)
Definition: volume.cc:926
const VolumeGrid * BKE_volume_grid_find_for_read(const struct Volume *volume, const char *name)
bool BKE_volume_load(const struct Volume *volume, const struct Main *bmain)
Volume data-block rendering and viewport drawing utilities.
float BKE_volume_density_scale(const struct Volume *volume, const float matrix[4][4])
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:172
struct LinkData * BLI_genericNodeN(void *data)
Definition: listbase.c:923
void void BLI_freelistN(struct ListBase *listbase) ATTR_NONNULL(1)
Definition: listbase.c:547
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:110
MINLINE float max_ff(float a, float b)
MINLINE float min_ff(float a, float b)
MINLINE int max_ii(int a, int b)
void mul_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4])
Definition: math_matrix.c:262
bool invert_m4_m4(float R[4][4], const float A[4][4])
Definition: math_matrix.c:1278
void size_to_mat4(float R[4][4], const float size[3])
Definition: math_matrix.c:2118
bool equals_m4m4(const float mat1[4][4], const float mat2[4][4])
Definition: math_matrix.c:2612
void mat4_to_size(float size[3], const float M[4][4])
Definition: math_matrix.c:2145
MINLINE void sub_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void copy_v3_v3_int(int r[3], const int a[3])
Random number functions.
void BLI_halton_3d(const unsigned int prime[3], double offset[3], int n, double *r)
Definition: rand.cc:323
#define STR_ELEM(...)
Definition: BLI_string.h:218
unsigned int uint
Definition: BLI_sys_types.h:83
#define SWAP(type, a, b)
#define UNUSED(x)
#define STREQ(a, b)
float DEG_get_ctime(const Depsgraph *graph)
struct Scene * DEG_get_evaluated_scene(const struct Depsgraph *graph)
@ FLUID_DOMAIN_USE_NOISE
@ FLUID_DOMAIN_ACTIVE_COLORS
@ FLUID_DOMAIN_ACTIVE_COLOR_SET
@ FLUID_DOMAIN_TYPE_GAS
@ eModifierMode_Realtime
@ eModifierType_Fluid
@ OB_VOLUME
@ SCE_EEVEE_VOLUMETRIC_SHADOWS
@ SCE_EEVEE_SHADOW_SOFT
@ SCE_EEVEE_VOLUMETRIC_LIGHTS
@ DRW_TEX_WRAP
Definition: DRW_render.h:140
@ DRW_TEX_FILTER
Definition: DRW_render.h:139
@ DRW_STATE_BLEND_ADD
Definition: DRW_render.h:336
@ DRW_STATE_BLEND_ADD_FULL
Definition: DRW_render.h:338
@ DRW_STATE_WRITE_COLOR
Definition: DRW_render.h:315
@ DRW_STATE_BLEND_CUSTOM
Definition: DRW_render.h:348
#define DRW_PASS_CREATE(pass, state)
Definition: DRW_render.h:593
#define DRW_shgroup_call(shgroup, geom, ob)
Definition: DRW_render.h:420
#define DRW_TEXTURE_FREE_SAFE(tex)
Definition: DRW_render.h:180
bScreen * ED_screen_animation_no_scrub(const struct wmWindowManager *wm)
struct GPUFrameBuffer GPUFrameBuffer
#define GPU_FRAMEBUFFER_FREE_SAFE(fb)
void GPU_framebuffer_bind(GPUFrameBuffer *fb)
eGPUMaterialStatus GPU_material_status(GPUMaterial *mat)
Definition: gpu_material.c:619
eGPUMaterialStatus
Definition: GPU_material.h:126
@ GPU_MAT_SUCCESS
Definition: GPU_material.h:129
ListBase GPU_material_volume_grids(GPUMaterial *material)
Definition: gpu_material.c:582
eGPUVolumeDefaultValue
Definition: GPU_material.h:132
@ GPU_VOLUME_DEFAULT_0
Definition: GPU_material.h:133
@ GPU_VOLUME_DEFAULT_1
Definition: GPU_material.h:134
bool GPU_material_has_volume_output(GPUMaterial *mat)
Definition: gpu_material.c:631
struct GPUShader GPUShader
Definition: GPU_shader.h:33
void GPU_memory_barrier(eGPUBarrier barrier)
Definition: gpu_state.cc:392
@ GPU_BARRIER_TEXTURE_FETCH
Definition: GPU_state.h:41
struct GPUTexture GPUTexture
Definition: GPU_texture.h:33
void GPU_texture_compare_mode(GPUTexture *tex, bool use_compare)
Definition: gpu_texture.cc:460
eGPUTextureFormat
Definition: GPU_texture.h:84
@ GPU_RG16F
Definition: GPU_texture.h:104
@ GPU_RGBA32F
Definition: GPU_texture.h:91
@ GPU_RGBA16F
Definition: GPU_texture.h:94
@ GPU_R8
Definition: GPU_texture.h:108
@ GPU_R11F_G11F_B10F
Definition: GPU_texture.h:119
@ GPU_RGBA8
Definition: GPU_texture.h:88
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
Scene scene
GPUBatch * DRW_cache_fullscreen_quad_get(void)
Definition: draw_cache.c:358
DRWVolumeGrid * DRW_volume_batch_cache_get_grid(struct Volume *volume, const struct VolumeGrid *grid)
void DRW_smoke_free(struct FluidModifierData *fmd)
Definition: draw_fluid.c:438
void DRW_smoke_ensure(struct FluidModifierData *fmd, int highres)
Definition: draw_fluid.c:502
const DRWContextState * DRW_context_state_get(void)
const float * DRW_viewport_size_get(void)
Definition: draw_manager.c:439
bool DRW_state_is_image_render(void)
void DRW_viewport_request_redraw(void)
Definition: draw_manager.c:707
DefaultTextureList * DRW_viewport_texture_list_get(void)
Definition: draw_manager.c:702
DRWShadingGroup * DRW_shgroup_material_create(struct GPUMaterial *material, DRWPass *pass)
float DRW_view_near_distance_get(const DRWView *view)
void DRW_shgroup_uniform_float_copy(DRWShadingGroup *shgroup, const char *name, const float value)
void DRW_shgroup_uniform_block(DRWShadingGroup *shgroup, const char *name, const GPUUniformBuf *ubo)
void DRW_shgroup_uniform_texture(DRWShadingGroup *shgroup, const char *name, const GPUTexture *tex)
void DRW_shgroup_uniform_vec3_copy(DRWShadingGroup *shgroup, const char *name, const float *value)
void DRW_shgroup_uniform_vec3(DRWShadingGroup *shgroup, const char *name, const float *value, int arraysize)
bool DRW_view_is_persp_get(const DRWView *view)
void DRW_shgroup_call_procedural_triangles(DRWShadingGroup *shgroup, Object *ob, uint tri_count)
DRWShadingGroup * DRW_shgroup_create(struct GPUShader *shader, DRWPass *pass)
float DRW_view_far_distance_get(const DRWView *view)
void DRW_shgroup_uniform_texture_ref(DRWShadingGroup *shgroup, const char *name, GPUTexture **tex)
void DRW_shgroup_uniform_mat4(DRWShadingGroup *shgroup, const char *name, const float(*value)[4])
void DRW_shgroup_uniform_image_ref(DRWShadingGroup *shgroup, const char *name, GPUTexture **tex)
void DRW_shgroup_uniform_vec2(DRWShadingGroup *shgroup, const char *name, const float *value, int arraysize)
void DRW_draw_pass(DRWPass *pass)
void DRW_stats_group_start(const char *name)
void DRW_stats_group_end(void)
GPUTexture * DRW_texture_create_3d(int w, int h, int d, eGPUTextureFormat format, DRWTextureFlag flags, const float *fpixels)
void DRW_texture_ensure_fullscreen_2d(GPUTexture **tex, eGPUTextureFormat format, DRWTextureFlag flags)
@ VAR_MAT_VOLUME
@ VAR_MAT_MESH
#define LOOK_DEV_STUDIO_LIGHT_ENABLED(v3d)
struct GPUShader * EEVEE_shaders_volumes_scatter_sh_get(void)
struct GPUShader * EEVEE_shaders_volumes_integration_sh_get(void)
struct GPUShader * EEVEE_shaders_volumes_accum_sh_get(void)
@ EFFECT_POST_BUFFER
@ EFFECT_TAA
@ EFFECT_VOLUMETRIC
#define USE_VOLUME_OPTI
Definition: eevee_private.h:90
struct GPUMaterial * EEVEE_material_get(EEVEE_Data *vedata, struct Scene *scene, Material *ma, World *wo, int options)
struct GPUShader * EEVEE_shaders_volumes_scatter_with_lights_sh_get(void)
struct GPUShader * EEVEE_shaders_volumes_clear_sh_get(void)
struct GPUShader * EEVEE_shaders_volumes_resolve_sh_get(bool accum)
void EEVEE_volumes_cache_finish(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
void EEVEE_volumes_set_jitter(EEVEE_ViewLayerData *sldata, uint current_sample)
Definition: eevee_volumes.c:90
static bool eevee_volume_object_mesh_init(Scene *scene, Object *ob, ListBase *gpu_grids, DRWShadingGroup *grp)
ListBase smoke_domains
Definition: eevee_volumes.c:63
void EEVEE_volumes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
void EEVEE_volumes_free(void)
void EEVEE_volumes_compute(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
void EEVEE_volumes_free_smoke_textures(void)
GPUTexture * dummy_scatter
Definition: eevee_volumes.c:59
static struct @207 e_data
static void eevee_create_textures_volumes(void)
Definition: eevee_volumes.c:66
GPUTexture * depth_src
Definition: eevee_volumes.c:53
static GPUTexture * eevee_volume_default_texture(eGPUVolumeDefaultValue default_value)
Definition: eevee_volumes.c:78
GPUTexture * dummy_zero
Definition: eevee_volumes.c:55
GPUTexture * dummy_one
Definition: eevee_volumes.c:56
void EEVEE_volumes_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
static bool eevee_volume_object_grids_init(Object *ob, ListBase *gpu_grids, DRWShadingGroup *grp)
void EEVEE_volumes_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, uint tot_samples)
void EEVEE_volumes_resolve(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
GPUTexture * dummy_transmit
Definition: eevee_volumes.c:60
GPUTexture * dummy_flame
Definition: eevee_volumes.c:57
void EEVEE_volumes_output_accumulate(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
void EEVEE_volumes_cache_object_add(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, Scene *scene, Object *ob)
void EEVEE_volumes_draw_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
#define fmaxf(x, y)
#define ceilf(x)
static void clear(Message *msg)
Definition: msgfmt.c:294
static double epsilon
float vec[8][3]
struct Scene * scene
Definition: DRW_render.h:745
const struct bContext * evil_C
Definition: DRW_render.h:763
struct Depsgraph * depsgraph
Definition: DRW_render.h:753
struct View3D * v3d
Definition: DRW_render.h:742
float bounds_to_texture[4][4]
Definition: draw_cache.h:244
float object_to_bounds[4][4]
Definition: draw_cache.h:243
struct GPUTexture * texture
Definition: draw_cache.h:236
float object_to_texture[4][4]
Definition: draw_cache.h:240
struct GPUTexture * depth
EEVEE_TextureList * txl
EEVEE_StorageList * stl
EEVEE_PassList * psl
EEVEE_FramebufferList * fbl
struct GPUTexture * volume_transmit
struct GPUTexture * volume_scatter
EEVEE_EffectsFlag enabled_effects
struct GPUFrameBuffer * volumetric_fb
struct GPUFrameBuffer * main_fb
struct GPUFrameBuffer * volumetric_scat_fb
struct GPUFrameBuffer * volumetric_integ_fb
struct GPUFrameBuffer * main_color_fb
struct GPUFrameBuffer * volumetric_accum_fb
struct DRWPass * volumetric_objects_ps
struct DRWPass * volumetric_integration_ps
struct DRWPass * volumetric_world_ps
struct DRWPass * volumetric_scatter_ps
struct DRWPass * volumetric_resolve_ps
struct DRWPass * volumetric_accum_ps
struct LightCache * light_cache
struct EEVEE_PrivateData * g_data
struct EEVEE_EffectsInfo * effects
struct GPUTexture * volume_scatter_history
struct GPUTexture * volume_prop_extinction
struct GPUTexture * volume_scatter_accum
struct GPUTexture * volume_transmittance_accum
struct GPUTexture * volume_prop_emission
struct GPUTexture * volume_transmit
struct GPUTexture * volume_transmit_history
struct GPUTexture * volume_prop_phase
struct GPUTexture * volume_prop_scattering
struct GPUTexture * volume_scatter
struct EEVEE_CommonUniformBuffer common_data
struct GPUTexture * shadow_cube_pool
struct GPUUniformBuf * combined
struct GPUUniformBuf * shadow_ubo
struct GPUUniformBuf * probe_ubo
struct GPUUniformBuf * grid_ubo
struct GPUUniformBuf * planar_ubo
struct EEVEE_ViewLayerData::@202 renderpass_ubo
struct GPUUniformBuf * common_ubo
struct GPUUniformBuf * light_ubo
struct GPUTexture * shadow_cascade_pool
struct GPUTexture * tex_density
struct GPUTexture * tex_color
struct MANTA * fluid
struct PointCache * point_cache[2]
struct GPUTexture * tex_flame
struct FluidDomainSettings * domain
Material * ma
Definition: gpu_material.c:67
eGPUMaterialStatus status
Definition: gpu_material.c:69
struct GPUTexture * tex
LightCacheTexture grid_tx
ustring name
Definition: node.h:174
float obmat[4][4]
void * data
float volumetric_light_clamp
float volumetric_start
float volumetric_end
float volumetric_sample_distribution
int volumetric_shadow_samples
int volumetric_tile_size
struct World * world
struct SceneEEVEE eevee
struct bNodeTree * nodetree
short use_nodes
#define G(x, y, z)