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:
-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'