Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClément Foucault <foucault.clem@gmail.com>2019-05-16 22:41:22 +0300
committerClément Foucault <foucault.clem@gmail.com>2019-05-17 14:38:42 +0300
commit52669dda8049e05eaf0bc8147ef477a05c3717da (patch)
treedd846fbbd1882fb5bb19a6337f12732b0ebb26b8
parentb526221315e5734306ef3bf5e520529d7f9e24a2 (diff)
Eevee: Remove the Volumetric Render checkbox
This is to simplify the usage of Volumetrics. Now it automatically detect if there is any Volumetric material in the view and allocate the needed buffer if any.
-rw-r--r--release/scripts/startup/bl_ui/properties_render.py7
-rw-r--r--source/blender/blenloader/intern/versioning_280.c2
-rw-r--r--source/blender/draw/engines/eevee/eevee_effects.c29
-rw-r--r--source/blender/draw/engines/eevee/eevee_engine.c4
-rw-r--r--source/blender/draw/engines/eevee/eevee_lightcache.c4
-rw-r--r--source/blender/draw/engines/eevee/eevee_materials.c24
-rw-r--r--source/blender/draw/engines/eevee/eevee_private.h11
-rw-r--r--source/blender/draw/engines/eevee/eevee_render.c4
-rw-r--r--source/blender/draw/engines/eevee/eevee_volumes.c621
-rw-r--r--source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl4
-rw-r--r--source/blender/draw/intern/DRW_render.h2
-rw-r--r--source/blender/makesdna/DNA_scene_types.h2
-rw-r--r--source/blender/makesrna/intern/rna_scene.c8
-rwxr-xr-xtests/python/eevee_render_tests.py1
14 files changed, 374 insertions, 349 deletions
diff --git a/release/scripts/startup/bl_ui/properties_render.py b/release/scripts/startup/bl_ui/properties_render.py
index fbf247b2858..b99e2b9d731 100644
--- a/release/scripts/startup/bl_ui/properties_render.py
+++ b/release/scripts/startup/bl_ui/properties_render.py
@@ -241,11 +241,6 @@ class RENDER_PT_eevee_volumetric(RenderButtonsPanel, Panel):
def poll(cls, context):
return (context.engine in cls.COMPAT_ENGINES)
- def draw_header(self, context):
- scene = context.scene
- props = scene.eevee
- self.layout.prop(props, "use_volumetric", text="")
-
def draw(self, context):
layout = self.layout
layout.use_property_split = True
@@ -253,8 +248,6 @@ class RENDER_PT_eevee_volumetric(RenderButtonsPanel, Panel):
scene = context.scene
props = scene.eevee
- layout.active = props.use_volumetric
-
col = layout.column(align=True)
col.prop(props, "volumetric_start")
col.prop(props, "volumetric_end")
diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c
index 84c9aa01db3..d2489334c90 100644
--- a/source/blender/blenloader/intern/versioning_280.c
+++ b/source/blender/blenloader/intern/versioning_280.c
@@ -1673,7 +1673,7 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain)
IDProperty *props = IDP_GetPropertyFromGroup(scene->layer_properties,
RE_engine_id_BLENDER_EEVEE);
- EEVEE_GET_BOOL(props, volumetric_enable, SCE_EEVEE_VOLUMETRIC_ENABLED);
+ // EEVEE_GET_BOOL(props, volumetric_enable, SCE_EEVEE_VOLUMETRIC_ENABLED);
EEVEE_GET_BOOL(props, volumetric_lights, SCE_EEVEE_VOLUMETRIC_LIGHTS);
EEVEE_GET_BOOL(props, volumetric_shadows, SCE_EEVEE_VOLUMETRIC_SHADOWS);
EEVEE_GET_BOOL(props, gtao_enable, SCE_EEVEE_GTAO_ENABLED);
diff --git a/source/blender/draw/engines/eevee/eevee_effects.c b/source/blender/draw/engines/eevee/eevee_effects.c
index 91426b36415..79569216399 100644
--- a/source/blender/draw/engines/eevee/eevee_effects.c
+++ b/source/blender/draw/engines/eevee/eevee_effects.c
@@ -160,8 +160,8 @@ void EEVEE_effects_init(EEVEE_ViewLayerData *sldata,
effects->enabled_effects |= EEVEE_temporal_sampling_init(sldata, vedata);
effects->enabled_effects |= EEVEE_occlusion_init(sldata, vedata);
effects->enabled_effects |= EEVEE_screen_raytrace_init(sldata, vedata);
- effects->enabled_effects |= EEVEE_volumes_init(sldata, vedata);
+ EEVEE_volumes_init(sldata, vedata);
EEVEE_subsurface_init(sldata, vedata);
/* Force normal buffer creation. */
@@ -263,16 +263,6 @@ void EEVEE_effects_init(EEVEE_ViewLayerData *sldata,
GPU_FRAMEBUFFER_FREE_SAFE(fbl->double_buffer_depth_fb);
}
- /**
- * Setup double buffer so we can access last frame as it was before post processes.
- */
- if ((effects->enabled_effects & EFFECT_DOUBLE_BUFFER) != 0) {
- SETUP_BUFFER(txl->color_double_buffer, fbl->double_buffer_fb, fbl->double_buffer_color_fb);
- }
- else {
- CLEANUP_BUFFER(txl->color_double_buffer, fbl->double_buffer_fb, fbl->double_buffer_color_fb);
- }
-
if ((effects->enabled_effects & (EFFECT_TAA | EFFECT_TAA_REPROJECT)) != 0) {
SETUP_BUFFER(txl->taa_history, fbl->taa_history_fb, fbl->taa_history_color_fb);
}
@@ -384,6 +374,23 @@ void EEVEE_effects_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
}
}
+void EEVEE_effects_draw_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
+{
+ EEVEE_FramebufferList *fbl = vedata->fbl;
+ EEVEE_TextureList *txl = vedata->txl;
+ EEVEE_EffectsInfo *effects = vedata->stl->effects;
+ DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
+ /**
+ * Setup double buffer so we can access last frame as it was before post processes.
+ */
+ if ((effects->enabled_effects & EFFECT_DOUBLE_BUFFER) != 0) {
+ SETUP_BUFFER(txl->color_double_buffer, fbl->double_buffer_fb, fbl->double_buffer_color_fb);
+ }
+ else {
+ CLEANUP_BUFFER(txl->color_double_buffer, fbl->double_buffer_fb, fbl->double_buffer_color_fb);
+ }
+}
+
#if 0 /* Not required for now */
static void min_downsample_cb(void *vedata, int UNUSED(level))
{
diff --git a/source/blender/draw/engines/eevee/eevee_engine.c b/source/blender/draw/engines/eevee/eevee_engine.c
index 9fc11d989ce..481b566eff0 100644
--- a/source/blender/draw/engines/eevee/eevee_engine.c
+++ b/source/blender/draw/engines/eevee/eevee_engine.c
@@ -154,9 +154,13 @@ static void eevee_cache_finish(void *vedata)
{
EEVEE_ViewLayerData *sldata = EEVEE_view_layer_data_ensure();
+ EEVEE_volumes_cache_finish(sldata, vedata);
EEVEE_materials_cache_finish(sldata, vedata);
EEVEE_lights_cache_finish(sldata, vedata);
EEVEE_lightprobes_cache_finish(sldata, vedata);
+
+ EEVEE_effects_draw_init(sldata, vedata);
+ EEVEE_volumes_draw_init(sldata, vedata);
}
/* As renders in an HDR offscreen buffer, we need draw everything once
diff --git a/source/blender/draw/engines/eevee/eevee_lightcache.c b/source/blender/draw/engines/eevee/eevee_lightcache.c
index c639f4bdfcb..3e0e5f6d00f 100644
--- a/source/blender/draw/engines/eevee/eevee_lightcache.c
+++ b/source/blender/draw/engines/eevee/eevee_lightcache.c
@@ -757,10 +757,14 @@ static void eevee_lightbake_cache_create(EEVEE_Data *vedata, EEVEE_LightBake *lb
}
DRW_render_object_iter(vedata, NULL, lbake->depsgraph, EEVEE_render_cache);
+ EEVEE_volumes_cache_finish(sldata, vedata);
EEVEE_materials_cache_finish(sldata, vedata);
EEVEE_lights_cache_finish(sldata, vedata);
EEVEE_lightprobes_cache_finish(sldata, vedata);
+ EEVEE_effects_draw_init(sldata, vedata);
+ EEVEE_volumes_draw_init(sldata, vedata);
+
txl->color = NULL;
DRW_render_instance_buffer_finish();
diff --git a/source/blender/draw/engines/eevee/eevee_materials.c b/source/blender/draw/engines/eevee/eevee_materials.c
index e6369af5e0f..7989d4d7ec2 100644
--- a/source/blender/draw/engines/eevee/eevee_materials.c
+++ b/source/blender/draw/engines/eevee/eevee_materials.c
@@ -327,9 +327,6 @@ static char *eevee_get_defines(int options)
if ((options & VAR_MAT_ESM) != 0) {
BLI_dynstr_append(ds, "#define SHADOW_ESM\n");
}
- if (((options & VAR_MAT_VOLUME) != 0) && ((options & VAR_MAT_BLEND) != 0)) {
- BLI_dynstr_append(ds, "#define USE_ALPHA_BLEND_VOLUMETRICS\n");
- }
if ((options & VAR_MAT_LOOKDEV) != 0) {
/* Auto config shadow method. Avoid more permutation. */
BLI_assert((options & (VAR_MAT_VSM | VAR_MAT_ESM)) == 0);
@@ -376,6 +373,7 @@ static void add_standard_uniforms(DRWShadingGroup *shgrp,
bool use_alpha_blend)
{
LightCache *lcache = vedata->stl->g_data->light_cache;
+ EEVEE_EffectsInfo *effects = vedata->stl->effects;
if (ssr_id == NULL) {
static int no_ssr = -1.0f;
@@ -397,9 +395,8 @@ static void add_standard_uniforms(DRWShadingGroup *shgrp,
DRW_shgroup_uniform_texture_ref(shgrp, "maxzBuffer", &vedata->txl->maxzbuffer);
}
if ((use_diffuse || use_glossy) && !use_ssrefraction) {
- if ((vedata->stl->effects->enabled_effects & EFFECT_GTAO) != 0) {
- DRW_shgroup_uniform_texture_ref(
- shgrp, "horizonBuffer", &vedata->stl->effects->gtao_horizons);
+ if ((effects->enabled_effects & EFFECT_GTAO) != 0) {
+ DRW_shgroup_uniform_texture_ref(shgrp, "horizonBuffer", &effects->gtao_horizons);
}
else {
/* Use maxzbuffer as fallback to avoid sampling problem on certain platform, see: T52593 */
@@ -423,11 +420,9 @@ static void add_standard_uniforms(DRWShadingGroup *shgrp,
DRW_shgroup_uniform_texture_ref(shgrp, "colorBuffer", &vedata->txl->refract_color);
}
}
-
- if ((vedata->stl->effects->enabled_effects & EFFECT_VOLUMETRIC) != 0 && use_alpha_blend) {
- /* Do not use history buffers as they already have been swapped */
- DRW_shgroup_uniform_texture_ref(shgrp, "inScattering", &vedata->txl->volume_scatter);
- DRW_shgroup_uniform_texture_ref(shgrp, "inTransmittance", &vedata->txl->volume_transmittance);
+ if (use_alpha_blend) {
+ DRW_shgroup_uniform_texture_ref(shgrp, "inScattering", &effects->volume_scatter);
+ DRW_shgroup_uniform_texture_ref(shgrp, "inTransmittance", &effects->volume_transmit);
}
}
@@ -752,8 +747,6 @@ struct GPUMaterial *EEVEE_material_mesh_get(struct Scene *scene,
SET_FLAG_FROM_TEST(options, use_refract, VAR_MAT_REFRACT);
SET_FLAG_FROM_TEST(options, effects->sss_separate_albedo, VAR_MAT_SSSALBED);
SET_FLAG_FROM_TEST(options, use_translucency, VAR_MAT_TRANSLUC);
- SET_FLAG_FROM_TEST(
- options, ((effects->enabled_effects & EFFECT_VOLUMETRIC) != 0) && use_blend, VAR_MAT_VOLUME);
options |= eevee_material_shadow_option(shadow_method);
@@ -884,15 +877,12 @@ static struct DRWShadingGroup *EEVEE_default_shading_group_create(EEVEE_ViewLaye
bool use_ssr,
int shadow_method)
{
- EEVEE_EffectsInfo *effects = vedata->stl->effects;
static int ssr_id;
ssr_id = (use_ssr) ? 1 : -1;
int options = VAR_MAT_MESH;
SET_FLAG_FROM_TEST(options, is_hair, VAR_MAT_HAIR);
SET_FLAG_FROM_TEST(options, use_blend, VAR_MAT_BLEND);
- SET_FLAG_FROM_TEST(
- options, ((effects->enabled_effects & EFFECT_VOLUMETRIC) != 0) && use_blend, VAR_MAT_VOLUME);
options |= eevee_material_shadow_option(shadow_method);
@@ -1722,7 +1712,7 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata,
}
/* Volumetrics */
- if (((stl->effects->enabled_effects & EFFECT_VOLUMETRIC) != 0) && use_volume_material) {
+ if (use_volume_material) {
EEVEE_volumes_cache_object_add(sldata, vedata, scene, ob);
}
}
diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h
index 2db36e492f2..e2130615b1d 100644
--- a/source/blender/draw/engines/eevee/eevee_private.h
+++ b/source/blender/draw/engines/eevee/eevee_private.h
@@ -333,9 +333,9 @@ typedef struct EEVEE_TextureList {
struct GPUTexture *volume_prop_emission;
struct GPUTexture *volume_prop_phase;
struct GPUTexture *volume_scatter;
- struct GPUTexture *volume_transmittance;
+ struct GPUTexture *volume_transmit;
struct GPUTexture *volume_scatter_history;
- struct GPUTexture *volume_transmittance_history;
+ struct GPUTexture *volume_transmit_history;
struct GPUTexture *lookdev_grid_tx;
struct GPUTexture *lookdev_cube_tx;
@@ -552,6 +552,8 @@ typedef struct EEVEE_EffectsInfo {
struct GPUTexture *sss_stencil;
/* Volumetrics */
int volume_current_sample;
+ struct GPUTexture *volume_scatter;
+ struct GPUTexture *volume_transmit;
/* SSR */
bool reflection_trace_full;
bool ssr_was_persp;
@@ -1062,13 +1064,15 @@ void EEVEE_temporal_sampling_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data
void EEVEE_temporal_sampling_draw(EEVEE_Data *vedata);
/* eevee_volumes.c */
-int EEVEE_volumes_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
+void EEVEE_volumes_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_volumes_set_jitter(EEVEE_ViewLayerData *sldata, uint current_sample);
void EEVEE_volumes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_volumes_cache_object_add(EEVEE_ViewLayerData *sldata,
EEVEE_Data *vedata,
struct Scene *scene,
Object *ob);
+void EEVEE_volumes_cache_finish(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
+void EEVEE_volumes_draw_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_volumes_compute(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_volumes_resolve(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_volumes_free_smoke_textures(void);
@@ -1080,6 +1084,7 @@ void EEVEE_effects_init(EEVEE_ViewLayerData *sldata,
Object *camera,
const bool minimal);
void EEVEE_effects_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
+void EEVEE_effects_draw_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_create_minmax_buffer(EEVEE_Data *vedata, struct GPUTexture *depth_src, int layer);
void EEVEE_downsample_buffer(EEVEE_Data *vedata, struct GPUTexture *texture_src, int level);
void EEVEE_downsample_cube_buffer(EEVEE_Data *vedata, struct GPUTexture *texture_src, int level);
diff --git a/source/blender/draw/engines/eevee/eevee_render.c b/source/blender/draw/engines/eevee/eevee_render.c
index 8a2f7bdd1e0..8e3857ae8a8 100644
--- a/source/blender/draw/engines/eevee/eevee_render.c
+++ b/source/blender/draw/engines/eevee/eevee_render.c
@@ -486,10 +486,14 @@ void EEVEE_render_draw(EEVEE_Data *vedata, RenderEngine *engine, RenderLayer *rl
EEVEE_PrivateData *g_data = stl->g_data;
/* FINISH CACHE */
+ EEVEE_volumes_cache_finish(sldata, vedata);
EEVEE_materials_cache_finish(sldata, vedata);
EEVEE_lights_cache_finish(sldata, vedata);
EEVEE_lightprobes_cache_finish(sldata, vedata);
+ EEVEE_effects_draw_init(sldata, vedata);
+ EEVEE_volumes_draw_init(sldata, vedata);
+
/* Sort transparents before the loop. */
DRW_pass_sort_shgroup_z(psl->transparent_pass);
diff --git a/source/blender/draw/engines/eevee/eevee_volumes.c b/source/blender/draw/engines/eevee/eevee_volumes.c
index 8867bf107ec..39942617d2b 100644
--- a/source/blender/draw/engines/eevee/eevee_volumes.c
+++ b/source/blender/draw/engines/eevee/eevee_volumes.c
@@ -49,8 +49,8 @@ static struct {
char *volumetric_common_lights_lib;
struct GPUShader *volumetric_clear_sh;
- struct GPUShader *volumetric_scatter_sh;
- struct GPUShader *volumetric_scatter_with_lights_sh;
+ struct GPUShader *scatter_sh;
+ struct GPUShader *scatter_with_lights_sh;
struct GPUShader *volumetric_integration_sh;
struct GPUShader *volumetric_resolve_sh;
@@ -60,6 +60,9 @@ static struct {
GPUTexture *dummy_density;
GPUTexture *dummy_flame;
+ GPUTexture *dummy_scatter;
+ GPUTexture *dummy_transmit;
+
/* List of all smoke domains rendered within this frame. */
ListBase smoke_domains;
} e_data = {NULL}; /* Engine data */
@@ -100,22 +103,21 @@ static void eevee_create_shader_volumes(void)
e_data.volumetric_common_lib,
"#define VOLUMETRICS\n"
"#define CLEAR\n");
- e_data.volumetric_scatter_sh = DRW_shader_create_with_lib(datatoc_volumetric_vert_glsl,
- datatoc_volumetric_geom_glsl,
- datatoc_volumetric_scatter_frag_glsl,
- e_data.volumetric_common_lights_lib,
- SHADER_DEFINES
- "#define VOLUMETRICS\n"
- "#define VOLUME_SHADOW\n");
- e_data.volumetric_scatter_with_lights_sh = DRW_shader_create_with_lib(
- datatoc_volumetric_vert_glsl,
- datatoc_volumetric_geom_glsl,
- datatoc_volumetric_scatter_frag_glsl,
- e_data.volumetric_common_lights_lib,
- SHADER_DEFINES
- "#define VOLUMETRICS\n"
- "#define VOLUME_LIGHTING\n"
- "#define VOLUME_SHADOW\n");
+ e_data.scatter_sh = DRW_shader_create_with_lib(datatoc_volumetric_vert_glsl,
+ datatoc_volumetric_geom_glsl,
+ datatoc_volumetric_scatter_frag_glsl,
+ e_data.volumetric_common_lights_lib,
+ SHADER_DEFINES
+ "#define VOLUMETRICS\n"
+ "#define VOLUME_SHADOW\n");
+ e_data.scatter_with_lights_sh = DRW_shader_create_with_lib(datatoc_volumetric_vert_glsl,
+ datatoc_volumetric_geom_glsl,
+ datatoc_volumetric_scatter_frag_glsl,
+ e_data.volumetric_common_lights_lib,
+ SHADER_DEFINES
+ "#define VOLUMETRICS\n"
+ "#define VOLUME_LIGHTING\n"
+ "#define VOLUME_SHADOW\n");
e_data.volumetric_integration_sh = DRW_shader_create_with_lib(
datatoc_volumetric_vert_glsl,
datatoc_volumetric_geom_glsl,
@@ -150,7 +152,7 @@ void EEVEE_volumes_set_jitter(EEVEE_ViewLayerData *sldata, uint current_sample)
common_data->vol_jitter[2] = (float)ht_point[2];
}
-int EEVEE_volumes_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
+void EEVEE_volumes_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
{
EEVEE_StorageList *stl = vedata->stl;
EEVEE_FramebufferList *fbl = vedata->fbl;
@@ -165,312 +167,207 @@ int EEVEE_volumes_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
BLI_listbase_clear(&e_data.smoke_domains);
- if (scene_eval->eevee.flag & SCE_EEVEE_VOLUMETRIC_ENABLED) {
-
- /* Shaders */
- if (!e_data.volumetric_scatter_sh) {
- eevee_create_shader_volumes();
- }
-
- const int tile_size = scene_eval->eevee.volumetric_tile_size;
-
- /* Find Froxel Texture resolution. */
- int tex_size[3];
-
- tex_size[0] = (int)ceilf(fmaxf(1.0f, viewport_size[0] / (float)tile_size));
- tex_size[1] = (int)ceilf(fmaxf(1.0f, viewport_size[1] / (float)tile_size));
- tex_size[2] = max_ii(scene_eval->eevee.volumetric_samples, 1);
-
- common_data->vol_coord_scale[0] = viewport_size[0] / (float)(tile_size * tex_size[0]);
- common_data->vol_coord_scale[1] = viewport_size[1] / (float)(tile_size * tex_size[1]);
-
- /* TODO compute snap to maxZBuffer for clustered rendering */
-
- if ((common_data->vol_tex_size[0] != tex_size[0]) ||
- (common_data->vol_tex_size[1] != tex_size[1]) ||
- (common_data->vol_tex_size[2] != tex_size[2])) {
- DRW_TEXTURE_FREE_SAFE(txl->volume_prop_scattering);
- DRW_TEXTURE_FREE_SAFE(txl->volume_prop_extinction);
- DRW_TEXTURE_FREE_SAFE(txl->volume_prop_emission);
- DRW_TEXTURE_FREE_SAFE(txl->volume_prop_phase);
- DRW_TEXTURE_FREE_SAFE(txl->volume_scatter);
- DRW_TEXTURE_FREE_SAFE(txl->volume_transmittance);
- DRW_TEXTURE_FREE_SAFE(txl->volume_scatter_history);
- DRW_TEXTURE_FREE_SAFE(txl->volume_transmittance_history);
- GPU_FRAMEBUFFER_FREE_SAFE(fbl->volumetric_fb);
- GPU_FRAMEBUFFER_FREE_SAFE(fbl->volumetric_scat_fb);
- GPU_FRAMEBUFFER_FREE_SAFE(fbl->volumetric_integ_fb);
- common_data->vol_tex_size[0] = tex_size[0];
- common_data->vol_tex_size[1] = tex_size[1];
- common_data->vol_tex_size[2] = tex_size[2];
-
- common_data->vol_inv_tex_size[0] = 1.0f / (float)(tex_size[0]);
- common_data->vol_inv_tex_size[1] = 1.0f / (float)(tex_size[1]);
- common_data->vol_inv_tex_size[2] = 1.0f / (float)(tex_size[2]);
- }
-
- /* Like frostbite's paper, 5% blend of the new frame. */
- common_data->vol_history_alpha = (txl->volume_prop_scattering == NULL) ? 0.0f : 0.95f;
-
- if (txl->volume_prop_scattering == NULL) {
- /* Volume properties: We evaluate all volumetric objects
- * and store their final properties into each froxel */
- txl->volume_prop_scattering = DRW_texture_create_3d(
- tex_size[0], tex_size[1], tex_size[2], GPU_R11F_G11F_B10F, DRW_TEX_FILTER, NULL);
- txl->volume_prop_extinction = DRW_texture_create_3d(
- tex_size[0], tex_size[1], tex_size[2], GPU_R11F_G11F_B10F, DRW_TEX_FILTER, NULL);
- txl->volume_prop_emission = DRW_texture_create_3d(
- tex_size[0], tex_size[1], tex_size[2], GPU_R11F_G11F_B10F, DRW_TEX_FILTER, NULL);
- txl->volume_prop_phase = DRW_texture_create_3d(
- tex_size[0], tex_size[1], tex_size[2], GPU_RG16F, DRW_TEX_FILTER, NULL);
-
- /* Volume scattering: We compute for each froxel the
- * Scattered light towards the view. We also resolve temporal
- * super sampling during this stage. */
- txl->volume_scatter = DRW_texture_create_3d(
- tex_size[0], tex_size[1], tex_size[2], GPU_R11F_G11F_B10F, DRW_TEX_FILTER, NULL);
- txl->volume_transmittance = DRW_texture_create_3d(
- tex_size[0], tex_size[1], tex_size[2], GPU_R11F_G11F_B10F, DRW_TEX_FILTER, NULL);
+ const int tile_size = scene_eval->eevee.volumetric_tile_size;
+
+ /* Find Froxel Texture resolution. */
+ int tex_size[3];
+
+ tex_size[0] = (int)ceilf(fmaxf(1.0f, viewport_size[0] / (float)tile_size));
+ tex_size[1] = (int)ceilf(fmaxf(1.0f, viewport_size[1] / (float)tile_size));
+ tex_size[2] = max_ii(scene_eval->eevee.volumetric_samples, 1);
+
+ common_data->vol_coord_scale[0] = viewport_size[0] / (float)(tile_size * tex_size[0]);
+ common_data->vol_coord_scale[1] = viewport_size[1] / (float)(tile_size * tex_size[1]);
+
+ /* TODO compute snap to maxZBuffer for clustered rendering */
+ if ((common_data->vol_tex_size[0] != tex_size[0]) ||
+ (common_data->vol_tex_size[1] != tex_size[1]) ||
+ (common_data->vol_tex_size[2] != tex_size[2])) {
+ DRW_TEXTURE_FREE_SAFE(txl->volume_prop_scattering);
+ DRW_TEXTURE_FREE_SAFE(txl->volume_prop_extinction);
+ DRW_TEXTURE_FREE_SAFE(txl->volume_prop_emission);
+ DRW_TEXTURE_FREE_SAFE(txl->volume_prop_phase);
+ DRW_TEXTURE_FREE_SAFE(txl->volume_scatter);
+ DRW_TEXTURE_FREE_SAFE(txl->volume_transmit);
+ DRW_TEXTURE_FREE_SAFE(txl->volume_scatter_history);
+ DRW_TEXTURE_FREE_SAFE(txl->volume_transmit_history);
+ GPU_FRAMEBUFFER_FREE_SAFE(fbl->volumetric_fb);
+ GPU_FRAMEBUFFER_FREE_SAFE(fbl->volumetric_scat_fb);
+ GPU_FRAMEBUFFER_FREE_SAFE(fbl->volumetric_integ_fb);
+ copy_v3_v3_int(common_data->vol_tex_size, tex_size);
+
+ common_data->vol_inv_tex_size[0] = 1.0f / (float)(tex_size[0]);
+ common_data->vol_inv_tex_size[1] = 1.0f / (float)(tex_size[1]);
+ common_data->vol_inv_tex_size[2] = 1.0f / (float)(tex_size[2]);
+ }
- /* Final integration: We compute for each froxel the
- * amount of scattered light and extinction coef at this
- * given depth. We use theses textures as double buffer
- * for the volumetric history. */
- txl->volume_scatter_history = DRW_texture_create_3d(
- tex_size[0], tex_size[1], tex_size[2], GPU_R11F_G11F_B10F, DRW_TEX_FILTER, NULL);
- txl->volume_transmittance_history = DRW_texture_create_3d(
- tex_size[0], tex_size[1], tex_size[2], GPU_R11F_G11F_B10F, DRW_TEX_FILTER, NULL);
- }
+ /* Like frostbite's paper, 5% blend of the new frame. */
+ common_data->vol_history_alpha = (txl->volume_prop_scattering == NULL) ? 0.0f : 0.95f;
- /* Temporal Super sampling jitter */
- uint ht_primes[3] = {3, 7, 2};
- uint current_sample = 0;
+ /* Temporal Super sampling jitter */
+ uint ht_primes[3] = {3, 7, 2};
+ uint current_sample = 0;
- /* If TAA is in use do not use the history buffer. */
- bool do_taa = ((effects->enabled_effects & EFFECT_TAA) != 0);
+ /* If TAA is in use do not use the history buffer. */
+ bool do_taa = ((effects->enabled_effects & EFFECT_TAA) != 0);
- if (draw_ctx->evil_C != NULL) {
- struct wmWindowManager *wm = CTX_wm_manager(draw_ctx->evil_C);
- do_taa = do_taa && (ED_screen_animation_no_scrub(wm) == NULL);
- }
+ if (draw_ctx->evil_C != NULL) {
+ struct wmWindowManager *wm = CTX_wm_manager(draw_ctx->evil_C);
+ do_taa = do_taa && (ED_screen_animation_no_scrub(wm) == NULL);
+ }
- if (do_taa) {
- common_data->vol_history_alpha = 0.0f;
- current_sample = effects->taa_current_sample - 1;
- effects->volume_current_sample = -1;
- }
- else {
- const uint max_sample = (ht_primes[0] * ht_primes[1] * ht_primes[2]);
- current_sample = effects->volume_current_sample = (effects->volume_current_sample + 1) %
- max_sample;
- if (current_sample != max_sample - 1) {
- DRW_viewport_request_redraw();
- }
+ if (do_taa) {
+ common_data->vol_history_alpha = 0.0f;
+ current_sample = effects->taa_current_sample - 1;
+ effects->volume_current_sample = -1;
+ }
+ else {
+ const uint max_sample = (ht_primes[0] * ht_primes[1] * ht_primes[2]);
+ current_sample = effects->volume_current_sample = (effects->volume_current_sample + 1) %
+ max_sample;
+ if (current_sample != max_sample - 1) {
+ DRW_viewport_request_redraw();
}
+ }
- EEVEE_volumes_set_jitter(sldata, current_sample);
+ EEVEE_volumes_set_jitter(sldata, current_sample);
- /* Framebuffer setup */
- GPU_framebuffer_ensure_config(&fbl->volumetric_fb,
- {GPU_ATTACHMENT_NONE,
- GPU_ATTACHMENT_TEXTURE(txl->volume_prop_scattering),
- GPU_ATTACHMENT_TEXTURE(txl->volume_prop_extinction),
- GPU_ATTACHMENT_TEXTURE(txl->volume_prop_emission),
- GPU_ATTACHMENT_TEXTURE(txl->volume_prop_phase)});
- GPU_framebuffer_ensure_config(&fbl->volumetric_scat_fb,
- {GPU_ATTACHMENT_NONE,
- GPU_ATTACHMENT_TEXTURE(txl->volume_scatter),
- GPU_ATTACHMENT_TEXTURE(txl->volume_transmittance)});
- GPU_framebuffer_ensure_config(&fbl->volumetric_integ_fb,
- {GPU_ATTACHMENT_NONE,
- GPU_ATTACHMENT_TEXTURE(txl->volume_scatter_history),
- GPU_ATTACHMENT_TEXTURE(txl->volume_transmittance_history)});
-
- float integration_start = scene_eval->eevee.volumetric_start;
- float integration_end = scene_eval->eevee.volumetric_end;
- common_data->vol_light_clamp = scene_eval->eevee.volumetric_light_clamp;
- common_data->vol_shadow_steps = (float)scene_eval->eevee.volumetric_shadow_samples;
- if ((scene_eval->eevee.flag & SCE_EEVEE_VOLUMETRIC_SHADOWS) == 0) {
- common_data->vol_shadow_steps = 0;
- }
+ float integration_start = scene_eval->eevee.volumetric_start;
+ float integration_end = scene_eval->eevee.volumetric_end;
+ common_data->vol_light_clamp = scene_eval->eevee.volumetric_light_clamp;
+ common_data->vol_shadow_steps = (float)scene_eval->eevee.volumetric_shadow_samples;
+ if ((scene_eval->eevee.flag & SCE_EEVEE_VOLUMETRIC_SHADOWS) == 0) {
+ common_data->vol_shadow_steps = 0;
+ }
- /* Update view_vecs */
- float invproj[4][4], winmat[4][4];
- DRW_viewport_matrix_get(winmat, DRW_MAT_WIN);
- DRW_viewport_matrix_get(invproj, DRW_MAT_WININV);
- EEVEE_update_viewvecs(invproj, winmat, sldata->common_data.view_vecs);
-
- if (DRW_viewport_is_persp_get()) {
- float sample_distribution = scene_eval->eevee.volumetric_sample_distribution;
- sample_distribution = 4.0f * (1.00001f - sample_distribution);
-
- const float clip_start = common_data->view_vecs[0][2];
- /* Negate */
- float near = integration_start = min_ff(-integration_start, clip_start - 1e-4f);
- float far = integration_end = min_ff(-integration_end, near - 1e-4f);
-
- common_data->vol_depth_param[0] = (far - near * exp2(1.0f / sample_distribution)) /
- (far - near);
- common_data->vol_depth_param[1] = (1.0f - common_data->vol_depth_param[0]) / near;
- common_data->vol_depth_param[2] = sample_distribution;
- }
- else {
- const float clip_start = common_data->view_vecs[0][2];
- const float clip_end = clip_start + common_data->view_vecs[1][2];
- integration_start = min_ff(integration_end, clip_start);
- integration_end = max_ff(-integration_end, clip_end);
-
- common_data->vol_depth_param[0] = integration_start;
- common_data->vol_depth_param[1] = integration_end;
- common_data->vol_depth_param[2] = 1.0f / (integration_end - integration_start);
- }
+ /* Update view_vecs */
+ float invproj[4][4], winmat[4][4];
+ DRW_viewport_matrix_get(winmat, DRW_MAT_WIN);
+ DRW_viewport_matrix_get(invproj, DRW_MAT_WININV);
+ EEVEE_update_viewvecs(invproj, winmat, sldata->common_data.view_vecs);
+
+ if (DRW_viewport_is_persp_get()) {
+ float sample_distribution = scene_eval->eevee.volumetric_sample_distribution;
+ sample_distribution = 4.0f * (1.00001f - sample_distribution);
+
+ const float clip_start = common_data->view_vecs[0][2];
+ /* Negate */
+ float near = integration_start = min_ff(-integration_start, clip_start - 1e-4f);
+ float far = integration_end = min_ff(-integration_end, near - 1e-4f);
+
+ common_data->vol_depth_param[0] = (far - near * exp2(1.0f / sample_distribution)) /
+ (far - near);
+ common_data->vol_depth_param[1] = (1.0f - common_data->vol_depth_param[0]) / near;
+ common_data->vol_depth_param[2] = sample_distribution;
+ }
+ else {
+ const float clip_start = common_data->view_vecs[0][2];
+ const float clip_end = clip_start + common_data->view_vecs[1][2];
+ integration_start = min_ff(integration_end, clip_start);
+ integration_end = max_ff(-integration_end, clip_end);
+
+ common_data->vol_depth_param[0] = integration_start;
+ common_data->vol_depth_param[1] = integration_end;
+ common_data->vol_depth_param[2] = 1.0f / (integration_end - integration_start);
+ }
- /* Disable clamp if equal to 0. */
- if (common_data->vol_light_clamp == 0.0) {
- common_data->vol_light_clamp = FLT_MAX;
- }
+ /* Disable clamp if equal to 0. */
+ if (common_data->vol_light_clamp == 0.0) {
+ common_data->vol_light_clamp = FLT_MAX;
+ }
- common_data->vol_use_lights = (scene_eval->eevee.flag & SCE_EEVEE_VOLUMETRIC_LIGHTS) != 0;
+ common_data->vol_use_lights = (scene_eval->eevee.flag & SCE_EEVEE_VOLUMETRIC_LIGHTS) != 0;
- return EFFECT_VOLUMETRIC | EFFECT_POST_BUFFER;
+ if (!e_data.dummy_scatter) {
+ float scatter[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+ float transmit[4] = {1.0f, 1.0f, 1.0f, 1.0f};
+ e_data.dummy_scatter = DRW_texture_create_3d(1, 1, 1, GPU_RGBA8, DRW_TEX_WRAP, scatter);
+ e_data.dummy_transmit = DRW_texture_create_3d(1, 1, 1, GPU_RGBA8, DRW_TEX_WRAP, transmit);
}
-
- /* Cleanup to release memory */
- DRW_TEXTURE_FREE_SAFE(txl->volume_prop_scattering);
- DRW_TEXTURE_FREE_SAFE(txl->volume_prop_extinction);
- DRW_TEXTURE_FREE_SAFE(txl->volume_prop_emission);
- DRW_TEXTURE_FREE_SAFE(txl->volume_prop_phase);
- DRW_TEXTURE_FREE_SAFE(txl->volume_scatter);
- DRW_TEXTURE_FREE_SAFE(txl->volume_transmittance);
- DRW_TEXTURE_FREE_SAFE(txl->volume_scatter_history);
- DRW_TEXTURE_FREE_SAFE(txl->volume_transmittance_history);
- GPU_FRAMEBUFFER_FREE_SAFE(fbl->volumetric_fb);
- GPU_FRAMEBUFFER_FREE_SAFE(fbl->volumetric_scat_fb);
- GPU_FRAMEBUFFER_FREE_SAFE(fbl->volumetric_integ_fb);
-
- return 0;
}
void EEVEE_volumes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
{
EEVEE_PassList *psl = vedata->psl;
EEVEE_StorageList *stl = vedata->stl;
- EEVEE_TextureList *txl = vedata->txl;
EEVEE_EffectsInfo *effects = stl->effects;
- LightCache *lcache = stl->g_data->light_cache;
EEVEE_CommonUniformBuffer *common_data = &sldata->common_data;
- if ((effects->enabled_effects & EFFECT_VOLUMETRIC) != 0) {
- const DRWContextState *draw_ctx = DRW_context_state_get();
- Scene *scene = draw_ctx->scene;
- DRWShadingGroup *grp = NULL;
-
- /* Quick breakdown of the Volumetric rendering:
- *
- * The rendering is separated in 4 stages:
- *
- * - Material Parameters : we collect volume properties of
- * all participating media in the scene and store them in
- * a 3D texture aligned with the 3D frustum.
- * This is done in 2 passes, one that clear the texture
- * and/or evaluate the world volumes, and the 2nd one that
- * additively render object volumes.
- *
- * - Light Scattering : the volume properties then are sampled
- * and light scattering is evaluated for each cell of the
- * volume texture. Temporal super-sampling (if enabled) occurs here.
- *
- * - Volume Integration : the scattered light and extinction is
- * integrated (accumulated) along the view-rays. The result is stored
- * for every cell in another texture.
- *
- * - Full-screen Resolve : From the previous stage, we get two
- * 3D textures that contains integrated scattered light and extinction
- * for "every" positions in the frustum. We only need to sample
- * them and blend the scene color with those factors. This also
- * work for alpha blended materials.
- */
-
- /* World pass is not additive as it also clear the buffer. */
- psl->volumetric_world_ps = DRW_pass_create("Volumetric World", DRW_STATE_WRITE_COLOR);
-
- /* World Volumetric */
- struct World *wo = scene->world;
- if (wo != NULL && wo->use_nodes && wo->nodetree &&
- !LOOK_DEV_STUDIO_LIGHT_ENABLED(draw_ctx->v3d)) {
- struct GPUMaterial *mat = EEVEE_material_world_volume_get(scene, wo);
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ Scene *scene = draw_ctx->scene;
+ DRWShadingGroup *grp = NULL;
- grp = DRW_shgroup_material_create(mat, psl->volumetric_world_ps);
+ /* Shaders */
+ if (!e_data.scatter_sh) {
+ eevee_create_shader_volumes();
+ }
- if (grp) {
- DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
- /* TODO (fclem): remove those (need to clean the GLSL files). */
- DRW_shgroup_uniform_block(grp, "grid_block", sldata->grid_ubo);
- DRW_shgroup_uniform_block(grp, "probe_block", sldata->probe_ubo);
- DRW_shgroup_uniform_block(grp, "planar_block", sldata->planar_ubo);
- DRW_shgroup_uniform_block(grp, "light_block", sldata->light_ubo);
- DRW_shgroup_uniform_block(grp, "shadow_block", sldata->shadow_ubo);
-
- /* Fix principle volumetric not working with world materials. */
- DRW_shgroup_uniform_texture(grp, "sampdensity", e_data.dummy_density);
- DRW_shgroup_uniform_texture(grp, "sampflame", e_data.dummy_flame);
- DRW_shgroup_uniform_vec2(grp, "unftemperature", (float[2]){0.0f, 1.0f}, 1);
-
- DRW_shgroup_call_procedural_triangles(grp, common_data->vol_tex_size[2], NULL);
- }
+ /* Quick breakdown of the Volumetric rendering:
+ *
+ * The rendering is separated in 4 stages:
+ *
+ * - Material Parameters : we collect volume properties of
+ * all participating media in the scene and store them in
+ * a 3D texture aligned with the 3D frustum.
+ * This is done in 2 passes, one that clear the texture
+ * and/or evaluate the world volumes, and the 2nd one that
+ * additively render object volumes.
+ *
+ * - Light Scattering : the volume properties then are sampled
+ * and light scattering is evaluated for each cell of the
+ * volume texture. Temporal super-sampling (if enabled) occurs here.
+ *
+ * - Volume Integration : the scattered light and extinction is
+ * integrated (accumulated) along the view-rays. The result is stored
+ * for every cell in another texture.
+ *
+ * - Full-screen Resolve : From the previous stage, we get two
+ * 3D textures that contains integrated scattered light and extinction
+ * for "every" positions in the frustum. We only need to sample
+ * them and blend the scene color with those factors. This also
+ * work for alpha blended materials.
+ */
+
+ /* World pass is not additive as it also clear the buffer. */
+ DRW_PASS_CREATE(psl->volumetric_world_ps, DRW_STATE_WRITE_COLOR);
+ DRW_PASS_CREATE(psl->volumetric_objects_ps, DRW_STATE_WRITE_COLOR | DRW_STATE_ADDITIVE);
+
+ /* World Volumetric */
+ struct World *wo = scene->world;
+ if (wo != NULL && wo->use_nodes && wo->nodetree &&
+ !LOOK_DEV_STUDIO_LIGHT_ENABLED(draw_ctx->v3d)) {
+ struct GPUMaterial *mat = EEVEE_material_world_volume_get(scene, wo);
+
+ if (GPU_material_use_domain_volume(mat)) {
+ grp = DRW_shgroup_material_create(mat, psl->volumetric_world_ps);
}
- if (grp == NULL) {
- /* If no world or volume material is present just clear the buffer with this drawcall */
- grp = DRW_shgroup_create(e_data.volumetric_clear_sh, psl->volumetric_world_ps);
-
+ if (grp) {
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
+ /* TODO (fclem): remove those (need to clean the GLSL files). */
+ DRW_shgroup_uniform_block(grp, "grid_block", sldata->grid_ubo);
+ DRW_shgroup_uniform_block(grp, "probe_block", sldata->probe_ubo);
+ DRW_shgroup_uniform_block(grp, "planar_block", sldata->planar_ubo);
+ DRW_shgroup_uniform_block(grp, "light_block", sldata->light_ubo);
+ DRW_shgroup_uniform_block(grp, "shadow_block", sldata->shadow_ubo);
+
+ /* Fix principle volumetric not working with world materials. */
+ DRW_shgroup_uniform_texture(grp, "sampdensity", e_data.dummy_density);
+ DRW_shgroup_uniform_texture(grp, "sampflame", e_data.dummy_flame);
+ DRW_shgroup_uniform_vec2_copy(grp, "unftemperature", (float[2]){0.0f, 1.0f});
DRW_shgroup_call_procedural_triangles(grp, common_data->vol_tex_size[2], NULL);
- }
-
- /* Volumetric Objects */
- psl->volumetric_objects_ps = DRW_pass_create("Volumetric Properties",
- DRW_STATE_WRITE_COLOR | DRW_STATE_ADDITIVE);
-
- struct GPUShader *scatter_sh = (common_data->vol_use_lights) ?
- e_data.volumetric_scatter_with_lights_sh :
- e_data.volumetric_scatter_sh;
- psl->volumetric_scatter_ps = DRW_pass_create("Volumetric Scattering", DRW_STATE_WRITE_COLOR);
- grp = DRW_shgroup_create(scatter_sh, psl->volumetric_scatter_ps);
- DRW_shgroup_uniform_texture_ref(grp, "irradianceGrid", &lcache->grid_tx.tex);
- DRW_shgroup_uniform_texture_ref(grp, "shadowCubeTexture", &sldata->shadow_cube_pool);
- DRW_shgroup_uniform_texture_ref(grp, "shadowCascadeTexture", &sldata->shadow_cascade_pool);
- DRW_shgroup_uniform_texture_ref(grp, "volumeScattering", &txl->volume_prop_scattering);
- DRW_shgroup_uniform_texture_ref(grp, "volumeExtinction", &txl->volume_prop_extinction);
- DRW_shgroup_uniform_texture_ref(grp, "volumeEmission", &txl->volume_prop_emission);
- DRW_shgroup_uniform_texture_ref(grp, "volumePhase", &txl->volume_prop_phase);
- DRW_shgroup_uniform_texture_ref(grp, "historyScattering", &txl->volume_scatter_history);
- DRW_shgroup_uniform_texture_ref(
- grp, "historyTransmittance", &txl->volume_transmittance_history);
- DRW_shgroup_uniform_block(grp, "light_block", sldata->light_ubo);
- DRW_shgroup_uniform_block(grp, "shadow_block", sldata->shadow_ubo);
- DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
- DRW_shgroup_call_procedural_triangles(grp, common_data->vol_tex_size[2], NULL);
+ effects->enabled_effects |= (EFFECT_VOLUMETRIC | EFFECT_POST_BUFFER);
+ }
+ }
- psl->volumetric_integration_ps = DRW_pass_create("Volumetric Integration",
- DRW_STATE_WRITE_COLOR);
- grp = DRW_shgroup_create(e_data.volumetric_integration_sh, psl->volumetric_integration_ps);
- DRW_shgroup_uniform_texture_ref(grp, "volumeScattering", &txl->volume_scatter);
- DRW_shgroup_uniform_texture_ref(grp, "volumeExtinction", &txl->volume_transmittance);
+ if (grp == NULL) {
+ /* If no world or volume material is present just clear the buffer with this drawcall */
+ grp = DRW_shgroup_create(e_data.volumetric_clear_sh, psl->volumetric_world_ps);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
DRW_shgroup_call_procedural_triangles(grp, common_data->vol_tex_size[2], NULL);
-
- psl->volumetric_resolve_ps = DRW_pass_create("Volumetric Resolve", DRW_STATE_WRITE_COLOR);
- grp = DRW_shgroup_create(e_data.volumetric_resolve_sh, psl->volumetric_resolve_ps);
- DRW_shgroup_uniform_texture_ref(grp, "inScattering", &txl->volume_scatter);
- DRW_shgroup_uniform_texture_ref(grp, "inTransmittance", &txl->volume_transmittance);
- DRW_shgroup_uniform_texture_ref(grp, "inSceneColor", &e_data.color_src);
- DRW_shgroup_uniform_texture_ref(grp, "inSceneDepth", &e_data.depth_src);
- DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
- DRW_shgroup_call(grp, DRW_cache_fullscreen_quad_get(), NULL);
}
}
@@ -581,6 +478,135 @@ void EEVEE_volumes_cache_object_add(EEVEE_ViewLayerData *sldata,
/* TODO Reduce to number of slices intersecting. */
/* TODO Preemptive culling. */
DRW_shgroup_call_procedural_triangles(grp, sldata->common_data.vol_tex_size[2], NULL);
+
+ vedata->stl->effects->enabled_effects |= (EFFECT_VOLUMETRIC | EFFECT_POST_BUFFER);
+}
+
+void EEVEE_volumes_cache_finish(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
+{
+ EEVEE_PassList *psl = vedata->psl;
+ EEVEE_TextureList *txl = vedata->txl;
+ EEVEE_EffectsInfo *effects = vedata->stl->effects;
+ LightCache *lcache = vedata->stl->g_data->light_cache;
+ EEVEE_CommonUniformBuffer *common_data = &sldata->common_data;
+
+ if ((effects->enabled_effects & EFFECT_VOLUMETRIC) != 0) {
+ DRWShadingGroup *grp;
+ struct GPUShader *sh;
+
+ DRW_PASS_CREATE(psl->volumetric_scatter_ps, DRW_STATE_WRITE_COLOR);
+ sh = (common_data->vol_use_lights) ? e_data.scatter_with_lights_sh : e_data.scatter_sh;
+ grp = DRW_shgroup_create(sh, psl->volumetric_scatter_ps);
+ DRW_shgroup_uniform_texture_ref(grp, "irradianceGrid", &lcache->grid_tx.tex);
+ DRW_shgroup_uniform_texture_ref(grp, "shadowCubeTexture", &sldata->shadow_cube_pool);
+ DRW_shgroup_uniform_texture_ref(grp, "shadowCascadeTexture", &sldata->shadow_cascade_pool);
+ DRW_shgroup_uniform_texture_ref(grp, "volumeScattering", &txl->volume_prop_scattering);
+ DRW_shgroup_uniform_texture_ref(grp, "volumeExtinction", &txl->volume_prop_extinction);
+ DRW_shgroup_uniform_texture_ref(grp, "volumeEmission", &txl->volume_prop_emission);
+ DRW_shgroup_uniform_texture_ref(grp, "volumePhase", &txl->volume_prop_phase);
+ DRW_shgroup_uniform_texture_ref(grp, "historyScattering", &txl->volume_scatter_history);
+ DRW_shgroup_uniform_texture_ref(grp, "historyTransmittance", &txl->volume_transmit_history);
+ DRW_shgroup_uniform_block(grp, "light_block", sldata->light_ubo);
+ DRW_shgroup_uniform_block(grp, "shadow_block", sldata->shadow_ubo);
+ DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
+
+ DRW_shgroup_call_procedural_triangles(grp, common_data->vol_tex_size[2], NULL);
+
+ DRW_PASS_CREATE(psl->volumetric_integration_ps, DRW_STATE_WRITE_COLOR);
+ grp = DRW_shgroup_create(e_data.volumetric_integration_sh, psl->volumetric_integration_ps);
+ DRW_shgroup_uniform_texture_ref(grp, "volumeScattering", &txl->volume_scatter);
+ DRW_shgroup_uniform_texture_ref(grp, "volumeExtinction", &txl->volume_transmit);
+ DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
+
+ DRW_shgroup_call_procedural_triangles(grp, common_data->vol_tex_size[2], NULL);
+
+ DRW_PASS_CREATE(psl->volumetric_resolve_ps, DRW_STATE_WRITE_COLOR);
+ grp = DRW_shgroup_create(e_data.volumetric_resolve_sh, psl->volumetric_resolve_ps);
+ DRW_shgroup_uniform_texture_ref(grp, "inScattering", &txl->volume_scatter);
+ DRW_shgroup_uniform_texture_ref(grp, "inTransmittance", &txl->volume_transmit);
+ DRW_shgroup_uniform_texture_ref(grp, "inSceneColor", &e_data.color_src);
+ DRW_shgroup_uniform_texture_ref(grp, "inSceneDepth", &e_data.depth_src);
+ DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
+
+ DRW_shgroup_call_procedural_triangles(grp, 1, NULL);
+ }
+}
+
+void EEVEE_volumes_draw_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
+{
+ EEVEE_FramebufferList *fbl = vedata->fbl;
+ EEVEE_TextureList *txl = vedata->txl;
+ EEVEE_EffectsInfo *effects = vedata->stl->effects;
+ EEVEE_CommonUniformBuffer *common_data = &sldata->common_data;
+
+ if ((effects->enabled_effects & EFFECT_VOLUMETRIC) != 0) {
+ int *tex_size = common_data->vol_tex_size;
+
+ if (txl->volume_prop_scattering == NULL) {
+ /* Volume properties: We evaluate all volumetric objects
+ * and store their final properties into each froxel */
+ txl->volume_prop_scattering = DRW_texture_create_3d(
+ tex_size[0], tex_size[1], tex_size[2], GPU_R11F_G11F_B10F, DRW_TEX_FILTER, NULL);
+ txl->volume_prop_extinction = DRW_texture_create_3d(
+ tex_size[0], tex_size[1], tex_size[2], GPU_R11F_G11F_B10F, DRW_TEX_FILTER, NULL);
+ txl->volume_prop_emission = DRW_texture_create_3d(
+ tex_size[0], tex_size[1], tex_size[2], GPU_R11F_G11F_B10F, DRW_TEX_FILTER, NULL);
+ txl->volume_prop_phase = DRW_texture_create_3d(
+ tex_size[0], tex_size[1], tex_size[2], GPU_RG16F, DRW_TEX_FILTER, NULL);
+
+ /* Volume scattering: We compute for each froxel the
+ * Scattered light towards the view. We also resolve temporal
+ * super sampling during this stage. */
+ txl->volume_scatter = DRW_texture_create_3d(
+ tex_size[0], tex_size[1], tex_size[2], GPU_R11F_G11F_B10F, DRW_TEX_FILTER, NULL);
+ txl->volume_transmit = DRW_texture_create_3d(
+ tex_size[0], tex_size[1], tex_size[2], GPU_R11F_G11F_B10F, DRW_TEX_FILTER, NULL);
+
+ /* Final integration: We compute for each froxel the
+ * amount of scattered light and extinction coef at this
+ * given depth. We use theses textures as double buffer
+ * for the volumetric history. */
+ txl->volume_scatter_history = DRW_texture_create_3d(
+ tex_size[0], tex_size[1], tex_size[2], GPU_R11F_G11F_B10F, DRW_TEX_FILTER, NULL);
+ txl->volume_transmit_history = DRW_texture_create_3d(
+ tex_size[0], tex_size[1], tex_size[2], GPU_R11F_G11F_B10F, DRW_TEX_FILTER, NULL);
+ }
+
+ GPU_framebuffer_ensure_config(&fbl->volumetric_fb,
+ {GPU_ATTACHMENT_NONE,
+ GPU_ATTACHMENT_TEXTURE(txl->volume_prop_scattering),
+ GPU_ATTACHMENT_TEXTURE(txl->volume_prop_extinction),
+ GPU_ATTACHMENT_TEXTURE(txl->volume_prop_emission),
+ GPU_ATTACHMENT_TEXTURE(txl->volume_prop_phase)});
+ GPU_framebuffer_ensure_config(&fbl->volumetric_scat_fb,
+ {GPU_ATTACHMENT_NONE,
+ GPU_ATTACHMENT_TEXTURE(txl->volume_scatter),
+ GPU_ATTACHMENT_TEXTURE(txl->volume_transmit)});
+ GPU_framebuffer_ensure_config(&fbl->volumetric_integ_fb,
+ {GPU_ATTACHMENT_NONE,
+ GPU_ATTACHMENT_TEXTURE(txl->volume_scatter_history),
+ GPU_ATTACHMENT_TEXTURE(txl->volume_transmit_history)});
+
+ /* Usage happens after buffer have been swapped. */
+ effects->volume_scatter = txl->volume_scatter_history;
+ effects->volume_transmit = txl->volume_transmit_history;
+ }
+ else {
+ DRW_TEXTURE_FREE_SAFE(txl->volume_prop_scattering);
+ DRW_TEXTURE_FREE_SAFE(txl->volume_prop_extinction);
+ DRW_TEXTURE_FREE_SAFE(txl->volume_prop_emission);
+ DRW_TEXTURE_FREE_SAFE(txl->volume_prop_phase);
+ DRW_TEXTURE_FREE_SAFE(txl->volume_scatter);
+ DRW_TEXTURE_FREE_SAFE(txl->volume_transmit);
+ DRW_TEXTURE_FREE_SAFE(txl->volume_scatter_history);
+ DRW_TEXTURE_FREE_SAFE(txl->volume_transmit_history);
+ GPU_FRAMEBUFFER_FREE_SAFE(fbl->volumetric_fb);
+ GPU_FRAMEBUFFER_FREE_SAFE(fbl->volumetric_scat_fb);
+ GPU_FRAMEBUFFER_FREE_SAFE(fbl->volumetric_integ_fb);
+
+ effects->volume_scatter = e_data.dummy_scatter;
+ effects->volume_transmit = e_data.dummy_transmit;
+ }
}
void EEVEE_volumes_compute(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
@@ -593,23 +619,19 @@ void EEVEE_volumes_compute(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *veda
if ((effects->enabled_effects & EFFECT_VOLUMETRIC) != 0) {
DRW_stats_group_start("Volumetrics");
- /* Step 1: Participating Media Properties */
GPU_framebuffer_bind(fbl->volumetric_fb);
DRW_draw_pass(psl->volumetric_world_ps);
DRW_draw_pass(psl->volumetric_objects_ps);
- /* Step 2: Scatter Light */
GPU_framebuffer_bind(fbl->volumetric_scat_fb);
DRW_draw_pass(psl->volumetric_scatter_ps);
- /* Step 3: Integration */
GPU_framebuffer_bind(fbl->volumetric_integ_fb);
DRW_draw_pass(psl->volumetric_integration_ps);
- /* Swap volume history buffers */
SWAP(struct GPUFrameBuffer *, fbl->volumetric_scat_fb, fbl->volumetric_integ_fb);
SWAP(GPUTexture *, txl->volume_scatter, txl->volume_scatter_history);
- SWAP(GPUTexture *, txl->volume_transmittance, txl->volume_transmittance_history);
+ SWAP(GPUTexture *, txl->volume_transmit, txl->volume_transmit_history);
/* Restore */
GPU_framebuffer_bind(fbl->main_fb);
@@ -663,12 +685,15 @@ void EEVEE_volumes_free(void)
MEM_SAFE_FREE(e_data.volumetric_common_lib);
MEM_SAFE_FREE(e_data.volumetric_common_lights_lib);
+ DRW_TEXTURE_FREE_SAFE(e_data.dummy_scatter);
+ DRW_TEXTURE_FREE_SAFE(e_data.dummy_transmit);
+
DRW_TEXTURE_FREE_SAFE(e_data.dummy_density);
DRW_TEXTURE_FREE_SAFE(e_data.dummy_flame);
DRW_SHADER_FREE_SAFE(e_data.volumetric_clear_sh);
- DRW_SHADER_FREE_SAFE(e_data.volumetric_scatter_sh);
- DRW_SHADER_FREE_SAFE(e_data.volumetric_scatter_with_lights_sh);
+ DRW_SHADER_FREE_SAFE(e_data.scatter_sh);
+ DRW_SHADER_FREE_SAFE(e_data.scatter_with_lights_sh);
DRW_SHADER_FREE_SAFE(e_data.volumetric_integration_sh);
DRW_SHADER_FREE_SAFE(e_data.volumetric_resolve_sh);
}
diff --git a/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl b/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl
index 12e60f0250f..d7160aee340 100644
--- a/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl
@@ -898,7 +898,7 @@ layout(location = 4) out vec4 sssAlbedo;
Closure nodetree_exec(void); /* Prototype */
-# if defined(USE_ALPHA_BLEND_VOLUMETRICS)
+# if defined(USE_ALPHA_BLEND)
/* Prototype because this file is included before volumetric_lib.glsl */
vec4 volumetric_resolve(vec4 scene_color, vec2 frag_uvs, float frag_depth);
# endif
@@ -912,7 +912,7 @@ void main()
cl.opacity = 1.0;
# endif
-# if defined(USE_ALPHA_BLEND_VOLUMETRICS)
+# if defined(USE_ALPHA_BLEND)
/* XXX fragile, better use real viewport resolution */
vec2 uvs = gl_FragCoord.xy / vec2(2 * textureSize(maxzBuffer, 0).xy);
fragColor.rgb = volumetric_resolve(vec4(cl.radiance, cl.opacity), uvs, gl_FragCoord.z).rgb;
diff --git a/source/blender/draw/intern/DRW_render.h b/source/blender/draw/intern/DRW_render.h
index 8337255464a..8d4d66e5853 100644
--- a/source/blender/draw/intern/DRW_render.h
+++ b/source/blender/draw/intern/DRW_render.h
@@ -525,6 +525,8 @@ void DRW_pass_sort_shgroup_z(DRWPass *pass);
bool DRW_pass_is_empty(DRWPass *pass);
+#define DRW_PASS_CREATE(pass, state) (pass = DRW_pass_create(#pass, state))
+
/* Viewport */
typedef enum {
/* keep in sync with the union struct DRWMatrixState. */
diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h
index a5af5be4b57..c64a593c9e2 100644
--- a/source/blender/makesdna/DNA_scene_types.h
+++ b/source/blender/makesdna/DNA_scene_types.h
@@ -2369,7 +2369,7 @@ typedef enum eGPencil_Guide_Reference {
/* SceneEEVEE->flag */
enum {
- SCE_EEVEE_VOLUMETRIC_ENABLED = (1 << 0),
+ // SCE_EEVEE_VOLUMETRIC_ENABLED = (1 << 0), /* Unused */
SCE_EEVEE_VOLUMETRIC_LIGHTS = (1 << 1),
SCE_EEVEE_VOLUMETRIC_SHADOWS = (1 << 2),
// SCE_EEVEE_VOLUMETRIC_COLORED = (1 << 3), /* Unused */
diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c
index ad814ff0021..5733b31e02c 100644
--- a/source/blender/makesrna/intern/rna_scene.c
+++ b/source/blender/makesrna/intern/rna_scene.c
@@ -6872,14 +6872,6 @@ static void rna_def_scene_eevee(BlenderRNA *brna)
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
/* Volumetrics */
- prop = RNA_def_property(srna, "use_volumetric", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", SCE_EEVEE_VOLUMETRIC_ENABLED);
- RNA_def_property_boolean_default(prop, 0);
- RNA_def_property_ui_text(
- prop, "Volumetrics", "Enable scattering and absorbance of volumetric material");
- RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_STATIC);
- RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
-
prop = RNA_def_property(srna, "volumetric_start", PROP_FLOAT, PROP_DISTANCE);
RNA_def_property_float_default(prop, 0.1f);
RNA_def_property_ui_text(prop, "Start", "Start distance of the volumetric effect");
diff --git a/tests/python/eevee_render_tests.py b/tests/python/eevee_render_tests.py
index 8eaf04f8bea..5deb51fea4d 100755
--- a/tests/python/eevee_render_tests.py
+++ b/tests/python/eevee_render_tests.py
@@ -25,7 +25,6 @@ def setup():
eevee.use_gtao = True
eevee.use_dof = False
- eevee.use_volumetric = True
eevee.use_volumetric_shadows = True
eevee.volumetric_tile_size = '2'