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_view_layer.py95
-rw-r--r--source/blender/draw/CMakeLists.txt3
-rw-r--r--source/blender/draw/engines/eevee/eevee_bloom.c82
-rw-r--r--source/blender/draw/engines/eevee/eevee_data.c3
-rw-r--r--source/blender/draw/engines/eevee/eevee_effects.c10
-rw-r--r--source/blender/draw/engines/eevee/eevee_engine.c13
-rw-r--r--source/blender/draw/engines/eevee/eevee_lightprobes.c14
-rw-r--r--source/blender/draw/engines/eevee/eevee_materials.c731
-rw-r--r--source/blender/draw/engines/eevee/eevee_mist.c2
-rw-r--r--source/blender/draw/engines/eevee/eevee_occlusion.c8
-rw-r--r--source/blender/draw/engines/eevee/eevee_private.h78
-rw-r--r--source/blender/draw/engines/eevee/eevee_render.c210
-rw-r--r--source/blender/draw/engines/eevee/eevee_renderpasses.c232
-rw-r--r--source/blender/draw/engines/eevee/eevee_screen_raytrace.c41
-rw-r--r--source/blender/draw/engines/eevee/eevee_shadows.c89
-rw-r--r--source/blender/draw/engines/eevee/eevee_subsurface.c110
-rw-r--r--source/blender/draw/engines/eevee/eevee_temporal_sampling.c2
-rw-r--r--source/blender/draw/engines/eevee/eevee_volumes.c89
-rw-r--r--source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl34
-rw-r--r--source/blender/draw/engines/eevee/shaders/default_frag.glsl3
-rw-r--r--source/blender/draw/engines/eevee/shaders/effect_bloom_frag.glsl7
-rw-r--r--source/blender/draw/engines/eevee/shaders/effect_subsurface_frag.glsl11
-rw-r--r--source/blender/draw/engines/eevee/shaders/lights_lib.glsl42
-rw-r--r--source/blender/draw/engines/eevee/shaders/renderpass_postprocess_frag.glsl77
-rw-r--r--source/blender/draw/engines/eevee/shaders/shadow_accum_frag.glsl58
-rw-r--r--source/blender/draw/engines/eevee/shaders/volumetric_accum_frag.glsl11
-rw-r--r--source/blender/gpu/shaders/material/gpu_shader_material_diffuse.glsl2
-rw-r--r--source/blender/gpu/shaders/material/gpu_shader_material_eevee_specular.glsl4
-rw-r--r--source/blender/gpu/shaders/material/gpu_shader_material_emission.glsl2
-rw-r--r--source/blender/gpu/shaders/material/gpu_shader_material_glass.glsl6
-rw-r--r--source/blender/gpu/shaders/material/gpu_shader_material_glossy.glsl2
-rw-r--r--source/blender/gpu/shaders/material/gpu_shader_material_principled.glsl97
-rw-r--r--source/blender/gpu/shaders/material/gpu_shader_material_refraction.glsl2
-rw-r--r--source/blender/gpu/shaders/material/gpu_shader_material_subsurface_scattering.glsl1
-rw-r--r--source/blender/gpu/shaders/material/gpu_shader_material_translucent.glsl2
-rw-r--r--source/blender/makesdna/DNA_layer_types.h27
-rw-r--r--source/blender/makesdna/DNA_scene_types.h3
-rw-r--r--source/blender/makesrna/RNA_access.h1
-rw-r--r--source/blender/makesrna/intern/rna_scene.c30
-rw-r--r--source/blender/makesrna/intern/rna_space.c59
-rw-r--r--source/blender/nodes/composite/node_composite_tree.c7
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_image.c19
-rw-r--r--source/blender/render/extern/include/RE_engine.h5
-rw-r--r--source/blender/render/intern/source/external_engine.c2
-rw-r--r--source/blender/render/intern/source/render_result.c9
45 files changed, 1931 insertions, 404 deletions
diff --git a/release/scripts/startup/bl_ui/properties_view_layer.py b/release/scripts/startup/bl_ui/properties_view_layer.py
index 121b8f2f401..25244b7f065 100644
--- a/release/scripts/startup/bl_ui/properties_view_layer.py
+++ b/release/scripts/startup/bl_ui/properties_view_layer.py
@@ -59,14 +59,25 @@ class VIEWLAYER_PT_eevee_layer_passes(ViewLayerButtonsPanel, Panel):
COMPAT_ENGINES = {'BLENDER_EEVEE'}
def draw(self, context):
- layout = self.layout
+ pass
- layout.use_property_split = True
- flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False)
+class VIEWLAYER_PT_eevee_layer_passes_data(ViewLayerButtonsPanel, Panel):
+ bl_label = "Data"
+ bl_parent_id = "VIEWLAYER_PT_eevee_layer_passes"
+ COMPAT_ENGINES = {'BLENDER_EEVEE'}
+
+ def draw(self, context):
+ layout = self.layout
+ layout.use_property_split = True
+ layout.use_property_decorate = False
+
+ scene = context.scene
+ rd = scene.render
view_layer = context.view_layer
+ flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False)
col = flow.column()
col.prop(view_layer, "use_pass_combined")
col = flow.column()
@@ -75,17 +86,83 @@ class VIEWLAYER_PT_eevee_layer_passes(ViewLayerButtonsPanel, Panel):
col.prop(view_layer, "use_pass_mist")
col = flow.column()
col.prop(view_layer, "use_pass_normal")
- col = flow.column()
- col.prop(view_layer, "use_pass_ambient_occlusion")
- col = flow.column()
- col.prop(view_layer, "use_pass_subsurface_direct", text="Subsurface Direct")
- col = flow.column()
- col.prop(view_layer, "use_pass_subsurface_color", text="Subsurface Color")
+class VIEWLAYER_PT_eevee_layer_passes_light(ViewLayerButtonsPanel, Panel):
+ bl_label = "Light"
+ bl_parent_id = "VIEWLAYER_PT_eevee_layer_passes"
+ COMPAT_ENGINES = {'BLENDER_EEVEE'}
+
+ def draw(self, context):
+ layout = self.layout
+
+ layout.use_property_split = True
+ layout.use_property_decorate = False
+
+ view_layer = context.view_layer
+ view_layer_eevee = view_layer.eevee
+ scene = context.scene
+ scene_eevee = scene.eevee
+
+ split = layout.split(factor=0.35)
+ split.use_property_split = False
+ split.label(text="Diffuse")
+ row = split.row(align=True)
+ row.prop(view_layer, "use_pass_diffuse_direct", text="Light", toggle=True)
+ row.prop(view_layer, "use_pass_diffuse_color", text="Color", toggle=True)
+
+ split = layout.split(factor=0.35)
+ split.use_property_split = False
+ split.label(text="Specular")
+ row = split.row(align=True)
+ row.prop(view_layer, "use_pass_glossy_direct", text="Light", toggle=True)
+ row.prop(view_layer, "use_pass_glossy_color", text="Color", toggle=True)
+
+ split = layout.split(factor=0.35)
+ split.use_property_split = False
+ split.label(text="Volume")
+ row = split.row(align=True)
+ row.prop(view_layer_eevee, "use_pass_volume_transmittance", text="Transmittance", toggle=True)
+ row.prop(view_layer_eevee, "use_pass_volume_scatter", text="Scatter", toggle=True)
+ flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False)
+
+ col = layout.column(align=True)
+ col.prop(view_layer, "use_pass_emit", text="Emission")
+ col.prop(view_layer, "use_pass_environment")
+ col.prop(view_layer, "use_pass_shadow")
+ row = col.row()
+ row.prop(view_layer, "use_pass_ambient_occlusion", text="Ambient Occlusion")
+ row.active = scene_eevee.use_gtao
+
+
+class VIEWLAYER_PT_eevee_layer_passes_effects(ViewLayerButtonsPanel, Panel):
+ bl_label = "Effects"
+ bl_parent_id = "VIEWLAYER_PT_eevee_layer_passes"
+ COMPAT_ENGINES = {'BLENDER_EEVEE'}
+
+ def draw(self, context):
+ layout = self.layout
+
+ layout.use_property_split = True
+ layout.use_property_decorate = False
+
+ flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False)
+
+ view_layer = context.view_layer
+ view_layer_eevee = view_layer.eevee
+ scene = context.scene
+ scene_eevee = scene.eevee
+
+ col = flow.column()
+ col.prop(view_layer_eevee, "use_pass_bloom", text="Bloom")
+ col.active = scene_eevee.use_bloom
+
classes = (
VIEWLAYER_PT_layer,
VIEWLAYER_PT_eevee_layer_passes,
+ VIEWLAYER_PT_eevee_layer_passes_data,
+ VIEWLAYER_PT_eevee_layer_passes_light,
+ VIEWLAYER_PT_eevee_layer_passes_effects,
)
if __name__ == "__main__": # only for live edit.
diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt
index 37fe04e9d8a..07a8bba5023 100644
--- a/source/blender/draw/CMakeLists.txt
+++ b/source/blender/draw/CMakeLists.txt
@@ -219,6 +219,8 @@ data_to_c_simple(engines/eevee/shaders/lightprobe_planar_downsample_geom.glsl SR
data_to_c_simple(engines/eevee/shaders/lightprobe_planar_downsample_vert.glsl SRC)
data_to_c_simple(engines/eevee/shaders/prepass_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/prepass_vert.glsl SRC)
+data_to_c_simple(engines/eevee/shaders/shadow_accum_frag.glsl SRC)
+
data_to_c_simple(engines/eevee/shaders/shadow_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/shadow_vert.glsl SRC)
data_to_c_simple(engines/eevee/shaders/bsdf_lut_frag.glsl SRC)
@@ -232,6 +234,7 @@ data_to_c_simple(engines/eevee/shaders/renderpass_postprocess_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/ltc_lib.glsl SRC)
data_to_c_simple(engines/eevee/shaders/ssr_lib.glsl SRC)
data_to_c_simple(engines/eevee/shaders/update_noise_frag.glsl SRC)
+data_to_c_simple(engines/eevee/shaders/volumetric_accum_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/volumetric_lib.glsl SRC)
data_to_c_simple(engines/eevee/shaders/volumetric_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/volumetric_geom.glsl SRC)
diff --git a/source/blender/draw/engines/eevee/eevee_bloom.c b/source/blender/draw/engines/eevee/eevee_bloom.c
index c6cc336db56..53465455d57 100644
--- a/source/blender/draw/engines/eevee/eevee_bloom.c
+++ b/source/blender/draw/engines/eevee/eevee_bloom.c
@@ -40,6 +40,8 @@ static struct {
extern char datatoc_effect_bloom_frag_glsl[];
+const bool use_highres = true;
+
static void eevee_create_shader_bloom(void)
{
e_data.bloom_blit_sh[0] = DRW_shader_create_fullscreen(datatoc_effect_bloom_frag_glsl,
@@ -179,7 +181,8 @@ static DRWShadingGroup *eevee_create_bloom_pass(const char *name,
EEVEE_EffectsInfo *effects,
struct GPUShader *sh,
DRWPass **pass,
- bool upsample)
+ bool upsample,
+ bool resolve)
{
struct GPUBatch *quad = DRW_cache_fullscreen_quad_get();
@@ -193,6 +196,10 @@ static DRWShadingGroup *eevee_create_bloom_pass(const char *name,
DRW_shgroup_uniform_texture_ref(grp, "baseBuffer", &effects->unf_base_buffer);
DRW_shgroup_uniform_float(grp, "sampleScale", &effects->bloom_sample_scale, 1);
}
+ if (resolve) {
+ DRW_shgroup_uniform_vec3(grp, "bloomColor", effects->bloom_color, 1);
+ DRW_shgroup_uniform_bool_copy(grp, "bloomAddBase", true);
+ }
return grp;
}
@@ -203,6 +210,8 @@ void EEVEE_bloom_cache_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *ved
EEVEE_StorageList *stl = vedata->stl;
EEVEE_EffectsInfo *effects = stl->effects;
+ psl->bloom_accum_ps = NULL;
+
if ((effects->enabled_effects & EFFECT_BLOOM) != 0) {
/** Bloom algorithm
*
@@ -234,29 +243,41 @@ void EEVEE_bloom_cache_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *ved
* </pre>
*/
DRWShadingGroup *grp;
- const bool use_highres = true;
const bool use_antiflicker = true;
eevee_create_bloom_pass("Bloom Downsample First",
effects,
e_data.bloom_downsample_sh[use_antiflicker],
&psl->bloom_downsample_first,
+ false,
+ false);
+ eevee_create_bloom_pass("Bloom Downsample",
+ effects,
+ e_data.bloom_downsample_sh[0],
+ &psl->bloom_downsample,
+ false,
false);
- eevee_create_bloom_pass(
- "Bloom Downsample", effects, e_data.bloom_downsample_sh[0], &psl->bloom_downsample, false);
eevee_create_bloom_pass("Bloom Upsample",
effects,
e_data.bloom_upsample_sh[use_highres],
&psl->bloom_upsample,
- true);
+ true,
+ false);
- grp = eevee_create_bloom_pass(
- "Bloom Blit", effects, e_data.bloom_blit_sh[use_antiflicker], &psl->bloom_blit, false);
+ grp = eevee_create_bloom_pass("Bloom Blit",
+ effects,
+ e_data.bloom_blit_sh[use_antiflicker],
+ &psl->bloom_blit,
+ false,
+ false);
DRW_shgroup_uniform_vec4(grp, "curveThreshold", effects->bloom_curve_threshold, 1);
DRW_shgroup_uniform_float(grp, "clampIntensity", &effects->bloom_clamp, 1);
- grp = eevee_create_bloom_pass(
- "Bloom Resolve", effects, e_data.bloom_resolve_sh[use_highres], &psl->bloom_resolve, true);
- DRW_shgroup_uniform_vec3(grp, "bloomColor", effects->bloom_color, 1);
+ grp = eevee_create_bloom_pass("Bloom Resolve",
+ effects,
+ e_data.bloom_resolve_sh[use_highres],
+ &psl->bloom_resolve,
+ true,
+ true);
}
}
@@ -322,6 +343,47 @@ void EEVEE_bloom_draw(EEVEE_Data *vedata)
}
}
+void EEVEE_bloom_output_init(EEVEE_ViewLayerData *UNUSED(sldata),
+ EEVEE_Data *vedata,
+ uint UNUSED(tot_samples))
+{
+ EEVEE_FramebufferList *fbl = vedata->fbl;
+ EEVEE_TextureList *txl = vedata->txl;
+ EEVEE_PassList *psl = vedata->psl;
+ EEVEE_StorageList *stl = vedata->stl;
+ EEVEE_EffectsInfo *effects = stl->effects;
+
+ /* Create FrameBuffer. */
+ DRW_texture_ensure_fullscreen_2d(&txl->bloom_accum, GPU_R11F_G11F_B10F, 0);
+
+ GPU_framebuffer_ensure_config(&fbl->bloom_pass_accum_fb,
+ {GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(txl->bloom_accum)});
+
+ /* Create Pass and shgroup. */
+ DRWShadingGroup *grp = eevee_create_bloom_pass("Bloom Accumulate",
+ effects,
+ e_data.bloom_resolve_sh[use_highres],
+ &psl->bloom_accum_ps,
+ true,
+ true);
+ DRW_shgroup_uniform_bool_copy(grp, "bloomAddBase", false);
+}
+
+void EEVEE_bloom_output_accumulate(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
+{
+ EEVEE_FramebufferList *fbl = vedata->fbl;
+ EEVEE_PassList *psl = vedata->psl;
+ EEVEE_StorageList *stl = vedata->stl;
+
+ if (stl->g_data->render_passes & EEVEE_RENDER_PASS_BLOOM) {
+ GPU_framebuffer_bind(fbl->bloom_pass_accum_fb);
+ DRW_draw_pass(psl->bloom_accum_ps);
+
+ /* Restore */
+ GPU_framebuffer_bind(fbl->main_fb);
+ }
+}
+
void EEVEE_bloom_free(void)
{
for (int i = 0; i < 2; i++) {
diff --git a/source/blender/draw/engines/eevee/eevee_data.c b/source/blender/draw/engines/eevee/eevee_data.c
index dd70ee1bd4b..e586fc7b1db 100644
--- a/source/blender/draw/engines/eevee/eevee_data.c
+++ b/source/blender/draw/engines/eevee/eevee_data.c
@@ -54,6 +54,9 @@ void EEVEE_view_layer_data_free(void *storage)
DRW_UBO_FREE_SAFE(sldata->grid_ubo);
DRW_UBO_FREE_SAFE(sldata->planar_ubo);
DRW_UBO_FREE_SAFE(sldata->common_ubo);
+ for (int i = 0; i < MAX_MATERIAL_RENDER_PASSES_UBO; i++) {
+ DRW_UBO_FREE_SAFE(sldata->renderpass_ubo[i]);
+ }
}
EEVEE_ViewLayerData *EEVEE_view_layer_data_get(void)
diff --git a/source/blender/draw/engines/eevee/eevee_effects.c b/source/blender/draw/engines/eevee/eevee_effects.c
index a20921b639f..90bfad45f60 100644
--- a/source/blender/draw/engines/eevee/eevee_effects.c
+++ b/source/blender/draw/engines/eevee/eevee_effects.c
@@ -170,7 +170,7 @@ void EEVEE_effects_init(EEVEE_ViewLayerData *sldata,
EEVEE_subsurface_init(sldata, vedata);
/* Force normal buffer creation. */
- if (!minimal && (stl->g_data->render_passes & SCE_PASS_NORMAL) != 0) {
+ if (!minimal && (stl->g_data->render_passes & EEVEE_RENDER_PASS_NORMAL) != 0) {
effects->enabled_effects |= EFFECT_NORMAL_BUFFER;
}
@@ -333,6 +333,8 @@ void EEVEE_effects_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
grp = DRW_shgroup_create(EEVEE_shaders_velocity_resolve_sh_get(), psl->velocity_resolve);
DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &e_data.depth_src);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
+ DRW_shgroup_uniform_block(
+ grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_uniform_mat4(grp, "currPersinv", effects->velocity_curr_persinv);
DRW_shgroup_uniform_mat4(grp, "pastPersmat", effects->velocity_past_persmat);
DRW_shgroup_call(grp, quad, NULL);
@@ -513,7 +515,7 @@ static void EEVEE_velocity_resolve(EEVEE_Data *vedata)
DRW_view_persmat_get(view, effects->velocity_past_persmat, false);
}
-void EEVEE_draw_effects(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
+void EEVEE_draw_effects(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
{
EEVEE_TextureList *txl = vedata->txl;
EEVEE_FramebufferList *fbl = vedata->fbl;
@@ -541,6 +543,10 @@ void EEVEE_draw_effects(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
EEVEE_temporal_sampling_draw(vedata);
EEVEE_bloom_draw(vedata);
+ /* Post effect render passes are done here just after the drawing of the effects and just before
+ * the swapping of the buffers. */
+ EEVEE_renderpasses_output_accumulate(sldata, vedata, true);
+
/* Save the final texture and framebuffer for final transformation or read. */
effects->final_tx = effects->source_buffer;
effects->final_fb = (effects->target_buffer != fbl->main_color_fb) ? fbl->main_fb :
diff --git a/source/blender/draw/engines/eevee/eevee_engine.c b/source/blender/draw/engines/eevee/eevee_engine.c
index e3b50bb2142..3337cbcc59d 100644
--- a/source/blender/draw/engines/eevee/eevee_engine.c
+++ b/source/blender/draw/engines/eevee/eevee_engine.c
@@ -151,7 +151,8 @@ void EEVEE_cache_populate(void *vedata, Object *ob)
static void eevee_cache_finish(void *vedata)
{
EEVEE_ViewLayerData *sldata = EEVEE_view_layer_data_ensure();
- EEVEE_PrivateData *g_data = ((EEVEE_Data *)vedata)->stl->g_data;
+ EEVEE_StorageList *stl = ((EEVEE_Data *)vedata)->stl;
+ EEVEE_PrivateData *g_data = stl->g_data;
const DRWContextState *draw_ctx = DRW_context_state_get();
const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph);
@@ -176,6 +177,9 @@ static void eevee_cache_finish(void *vedata)
if (g_data->queued_shaders_count != g_data->queued_shaders_count_prev) {
g_data->queued_shaders_count_prev = g_data->queued_shaders_count;
EEVEE_temporal_sampling_reset(vedata);
+ /* At this moment the TAA sampling will be redrawn in the next iteration.
+ * we set the taa_current_sample to 0 so the next iteration will use sample 1 */
+ stl->effects->taa_current_sample = 0;
}
}
@@ -307,6 +311,9 @@ static void eevee_draw_scene(void *vedata)
/* Volumetrics Resolve Opaque */
EEVEE_volumes_resolve(sldata, vedata);
+ /* Renderpasses */
+ EEVEE_renderpasses_output_accumulate(sldata, vedata, false);
+
/* Transparent */
/* TODO(fclem): should be its own Framebuffer.
* This is needed because dualsource blending only works with 1 color buffer. */
@@ -321,8 +328,6 @@ static void eevee_draw_scene(void *vedata)
EEVEE_draw_effects(sldata, vedata);
DRW_stats_group_end();
- EEVEE_renderpasses_output_accumulate(sldata, vedata);
-
DRW_view_set_active(NULL);
if (DRW_state_is_image_render() && (stl->effects->enabled_effects & EFFECT_SSR) &&
@@ -336,7 +341,7 @@ static void eevee_draw_scene(void *vedata)
}
}
- if ((stl->g_data->render_passes & SCE_PASS_COMBINED) > 0) {
+ if ((stl->g_data->render_passes & EEVEE_RENDER_PASS_COMBINED) != 0) {
/* Transfer result to default framebuffer. */
GPU_framebuffer_bind(dfbl->default_fb);
DRW_transform_none(stl->effects->final_tx);
diff --git a/source/blender/draw/engines/eevee/eevee_lightprobes.c b/source/blender/draw/engines/eevee/eevee_lightprobes.c
index 7da9af55330..92e36597d99 100644
--- a/source/blender/draw/engines/eevee/eevee_lightprobes.c
+++ b/source/blender/draw/engines/eevee/eevee_lightprobes.c
@@ -251,6 +251,8 @@ void EEVEE_lightbake_cache_init(EEVEE_ViewLayerData *sldata,
// DRW_shgroup_uniform_texture(grp, "texJitter", e_data.jitter);
DRW_shgroup_uniform_texture(grp, "probeHdr", rt_color);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
+ DRW_shgroup_uniform_block(
+ grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
struct GPUBatch *geom = DRW_cache_fullscreen_quad_get();
DRW_shgroup_call(grp, geom, NULL);
@@ -272,6 +274,8 @@ void EEVEE_lightbake_cache_init(EEVEE_ViewLayerData *sldata,
DRW_shgroup_uniform_float(grp, "intensityFac", &pinfo->intensity_fac, 1);
DRW_shgroup_uniform_texture(grp, "probeHdr", rt_color);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
+ DRW_shgroup_uniform_block(
+ grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
struct GPUBatch *geom = DRW_cache_fullscreen_quad_get();
DRW_shgroup_call(grp, geom, NULL);
@@ -292,6 +296,8 @@ void EEVEE_lightbake_cache_init(EEVEE_ViewLayerData *sldata,
DRW_shgroup_uniform_texture(grp, "texHammersley", e_data.hammersley);
DRW_shgroup_uniform_texture(grp, "probeDepth", rt_depth);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
+ DRW_shgroup_uniform_block(
+ grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
struct GPUBatch *geom = DRW_cache_fullscreen_quad_get();
DRW_shgroup_call(grp, geom, NULL);
@@ -360,6 +366,8 @@ void EEVEE_lightprobes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedat
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);
+ DRW_shgroup_uniform_block(
+ grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_call(grp, geom, NULL);
break;
case GPU_MAT_QUEUED:
@@ -403,6 +411,8 @@ void EEVEE_lightprobes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedat
/* TODO (fclem) get rid of those UBO. */
DRW_shgroup_uniform_block(grp, "planar_block", sldata->planar_ubo);
DRW_shgroup_uniform_block(grp, "grid_block", sldata->grid_ubo);
+ DRW_shgroup_uniform_block(
+ grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_call_procedural_triangles(grp, NULL, cube_len * 2);
}
@@ -429,6 +439,8 @@ void EEVEE_lightprobes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedat
DRW_shgroup_uniform_block(shgrp, "planar_block", sldata->planar_ubo);
DRW_shgroup_uniform_block(shgrp, "grid_block", sldata->grid_ubo);
DRW_shgroup_uniform_block(shgrp, "common_block", sldata->common_ubo);
+ DRW_shgroup_uniform_block(
+ shgrp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
int tri_count = egrid->resolution[0] * egrid->resolution[1] * egrid->resolution[2] * 2;
DRW_shgroup_call_procedural_triangles(shgrp, NULL, tri_count);
}
@@ -446,6 +458,8 @@ void EEVEE_lightprobes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedat
DRWShadingGroup *grp = DRW_shgroup_create(EEVEE_shaders_probe_planar_display_sh_get(),
psl->probe_display);
DRW_shgroup_uniform_texture_ref(grp, "probePlanars", &txl->planar_pool);
+ DRW_shgroup_uniform_block(
+ grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
stl->g_data->planar_display_shgrp = DRW_shgroup_call_buffer_instance(
grp, e_data.format_probe_display_planar, DRW_cache_quad_get());
diff --git a/source/blender/draw/engines/eevee/eevee_materials.c b/source/blender/draw/engines/eevee/eevee_materials.c
index 1c0a1289ba4..3c793ca0693 100644
--- a/source/blender/draw/engines/eevee/eevee_materials.c
+++ b/source/blender/draw/engines/eevee/eevee_materials.c
@@ -25,6 +25,7 @@
#include "BLI_dynstr.h"
#include "BLI_ghash.h"
#include "BLI_alloca.h"
+#include "BLI_math_bits.h"
#include "BLI_rand.h"
#include "BLI_string_utils.h"
@@ -101,9 +102,37 @@ extern char datatoc_volumetric_vert_glsl[];
extern char datatoc_volumetric_geom_glsl[];
extern char datatoc_volumetric_frag_glsl[];
extern char datatoc_volumetric_lib_glsl[];
-
extern char datatoc_gpu_shader_uniform_color_frag_glsl[];
+#define DEFAULT_RENDER_PASS_FLAG 0xefffffff
+
+/* Iterator for render passes. This iteration will only do the material based render passes. it
+ * will ignore `EEVEE_RENDER_PASS_ENVIRONMENT`.
+ *
+ * parameters:
+ * - `render_passes_` is a bitflag for render_passes that needs to be iterated over.
+ * - `render_pass_index_` is a parameter name where the index of the render_pass will be available
+ * during iteration. This index can be used to select the right pass in the `psl`.
+ * - `render_pass_` is the bitflag of the render_pass of the current iteration.
+ *
+ * The `render_pass_index_` parameter needs to be the same for the `RENDER_PASS_ITER_BEGIN` and
+ * `RENDER_PASS_ITER_END`.
+ */
+#define RENDER_PASS_ITER_BEGIN(render_passes_, render_pass_index_, render_pass_) \
+ const eViewLayerEEVEEPassType __filtered_##render_pass_index_ = render_passes_ & \
+ EEVEE_RENDERPASSES_MATERIAL & \
+ ~EEVEE_RENDER_PASS_ENVIRONMENT; \
+ if (__filtered_##render_pass_index_ != 0) { \
+ int render_pass_index_ = 1; \
+ for (int bit_##render_pass_ = 0; bit_##render_pass_ < 32; bit_##render_pass_++) { \
+ eViewLayerEEVEEPassType render_pass_ = (1 << bit_##render_pass_); \
+ if ((__filtered_##render_pass_index_ & render_pass_) != 0) {
+#define RENDER_PASS_ITER_END(render_pass_index_) \
+ render_pass_index_ += 1; \
+ } \
+ } \
+ }
+
/* *********** FUNCTIONS *********** */
#if 0 /* Used only to generate the LUT values */
@@ -337,6 +366,39 @@ static char *eevee_get_volume_defines(int options)
return str;
}
+/* Get the default render pass ubo. This is a ubo that enables all bsdf render passes. */
+struct GPUUniformBuffer *EEVEE_material_default_render_pass_ubo_get(EEVEE_ViewLayerData *sldata)
+{
+ return sldata->renderpass_ubo[0];
+}
+
+/* Get the render pass ubo for rendering the given render_pass. */
+static struct GPUUniformBuffer *get_render_pass_ubo(EEVEE_ViewLayerData *sldata,
+ eViewLayerEEVEEPassType render_pass)
+{
+ int index;
+ switch (render_pass) {
+ case EEVEE_RENDER_PASS_DIFFUSE_COLOR:
+ index = 1;
+ break;
+ case EEVEE_RENDER_PASS_DIFFUSE_LIGHT:
+ index = 2;
+ break;
+ case EEVEE_RENDER_PASS_SPECULAR_COLOR:
+ index = 3;
+ break;
+ case EEVEE_RENDER_PASS_SPECULAR_LIGHT:
+ index = 4;
+ break;
+ case EEVEE_RENDER_PASS_EMIT:
+ index = 5;
+ break;
+ default:
+ index = 0;
+ break;
+ }
+ return sldata->renderpass_ubo[index];
+}
/**
* ssr_id can be null to disable ssr contribution.
*/
@@ -349,7 +411,8 @@ static void add_standard_uniforms(DRWShadingGroup *shgrp,
bool use_glossy,
bool use_refract,
bool use_ssrefraction,
- bool use_alpha_blend)
+ bool use_alpha_blend,
+ eViewLayerEEVEEPassType render_pass)
{
LightCache *lcache = vedata->stl->g_data->light_cache;
EEVEE_EffectsInfo *effects = vedata->stl->effects;
@@ -360,9 +423,9 @@ static void add_standard_uniforms(DRWShadingGroup *shgrp,
DRW_shgroup_uniform_block(shgrp, "light_block", sldata->light_ubo);
DRW_shgroup_uniform_block(shgrp, "shadow_block", sldata->shadow_ubo);
DRW_shgroup_uniform_block(shgrp, "common_block", sldata->common_ubo);
+ DRW_shgroup_uniform_block(shgrp, "renderpass_block", get_render_pass_ubo(sldata, render_pass));
DRW_shgroup_uniform_int_copy(shgrp, "outputSssId", 1);
-
if (use_diffuse || use_glossy || use_refract) {
DRW_shgroup_uniform_texture(shgrp, "utilTex", e_data.util_tex);
DRW_shgroup_uniform_texture_ref(shgrp, "shadowCubeTexture", &sldata->shadow_cube_pool);
@@ -395,6 +458,24 @@ static void add_standard_uniforms(DRWShadingGroup *shgrp,
}
}
+/* Add the uniforms for the background shader to `shgrp`. */
+static void add_background_uniforms(DRWShadingGroup *shgrp,
+ EEVEE_ViewLayerData *sldata,
+ EEVEE_Data *vedata)
+{
+ EEVEE_StorageList *stl = ((EEVEE_Data *)vedata)->stl;
+ DRW_shgroup_uniform_float(shgrp, "backgroundAlpha", &stl->g_data->background_alpha, 1);
+ /* TODO (fclem): remove those (need to clean the GLSL files). */
+ DRW_shgroup_uniform_block(shgrp, "common_block", sldata->common_ubo);
+ DRW_shgroup_uniform_block(shgrp, "grid_block", sldata->grid_ubo);
+ DRW_shgroup_uniform_block(shgrp, "probe_block", sldata->probe_ubo);
+ DRW_shgroup_uniform_block(shgrp, "planar_block", sldata->planar_ubo);
+ DRW_shgroup_uniform_block(shgrp, "light_block", sldata->light_ubo);
+ DRW_shgroup_uniform_block(shgrp, "shadow_block", sldata->shadow_ubo);
+ DRW_shgroup_uniform_block(
+ shgrp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
+}
+
static void create_default_shader(int options)
{
char *frag_str = BLI_string_joinN(e_data.frag_shader_lib, datatoc_default_frag_glsl);
@@ -523,6 +604,9 @@ void EEVEE_materials_init(EEVEE_ViewLayerData *sldata,
EEVEE_StorageList *stl,
EEVEE_FramebufferList *fbl)
{
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ EEVEE_PrivateData *g_data = stl->g_data;
+
if (!e_data.frag_shader_lib) {
/* Shaders */
e_data.frag_shader_lib = BLI_string_joinN(datatoc_common_view_lib_glsl,
@@ -600,7 +684,6 @@ void EEVEE_materials_init(EEVEE_ViewLayerData *sldata,
datatoc_prepass_frag_glsl,
"#define HAIR_SHADER\n"
"#define CLIP_PLANES\n");
-
MEM_freeN(vert_str);
e_data.update_noise_sh = DRW_shader_create_fullscreen(datatoc_update_noise_frag_glsl, NULL);
@@ -635,6 +718,66 @@ void EEVEE_materials_init(EEVEE_ViewLayerData *sldata,
&fbl->update_noise_fb,
{GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE_LAYER(e_data.util_tex, 2)});
}
+
+ {
+ /* Create RenderPass UBO */
+ if (sldata->renderpass_ubo[0] == NULL) {
+ sldata->renderpass_data[0].renderPassDiffuse = true;
+ sldata->renderpass_data[0].renderPassDiffuseLight = true;
+ sldata->renderpass_data[0].renderPassGlossy = true;
+ sldata->renderpass_data[0].renderPassGlossyLight = true;
+ sldata->renderpass_data[0].renderPassEmit = true;
+ sldata->renderpass_data[0].renderPassSSSColor = false;
+ sldata->renderpass_data[1].renderPassDiffuse = true;
+ sldata->renderpass_data[1].renderPassDiffuseLight = false;
+ sldata->renderpass_data[1].renderPassGlossy = false;
+ sldata->renderpass_data[1].renderPassGlossyLight = false;
+ sldata->renderpass_data[1].renderPassEmit = false;
+ sldata->renderpass_data[1].renderPassSSSColor = true;
+ sldata->renderpass_data[2].renderPassDiffuse = true;
+ sldata->renderpass_data[2].renderPassDiffuseLight = true;
+ sldata->renderpass_data[2].renderPassGlossy = false;
+ sldata->renderpass_data[2].renderPassGlossyLight = false;
+ sldata->renderpass_data[2].renderPassEmit = false;
+ sldata->renderpass_data[2].renderPassSSSColor = false;
+ sldata->renderpass_data[3].renderPassDiffuse = false;
+ sldata->renderpass_data[3].renderPassDiffuseLight = false;
+ sldata->renderpass_data[3].renderPassGlossy = true;
+ sldata->renderpass_data[3].renderPassGlossyLight = false;
+ sldata->renderpass_data[3].renderPassEmit = false;
+ sldata->renderpass_data[3].renderPassSSSColor = false;
+ sldata->renderpass_data[4].renderPassDiffuse = false;
+ sldata->renderpass_data[4].renderPassDiffuseLight = false;
+ sldata->renderpass_data[4].renderPassGlossy = true;
+ sldata->renderpass_data[4].renderPassGlossyLight = true;
+ sldata->renderpass_data[4].renderPassEmit = false;
+ sldata->renderpass_data[4].renderPassSSSColor = false;
+ sldata->renderpass_data[5].renderPassDiffuse = false;
+ sldata->renderpass_data[5].renderPassDiffuseLight = false;
+ sldata->renderpass_data[5].renderPassGlossy = false;
+ sldata->renderpass_data[5].renderPassGlossyLight = false;
+ sldata->renderpass_data[5].renderPassEmit = true;
+ sldata->renderpass_data[5].renderPassSSSColor = false;
+
+ for (int i = 0; i < MAX_MATERIAL_RENDER_PASSES_UBO; i++) {
+ sldata->renderpass_ubo[i] = DRW_uniformbuffer_create(sizeof(EEVEE_RenderPassData),
+ &sldata->renderpass_data[i]);
+ }
+ }
+
+ /* HACK: EEVEE_material_world_background_get can create a new context. This can only be
+ * done when there is no active framebuffer. We do this here otherwise
+ * `EEVEE_renderpasses_output_init` will fail. It cannot be done in
+ * `EEVEE_renderpasses_init` as the `e_data.vertcode` can be uninitialized.
+ */
+ if (g_data->render_passes & EEVEE_RENDER_PASS_ENVIRONMENT) {
+ struct Scene *scene = draw_ctx->scene;
+ struct World *wo = scene->world;
+ if (wo && wo->use_nodes) {
+ EEVEE_material_world_background_get(scene, wo);
+ }
+ }
+ }
}
struct GPUMaterial *EEVEE_material_world_lightprobe_get(struct Scene *scene, World *wo)
@@ -852,7 +995,17 @@ static struct DRWShadingGroup *EEVEE_default_shading_group_create(EEVEE_ViewLaye
}
DRWShadingGroup *shgrp = DRW_shgroup_create(e_data.default_lit[options], pass);
- add_standard_uniforms(shgrp, sldata, vedata, &ssr_id, NULL, true, true, false, false, use_blend);
+ add_standard_uniforms(shgrp,
+ sldata,
+ vedata,
+ &ssr_id,
+ NULL,
+ true,
+ true,
+ false,
+ false,
+ use_blend,
+ DEFAULT_RENDER_PASS_FLAG);
return shgrp;
}
@@ -894,14 +1047,34 @@ static struct DRWShadingGroup *EEVEE_default_shading_group_get(EEVEE_ViewLayerDa
if (!is_hair) {
DRWShadingGroup *shgrp = DRW_shgroup_create(e_data.default_lit[options],
psl->default_pass[options]);
- add_standard_uniforms(shgrp, sldata, vedata, &ssr_id, NULL, true, true, false, false, false);
+ add_standard_uniforms(shgrp,
+ sldata,
+ vedata,
+ &ssr_id,
+ NULL,
+ true,
+ true,
+ false,
+ false,
+ false,
+ DEFAULT_RENDER_PASS_FLAG);
}
}
if (is_hair) {
DRWShadingGroup *shgrp = DRW_shgroup_hair_create(
ob, psys, md, vedata->psl->default_pass[options], e_data.default_lit[options]);
- add_standard_uniforms(shgrp, sldata, vedata, &ssr_id, NULL, true, true, false, false, false);
+ add_standard_uniforms(shgrp,
+ sldata,
+ vedata,
+ &ssr_id,
+ NULL,
+ true,
+ true,
+ false,
+ false,
+ false,
+ DEFAULT_RENDER_PASS_FLAG);
return shgrp;
}
else {
@@ -909,6 +1082,60 @@ static struct DRWShadingGroup *EEVEE_default_shading_group_get(EEVEE_ViewLayerDa
}
}
+static struct DRWShadingGroup *EEVEE_default_render_pass_shading_group_get(
+ EEVEE_ViewLayerData *sldata,
+ EEVEE_Data *vedata,
+ bool holdout,
+ bool use_ssr,
+ DRWPass *pass,
+ eViewLayerEEVEEPassType render_pass_flag)
+{
+ static int ssr_id;
+ ssr_id = (use_ssr) ? 1 : -1;
+ int options = VAR_MAT_MESH;
+
+ SET_FLAG_FROM_TEST(options, holdout, VAR_MAT_HOLDOUT);
+
+ if (e_data.default_lit[options] == NULL) {
+ create_default_shader(options);
+ }
+
+ DRWShadingGroup *shgrp = DRW_shgroup_create(e_data.default_lit[options], pass);
+ add_standard_uniforms(
+ shgrp, sldata, vedata, &ssr_id, NULL, true, true, false, false, false, render_pass_flag);
+ return shgrp;
+}
+
+static struct DRWShadingGroup *EEVEE_default_hair_render_pass_shading_group_get(
+ EEVEE_ViewLayerData *sldata,
+ EEVEE_Data *vedata,
+ Object *ob,
+ ParticleSystem *psys,
+ ModifierData *md,
+ bool holdout,
+ bool use_ssr,
+ DRWPass *pass,
+ eViewLayerEEVEEPassType render_pass_flag)
+{
+ static int ssr_id;
+ ssr_id = (use_ssr) ? 1 : -1;
+ int options = VAR_MAT_MESH | VAR_MAT_HAIR;
+
+ BLI_assert((ob && psys && md));
+
+ SET_FLAG_FROM_TEST(options, holdout, VAR_MAT_HOLDOUT);
+
+ if (e_data.default_lit[options] == NULL) {
+ create_default_shader(options);
+ }
+
+ DRWShadingGroup *shgrp = DRW_shgroup_hair_create(
+ ob, psys, md, pass, e_data.default_lit[options]);
+ add_standard_uniforms(
+ shgrp, sldata, vedata, &ssr_id, NULL, true, true, false, false, false, render_pass_flag);
+ return shgrp;
+}
+
void EEVEE_materials_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
{
EEVEE_PassList *psl = ((EEVEE_Data *)vedata)->psl;
@@ -945,14 +1172,7 @@ void EEVEE_materials_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
switch (GPU_material_status(gpumat)) {
case GPU_MAT_SUCCESS:
grp = DRW_shgroup_material_create(gpumat, psl->background_pass);
- DRW_shgroup_uniform_float(grp, "backgroundAlpha", &stl->g_data->background_alpha, 1);
- /* TODO (fclem): remove those (need to clean the GLSL files). */
- DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
- 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);
+ add_background_uniforms(grp, sldata, vedata);
DRW_shgroup_call(grp, geom, NULL);
break;
case GPU_MAT_QUEUED:
@@ -1071,7 +1291,17 @@ void EEVEE_materials_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
DRW_PASS_CREATE(psl->lookdev_diffuse_pass, state);
shgrp = DRW_shgroup_create(e_data.default_lit[options], psl->lookdev_diffuse_pass);
- add_standard_uniforms(shgrp, sldata, vedata, NULL, NULL, true, true, false, false, false);
+ add_standard_uniforms(shgrp,
+ sldata,
+ vedata,
+ NULL,
+ NULL,
+ true,
+ true,
+ false,
+ false,
+ false,
+ DEFAULT_RENDER_PASS_FLAG);
DRW_shgroup_uniform_vec3(shgrp, "basecol", color_diffuse, 1);
DRW_shgroup_uniform_float_copy(shgrp, "metallic", 0.0f);
DRW_shgroup_uniform_float_copy(shgrp, "specular", 0.5f);
@@ -1080,12 +1310,31 @@ void EEVEE_materials_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
DRW_PASS_CREATE(psl->lookdev_glossy_pass, state);
shgrp = DRW_shgroup_create(e_data.default_lit[options], psl->lookdev_glossy_pass);
- add_standard_uniforms(shgrp, sldata, vedata, NULL, NULL, true, true, false, false, false);
+ add_standard_uniforms(shgrp,
+ sldata,
+ vedata,
+ NULL,
+ NULL,
+ true,
+ true,
+ false,
+ false,
+ false,
+ DEFAULT_RENDER_PASS_FLAG);
DRW_shgroup_uniform_vec3(shgrp, "basecol", color_chrome, 1);
DRW_shgroup_uniform_float_copy(shgrp, "metallic", 1.0f);
DRW_shgroup_uniform_float_copy(shgrp, "roughness", 0.0f);
DRW_shgroup_call(shgrp, sphere, NULL);
}
+
+ {
+ memset(psl->material_accum_pass, 0, sizeof(psl->material_accum_pass));
+ for (int pass_index = 0; pass_index < stl->g_data->render_passes_material_count;
+ pass_index++) {
+ DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL | DRW_STATE_BLEND_ADD;
+ DRW_PASS_CREATE(psl->material_accum_pass[pass_index], state);
+ }
+ }
}
#define ADD_SHGROUP_CALL(shgrp, ob, geom, oedata) \
@@ -1109,6 +1358,7 @@ typedef struct EeveeMaterialShadingGroups {
struct DRWShadingGroup *shading_grp;
struct DRWShadingGroup *depth_grp;
struct DRWShadingGroup *depth_clip_grp;
+ struct DRWShadingGroup *material_accum_grp[MAX_MATERIAL_RENDER_PASSES];
} EeveeMaterialShadingGroups;
static void material_opaque(Material *ma,
@@ -1117,9 +1367,7 @@ static void material_opaque(Material *ma,
EEVEE_Data *vedata,
struct GPUMaterial **gpumat,
struct GPUMaterial **gpumat_depth,
- struct DRWShadingGroup **shgrp,
- struct DRWShadingGroup **shgrp_depth,
- struct DRWShadingGroup **shgrp_depth_clip,
+ struct EeveeMaterialShadingGroups *shgrps,
bool holdout)
{
EEVEE_EffectsInfo *effects = vedata->stl->effects;
@@ -1128,7 +1376,7 @@ static void material_opaque(Material *ma,
EEVEE_StorageList *stl = ((EEVEE_Data *)vedata)->stl;
EEVEE_PassList *psl = ((EEVEE_Data *)vedata)->psl;
bool use_diffuse, use_glossy, use_refract;
-
+ bool store_material = true;
float *color_p = &ma->r;
float *metal_p = &ma->metallic;
float *spec_p = &ma->spec;
@@ -1143,9 +1391,7 @@ static void material_opaque(Material *ma,
EeveeMaterialShadingGroups *emsg = BLI_ghash_lookup(material_hash, (const void *)ma);
if (emsg) {
- *shgrp = emsg->shading_grp;
- *shgrp_depth = emsg->depth_grp;
- *shgrp_depth_clip = emsg->depth_clip_grp;
+ memcpy(shgrps, emsg, sizeof(EeveeMaterialShadingGroups));
/* This will have been created already, just perform a lookup. */
*gpumat = (use_gpumat) ? EEVEE_material_mesh_get(scene, ma, vedata, false, use_ssrefract) :
@@ -1156,6 +1402,7 @@ static void material_opaque(Material *ma,
return;
}
+ emsg = MEM_callocN(sizeof(EeveeMaterialShadingGroups), "EeveeMaterialShadingGroups");
if (use_gpumat) {
static float error_col[3] = {1.0f, 0.0f, 1.0f};
static float compile_col[3] = {0.5f, 0.5f, 0.5f};
@@ -1179,25 +1426,25 @@ static void material_opaque(Material *ma,
status_mat_surface = status_mat_depth;
}
else if (use_ssrefract) {
- *shgrp_depth = DRW_shgroup_material_create(
+ emsg->depth_grp = DRW_shgroup_material_create(
*gpumat_depth, (do_cull) ? psl->refract_depth_pass_cull : psl->refract_depth_pass);
- *shgrp_depth_clip = DRW_shgroup_material_create(
+ emsg->depth_clip_grp = DRW_shgroup_material_create(
*gpumat_depth,
(do_cull) ? psl->refract_depth_pass_clip_cull : psl->refract_depth_pass_clip);
}
else {
- *shgrp_depth = DRW_shgroup_material_create(
+ emsg->depth_grp = DRW_shgroup_material_create(
*gpumat_depth, (do_cull) ? psl->depth_pass_cull : psl->depth_pass);
- *shgrp_depth_clip = DRW_shgroup_material_create(
+ emsg->depth_clip_grp = DRW_shgroup_material_create(
*gpumat_depth, (do_cull) ? psl->depth_pass_clip_cull : psl->depth_pass_clip);
}
- if (*shgrp_depth != NULL) {
+ if (emsg->depth_grp != NULL) {
use_diffuse = GPU_material_flag_get(*gpumat_depth, GPU_MATFLAG_DIFFUSE);
use_glossy = GPU_material_flag_get(*gpumat_depth, GPU_MATFLAG_GLOSSY);
use_refract = GPU_material_flag_get(*gpumat_depth, GPU_MATFLAG_REFRACT);
- add_standard_uniforms(*shgrp_depth,
+ add_standard_uniforms(emsg->depth_grp,
sldata,
vedata,
NULL,
@@ -1206,8 +1453,9 @@ static void material_opaque(Material *ma,
use_glossy,
use_refract,
false,
- false);
- add_standard_uniforms(*shgrp_depth_clip,
+ false,
+ DEFAULT_RENDER_PASS_FLAG);
+ add_standard_uniforms(emsg->depth_clip_grp,
sldata,
vedata,
NULL,
@@ -1216,11 +1464,13 @@ static void material_opaque(Material *ma,
use_glossy,
use_refract,
false,
- false);
+ false,
+ DEFAULT_RENDER_PASS_FLAG);
if (ma->blend_method == MA_BM_CLIP) {
- DRW_shgroup_uniform_float(*shgrp_depth, "alphaThreshold", &ma->alpha_threshold, 1);
- DRW_shgroup_uniform_float(*shgrp_depth_clip, "alphaThreshold", &ma->alpha_threshold, 1);
+ DRW_shgroup_uniform_float(emsg->depth_grp, "alphaThreshold", &ma->alpha_threshold, 1);
+ DRW_shgroup_uniform_float(
+ emsg->depth_clip_grp, "alphaThreshold", &ma->alpha_threshold, 1);
}
}
}
@@ -1237,14 +1487,14 @@ static void material_opaque(Material *ma,
use_glossy = GPU_material_flag_get(*gpumat, GPU_MATFLAG_GLOSSY);
use_refract = GPU_material_flag_get(*gpumat, GPU_MATFLAG_REFRACT);
- *shgrp = DRW_shgroup_material_create(
+ emsg->shading_grp = DRW_shgroup_material_create(
*gpumat,
(use_ssrefract) ?
psl->refract_pass :
(use_sss) ? ((do_cull) ? psl->sss_pass_cull : psl->sss_pass) :
((do_cull) ? psl->material_pass_cull : psl->material_pass));
- add_standard_uniforms(*shgrp,
+ add_standard_uniforms(emsg->shading_grp,
sldata,
vedata,
ssr_id,
@@ -1253,7 +1503,8 @@ static void material_opaque(Material *ma,
use_glossy,
use_refract,
use_ssrefract,
- false);
+ false,
+ DEFAULT_RENDER_PASS_FLAG);
if (use_sss) {
struct GPUTexture *sss_tex_profile = NULL;
@@ -1264,7 +1515,7 @@ static void material_opaque(Material *ma,
/* Limit of 8 bit stencil buffer. ID 255 is refraction. */
if (e_data.sss_count < 254) {
int sss_id = e_data.sss_count + 1;
- DRW_shgroup_stencil_mask(*shgrp, sss_id);
+ DRW_shgroup_stencil_mask(emsg->shading_grp, sss_id);
EEVEE_subsurface_add_pass(sldata, vedata, sss_id, sss_profile);
if (use_translucency) {
EEVEE_subsurface_translucency_add_pass(
@@ -1278,12 +1529,30 @@ static void material_opaque(Material *ma,
}
}
}
+
+ RENDER_PASS_ITER_BEGIN(stl->g_data->render_passes, render_pass_index, render_pass_flag)
+ emsg->material_accum_grp[render_pass_index] = DRW_shgroup_material_create(
+ *gpumat, psl->material_accum_pass[render_pass_index]);
+ add_standard_uniforms(emsg->material_accum_grp[render_pass_index],
+ sldata,
+ vedata,
+ ssr_id,
+ &ma->refract_depth,
+ use_diffuse,
+ use_glossy,
+ use_refract,
+ use_ssrefract,
+ false,
+ render_pass_flag);
+ RENDER_PASS_ITER_END(render_pass_index)
+
break;
}
case GPU_MAT_QUEUED: {
stl->g_data->queued_shaders_count++;
color_p = compile_col;
metal_p = spec_p = rough_p = &half;
+ store_material = false;
break;
}
case GPU_MAT_FAILED:
@@ -1295,44 +1564,61 @@ static void material_opaque(Material *ma,
}
/* Fallback to default shader */
- if (*shgrp == NULL) {
+ if (emsg->shading_grp == NULL) {
bool use_ssr = ((effects->enabled_effects & EFFECT_SSR) != 0);
- *shgrp = EEVEE_default_shading_group_get(
+ emsg->shading_grp = EEVEE_default_shading_group_get(
sldata, vedata, NULL, NULL, NULL, false, holdout, use_ssr);
- DRW_shgroup_uniform_vec3(*shgrp, "basecol", color_p, 1);
- DRW_shgroup_uniform_float(*shgrp, "metallic", metal_p, 1);
- DRW_shgroup_uniform_float(*shgrp, "specular", spec_p, 1);
- DRW_shgroup_uniform_float(*shgrp, "roughness", rough_p, 1);
+ DRW_shgroup_uniform_vec3(emsg->shading_grp, "basecol", color_p, 1);
+ DRW_shgroup_uniform_float(emsg->shading_grp, "metallic", metal_p, 1);
+ DRW_shgroup_uniform_float(emsg->shading_grp, "specular", spec_p, 1);
+ DRW_shgroup_uniform_float(emsg->shading_grp, "roughness", rough_p, 1);
+
+ RENDER_PASS_ITER_BEGIN(stl->g_data->render_passes, render_pass_index, render_pass_flag)
+ DRWShadingGroup *shgrp = EEVEE_default_render_pass_shading_group_get(
+ sldata,
+ vedata,
+ holdout,
+ use_ssr,
+ psl->material_accum_pass[render_pass_index],
+ render_pass_flag);
+
+ DRW_shgroup_uniform_vec3(shgrp, "basecol", color_p, 1);
+ DRW_shgroup_uniform_float(shgrp, "metallic", metal_p, 1);
+ DRW_shgroup_uniform_float(shgrp, "specular", spec_p, 1);
+ DRW_shgroup_uniform_float(shgrp, "roughness", rough_p, 1);
+ emsg->material_accum_grp[render_pass_index] = shgrp;
+ RENDER_PASS_ITER_END(render_pass_index)
}
/* Fallback default depth prepass */
- if (*shgrp_depth == NULL) {
+ if (emsg->depth_grp == NULL) {
if (use_ssrefract) {
- *shgrp_depth = (do_cull) ? stl->g_data->refract_depth_shgrp_cull :
- stl->g_data->refract_depth_shgrp;
- *shgrp_depth_clip = (do_cull) ? stl->g_data->refract_depth_shgrp_clip_cull :
- stl->g_data->refract_depth_shgrp_clip;
+ emsg->depth_grp = (do_cull) ? stl->g_data->refract_depth_shgrp_cull :
+ stl->g_data->refract_depth_shgrp;
+ emsg->depth_clip_grp = (do_cull) ? stl->g_data->refract_depth_shgrp_clip_cull :
+ stl->g_data->refract_depth_shgrp_clip;
}
else {
- *shgrp_depth = (do_cull) ? stl->g_data->depth_shgrp_cull : stl->g_data->depth_shgrp;
- *shgrp_depth_clip = (do_cull) ? stl->g_data->depth_shgrp_clip_cull :
- stl->g_data->depth_shgrp_clip;
+ emsg->depth_grp = (do_cull) ? stl->g_data->depth_shgrp_cull : stl->g_data->depth_shgrp;
+ emsg->depth_clip_grp = (do_cull) ? stl->g_data->depth_shgrp_clip_cull :
+ stl->g_data->depth_shgrp_clip;
}
}
- emsg = MEM_mallocN(sizeof(EeveeMaterialShadingGroups), "EeveeMaterialShadingGroups");
- emsg->shading_grp = *shgrp;
- emsg->depth_grp = *shgrp_depth;
- emsg->depth_clip_grp = *shgrp_depth_clip;
- BLI_ghash_insert(material_hash, ma, emsg);
+ memcpy(shgrps, emsg, sizeof(EeveeMaterialShadingGroups));
+ if (store_material) {
+ BLI_ghash_insert(material_hash, ma, emsg);
+ }
+ else {
+ MEM_freeN(emsg);
+ }
}
static void material_transparent(Material *ma,
EEVEE_ViewLayerData *sldata,
EEVEE_Data *vedata,
struct GPUMaterial **gpumat,
- struct DRWShadingGroup **shgrp,
- struct DRWShadingGroup **shgrp_depth)
+ struct EeveeMaterialShadingGroups *shgrps)
{
const DRWContextState *draw_ctx = DRW_context_state_get();
Scene *scene = draw_ctx->scene;
@@ -1357,13 +1643,13 @@ static void material_transparent(Material *ma,
/* Depth prepass */
if (use_prepass) {
- *shgrp_depth = DRW_shgroup_create(e_data.default_prepass_clip_sh, psl->transparent_pass);
+ shgrps->depth_grp = DRW_shgroup_create(e_data.default_prepass_clip_sh, psl->transparent_pass);
cur_state = DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL;
cur_state |= (do_cull) ? DRW_STATE_CULL_BACK : 0;
- DRW_shgroup_state_disable(*shgrp_depth, all_state);
- DRW_shgroup_state_enable(*shgrp_depth, cur_state);
+ DRW_shgroup_state_disable(shgrps->depth_grp, all_state);
+ DRW_shgroup_state_enable(shgrps->depth_grp, cur_state);
}
if (use_gpumat) {
@@ -1378,14 +1664,14 @@ static void material_transparent(Material *ma,
case GPU_MAT_SUCCESS: {
static int ssr_id = -1; /* TODO transparent SSR */
- *shgrp = DRW_shgroup_material_create(*gpumat, psl->transparent_pass);
+ shgrps->shading_grp = DRW_shgroup_material_create(*gpumat, psl->transparent_pass);
bool use_blend = true;
bool use_diffuse = GPU_material_flag_get(*gpumat, GPU_MATFLAG_DIFFUSE);
bool use_glossy = GPU_material_flag_get(*gpumat, GPU_MATFLAG_GLOSSY);
bool use_refract = GPU_material_flag_get(*gpumat, GPU_MATFLAG_REFRACT);
- add_standard_uniforms(*shgrp,
+ add_standard_uniforms(shgrps->shading_grp,
sldata,
vedata,
&ssr_id,
@@ -1394,7 +1680,8 @@ static void material_transparent(Material *ma,
use_glossy,
use_refract,
use_ssrefract,
- use_blend);
+ use_blend,
+ DEFAULT_RENDER_PASS_FLAG);
break;
}
case GPU_MAT_QUEUED: {
@@ -1413,13 +1700,13 @@ static void material_transparent(Material *ma,
}
/* Fallback to default shader */
- if (*shgrp == NULL) {
- *shgrp = EEVEE_default_shading_group_create(
+ if (shgrps->shading_grp == NULL) {
+ shgrps->shading_grp = EEVEE_default_shading_group_create(
sldata, vedata, psl->transparent_pass, false, true, false);
- DRW_shgroup_uniform_vec3(*shgrp, "basecol", color_p, 1);
- DRW_shgroup_uniform_float(*shgrp, "metallic", metal_p, 1);
- DRW_shgroup_uniform_float(*shgrp, "specular", spec_p, 1);
- DRW_shgroup_uniform_float(*shgrp, "roughness", rough_p, 1);
+ DRW_shgroup_uniform_vec3(shgrps->shading_grp, "basecol", color_p, 1);
+ DRW_shgroup_uniform_float(shgrps->shading_grp, "metallic", metal_p, 1);
+ DRW_shgroup_uniform_float(shgrps->shading_grp, "specular", spec_p, 1);
+ DRW_shgroup_uniform_float(shgrps->shading_grp, "roughness", rough_p, 1);
}
cur_state = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_CUSTOM;
@@ -1427,8 +1714,8 @@ static void material_transparent(Material *ma,
cur_state |= (do_cull) ? DRW_STATE_CULL_BACK : 0;
/* Disable other blend modes and use the one we want. */
- DRW_shgroup_state_disable(*shgrp, all_state);
- DRW_shgroup_state_enable(*shgrp, cur_state);
+ DRW_shgroup_state_disable(shgrps->shading_grp, all_state);
+ DRW_shgroup_state_enable(shgrps->shading_grp, cur_state);
}
/* Return correct material or empty default material if slot is empty. */
@@ -1460,10 +1747,7 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata,
if (ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_MBALL)) {
const int materials_len = DRW_cache_object_material_count_get(ob);
- struct DRWShadingGroup **shgrp_array = BLI_array_alloca(shgrp_array, materials_len);
- struct DRWShadingGroup **shgrp_depth_array = BLI_array_alloca(shgrp_depth_array,
- materials_len);
- struct DRWShadingGroup **shgrp_depth_clip_array = BLI_array_alloca(shgrp_depth_clip_array,
+ struct EeveeMaterialShadingGroups *shgrps_array = BLI_array_alloca(shgrps_array,
materials_len);
struct GPUMaterial **gpumat_array = BLI_array_alloca(gpumat_array, materials_len);
@@ -1472,11 +1756,9 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata,
for (int i = 0; i < materials_len; i++) {
ma_array[i] = eevee_object_material_get(ob, i);
+ memset(&shgrps_array[i], 0, sizeof(EeveeMaterialShadingGroups));
gpumat_array[i] = NULL;
gpumat_depth_array[i] = NULL;
- shgrp_array[i] = NULL;
- shgrp_depth_array[i] = NULL;
- shgrp_depth_clip_array[i] = NULL;
if (holdout) {
material_opaque(ma_array[i],
@@ -1485,9 +1767,7 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata,
vedata,
&gpumat_array[i],
&gpumat_depth_array[i],
- &shgrp_array[i],
- &shgrp_depth_array[i],
- &shgrp_depth_clip_array[i],
+ &shgrps_array[i],
true);
continue;
}
@@ -1502,18 +1782,11 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata,
vedata,
&gpumat_array[i],
&gpumat_depth_array[i],
- &shgrp_array[i],
- &shgrp_depth_array[i],
- &shgrp_depth_clip_array[i],
+ &shgrps_array[i],
false);
break;
case MA_BM_BLEND:
- material_transparent(ma_array[i],
- sldata,
- vedata,
- &gpumat_array[i],
- &shgrp_array[i],
- &shgrp_depth_array[i]);
+ material_transparent(ma_array[i], sldata, vedata, &gpumat_array[i], &shgrps_array[i]);
break;
default:
BLI_assert(0);
@@ -1538,10 +1811,32 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata,
if (use_sculpt_pbvh) {
/* Vcol is not supported in the modes that require PBVH drawing. */
- bool use_vcol = false;
- DRW_shgroup_call_sculpt_with_materials(shgrp_array, ob, use_vcol);
- DRW_shgroup_call_sculpt_with_materials(shgrp_depth_array, ob, use_vcol);
- DRW_shgroup_call_sculpt_with_materials(shgrp_depth_clip_array, ob, use_vcol);
+ const bool use_vcol = false;
+ struct DRWShadingGroup **sculpt_shgrps_array = BLI_array_alloca(sculpt_shgrps_array,
+ materials_len);
+ for (int i = 0; i < materials_len; i++) {
+ sculpt_shgrps_array[i] = shgrps_array[i].shading_grp;
+ }
+ DRW_shgroup_call_sculpt_with_materials(sculpt_shgrps_array, ob, use_vcol);
+
+ for (int i = 0; i < materials_len; i++) {
+ sculpt_shgrps_array[i] = shgrps_array[i].depth_grp;
+ }
+ DRW_shgroup_call_sculpt_with_materials(sculpt_shgrps_array, ob, use_vcol);
+ for (int i = 0; i < materials_len; i++) {
+ sculpt_shgrps_array[i] = shgrps_array[i].depth_clip_grp;
+ }
+ DRW_shgroup_call_sculpt_with_materials(sculpt_shgrps_array, ob, use_vcol);
+
+ for (int renderpass_index = 0;
+ renderpass_index < stl->g_data->render_passes_material_count;
+ renderpass_index++) {
+ for (int i = 0; i < materials_len; i++) {
+ sculpt_shgrps_array[i] = shgrps_array[i].material_accum_grp[renderpass_index];
+ }
+ DRW_shgroup_call_sculpt_with_materials(sculpt_shgrps_array, ob, use_vcol);
+ }
+
/* TODO(fclem): Support shadows in sculpt mode. */
}
else if (mat_geom) {
@@ -1565,10 +1860,16 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata,
oedata->ob = ob;
oedata->test_data = &sldata->probes->vis_data;
}
-
- ADD_SHGROUP_CALL(shgrp_array[i], ob, mat_geom[i], oedata);
- ADD_SHGROUP_CALL_SAFE(shgrp_depth_array[i], ob, mat_geom[i], oedata);
- ADD_SHGROUP_CALL_SAFE(shgrp_depth_clip_array[i], ob, mat_geom[i], oedata);
+ EeveeMaterialShadingGroups *shgrps = &shgrps_array[i];
+ ADD_SHGROUP_CALL(shgrps->shading_grp, ob, mat_geom[i], oedata);
+ ADD_SHGROUP_CALL_SAFE(shgrps->depth_grp, ob, mat_geom[i], oedata);
+ ADD_SHGROUP_CALL_SAFE(shgrps->depth_clip_grp, ob, mat_geom[i], oedata);
+ for (int renderpass_index = 0;
+ renderpass_index < stl->g_data->render_passes_material_count;
+ renderpass_index++) {
+ ADD_SHGROUP_CALL_SAFE(
+ shgrps->material_accum_grp[renderpass_index], ob, mat_geom[i], oedata);
+ }
/* Shadow Pass */
struct GPUMaterial *gpumat;
@@ -1667,9 +1968,33 @@ void EEVEE_hair_cache_populate(EEVEE_Data *vedata,
shgrp = DRW_shgroup_material_hair_create(ob, psys, md, psl->material_pass, gpumat);
if (!use_diffuse && !use_glossy && !use_refract) {
- /* FIXME: Small hack to avoid issue when utilTex is needed for
+ /* HACK: Small hack to avoid issue when utilTex is needed for
+ * world_normals_get and none of the bsdfs are present.
+ * This binds utilTex even if not needed. */
+ DRW_shgroup_uniform_texture(shgrp, "utilTex", e_data.util_tex);
+ }
+
+ add_standard_uniforms(shgrp,
+ sldata,
+ vedata,
+ &ssr_id,
+ NULL,
+ use_diffuse,
+ use_glossy,
+ use_refract,
+ false,
+ false,
+ DEFAULT_RENDER_PASS_FLAG);
+
+ /* Add the hair to all the render_passes that are enabled */
+ RENDER_PASS_ITER_BEGIN(
+ stl->g_data->render_passes, render_pass_index, render_pass_flag)
+ shgrp = DRW_shgroup_material_hair_create(
+ ob, psys, md, psl->material_accum_pass[render_pass_index], gpumat);
+ if (!use_diffuse && !use_glossy && !use_refract) {
+ /* Small hack to avoid issue when utilTex is needed for
* world_normals_get and none of the bsdfs that need it are present.
- * This can try to bind utilTex even if not needed. */
+ * This binds `utilTex` even if not needed. */
DRW_shgroup_uniform_texture(shgrp, "utilTex", e_data.util_tex);
}
@@ -1682,7 +2007,10 @@ void EEVEE_hair_cache_populate(EEVEE_Data *vedata,
use_glossy,
use_refract,
false,
- false);
+ false,
+ render_pass_flag);
+ RENDER_PASS_ITER_END(render_pass_index)
+
break;
}
case GPU_MAT_QUEUED: {
@@ -1707,6 +2035,24 @@ void EEVEE_hair_cache_populate(EEVEE_Data *vedata,
DRW_shgroup_uniform_float(shgrp, "metallic", metal_p, 1);
DRW_shgroup_uniform_float(shgrp, "specular", spec_p, 1);
DRW_shgroup_uniform_float(shgrp, "roughness", rough_p, 1);
+
+ RENDER_PASS_ITER_BEGIN(stl->g_data->render_passes, render_pass_index, render_pass_flag)
+ shgrp = EEVEE_default_hair_render_pass_shading_group_get(
+ sldata,
+ vedata,
+ ob,
+ psys,
+ md,
+ holdout,
+ use_ssr,
+ psl->material_accum_pass[render_pass_index],
+ render_pass_flag);
+
+ DRW_shgroup_uniform_vec3(shgrp, "basecol", color_p, 1);
+ DRW_shgroup_uniform_float(shgrp, "metallic", metal_p, 1);
+ DRW_shgroup_uniform_float(shgrp, "specular", spec_p, 1);
+ DRW_shgroup_uniform_float(shgrp, "roughness", rough_p, 1);
+ RENDER_PASS_ITER_END(render_pass_index)
}
/* Shadows */
@@ -1762,3 +2108,180 @@ void EEVEE_materials_draw_opaque(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Pass
DRW_draw_pass(psl->material_pass);
DRW_draw_pass(psl->material_pass_cull);
}
+
+/* -------------------------------------------------------------------- */
+
+/** \name Render Passes
+ * \{ */
+
+void EEVEE_material_renderpasses_init(EEVEE_Data *vedata)
+{
+ EEVEE_StorageList *stl = vedata->stl;
+ EEVEE_PrivateData *g_data = stl->g_data;
+
+ /* For diffuse and glossy we calculate the final light + color buffer where we extract the
+ * light from by dividing by the color buffer. When one the light is requested we also tag
+ * the color buffer to do the extraction. */
+ if (g_data->render_passes & EEVEE_RENDER_PASS_DIFFUSE_LIGHT) {
+ g_data->render_passes |= EEVEE_RENDER_PASS_DIFFUSE_COLOR;
+ }
+ if (g_data->render_passes & EEVEE_RENDER_PASS_SPECULAR_LIGHT) {
+ g_data->render_passes |= EEVEE_RENDER_PASS_SPECULAR_COLOR;
+ }
+
+ /* Calculate the number of material based render passes */
+ uint num_render_passes = count_bits_i(stl->g_data->render_passes & EEVEE_RENDERPASSES_MATERIAL);
+ if ((num_render_passes != 0 && stl->g_data->render_passes & EEVEE_RENDER_PASS_ENVIRONMENT) ==
+ 0) {
+ num_render_passes += 1;
+ }
+ stl->g_data->render_passes_material_count = num_render_passes;
+}
+
+void EEVEE_material_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, uint tot_samples)
+{
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ EEVEE_FramebufferList *fbl = vedata->fbl;
+ DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
+ EEVEE_TextureList *txl = vedata->txl;
+ EEVEE_StorageList *stl = vedata->stl;
+ EEVEE_PassList *psl = vedata->psl;
+ EEVEE_EffectsInfo *effects = stl->effects;
+
+ float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+
+ /* Create FrameBuffer. */
+
+ /* Should be enough precision for many samples. */
+ const eGPUTextureFormat texture_format_material_accum = (tot_samples > 128) ? GPU_RGBA32F :
+ GPU_RGBA16F;
+ const eViewLayerEEVEEPassType render_passes = stl->g_data->render_passes &
+ EEVEE_RENDERPASSES_MATERIAL;
+ if (render_passes != 0) {
+ GPU_framebuffer_ensure_config(&fbl->material_accum_fb,
+ {GPU_ATTACHMENT_TEXTURE(dtxl->depth), GPU_ATTACHMENT_LEAVE});
+ int render_pass_index = ((render_passes & EEVEE_RENDER_PASS_ENVIRONMENT) != 0) ? 0 : 1;
+ for (int bit = 0; bit < 32; bit++) {
+ eViewLayerEEVEEPassType bitflag = (1 << bit);
+ if ((render_passes & bitflag) != 0) {
+
+ DRW_texture_ensure_fullscreen_2d(
+ &txl->material_accum[render_pass_index], texture_format_material_accum, 0);
+
+ /* Clear texture. */
+ if (DRW_state_is_image_render() || effects->taa_current_sample == 1) {
+ GPU_framebuffer_texture_attach(
+ fbl->material_accum_fb, txl->material_accum[render_pass_index], 0, 0);
+ GPU_framebuffer_bind(fbl->material_accum_fb);
+ GPU_framebuffer_clear_color(fbl->material_accum_fb, clear);
+ GPU_framebuffer_bind(fbl->main_fb);
+ GPU_framebuffer_texture_detach(fbl->material_accum_fb,
+ txl->material_accum[render_pass_index]);
+ }
+ render_pass_index++;
+ }
+ }
+
+ if ((render_passes & EEVEE_RENDER_PASS_SPECULAR_LIGHT) &&
+ (effects->enabled_effects & EFFECT_SSR)) {
+ EEVEE_reflection_output_init(sldata, vedata, tot_samples);
+ }
+
+ if (render_passes & EEVEE_RENDER_PASS_ENVIRONMENT) {
+ Scene *scene = draw_ctx->scene;
+ World *wo = scene->world;
+
+ if (wo && wo->use_nodes && wo->nodetree) {
+ struct GPUMaterial *gpumat = EEVEE_material_world_background_get(scene, wo);
+ if (GPU_material_status(gpumat) == GPU_MAT_SUCCESS) {
+ DRWShadingGroup *grp = DRW_shgroup_material_create(gpumat, psl->material_accum_pass[0]);
+ add_background_uniforms(grp, sldata, vedata);
+ DRW_shgroup_call(grp, DRW_cache_fullscreen_quad_get(), NULL);
+ }
+ }
+ }
+ }
+}
+
+void EEVEE_material_output_accumulate(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
+{
+ EEVEE_FramebufferList *fbl = vedata->fbl;
+ EEVEE_PassList *psl = vedata->psl;
+ EEVEE_StorageList *stl = vedata->stl;
+ EEVEE_TextureList *txl = vedata->txl;
+
+ if (fbl->material_accum_fb != NULL) {
+ for (int renderpass_index = 0; renderpass_index < stl->g_data->render_passes_material_count;
+ renderpass_index++) {
+ if (txl->material_accum[renderpass_index] != NULL) {
+ GPU_framebuffer_texture_attach(
+ fbl->material_accum_fb, txl->material_accum[renderpass_index], 0, 0);
+ GPU_framebuffer_bind(fbl->material_accum_fb);
+ DRW_draw_pass(psl->material_accum_pass[renderpass_index]);
+ GPU_framebuffer_bind(fbl->main_fb);
+ GPU_framebuffer_texture_detach(fbl->material_accum_fb,
+ txl->material_accum[renderpass_index]);
+ }
+ }
+ if ((stl->g_data->render_passes & EEVEE_RENDER_PASS_SPECULAR_LIGHT) &&
+ (stl->effects->enabled_effects & EFFECT_SSR)) {
+ EEVEE_reflection_output_accumulate(sldata, vedata);
+ }
+ }
+}
+
+int EEVEE_material_output_pass_index_get(EEVEE_ViewLayerData *UNUSED(sldata),
+ EEVEE_Data *vedata,
+ eViewLayerEEVEEPassType renderpass_type)
+{
+ EEVEE_StorageList *stl = vedata->stl;
+
+ BLI_assert((stl->g_data->render_passes & EEVEE_RENDERPASSES_MATERIAL) != 0);
+ BLI_assert((stl->g_data->render_passes & EEVEE_RENDERPASSES_MATERIAL & renderpass_type) != 0);
+
+ /* pass_index 0 is reserved for the environment pass. */
+ if ((stl->g_data->render_passes & EEVEE_RENDER_PASS_ENVIRONMENT & renderpass_type) != 0) {
+ return 0;
+ }
+
+ /* pass_index 0 is reserved for the environment pass. Other passes start from index 1 */
+ int index = 1;
+ eViewLayerEEVEEPassType active_material_passes = stl->g_data->render_passes &
+ EEVEE_RENDERPASSES_MATERIAL &
+ ~EEVEE_RENDER_PASS_ENVIRONMENT;
+
+ for (int bitshift = 0; bitshift < 32; bitshift++) {
+ eViewLayerEEVEEPassType pass_flag = (1 << bitshift);
+ if (pass_flag == renderpass_type) {
+ break;
+ }
+ if (active_material_passes & pass_flag) {
+ index++;
+ }
+ }
+
+ return index;
+}
+
+/* Get the pass index that contains the color pass for the given renderpass_type. */
+int EEVEE_material_output_color_pass_index_get(EEVEE_ViewLayerData *sldata,
+ EEVEE_Data *vedata,
+ eViewLayerEEVEEPassType renderpass_type)
+{
+ BLI_assert(
+ ELEM(renderpass_type, EEVEE_RENDER_PASS_DIFFUSE_LIGHT, EEVEE_RENDER_PASS_SPECULAR_LIGHT));
+ eViewLayerEEVEEPassType color_pass_type;
+ switch (renderpass_type) {
+ case EEVEE_RENDER_PASS_DIFFUSE_LIGHT:
+ color_pass_type = EEVEE_RENDER_PASS_DIFFUSE_COLOR;
+ break;
+ case EEVEE_RENDER_PASS_SPECULAR_LIGHT:
+ color_pass_type = EEVEE_RENDER_PASS_SPECULAR_COLOR;
+ break;
+ default:
+ color_pass_type = 0;
+ BLI_assert(false);
+ }
+ return EEVEE_material_output_pass_index_get(sldata, vedata, color_pass_type);
+}
+/* \} */
diff --git a/source/blender/draw/engines/eevee/eevee_mist.c b/source/blender/draw/engines/eevee/eevee_mist.c
index c9b56a6d551..cdcfd64d995 100644
--- a/source/blender/draw/engines/eevee/eevee_mist.c
+++ b/source/blender/draw/engines/eevee/eevee_mist.c
@@ -114,6 +114,8 @@ void EEVEE_mist_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
DRWShadingGroup *grp = DRW_shgroup_create(e_data.mist_sh, psl->mist_accum_ps);
DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &dtxl->depth);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
+ DRW_shgroup_uniform_block(
+ grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_uniform_vec3(grp, "mistSettings", &g_data->mist_start, 1);
DRW_shgroup_call(grp, DRW_cache_fullscreen_quad_get(), NULL);
}
diff --git a/source/blender/draw/engines/eevee/eevee_occlusion.c b/source/blender/draw/engines/eevee/eevee_occlusion.c
index 6ba518b3a28..be4dfd07ce1 100644
--- a/source/blender/draw/engines/eevee/eevee_occlusion.c
+++ b/source/blender/draw/engines/eevee/eevee_occlusion.c
@@ -170,6 +170,8 @@ void EEVEE_occlusion_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata
DRW_shgroup_uniform_texture_ref(grp, "normalBuffer", &effects->ssr_normal_input);
DRW_shgroup_uniform_texture_ref(grp, "horizonBuffer", &effects->gtao_horizons);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
+ DRW_shgroup_uniform_block(
+ grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_call(grp, DRW_cache_fullscreen_quad_get(), NULL);
}
else {
@@ -207,6 +209,8 @@ void EEVEE_occlusion_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
DRW_shgroup_uniform_texture_ref(grp, "maxzBuffer", &txl->maxzbuffer);
DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &effects->ao_src_depth);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
+ DRW_shgroup_uniform_block(
+ grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_call(grp, quad, NULL);
DRW_PASS_CREATE(psl->ao_horizon_search_layer, DRW_STATE_WRITE_COLOR);
@@ -215,6 +219,8 @@ void EEVEE_occlusion_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
DRW_shgroup_uniform_texture_ref(grp, "maxzBuffer", &txl->maxzbuffer);
DRW_shgroup_uniform_texture_ref(grp, "depthBufferLayered", &effects->ao_src_depth);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
+ DRW_shgroup_uniform_block(
+ grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_uniform_int(grp, "layer", &stl->effects->ao_depth_layer, 1);
DRW_shgroup_call(grp, quad, NULL);
@@ -227,6 +233,8 @@ void EEVEE_occlusion_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
DRW_shgroup_uniform_texture_ref(grp, "normalBuffer", &effects->ssr_normal_input);
DRW_shgroup_uniform_texture_ref(grp, "horizonBuffer", &effects->gtao_horizons);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
+ DRW_shgroup_uniform_block(
+ grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_call(grp, quad, NULL);
}
}
diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h
index 7810de289df..db29e103226 100644
--- a/source/blender/draw/engines/eevee/eevee_private.h
+++ b/source/blender/draw/engines/eevee/eevee_private.h
@@ -141,6 +141,13 @@ extern struct DrawEngineType draw_engine_eevee_type;
#define MIN_CUBE_LOD_LEVEL 3
#define MAX_PLANAR_LOD_LEVEL 9
+/* All the renderpasses that use the GPUMaterial for accumulation */
+#define EEVEE_RENDERPASSES_MATERIAL \
+ (EEVEE_RENDER_PASS_EMIT | EEVEE_RENDER_PASS_DIFFUSE_COLOR | EEVEE_RENDER_PASS_DIFFUSE_LIGHT | \
+ EEVEE_RENDER_PASS_SPECULAR_COLOR | EEVEE_RENDER_PASS_SPECULAR_LIGHT | \
+ EEVEE_RENDER_PASS_ENVIRONMENT)
+#define MAX_MATERIAL_RENDER_PASSES 6
+#define MAX_MATERIAL_RENDER_PASSES_UBO 6
/* World shader variations */
enum {
VAR_WORLD_BACKGROUND = 0,
@@ -198,6 +205,7 @@ typedef struct EEVEE_BoundBox {
typedef struct EEVEE_PassList {
/* Shadows */
struct DRWPass *shadow_pass;
+ struct DRWPass *shadow_accum_pass;
/* Probes */
struct DRWPass *probe_background;
@@ -220,6 +228,7 @@ typedef struct EEVEE_PassList {
struct DRWPass *bloom_downsample;
struct DRWPass *bloom_upsample;
struct DRWPass *bloom_resolve;
+ struct DRWPass *bloom_accum_ps;
struct DRWPass *dof_down;
struct DRWPass *dof_scatter;
struct DRWPass *dof_resolve;
@@ -228,11 +237,11 @@ typedef struct EEVEE_PassList {
struct DRWPass *volumetric_scatter_ps;
struct DRWPass *volumetric_integration_ps;
struct DRWPass *volumetric_resolve_ps;
+ struct DRWPass *volumetric_accum_ps;
struct DRWPass *ssr_raytrace;
struct DRWPass *ssr_resolve;
struct DRWPass *sss_blur_ps;
struct DRWPass *sss_resolve_ps;
- struct DRWPass *sss_accum_ps;
struct DRWPass *sss_translucency_ps;
struct DRWPass *color_downsample_ps;
struct DRWPass *color_downsample_cube_ps;
@@ -264,6 +273,7 @@ typedef struct EEVEE_PassList {
struct DRWPass *sss_pass_cull;
struct DRWPass *material_pass;
struct DRWPass *material_pass_cull;
+ struct DRWPass *material_accum_pass[MAX_MATERIAL_RENDER_PASSES];
struct DRWPass *refract_pass;
struct DRWPass *transparent_pass;
struct DRWPass *background_pass;
@@ -281,6 +291,9 @@ typedef struct EEVEE_FramebufferList {
struct GPUFrameBuffer *bloom_blit_fb;
struct GPUFrameBuffer *bloom_down_fb[MAX_BLOOM_STEP];
struct GPUFrameBuffer *bloom_accum_fb[MAX_BLOOM_STEP - 1];
+ struct GPUFrameBuffer *bloom_pass_accum_fb;
+ struct GPUFrameBuffer *shadow_accum_fb;
+ struct GPUFrameBuffer *ssr_accum_fb;
struct GPUFrameBuffer *sss_blur_fb;
struct GPUFrameBuffer *sss_blit_fb;
struct GPUFrameBuffer *sss_resolve_fb;
@@ -292,9 +305,11 @@ typedef struct EEVEE_FramebufferList {
struct GPUFrameBuffer *volumetric_fb;
struct GPUFrameBuffer *volumetric_scat_fb;
struct GPUFrameBuffer *volumetric_integ_fb;
+ struct GPUFrameBuffer *volumetric_accum_fb;
struct GPUFrameBuffer *screen_tracing_fb;
struct GPUFrameBuffer *refract_fb;
struct GPUFrameBuffer *mist_accum_fb;
+ struct GPUFrameBuffer *material_accum_fb;
struct GPUFrameBuffer *renderpass_fb;
struct GPUFrameBuffer *ao_accum_fb;
struct GPUFrameBuffer *velocity_resolve_fb;
@@ -320,8 +335,11 @@ typedef struct EEVEE_TextureList {
struct GPUTexture *color_post; /* R16_G16_B16 */
struct GPUTexture *mist_accum;
struct GPUTexture *ao_accum;
- struct GPUTexture *sss_dir_accum;
- struct GPUTexture *sss_col_accum;
+ struct GPUTexture *sss_accum;
+ struct GPUTexture *material_accum[MAX_MATERIAL_RENDER_PASSES];
+ struct GPUTexture *bloom_accum;
+ struct GPUTexture *ssr_accum;
+ struct GPUTexture *shadow_accum;
struct GPUTexture *refract_color;
struct GPUTexture *taa_history;
@@ -333,6 +351,8 @@ typedef struct EEVEE_TextureList {
struct GPUTexture *volume_transmit;
struct GPUTexture *volume_scatter_history;
struct GPUTexture *volume_transmit_history;
+ struct GPUTexture *volume_scatter_accum;
+ struct GPUTexture *volume_transmittance_accum;
struct GPUTexture *lookdev_grid_tx;
struct GPUTexture *lookdev_cube_tx;
@@ -361,6 +381,17 @@ typedef struct EEVEE_StorageList {
LightCacheTexture *lookdev_cube_mips;
} EEVEE_StorageList;
+/* ************ RENDERPASS UBO ************* */
+typedef struct EEVEE_RenderPassData {
+ int renderPassDiffuse;
+ int renderPassDiffuseLight;
+ int renderPassGlossy;
+ int renderPassGlossyLight;
+ int renderPassEmit;
+ int renderPassSSSColor;
+ int _pad[2];
+} EEVEE_RenderPassData;
+
/* ************ LIGHT UBO ************* */
typedef struct EEVEE_Light {
float position[3], invsqrdist;
@@ -408,6 +439,7 @@ BLI_STATIC_ASSERT_ALIGN(EEVEE_Light, 16)
BLI_STATIC_ASSERT_ALIGN(EEVEE_Shadow, 16)
BLI_STATIC_ASSERT_ALIGN(EEVEE_ShadowCube, 16)
BLI_STATIC_ASSERT_ALIGN(EEVEE_ShadowCascade, 16)
+BLI_STATIC_ASSERT_ALIGN(EEVEE_RenderPassData, 16)
BLI_STATIC_ASSERT(sizeof(EEVEE_Shadow) * MAX_SHADOW +
sizeof(EEVEE_ShadowCascade) * MAX_SHADOW_CASCADE +
@@ -708,6 +740,10 @@ typedef struct EEVEE_ViewLayerData {
struct GPUUniformBuffer *grid_ubo;
struct GPUUniformBuffer *planar_ubo;
+ /* Material Render passes */
+ struct EEVEE_RenderPassData renderpass_data[MAX_MATERIAL_RENDER_PASSES_UBO];
+ struct GPUUniformBuffer *renderpass_ubo[MAX_MATERIAL_RENDER_PASSES_UBO];
+
/* Common Uniform Buffer */
struct EEVEE_CommonUniformBuffer common_data;
struct GPUUniformBuffer *common_ubo;
@@ -759,6 +795,7 @@ typedef struct EEVEE_Data {
typedef struct EEVEE_PrivateData {
struct DRWShadingGroup *shadow_shgrp;
+ struct DRWShadingGroup *shadow_accum_shgrp;
struct DRWShadingGroup *depth_shgrp;
struct DRWShadingGroup *depth_shgrp_cull;
struct DRWShadingGroup *depth_shgrp_clip;
@@ -803,12 +840,17 @@ typedef struct EEVEE_PrivateData {
/* Renderpasses */
/* Bitmask containing the active render_passes */
- eScenePassType render_passes;
+ eViewLayerEEVEEPassType render_passes;
/* Uniform references that are referenced inside the `renderpass_pass`. They are updated
* to reuse the drawing pass and the shading group. */
int renderpass_type;
+ int renderpass_postprocess;
int renderpass_current_sample;
GPUTexture *renderpass_input;
+ GPUTexture *renderpass_col_input;
+ GPUTexture *renderpass_light_input;
+ /* The number of active material based render passes */
+ uint render_passes_material_count;
/** For rendering shadows. */
struct DRWView *cube_views[6];
@@ -860,11 +902,20 @@ struct GPUMaterial *EEVEE_material_mesh_depth_get(struct Scene *scene,
bool use_hashed_alpha,
bool is_shadow);
struct GPUMaterial *EEVEE_material_hair_get(struct Scene *scene, Material *ma);
+struct GPUUniformBuffer *EEVEE_material_default_render_pass_ubo_get(EEVEE_ViewLayerData *sldata);
void EEVEE_materials_free(void);
void EEVEE_materials_draw_opaque(EEVEE_ViewLayerData *sldata, EEVEE_PassList *psl);
void EEVEE_update_noise(EEVEE_PassList *psl, EEVEE_FramebufferList *fbl, const double offsets[3]);
void EEVEE_update_viewvecs(float invproj[4][4], float winmat[4][4], float (*r_viewvecs)[4]);
-
+void EEVEE_material_renderpasses_init(EEVEE_Data *vedata);
+void EEVEE_material_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, uint tot_samples);
+void EEVEE_material_output_accumulate(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
+int EEVEE_material_output_pass_index_get(EEVEE_ViewLayerData *UNUSED(sldata),
+ EEVEE_Data *vedata,
+ eViewLayerEEVEEPassType renderpass_type);
+int EEVEE_material_output_color_pass_index_get(EEVEE_ViewLayerData *sldata,
+ EEVEE_Data *vedata,
+ eViewLayerEEVEEPassType renderpass_type);
/* eevee_lights.c */
void eevee_light_matrix_get(const EEVEE_Light *evli, float r_mat[4][4]);
void EEVEE_lights_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
@@ -896,6 +947,8 @@ void EEVEE_shadows_draw_cascades(EEVEE_ViewLayerData *sldata,
EEVEE_Data *vedata,
DRWView *view,
int cascade_index);
+void EEVEE_shadow_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, uint tot_samples);
+void EEVEE_shadow_output_accumulate(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_shadows_free(void);
/* eevee_sampling.c */
@@ -995,6 +1048,8 @@ void EEVEE_depth_of_field_free(void);
int EEVEE_bloom_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_bloom_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_bloom_draw(EEVEE_Data *vedata);
+void EEVEE_bloom_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, uint tot_samples);
+void EEVEE_bloom_output_accumulate(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_bloom_free(void);
/* eevee_occlusion.c */
@@ -1016,6 +1071,11 @@ int EEVEE_screen_raytrace_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_screen_raytrace_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_refraction_compute(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_reflection_compute(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
+void EEVEE_reflection_output_init(EEVEE_ViewLayerData *sldata,
+ EEVEE_Data *vedata,
+ uint tot_samples);
+void EEVEE_reflection_output_accumulate(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
+
void EEVEE_screen_raytrace_free(void);
/* eevee_subsurface.c */
@@ -1055,10 +1115,12 @@ void EEVEE_renderpasses_init(EEVEE_Data *vedata);
void EEVEE_renderpasses_output_init(EEVEE_ViewLayerData *sldata,
EEVEE_Data *vedata,
uint tot_samples);
-void EEVEE_renderpasses_output_accumulate(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
+void EEVEE_renderpasses_output_accumulate(EEVEE_ViewLayerData *sldata,
+ EEVEE_Data *vedata,
+ bool post_effect);
void EEVEE_renderpasses_postprocess(EEVEE_ViewLayerData *sldata,
EEVEE_Data *vedata,
- eScenePassType renderpass_type);
+ eViewLayerEEVEEPassType renderpass_type);
void EEVEE_renderpasses_draw(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_renderpasses_draw_debug(EEVEE_Data *vedata);
void EEVEE_renderpasses_free(void);
@@ -1087,6 +1149,8 @@ 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_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, uint tot_samples);
+void EEVEE_volumes_output_accumulate(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_volumes_free_smoke_textures(void);
void EEVEE_volumes_free(void);
diff --git a/source/blender/draw/engines/eevee/eevee_render.c b/source/blender/draw/engines/eevee/eevee_render.c
index 063510d51e6..9b20f006387 100644
--- a/source/blender/draw/engines/eevee/eevee_render.c
+++ b/source/blender/draw/engines/eevee/eevee_render.c
@@ -230,6 +230,9 @@ static void eevee_render_color_result(RenderLayer *rl,
EEVEE_Data *vedata)
{
RenderPass *rp = RE_pass_find_by_name(rl, render_pass_name, viewname);
+ if (rp == NULL) {
+ return;
+ }
GPU_framebuffer_bind(framebuffer);
GPU_framebuffer_read_color(framebuffer,
vedata->stl->g_data->overscan_pixels + rect->xmin,
@@ -251,35 +254,6 @@ static void eevee_render_result_combined(RenderLayer *rl,
rl, viewname, rect, RE_PASSNAME_COMBINED, 4, vedata->stl->effects->final_fb, vedata);
}
-static void eevee_render_result_subsurface(RenderLayer *rl,
- const char *viewname,
- const rcti *rect,
- EEVEE_Data *vedata,
- EEVEE_ViewLayerData *sldata)
-{
- if (vedata->fbl->sss_accum_fb == NULL) {
- /* SSS is not enabled. */
- return;
- }
-
- if ((vedata->stl->g_data->render_passes & SCE_PASS_SUBSURFACE_COLOR) != 0) {
- EEVEE_renderpasses_postprocess(sldata, vedata, SCE_PASS_SUBSURFACE_COLOR);
- eevee_render_color_result(
- rl, viewname, rect, RE_PASSNAME_SUBSURFACE_COLOR, 3, vedata->fbl->renderpass_fb, vedata);
- }
-
- if ((vedata->stl->g_data->render_passes & SCE_PASS_SUBSURFACE_DIRECT) != 0) {
- EEVEE_renderpasses_postprocess(sldata, vedata, SCE_PASS_SUBSURFACE_DIRECT);
- eevee_render_color_result(
- rl, viewname, rect, RE_PASSNAME_SUBSURFACE_DIRECT, 3, vedata->fbl->renderpass_fb, vedata);
- }
-
- if ((vedata->stl->g_data->render_passes & SCE_PASS_SUBSURFACE_INDIRECT) != 0) {
- /* Do nothing as all the lighting is in the direct pass.
- * TODO : Separate Direct from indirect lighting. */
- }
-}
-
static void eevee_render_result_normal(RenderLayer *rl,
const char *viewname,
const rcti *rect,
@@ -293,8 +267,8 @@ static void eevee_render_result_normal(RenderLayer *rl,
return;
}
- if ((vedata->stl->g_data->render_passes & SCE_PASS_NORMAL) != 0) {
- EEVEE_renderpasses_postprocess(sldata, vedata, SCE_PASS_NORMAL);
+ if ((vedata->stl->g_data->render_passes & EEVEE_RENDER_PASS_NORMAL) != 0) {
+ EEVEE_renderpasses_postprocess(sldata, vedata, EEVEE_RENDER_PASS_NORMAL);
eevee_render_color_result(
rl, viewname, rect, RE_PASSNAME_NORMAL, 3, vedata->fbl->renderpass_fb, vedata);
}
@@ -313,8 +287,8 @@ static void eevee_render_result_z(RenderLayer *rl,
return;
}
- if ((vedata->stl->g_data->render_passes & SCE_PASS_Z) != 0) {
- EEVEE_renderpasses_postprocess(sldata, vedata, SCE_PASS_Z);
+ if ((vedata->stl->g_data->render_passes & EEVEE_RENDER_PASS_Z) != 0) {
+ EEVEE_renderpasses_postprocess(sldata, vedata, EEVEE_RENDER_PASS_Z);
eevee_render_color_result(
rl, viewname, rect, RE_PASSNAME_Z, 1, vedata->fbl->renderpass_fb, vedata);
}
@@ -326,31 +300,142 @@ static void eevee_render_result_mist(RenderLayer *rl,
EEVEE_Data *vedata,
EEVEE_ViewLayerData *sldata)
{
- if ((vedata->stl->g_data->render_passes & SCE_PASS_MIST) != 0) {
- EEVEE_renderpasses_postprocess(sldata, vedata, SCE_PASS_MIST);
+ if ((vedata->stl->g_data->render_passes & EEVEE_RENDER_PASS_MIST) != 0) {
+ EEVEE_renderpasses_postprocess(sldata, vedata, EEVEE_RENDER_PASS_MIST);
eevee_render_color_result(
rl, viewname, rect, RE_PASSNAME_MIST, 1, vedata->fbl->renderpass_fb, vedata);
}
}
+static void eevee_render_result_shadow(RenderLayer *rl,
+ const char *viewname,
+ const rcti *rect,
+ EEVEE_Data *vedata,
+ EEVEE_ViewLayerData *sldata)
+{
+ if ((vedata->stl->g_data->render_passes & EEVEE_RENDER_PASS_SHADOW) != 0) {
+ EEVEE_renderpasses_postprocess(sldata, vedata, EEVEE_RENDER_PASS_SHADOW);
+ eevee_render_color_result(
+ rl, viewname, rect, RE_PASSNAME_SHADOW, 3, vedata->fbl->renderpass_fb, vedata);
+ }
+}
+
static void eevee_render_result_occlusion(RenderLayer *rl,
const char *viewname,
const rcti *rect,
EEVEE_Data *vedata,
EEVEE_ViewLayerData *sldata)
{
- if (vedata->fbl->ao_accum_fb == NULL) {
+ if ((vedata->stl->effects->enabled_effects & EFFECT_GTAO) == 0) {
/* AO is not enabled. */
return;
}
- if ((vedata->stl->g_data->render_passes & SCE_PASS_AO) != 0) {
- EEVEE_renderpasses_postprocess(sldata, vedata, SCE_PASS_AO);
+ if ((vedata->stl->g_data->render_passes & EEVEE_RENDER_PASS_AO) != 0) {
+ EEVEE_renderpasses_postprocess(sldata, vedata, EEVEE_RENDER_PASS_AO);
eevee_render_color_result(
rl, viewname, rect, RE_PASSNAME_AO, 3, vedata->fbl->renderpass_fb, vedata);
}
}
+static void eevee_render_result_bloom(RenderLayer *rl,
+ const char *viewname,
+ const rcti *rect,
+ EEVEE_Data *vedata,
+ EEVEE_ViewLayerData *sldata)
+{
+ if ((vedata->stl->effects->enabled_effects & EFFECT_BLOOM) == 0) {
+ /* Bloom is not enabled. */
+ return;
+ }
+
+ if ((vedata->stl->g_data->render_passes & EEVEE_RENDER_PASS_BLOOM) != 0) {
+ EEVEE_renderpasses_postprocess(sldata, vedata, EEVEE_RENDER_PASS_BLOOM);
+ eevee_render_color_result(
+ rl, viewname, rect, RE_PASSNAME_BLOOM, 3, vedata->fbl->renderpass_fb, vedata);
+ }
+}
+
+#define EEVEE_RENDER_RESULT_MATERIAL_PASS(pass_name, eevee_pass_type) \
+ if ((vedata->stl->g_data->render_passes & EEVEE_RENDER_PASS_##eevee_pass_type) != 0) { \
+ EEVEE_renderpasses_postprocess(sldata, vedata, EEVEE_RENDER_PASS_##eevee_pass_type); \
+ eevee_render_color_result( \
+ rl, viewname, rect, RE_PASSNAME_##pass_name, 3, vedata->fbl->renderpass_fb, vedata); \
+ }
+
+static void eevee_render_result_diffuse_color(RenderLayer *rl,
+ const char *viewname,
+ const rcti *rect,
+ EEVEE_Data *vedata,
+ EEVEE_ViewLayerData *sldata)
+{
+ EEVEE_RENDER_RESULT_MATERIAL_PASS(DIFFUSE_COLOR, DIFFUSE_COLOR)
+}
+
+static void eevee_render_result_diffuse_direct(RenderLayer *rl,
+ const char *viewname,
+ const rcti *rect,
+ EEVEE_Data *vedata,
+ EEVEE_ViewLayerData *sldata)
+{
+ EEVEE_RENDER_RESULT_MATERIAL_PASS(DIFFUSE_DIRECT, DIFFUSE_LIGHT)
+}
+
+static void eevee_render_result_specular_color(RenderLayer *rl,
+ const char *viewname,
+ const rcti *rect,
+ EEVEE_Data *vedata,
+ EEVEE_ViewLayerData *sldata)
+{
+ EEVEE_RENDER_RESULT_MATERIAL_PASS(GLOSSY_COLOR, SPECULAR_COLOR)
+}
+
+static void eevee_render_result_specular_direct(RenderLayer *rl,
+ const char *viewname,
+ const rcti *rect,
+ EEVEE_Data *vedata,
+ EEVEE_ViewLayerData *sldata)
+{
+ EEVEE_RENDER_RESULT_MATERIAL_PASS(GLOSSY_DIRECT, SPECULAR_LIGHT)
+}
+
+static void eevee_render_result_emission(RenderLayer *rl,
+ const char *viewname,
+ const rcti *rect,
+ EEVEE_Data *vedata,
+ EEVEE_ViewLayerData *sldata)
+{
+ EEVEE_RENDER_RESULT_MATERIAL_PASS(EMIT, EMIT)
+}
+
+static void eevee_render_result_environment(RenderLayer *rl,
+ const char *viewname,
+ const rcti *rect,
+ EEVEE_Data *vedata,
+ EEVEE_ViewLayerData *sldata)
+{
+ EEVEE_RENDER_RESULT_MATERIAL_PASS(ENVIRONMENT, ENVIRONMENT)
+}
+
+static void eevee_render_result_volume_scatter(RenderLayer *rl,
+ const char *viewname,
+ const rcti *rect,
+ EEVEE_Data *vedata,
+ EEVEE_ViewLayerData *sldata)
+{
+ EEVEE_RENDER_RESULT_MATERIAL_PASS(VOLUME_SCATTER, VOLUME_SCATTER)
+}
+static void eevee_render_result_volume_transmittance(RenderLayer *rl,
+ const char *viewname,
+ const rcti *rect,
+ EEVEE_Data *vedata,
+ EEVEE_ViewLayerData *sldata)
+{
+ EEVEE_RENDER_RESULT_MATERIAL_PASS(VOLUME_TRANSMITTANCE, VOLUME_TRANSMITTANCE)
+}
+
+#undef EEVEE_RENDER_RESULT_MATERIAL_PASS
+
static void eevee_render_draw_background(EEVEE_Data *vedata)
{
EEVEE_FramebufferList *fbl = vedata->fbl;
@@ -508,7 +593,7 @@ void EEVEE_render_draw(EEVEE_Data *vedata, RenderEngine *engine, RenderLayer *rl
/* Volumetrics Resolve Opaque */
EEVEE_volumes_resolve(sldata, vedata);
/* Subsurface output, Occlusion output, Mist output */
- EEVEE_renderpasses_output_accumulate(sldata, vedata);
+ EEVEE_renderpasses_output_accumulate(sldata, vedata, false);
/* Transparent */
GPU_framebuffer_texture_attach(fbl->main_color_fb, dtxl->depth, 0, 0);
GPU_framebuffer_bind(fbl->main_color_fb);
@@ -527,9 +612,18 @@ void EEVEE_render_draw(EEVEE_Data *vedata, RenderEngine *engine, RenderLayer *rl
}
eevee_render_result_combined(rl, viewname, rect, vedata, sldata);
- eevee_render_result_subsurface(rl, viewname, rect, vedata, sldata);
eevee_render_result_mist(rl, viewname, rect, vedata, sldata);
eevee_render_result_occlusion(rl, viewname, rect, vedata, sldata);
+ eevee_render_result_shadow(rl, viewname, rect, vedata, sldata);
+ eevee_render_result_diffuse_color(rl, viewname, rect, vedata, sldata);
+ eevee_render_result_diffuse_direct(rl, viewname, rect, vedata, sldata);
+ eevee_render_result_specular_color(rl, viewname, rect, vedata, sldata);
+ eevee_render_result_specular_direct(rl, viewname, rect, vedata, sldata);
+ eevee_render_result_emission(rl, viewname, rect, vedata, sldata);
+ eevee_render_result_environment(rl, viewname, rect, vedata, sldata);
+ eevee_render_result_bloom(rl, viewname, rect, vedata, sldata);
+ eevee_render_result_volume_scatter(rl, viewname, rect, vedata, sldata);
+ eevee_render_result_volume_transmittance(rl, viewname, rect, vedata, sldata);
/* Restore original viewport size. */
DRW_render_viewport_size_set((int[2]){g_data->size_orig[0], g_data->size_orig[1]});
@@ -537,29 +631,35 @@ void EEVEE_render_draw(EEVEE_Data *vedata, RenderEngine *engine, RenderLayer *rl
void EEVEE_render_update_passes(RenderEngine *engine, Scene *scene, ViewLayer *view_layer)
{
- int type;
-
RE_engine_register_pass(engine, scene, view_layer, RE_PASSNAME_COMBINED, 4, "RGBA", SOCK_RGBA);
-#define CHECK_PASS(name, channels, chanid) \
+#define CHECK_PASS_LEGACY(name, type, channels, chanid) \
if (view_layer->passflag & (SCE_PASS_##name)) { \
- if (channels == 4) \
- type = SOCK_RGBA; \
- else if (channels == 3) \
- type = SOCK_VECTOR; \
- else \
- type = SOCK_FLOAT; \
+ RE_engine_register_pass( \
+ engine, scene, view_layer, RE_PASSNAME_##name, channels, chanid, type); \
+ } \
+ ((void)0)
+#define CHECK_PASS_EEVEE(name, type, channels, chanid) \
+ if (view_layer->eevee.render_passes & (EEVEE_RENDER_PASS_##name)) { \
RE_engine_register_pass( \
engine, scene, view_layer, RE_PASSNAME_##name, channels, chanid, type); \
} \
((void)0)
- CHECK_PASS(Z, 1, "Z");
- CHECK_PASS(MIST, 1, "Z");
- CHECK_PASS(NORMAL, 3, "XYZ");
- CHECK_PASS(AO, 3, "RGB");
- CHECK_PASS(SUBSURFACE_COLOR, 3, "RGB");
- CHECK_PASS(SUBSURFACE_DIRECT, 3, "RGB");
+ CHECK_PASS_LEGACY(Z, SOCK_FLOAT, 1, "Z");
+ CHECK_PASS_LEGACY(MIST, SOCK_FLOAT, 1, "Z");
+ CHECK_PASS_LEGACY(NORMAL, SOCK_VECTOR, 3, "XYZ");
+ CHECK_PASS_LEGACY(SHADOW, SOCK_RGBA, 3, "RGB");
+ CHECK_PASS_LEGACY(AO, SOCK_RGBA, 3, "RGB");
+ CHECK_PASS_LEGACY(DIFFUSE_COLOR, SOCK_RGBA, 3, "RGB");
+ CHECK_PASS_LEGACY(DIFFUSE_DIRECT, SOCK_RGBA, 3, "RGB");
+ CHECK_PASS_LEGACY(GLOSSY_COLOR, SOCK_RGBA, 3, "RGB");
+ CHECK_PASS_LEGACY(GLOSSY_DIRECT, SOCK_RGBA, 3, "RGB");
+ CHECK_PASS_LEGACY(EMIT, SOCK_RGBA, 3, "RGB");
+ CHECK_PASS_LEGACY(ENVIRONMENT, SOCK_RGBA, 3, "RGB");
+ CHECK_PASS_EEVEE(VOLUME_SCATTER, SOCK_RGBA, 3, "RGB");
+ CHECK_PASS_EEVEE(VOLUME_TRANSMITTANCE, SOCK_RGBA, 3, "RGB");
+ CHECK_PASS_EEVEE(BLOOM, SOCK_RGBA, 3, "RGB");
#undef CHECK_PASS
}
diff --git a/source/blender/draw/engines/eevee/eevee_renderpasses.c b/source/blender/draw/engines/eevee/eevee_renderpasses.c
index 44a6c41e170..2f9e8f3d555 100644
--- a/source/blender/draw/engines/eevee/eevee_renderpasses.c
+++ b/source/blender/draw/engines/eevee/eevee_renderpasses.c
@@ -42,19 +42,35 @@ static struct {
struct GPUShader *postprocess_sh;
} e_data = {NULL}; /* Engine data */
+typedef enum eRenderPassPostProcessType {
+ PASS_POST_UNDEFINED = 0,
+ PASS_POST_ACCUMULATED_COLOR = 1,
+ PASS_POST_ACCUMULATED_LIGHT = 2,
+ PASS_POST_ACCUMULATED_VALUE = 3,
+ PASS_POST_DEPTH = 4,
+ PASS_POST_AO = 5,
+ PASS_POST_NORMAL = 6,
+ PASS_POST_TWO_LIGHT_BUFFERS = 7,
+} eRenderPassPostProcessType;
+
/* bitmask containing all renderpasses that need post-processing */
#define EEVEE_RENDERPASSES_WITH_POST_PROCESSING \
- (SCE_PASS_Z | SCE_PASS_MIST | SCE_PASS_NORMAL | SCE_PASS_AO | SCE_PASS_SUBSURFACE_COLOR | \
- SCE_PASS_SUBSURFACE_DIRECT)
-
-#define EEVEE_RENDERPASSES_SUBSURFACE \
- (SCE_PASS_SUBSURFACE_COLOR | SCE_PASS_SUBSURFACE_DIRECT | SCE_PASS_SUBSURFACE_INDIRECT)
+ (EEVEE_RENDER_PASS_Z | EEVEE_RENDER_PASS_MIST | EEVEE_RENDER_PASS_NORMAL | \
+ EEVEE_RENDER_PASS_AO | EEVEE_RENDER_PASS_BLOOM | EEVEE_RENDER_PASS_VOLUME_SCATTER | \
+ EEVEE_RENDER_PASS_VOLUME_TRANSMITTANCE | EEVEE_RENDER_PASS_SHADOW | \
+ EEVEE_RENDERPASSES_MATERIAL)
-#define EEVEE_RENDERPASSES_ALL (EEVEE_RENDERPASSES_WITH_POST_PROCESSING | SCE_PASS_COMBINED)
+#define EEVEE_RENDERPASSES_ALL \
+ (EEVEE_RENDERPASSES_WITH_POST_PROCESSING | EEVEE_RENDER_PASS_COMBINED)
-#define EEVEE_RENDERPASSES_POST_PROCESS_ON_FIRST_SAMPLE (SCE_PASS_Z | SCE_PASS_NORMAL)
+#define EEVEE_RENDERPASSES_POST_PROCESS_ON_FIRST_SAMPLE \
+ (EEVEE_RENDER_PASS_Z | EEVEE_RENDER_PASS_NORMAL)
-#define EEVEE_RENDERPASSES_COLOR_PASS (SCE_PASS_SUBSURFACE_COLOR | SCE_PASS_SUBSURFACE_DIRECT)
+#define EEVEE_RENDERPASSES_COLOR_PASS \
+ (EEVEE_RENDER_PASS_DIFFUSE_COLOR | EEVEE_RENDER_PASS_SPECULAR_COLOR | EEVEE_RENDER_PASS_EMIT | \
+ EEVEE_RENDER_PASS_BLOOM)
+#define EEVEE_RENDERPASSES_LIGHT_PASS \
+ (EEVEE_RENDER_PASS_DIFFUSE_LIGHT | EEVEE_RENDER_PASS_SPECULAR_LIGHT)
bool EEVEE_renderpasses_only_first_sample_pass_active(EEVEE_Data *vedata)
{
@@ -75,8 +91,33 @@ void EEVEE_renderpasses_init(EEVEE_Data *vedata)
g_data->render_passes = v3d->shading.render_pass;
}
else {
- g_data->render_passes = (view_layer->passflag & EEVEE_RENDERPASSES_ALL) | SCE_PASS_COMBINED;
+ eViewLayerEEVEEPassType enabled_render_passes = view_layer->eevee.render_passes;
+
+#define ENABLE_FROM_LEGACY(name_legacy, name_eevee) \
+ SET_FLAG_FROM_TEST(enabled_render_passes, \
+ (view_layer->passflag & SCE_PASS_##name_legacy) != 0, \
+ EEVEE_RENDER_PASS_##name_eevee);
+
+ ENABLE_FROM_LEGACY(Z, Z)
+ ENABLE_FROM_LEGACY(MIST, MIST)
+ ENABLE_FROM_LEGACY(NORMAL, NORMAL)
+ ENABLE_FROM_LEGACY(SHADOW, SHADOW)
+ ENABLE_FROM_LEGACY(AO, AO)
+ ENABLE_FROM_LEGACY(EMIT, EMIT)
+ ENABLE_FROM_LEGACY(ENVIRONMENT, ENVIRONMENT)
+ ENABLE_FROM_LEGACY(DIFFUSE_COLOR, DIFFUSE_COLOR)
+ ENABLE_FROM_LEGACY(GLOSSY_COLOR, SPECULAR_COLOR)
+ ENABLE_FROM_LEGACY(DIFFUSE_DIRECT, DIFFUSE_LIGHT)
+ ENABLE_FROM_LEGACY(GLOSSY_DIRECT, SPECULAR_LIGHT)
+
+ ENABLE_FROM_LEGACY(ENVIRONMENT, ENVIRONMENT)
+
+#undef ENABLE_FROM_LEGACY
+ g_data->render_passes = (enabled_render_passes & EEVEE_RENDERPASSES_ALL) |
+ EEVEE_RENDER_PASS_COMBINED;
}
+
+ EEVEE_material_renderpasses_init(vedata);
}
void EEVEE_renderpasses_output_init(EEVEE_ViewLayerData *sldata,
@@ -87,6 +128,7 @@ void EEVEE_renderpasses_output_init(EEVEE_ViewLayerData *sldata,
EEVEE_TextureList *txl = vedata->txl;
EEVEE_PassList *psl = vedata->psl;
EEVEE_StorageList *stl = vedata->stl;
+ EEVEE_EffectsInfo *effects = stl->effects;
EEVEE_PrivateData *g_data = stl->g_data;
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
@@ -106,33 +148,54 @@ void EEVEE_renderpasses_output_init(EEVEE_ViewLayerData *sldata,
/* Should be enough to store the data needs for a single pass.
* Some passes will use less, but it is only relevant for final renderings and
- * when renderpasses other than `SCE_PASS_COMBINED` are requested */
+ * when renderpasses other than `EEVEE_RENDER_PASS_COMBINED` are requested */
DRW_texture_ensure_fullscreen_2d(&txl->renderpass, GPU_RGBA16F, 0);
GPU_framebuffer_ensure_config(&fbl->renderpass_fb,
{GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(txl->renderpass)});
- if ((g_data->render_passes & EEVEE_RENDERPASSES_SUBSURFACE) != 0) {
- EEVEE_subsurface_output_init(sldata, vedata, tot_samples);
+ if ((g_data->render_passes & EEVEE_RENDERPASSES_MATERIAL) != 0) {
+ EEVEE_material_output_init(sldata, vedata, tot_samples);
}
- if ((g_data->render_passes & SCE_PASS_MIST) != 0) {
+ if ((g_data->render_passes & EEVEE_RENDER_PASS_MIST) != 0) {
EEVEE_mist_output_init(sldata, vedata);
}
+ if ((g_data->render_passes & EEVEE_RENDER_PASS_SHADOW) != 0) {
+ EEVEE_shadow_output_init(sldata, vedata, tot_samples);
+ }
- if ((g_data->render_passes & SCE_PASS_AO) != 0) {
+ if ((g_data->render_passes & EEVEE_RENDER_PASS_AO) != 0) {
EEVEE_occlusion_output_init(sldata, vedata, tot_samples);
}
+ if ((g_data->render_passes & EEVEE_RENDER_PASS_BLOOM) != 0 &&
+ (effects->enabled_effects & EFFECT_BLOOM) != 0) {
+ EEVEE_bloom_output_init(sldata, vedata, tot_samples);
+ }
+
+ if ((g_data->render_passes &
+ (EEVEE_RENDER_PASS_VOLUME_TRANSMITTANCE | EEVEE_RENDER_PASS_VOLUME_SCATTER)) != 0) {
+ EEVEE_volumes_output_init(sldata, vedata, tot_samples);
+ }
+
/* Create Pass. */
DRW_PASS_CREATE(psl->renderpass_pass, DRW_STATE_WRITE_COLOR);
DRWShadingGroup *grp = DRW_shgroup_create(e_data.postprocess_sh, psl->renderpass_pass);
/* We set a default texture as not all post processes uses the inputBuffer. */
g_data->renderpass_input = txl->color;
+ g_data->renderpass_col_input = txl->color;
+ g_data->renderpass_light_input = txl->color;
DRW_shgroup_uniform_texture_ref(grp, "inputBuffer", &g_data->renderpass_input);
+ DRW_shgroup_uniform_texture_ref(grp, "inputColorBuffer", &g_data->renderpass_col_input);
+ DRW_shgroup_uniform_texture_ref(
+ grp, "inputSecondLightBuffer", &g_data->renderpass_light_input);
DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &dtxl->depth);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
+ DRW_shgroup_uniform_block(
+ grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_uniform_int(grp, "currentSample", &g_data->renderpass_current_sample, 1);
DRW_shgroup_uniform_int(grp, "renderpassType", &g_data->renderpass_type, 1);
+ DRW_shgroup_uniform_int(grp, "postProcessType", &g_data->renderpass_postprocess, 1);
DRW_shgroup_call(grp, DRW_cache_fullscreen_quad_get(), NULL);
}
else {
@@ -152,12 +215,13 @@ void EEVEE_renderpasses_output_init(EEVEE_ViewLayerData *sldata,
* Only invoke this function for passes that need post-processing.
*
* After invoking this function the active framebuffer is set to `vedata->fbl->renderpass_fb`. */
-void EEVEE_renderpasses_postprocess(EEVEE_ViewLayerData *UNUSED(sldata),
+void EEVEE_renderpasses_postprocess(EEVEE_ViewLayerData *sldata,
EEVEE_Data *vedata,
- eScenePassType renderpass_type)
+ eViewLayerEEVEEPassType renderpass_type)
{
EEVEE_PassList *psl = vedata->psl;
EEVEE_TextureList *txl = vedata->txl;
+ EEVEE_FramebufferList *fbl = vedata->fbl;
EEVEE_StorageList *stl = vedata->stl;
EEVEE_PrivateData *g_data = stl->g_data;
EEVEE_EffectsInfo *effects = stl->effects;
@@ -165,51 +229,133 @@ void EEVEE_renderpasses_postprocess(EEVEE_ViewLayerData *UNUSED(sldata),
const int current_sample = effects->taa_current_sample;
g_data->renderpass_current_sample = current_sample;
g_data->renderpass_type = renderpass_type;
+ g_data->renderpass_postprocess = PASS_POST_UNDEFINED;
switch (renderpass_type) {
- case SCE_PASS_AO: {
+ case EEVEE_RENDER_PASS_Z: {
+ g_data->renderpass_postprocess = PASS_POST_DEPTH;
+ break;
+ }
+ case EEVEE_RENDER_PASS_AO: {
+ g_data->renderpass_postprocess = PASS_POST_AO;
g_data->renderpass_input = txl->ao_accum;
break;
}
- case SCE_PASS_NORMAL: {
+ case EEVEE_RENDER_PASS_NORMAL: {
+ g_data->renderpass_postprocess = PASS_POST_NORMAL;
g_data->renderpass_input = effects->ssr_normal_input;
break;
}
- case SCE_PASS_MIST: {
+ case EEVEE_RENDER_PASS_MIST: {
+ g_data->renderpass_postprocess = PASS_POST_ACCUMULATED_VALUE;
g_data->renderpass_input = txl->mist_accum;
break;
}
- case SCE_PASS_SUBSURFACE_DIRECT: {
- g_data->renderpass_input = txl->sss_dir_accum;
+ case EEVEE_RENDER_PASS_VOLUME_SCATTER: {
+ g_data->renderpass_postprocess = PASS_POST_ACCUMULATED_COLOR;
+ g_data->renderpass_input = txl->volume_scatter_accum;
+ break;
+ }
+ case EEVEE_RENDER_PASS_VOLUME_TRANSMITTANCE: {
+ g_data->renderpass_postprocess = PASS_POST_ACCUMULATED_COLOR;
+ g_data->renderpass_input = txl->volume_transmittance_accum;
+ break;
+ }
+ case EEVEE_RENDER_PASS_SHADOW: {
+ g_data->renderpass_postprocess = PASS_POST_ACCUMULATED_VALUE;
+ g_data->renderpass_input = txl->shadow_accum;
break;
}
- case SCE_PASS_SUBSURFACE_COLOR: {
- g_data->renderpass_input = txl->sss_col_accum;
+ case EEVEE_RENDER_PASS_DIFFUSE_COLOR:
+ case EEVEE_RENDER_PASS_SPECULAR_COLOR:
+ case EEVEE_RENDER_PASS_ENVIRONMENT:
+ case EEVEE_RENDER_PASS_EMIT: {
+ g_data->renderpass_postprocess = PASS_POST_ACCUMULATED_COLOR;
+ int renderpass_index = EEVEE_material_output_pass_index_get(sldata, vedata, renderpass_type);
+ g_data->renderpass_input = txl->material_accum[renderpass_index];
+ break;
+ }
+ case EEVEE_RENDER_PASS_SPECULAR_LIGHT: {
+ g_data->renderpass_postprocess = PASS_POST_ACCUMULATED_LIGHT;
+ int renderpass_index = EEVEE_material_output_pass_index_get(sldata, vedata, renderpass_type);
+ int renderpass_index_color = EEVEE_material_output_color_pass_index_get(
+ sldata, vedata, renderpass_type);
+ g_data->renderpass_input = txl->material_accum[renderpass_index];
+ g_data->renderpass_col_input = txl->material_accum[renderpass_index_color];
+ if ((stl->effects->enabled_effects & EFFECT_SSR) != 0) {
+ g_data->renderpass_postprocess = PASS_POST_TWO_LIGHT_BUFFERS;
+ g_data->renderpass_light_input = txl->ssr_accum;
+ }
+ else {
+ g_data->renderpass_postprocess = PASS_POST_ACCUMULATED_LIGHT;
+ }
+ break;
+ }
+ case EEVEE_RENDER_PASS_DIFFUSE_LIGHT: {
+ g_data->renderpass_postprocess = PASS_POST_ACCUMULATED_LIGHT;
+ int renderpass_index = EEVEE_material_output_pass_index_get(sldata, vedata, renderpass_type);
+ int renderpass_index_color = EEVEE_material_output_color_pass_index_get(
+ sldata, vedata, renderpass_type);
+ g_data->renderpass_input = txl->material_accum[renderpass_index];
+ g_data->renderpass_col_input = txl->material_accum[renderpass_index_color];
+ if ((stl->effects->enabled_effects & EFFECT_SSS) != 0) {
+ g_data->renderpass_postprocess = PASS_POST_TWO_LIGHT_BUFFERS;
+ g_data->renderpass_light_input = txl->sss_accum;
+ }
+ else {
+ g_data->renderpass_postprocess = PASS_POST_ACCUMULATED_LIGHT;
+ }
+ break;
+ }
+ case EEVEE_RENDER_PASS_BLOOM: {
+ g_data->renderpass_postprocess = PASS_POST_ACCUMULATED_COLOR;
+ g_data->renderpass_input = txl->bloom_accum;
+ g_data->renderpass_current_sample = 1;
break;
}
default: {
break;
}
}
- GPU_framebuffer_bind(vedata->fbl->renderpass_fb);
+ GPU_framebuffer_bind(fbl->renderpass_fb);
DRW_draw_pass(psl->renderpass_pass);
}
-void EEVEE_renderpasses_output_accumulate(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
+void EEVEE_renderpasses_output_accumulate(EEVEE_ViewLayerData *sldata,
+ EEVEE_Data *vedata,
+ bool post_effect)
{
EEVEE_StorageList *stl = vedata->stl;
EEVEE_EffectsInfo *effects = stl->effects;
- eScenePassType render_pass = stl->g_data->render_passes;
+ eViewLayerEEVEEPassType render_pass = stl->g_data->render_passes;
- if ((render_pass & SCE_PASS_MIST) != 0) {
- EEVEE_mist_output_accumulate(sldata, vedata);
- }
- if ((effects->enabled_effects & EFFECT_SSS) &&
- (render_pass & EEVEE_RENDERPASSES_SUBSURFACE) != 0) {
- EEVEE_subsurface_output_accumulate(sldata, vedata);
+ if (!post_effect) {
+ if ((render_pass & EEVEE_RENDER_PASS_MIST) != 0) {
+ EEVEE_mist_output_accumulate(sldata, vedata);
+ }
+ if ((render_pass & EEVEE_RENDER_PASS_DIFFUSE_LIGHT) != 0 &&
+ (effects->enabled_effects & EFFECT_SSS) != 0) {
+ EEVEE_subsurface_output_accumulate(sldata, vedata);
+ }
+ if ((render_pass & EEVEE_RENDER_PASS_AO) != 0) {
+ EEVEE_occlusion_output_accumulate(sldata, vedata);
+ }
+ if ((render_pass & EEVEE_RENDER_PASS_SHADOW) != 0) {
+ EEVEE_shadow_output_accumulate(sldata, vedata);
+ }
+ if ((render_pass & EEVEE_RENDERPASSES_MATERIAL) != 0) {
+ EEVEE_material_output_accumulate(sldata, vedata);
+ }
+ if ((render_pass &
+ (EEVEE_RENDER_PASS_VOLUME_TRANSMITTANCE | EEVEE_RENDER_PASS_VOLUME_SCATTER)) != 0) {
+ EEVEE_volumes_output_accumulate(sldata, vedata);
+ }
}
- if ((render_pass & SCE_PASS_AO) != 0) {
- EEVEE_occlusion_output_accumulate(sldata, vedata);
+ else {
+ if ((render_pass & EEVEE_RENDER_PASS_BLOOM) != 0 &&
+ (effects->enabled_effects & EFFECT_BLOOM) != 0) {
+ EEVEE_bloom_output_accumulate(sldata, vedata);
+ }
}
}
@@ -220,7 +366,13 @@ void EEVEE_renderpasses_draw(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
EEVEE_StorageList *stl = vedata->stl;
EEVEE_EffectsInfo *effects = stl->effects;
DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
- eScenePassType render_pass = stl->g_data->render_passes;
+
+ /* We can only draw a single renderpass. Lightpasses also select their color pass (a second
+ pass). We mask the light pass when a light pass is selected. */
+ const eViewLayerEEVEEPassType render_pass =
+ ((stl->g_data->render_passes & EEVEE_RENDERPASSES_LIGHT_PASS) != 0) ?
+ (stl->g_data->render_passes & EEVEE_RENDERPASSES_LIGHT_PASS) :
+ stl->g_data->render_passes;
const DRWContextState *draw_ctx = DRW_context_state_get();
const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph);
@@ -229,14 +381,14 @@ void EEVEE_renderpasses_draw(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
DRW_state_is_opengl_render();
UNUSED_VARS(needs_color_transfer);
- /* When SSS isn't available, but the pass is requested, we mark it as invalid */
- if ((render_pass & EEVEE_RENDERPASSES_SUBSURFACE) != 0 &&
- (effects->enabled_effects & EFFECT_SSS) == 0) {
+ if ((render_pass & EEVEE_RENDER_PASS_BLOOM) != 0 &&
+ (effects->enabled_effects & EFFECT_BLOOM) == 0) {
is_valid = false;
}
/* When SSS isn't available, but the pass is requested, we mark it as invalid */
- if ((render_pass & SCE_PASS_AO) != 0 && (scene_eval->eevee.flag & SCE_EEVEE_GTAO_ENABLED) == 0) {
+ if ((render_pass & EEVEE_RENDER_PASS_AO) != 0 &&
+ (scene_eval->eevee.flag & SCE_EEVEE_GTAO_ENABLED) == 0) {
is_valid = false;
}
@@ -254,7 +406,7 @@ void EEVEE_renderpasses_draw(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
}
else {
/* Draw state is not valid for this pass, clear the buffer */
- static float clear_color[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+ static float clear_color[4] = {0.0f, 0.0f, 0.0f, 1.0f};
GPU_framebuffer_bind(dfbl->default_fb);
GPU_framebuffer_clear_color(dfbl->default_fb, clear_color);
}
diff --git a/source/blender/draw/engines/eevee/eevee_screen_raytrace.c b/source/blender/draw/engines/eevee/eevee_screen_raytrace.c
index 591ca31017c..d231edf1383 100644
--- a/source/blender/draw/engines/eevee/eevee_screen_raytrace.c
+++ b/source/blender/draw/engines/eevee/eevee_screen_raytrace.c
@@ -235,6 +235,8 @@ void EEVEE_screen_raytrace_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *v
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, "common_block", sldata->common_ubo);
+ DRW_shgroup_uniform_block(
+ grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
if (!effects->reflection_trace_full) {
DRW_shgroup_uniform_ivec2(grp, "halfresOffset", effects->ssr_halfres_ofs, 1);
}
@@ -255,6 +257,8 @@ void EEVEE_screen_raytrace_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *v
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, "common_block", sldata->common_ubo);
+ DRW_shgroup_uniform_block(
+ grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_uniform_int(grp, "neighborOffset", &effects->ssr_neighbor_ofs, 1);
if ((effects->enabled_effects & EFFECT_GTAO) != 0) {
DRW_shgroup_uniform_texture(grp, "utilTex", EEVEE_materials_get_util_tex());
@@ -335,6 +339,43 @@ void EEVEE_reflection_compute(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *v
}
}
+void EEVEE_reflection_output_init(EEVEE_ViewLayerData *UNUSED(sldata),
+ EEVEE_Data *vedata,
+ uint tot_samples)
+{
+ EEVEE_FramebufferList *fbl = vedata->fbl;
+ EEVEE_TextureList *txl = vedata->txl;
+ EEVEE_StorageList *stl = vedata->stl;
+ EEVEE_EffectsInfo *effects = stl->effects;
+
+ float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+
+ /* Create FrameBuffer. */
+ const eGPUTextureFormat texture_format = (tot_samples > 256) ? GPU_RGBA32F : GPU_RGBA16F;
+ DRW_texture_ensure_fullscreen_2d(&txl->ssr_accum, texture_format, 0);
+
+ GPU_framebuffer_ensure_config(&fbl->ssr_accum_fb,
+ {GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(txl->ssr_accum)});
+
+ /* Clear texture. */
+ if (DRW_state_is_image_render() || effects->taa_current_sample == 1) {
+ GPU_framebuffer_bind(fbl->ssr_accum_fb);
+ GPU_framebuffer_clear_color(fbl->ssr_accum_fb, clear);
+ }
+}
+
+void EEVEE_reflection_output_accumulate(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
+{
+ EEVEE_FramebufferList *fbl = vedata->fbl;
+ EEVEE_PassList *psl = vedata->psl;
+ EEVEE_StorageList *stl = vedata->stl;
+
+ if (stl->g_data->valid_double_buffer) {
+ GPU_framebuffer_bind(fbl->ssr_accum_fb);
+ DRW_draw_pass(psl->ssr_resolve);
+ }
+}
+
void EEVEE_screen_raytrace_free(void)
{
for (int i = 0; i < SSR_MAX_SHADER; i++) {
diff --git a/source/blender/draw/engines/eevee/eevee_shadows.c b/source/blender/draw/engines/eevee/eevee_shadows.c
index 1776f535237..f5b98d464dd 100644
--- a/source/blender/draw/engines/eevee/eevee_shadows.c
+++ b/source/blender/draw/engines/eevee/eevee_shadows.c
@@ -21,6 +21,7 @@
*/
#include "BLI_sys_types.h" /* bool */
+#include "BLI_string_utils.h"
// #include "BLI_dynstr.h"
// #include "BLI_rand.h"
@@ -35,11 +36,17 @@
static struct {
struct GPUShader *shadow_sh;
+ struct GPUShader *shadow_accum_sh;
} e_data = {NULL}; /* Engine data */
extern char datatoc_shadow_vert_glsl[];
extern char datatoc_shadow_frag_glsl[];
+extern char datatoc_shadow_accum_frag_glsl[];
extern char datatoc_common_view_lib_glsl[];
+extern char datatoc_common_uniforms_lib_glsl[];
+extern char datatoc_bsdf_common_lib_glsl[];
+extern char datatoc_lights_lib_glsl[];
+extern char datatoc_raytrace_lib_glsl[];
void eevee_contact_shadow_setup(const Light *la, EEVEE_Shadow *evsh)
{
@@ -65,6 +72,18 @@ void EEVEE_shadows_init(EEVEE_ViewLayerData *sldata)
NULL);
}
+ if (!e_data.shadow_accum_sh) {
+ char *frag_str = BLI_string_joinN(datatoc_common_view_lib_glsl,
+ datatoc_common_uniforms_lib_glsl,
+ datatoc_bsdf_common_lib_glsl,
+ datatoc_raytrace_lib_glsl,
+ datatoc_lights_lib_glsl,
+ datatoc_shadow_accum_frag_glsl);
+
+ e_data.shadow_accum_sh = DRW_shader_create_fullscreen(frag_str, SHADER_DEFINES);
+ MEM_freeN(frag_str);
+ }
+
if (!sldata->lights) {
sldata->lights = MEM_callocN(sizeof(EEVEE_LightsInfo), "EEVEE_LightsInfo");
sldata->light_ubo = DRW_uniformbuffer_create(sizeof(EEVEE_Light) * MAX_LIGHT, NULL);
@@ -170,6 +189,8 @@ void EEVEE_shadows_caster_material_add(EEVEE_ViewLayerData *sldata,
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);
+ DRW_shgroup_uniform_block(
+ grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
if (alpha_threshold != NULL) {
@@ -406,7 +427,75 @@ void EEVEE_shadows_draw(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, DRWView
}
}
+/* -------------------------------------------------------------------- */
+
+/** \name Render Passes
+ * \{ */
+
+void EEVEE_shadow_output_init(EEVEE_ViewLayerData *sldata,
+ EEVEE_Data *vedata,
+ uint UNUSED(tot_samples))
+{
+ EEVEE_FramebufferList *fbl = vedata->fbl;
+ EEVEE_TextureList *txl = vedata->txl;
+ EEVEE_PassList *psl = vedata->psl;
+ EEVEE_StorageList *stl = vedata->stl;
+ EEVEE_EffectsInfo *effects = stl->effects;
+ DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
+
+ float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+
+ /* Create FrameBuffer. */
+ const eGPUTextureFormat texture_format = GPU_R32F;
+ DRW_texture_ensure_fullscreen_2d(&txl->shadow_accum, texture_format, 0);
+
+ GPU_framebuffer_ensure_config(&fbl->shadow_accum_fb,
+ {GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(txl->shadow_accum)});
+
+ /* Clear texture. */
+ if (DRW_state_is_image_render() || effects->taa_current_sample == 1) {
+ GPU_framebuffer_bind(fbl->shadow_accum_fb);
+ GPU_framebuffer_clear_color(fbl->shadow_accum_fb, clear);
+ }
+
+ /* Create Pass and shgroup. */
+ DRW_PASS_CREATE(psl->shadow_accum_pass,
+ DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_ALWAYS | DRW_STATE_BLEND_ADD_FULL);
+ DRWShadingGroup *grp = DRW_shgroup_create(e_data.shadow_accum_sh, psl->shadow_accum_pass);
+ DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &dtxl->depth);
+ DRW_shgroup_uniform_texture(grp, "utilTex", EEVEE_materials_get_util_tex());
+ DRW_shgroup_uniform_block(grp, "probe_block", sldata->probe_ubo);
+ DRW_shgroup_uniform_block(grp, "grid_block", sldata->grid_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);
+ DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
+ DRW_shgroup_uniform_block(
+ grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
+ DRW_shgroup_uniform_texture_ref(grp, "shadowCubeTexture", &sldata->shadow_cube_pool);
+ DRW_shgroup_uniform_texture_ref(grp, "shadowCascadeTexture", &sldata->shadow_cascade_pool);
+
+ DRW_shgroup_call(grp, DRW_cache_fullscreen_quad_get(), NULL);
+}
+
+void EEVEE_shadow_output_accumulate(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
+{
+ EEVEE_FramebufferList *fbl = vedata->fbl;
+ EEVEE_PassList *psl = vedata->psl;
+
+ if (fbl->shadow_accum_fb != NULL) {
+ GPU_framebuffer_bind(fbl->shadow_accum_fb);
+ DRW_draw_pass(psl->shadow_accum_pass);
+
+ /* Restore */
+ GPU_framebuffer_bind(fbl->main_fb);
+ }
+}
+
+/* \} */
+
void EEVEE_shadows_free(void)
{
DRW_SHADER_FREE_SAFE(e_data.shadow_sh);
+ DRW_SHADER_FREE_SAFE(e_data.shadow_accum_sh);
}
diff --git a/source/blender/draw/engines/eevee/eevee_subsurface.c b/source/blender/draw/engines/eevee/eevee_subsurface.c
index e94fc903694..98e799acb5e 100644
--- a/source/blender/draw/engines/eevee/eevee_subsurface.c
+++ b/source/blender/draw/engines/eevee/eevee_subsurface.c
@@ -33,7 +33,7 @@
#include "GPU_extensions.h"
static struct {
- struct GPUShader *sss_sh[4];
+ struct GPUShader *sss_sh[3];
} e_data = {{NULL}}; /* Engine data */
extern char datatoc_common_view_lib_glsl[];
@@ -64,8 +64,7 @@ static void eevee_create_shader_subsurface(void)
e_data.sss_sh[0] = DRW_shader_create_fullscreen(frag_str, "#define FIRST_PASS\n");
e_data.sss_sh[1] = DRW_shader_create_fullscreen(frag_str, "#define SECOND_PASS\n");
- e_data.sss_sh[2] = DRW_shader_create_fullscreen(frag_str, "#define RESULT_ACCUM\n");
- e_data.sss_sh[3] = DRW_shader_create_fullscreen(frag_translucent_str,
+ e_data.sss_sh[2] = DRW_shader_create_fullscreen(frag_translucent_str,
"#define EEVEE_TRANSLUCENCY\n" SHADER_DEFINES);
MEM_freeN(frag_translucent_str);
@@ -85,9 +84,10 @@ void EEVEE_subsurface_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
common_data->sss_jitter_threshold = scene_eval->eevee.sss_jitter_threshold;
}
-void EEVEE_subsurface_draw_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
+void EEVEE_subsurface_draw_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
{
EEVEE_EffectsInfo *effects = vedata->stl->effects;
+ EEVEE_StorageList *stl = vedata->stl;
EEVEE_FramebufferList *fbl = vedata->fbl;
EEVEE_TextureList *txl = vedata->txl;
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
@@ -138,72 +138,64 @@ void EEVEE_subsurface_draw_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data
{GPU_ATTACHMENT_NONE,
GPU_ATTACHMENT_TEXTURE(effects->sss_irradiance),
GPU_ATTACHMENT_TEXTURE(effects->sss_radius)});
+ if ((stl->g_data->render_passes & EEVEE_RENDER_PASS_DIFFUSE_LIGHT) != 0) {
+ EEVEE_subsurface_output_init(sldata, vedata, 0);
+ }
+ else {
+ GPU_FRAMEBUFFER_FREE_SAFE(fbl->sss_accum_fb);
+ txl->sss_accum = NULL;
+ }
}
else {
/* Cleanup to release memory */
GPU_FRAMEBUFFER_FREE_SAFE(fbl->sss_blur_fb);
GPU_FRAMEBUFFER_FREE_SAFE(fbl->sss_resolve_fb);
GPU_FRAMEBUFFER_FREE_SAFE(fbl->sss_clear_fb);
+ GPU_FRAMEBUFFER_FREE_SAFE(fbl->sss_accum_fb);
effects->sss_stencil = NULL;
effects->sss_blur = NULL;
effects->sss_irradiance = NULL;
effects->sss_radius = NULL;
+ txl->sss_accum = NULL;
}
}
-static void set_shgrp_stencil(void *UNUSED(userData), DRWShadingGroup *shgrp)
-{
- DRW_shgroup_stencil_mask(shgrp, 255);
-}
-
void EEVEE_subsurface_output_init(EEVEE_ViewLayerData *UNUSED(sldata),
EEVEE_Data *vedata,
- uint tot_samples)
+ uint UNUSED(tot_samples))
{
EEVEE_FramebufferList *fbl = vedata->fbl;
EEVEE_TextureList *txl = vedata->txl;
EEVEE_StorageList *stl = vedata->stl;
EEVEE_EffectsInfo *effects = stl->effects;
- if (effects->enabled_effects & EFFECT_SSS) {
- const eGPUTextureFormat texture_format_light = (tot_samples > 128) ? GPU_RGBA32F : GPU_RGBA16F;
- const eGPUTextureFormat texture_format_color = (tot_samples > 512) ? GPU_RGBA32F : GPU_RGBA16F;
- DRW_texture_ensure_fullscreen_2d(&txl->sss_dir_accum, texture_format_light, 0);
- DRW_texture_ensure_fullscreen_2d(&txl->sss_col_accum, texture_format_color, 0);
-
- GPUTexture *stencil_tex = effects->sss_stencil;
+ const eGPUTextureFormat texture_format_light = GPU_RGBA32F;
+ const bool texture_created = txl->sss_accum == NULL;
+ DRW_texture_ensure_fullscreen_2d(&txl->sss_accum, texture_format_light, 0);
- if (GPU_depth_blitting_workaround()) {
- DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
- /* Blitting stencil buffer does not work on macOS + Radeon Pro.
- * Blit depth instead and use sss_stencil's depth as depth texture,
- * and dtxl->depth as stencil mask. */
- stencil_tex = dtxl->depth;
- }
+ GPUTexture *stencil_tex = effects->sss_stencil;
- GPU_framebuffer_ensure_config(&fbl->sss_accum_fb,
- {GPU_ATTACHMENT_TEXTURE(stencil_tex),
- GPU_ATTACHMENT_TEXTURE(txl->sss_dir_accum),
- GPU_ATTACHMENT_TEXTURE(txl->sss_col_accum)});
+ if (GPU_depth_blitting_workaround()) {
+ DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
+ /* Blitting stencil buffer does not work on macOS + Radeon Pro.
+ * Blit depth instead and use sss_stencil's depth as depth texture,
+ * and dtxl->depth as stencil mask. */
+ stencil_tex = dtxl->depth;
+ }
- /* Clear texture. */
- if (DRW_state_is_image_render() || effects->taa_current_sample == 1) {
- float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f};
- GPU_framebuffer_bind(fbl->sss_accum_fb);
- GPU_framebuffer_clear_color(fbl->sss_accum_fb, clear);
- }
+ GPU_framebuffer_ensure_config(
+ &fbl->sss_accum_fb,
+ {GPU_ATTACHMENT_TEXTURE(stencil_tex), GPU_ATTACHMENT_TEXTURE(txl->sss_accum)});
- /* Make the opaque refraction pass mask the sss. */
- DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL | DRW_STATE_CLIP_PLANES |
- DRW_STATE_WRITE_STENCIL | DRW_STATE_STENCIL_ALWAYS;
- DRW_pass_state_set(vedata->psl->refract_pass, state);
- DRW_pass_foreach_shgroup(vedata->psl->refract_pass, &set_shgrp_stencil, NULL);
- }
- else {
- /* Cleanup to release memory */
- DRW_TEXTURE_FREE_SAFE(txl->sss_dir_accum);
- DRW_TEXTURE_FREE_SAFE(txl->sss_col_accum);
- GPU_FRAMEBUFFER_FREE_SAFE(fbl->sss_accum_fb);
+ /* Clear texture.
+ * Due to the late initialization of the SSS it can happen that the `taa_current_sample` is
+ * already higher than one. This is noticeable when loading a file that has the diffuse light
+ * pass in look dev mode active. `texture_created` will make sure that newly created textures
+ * are cleared. */
+ if (DRW_state_is_image_render() || effects->taa_current_sample == 1 || texture_created) {
+ float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+ GPU_framebuffer_bind(fbl->sss_accum_fb);
+ GPU_framebuffer_clear_color(fbl->sss_accum_fb, clear);
}
}
@@ -222,7 +214,6 @@ void EEVEE_subsurface_cache_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_STENCIL_EQUAL;
DRW_PASS_CREATE(psl->sss_blur_ps, state);
DRW_PASS_CREATE(psl->sss_resolve_ps, state | DRW_STATE_BLEND_ADD);
- DRW_PASS_CREATE(psl->sss_accum_ps, state | DRW_STATE_BLEND_ADD);
DRW_PASS_CREATE(psl->sss_translucency_ps, state | DRW_STATE_BLEND_ADD);
}
@@ -245,6 +236,8 @@ void EEVEE_subsurface_add_pass(EEVEE_ViewLayerData *sldata,
DRW_shgroup_uniform_texture_ref(grp, "sssRadius", &effects->sss_radius);
DRW_shgroup_uniform_block(grp, "sssProfile", sss_profile);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
+ DRW_shgroup_uniform_block(
+ grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_stencil_mask(grp, sss_id);
DRW_shgroup_call(grp, quad, NULL);
@@ -256,22 +249,10 @@ void EEVEE_subsurface_add_pass(EEVEE_ViewLayerData *sldata,
DRW_shgroup_uniform_texture_ref(grp, "sssRadius", &effects->sss_radius);
DRW_shgroup_uniform_block(grp, "sssProfile", sss_profile);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
+ DRW_shgroup_uniform_block(
+ grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_stencil_mask(grp, sss_id);
DRW_shgroup_call(grp, quad, NULL);
-
- if ((stl->g_data->render_passes & (SCE_PASS_SUBSURFACE_COLOR | SCE_PASS_SUBSURFACE_DIRECT)) !=
- 0) {
- grp = DRW_shgroup_create(e_data.sss_sh[2], psl->sss_accum_ps);
- DRW_shgroup_uniform_texture(grp, "utilTex", EEVEE_materials_get_util_tex());
- DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", depth_src);
- DRW_shgroup_uniform_texture_ref(grp, "sssIrradiance", &effects->sss_blur);
- DRW_shgroup_uniform_texture_ref(grp, "sssAlbedo", &effects->sss_albedo);
- DRW_shgroup_uniform_texture_ref(grp, "sssRadius", &effects->sss_radius);
- DRW_shgroup_uniform_block(grp, "sssProfile", sss_profile);
- DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
- DRW_shgroup_stencil_mask(grp, sss_id);
- DRW_shgroup_call(grp, quad, NULL);
- }
}
void EEVEE_subsurface_translucency_add_pass(EEVEE_ViewLayerData *sldata,
@@ -287,7 +268,7 @@ void EEVEE_subsurface_translucency_add_pass(EEVEE_ViewLayerData *sldata,
struct GPUBatch *quad = DRW_cache_fullscreen_quad_get();
GPUTexture **depth_src = GPU_depth_blitting_workaround() ? &effects->sss_stencil : &dtxl->depth;
- DRWShadingGroup *grp = DRW_shgroup_create(e_data.sss_sh[3], psl->sss_translucency_ps);
+ DRWShadingGroup *grp = DRW_shgroup_create(e_data.sss_sh[2], psl->sss_translucency_ps);
DRW_shgroup_uniform_texture(grp, "utilTex", EEVEE_materials_get_util_tex());
DRW_shgroup_uniform_texture(grp, "sssTexProfile", sss_tex_profile);
DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", depth_src);
@@ -298,6 +279,8 @@ void EEVEE_subsurface_translucency_add_pass(EEVEE_ViewLayerData *sldata,
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_uniform_block(
+ grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_stencil_mask(grp, sss_id);
DRW_shgroup_call(grp, quad, NULL);
}
@@ -408,11 +391,11 @@ void EEVEE_subsurface_output_accumulate(EEVEE_ViewLayerData *UNUSED(sldata), EEV
if (((effects->enabled_effects & EFFECT_SSS) != 0) && (fbl->sss_accum_fb != NULL)) {
/* Copy stencil channel, could be avoided (see EEVEE_subsurface_init) */
- GPU_framebuffer_blit(fbl->main_fb, 0, fbl->sss_blur_fb, 0, GPU_STENCIL_BIT);
+ GPU_framebuffer_blit(fbl->main_fb, 0, fbl->sss_accum_fb, 0, GPU_STENCIL_BIT);
/* Only do vertical pass + Resolve */
GPU_framebuffer_bind(fbl->sss_accum_fb);
- DRW_draw_pass(psl->sss_accum_ps);
+ DRW_draw_pass(psl->sss_resolve_ps);
/* Restore */
GPU_framebuffer_bind(fbl->main_fb);
@@ -424,5 +407,4 @@ void EEVEE_subsurface_free(void)
DRW_SHADER_FREE_SAFE(e_data.sss_sh[0]);
DRW_SHADER_FREE_SAFE(e_data.sss_sh[1]);
DRW_SHADER_FREE_SAFE(e_data.sss_sh[2]);
- DRW_SHADER_FREE_SAFE(e_data.sss_sh[3]);
}
diff --git a/source/blender/draw/engines/eevee/eevee_temporal_sampling.c b/source/blender/draw/engines/eevee/eevee_temporal_sampling.c
index 093a4780a97..bd77279eb4a 100644
--- a/source/blender/draw/engines/eevee/eevee_temporal_sampling.c
+++ b/source/blender/draw/engines/eevee/eevee_temporal_sampling.c
@@ -290,6 +290,8 @@ void EEVEE_temporal_sampling_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data
DRW_shgroup_uniform_texture_ref(grp, "colorHistoryBuffer", &txl->taa_history);
DRW_shgroup_uniform_texture_ref(grp, "colorBuffer", &effects->source_buffer);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
+ DRW_shgroup_uniform_block(
+ grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
if (effects->enabled_effects & EFFECT_TAA_REPROJECT) {
// DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
diff --git a/source/blender/draw/engines/eevee/eevee_volumes.c b/source/blender/draw/engines/eevee/eevee_volumes.c
index 7026894076a..456673c92fa 100644
--- a/source/blender/draw/engines/eevee/eevee_volumes.c
+++ b/source/blender/draw/engines/eevee/eevee_volumes.c
@@ -54,6 +54,7 @@ static struct {
struct GPUShader *scatter_with_lights_sh;
struct GPUShader *volumetric_integration_sh;
struct GPUShader *volumetric_resolve_sh;
+ struct GPUShader *volumetric_accum_sh;
GPUTexture *depth_src;
@@ -73,6 +74,7 @@ extern char datatoc_common_view_lib_glsl[];
extern char datatoc_octahedron_lib_glsl[];
extern char datatoc_irradiance_lib_glsl[];
extern char datatoc_lights_lib_glsl[];
+extern char datatoc_volumetric_accum_frag_glsl[];
extern char datatoc_volumetric_frag_glsl[];
extern char datatoc_volumetric_geom_glsl[];
extern char datatoc_volumetric_vert_glsl[];
@@ -136,6 +138,8 @@ static void eevee_create_shader_volumes(void)
datatoc_volumetric_resolve_frag_glsl,
e_data.volumetric_common_lib,
NULL);
+ e_data.volumetric_accum_sh = DRW_shader_create_fullscreen(datatoc_volumetric_accum_frag_glsl,
+ NULL);
float color[4] = {1.0f, 1.0f, 1.0f, 1.0f};
e_data.dummy_density = DRW_texture_create_3d(1, 1, 1, GPU_RGBA8, DRW_TEX_WRAP, color);
@@ -359,6 +363,8 @@ void EEVEE_volumes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
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);
+ DRW_shgroup_uniform_block(
+ grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
/* Fix principle volumetric not working with world materials. */
DRW_shgroup_uniform_texture(grp, "sampdensity", e_data.dummy_density);
@@ -375,6 +381,8 @@ void EEVEE_volumes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
/* 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_uniform_block(
+ grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_call_procedural_triangles(grp, NULL, common_data->vol_tex_size[2]);
}
@@ -430,8 +438,12 @@ void EEVEE_volumes_cache_object_add(EEVEE_ViewLayerData *sldata,
DRW_shgroup_uniform_block(grp, "shadow_block", sldata->shadow_ubo);
DRW_shgroup_uniform_block(grp, "light_block", sldata->light_ubo);
DRW_shgroup_uniform_block(grp, "grid_block", sldata->grid_ubo);
+ DRW_shgroup_uniform_block(
+ grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
+ DRW_shgroup_uniform_block(
+ grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_uniform_vec3(grp, "volumeOrcoLoc", texcoloc, 1);
DRW_shgroup_uniform_vec3(grp, "volumeOrcoSize", texcosize, 1);
@@ -522,6 +534,8 @@ void EEVEE_volumes_cache_finish(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
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_uniform_block(
+ grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_call_procedural_triangles(grp, NULL, common_data->vol_tex_size[2]);
@@ -530,6 +544,8 @@ void EEVEE_volumes_cache_finish(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
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_uniform_block(
+ grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_call_procedural_triangles(
grp, NULL, USE_VOLUME_OPTI ? 1 : common_data->vol_tex_size[2]);
@@ -540,6 +556,8 @@ void EEVEE_volumes_cache_finish(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
DRW_shgroup_uniform_texture_ref(grp, "inTransmittance", &txl->volume_transmit);
DRW_shgroup_uniform_texture_ref(grp, "inSceneDepth", &e_data.depth_src);
DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
+ DRW_shgroup_uniform_block(
+ grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
DRW_shgroup_call_procedural_triangles(grp, NULL, 1);
}
@@ -729,4 +747,75 @@ void EEVEE_volumes_free(void)
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);
+ DRW_SHADER_FREE_SAFE(e_data.volumetric_accum_sh);
+}
+
+/* -------------------------------------------------------------------- */
+
+/** \name Render Passes
+ * \{ */
+
+void EEVEE_volumes_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, uint tot_samples)
+{
+ EEVEE_FramebufferList *fbl = vedata->fbl;
+ EEVEE_TextureList *txl = vedata->txl;
+ EEVEE_StorageList *stl = vedata->stl;
+ EEVEE_PassList *psl = vedata->psl;
+ EEVEE_EffectsInfo *effects = stl->effects;
+
+ float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+
+ /* Create FrameBuffer. */
+
+ /* Should be enough precision for many samples. */
+ const eGPUTextureFormat texture_format_accum = (tot_samples > 128) ? GPU_RGBA32F : GPU_RGBA16F;
+ DRW_texture_ensure_fullscreen_2d(&txl->volume_scatter_accum, texture_format_accum, 0);
+ DRW_texture_ensure_fullscreen_2d(&txl->volume_transmittance_accum, texture_format_accum, 0);
+
+ GPU_framebuffer_ensure_config(&fbl->volumetric_accum_fb,
+ {GPU_ATTACHMENT_NONE,
+ GPU_ATTACHMENT_TEXTURE(txl->volume_scatter_accum),
+ GPU_ATTACHMENT_TEXTURE(txl->volume_transmittance_accum)});
+
+ /* Clear texture. */
+ if (DRW_state_is_image_render() || effects->taa_current_sample == 1) {
+ GPU_framebuffer_bind(fbl->volumetric_accum_fb);
+ GPU_framebuffer_clear_color(fbl->volumetric_accum_fb, clear);
+ }
+
+ /* Create Pass and shgroup. */
+ DRW_PASS_CREATE(psl->volumetric_accum_ps, DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ADD_FULL);
+ DRWShadingGroup *grp = NULL;
+ if ((effects->enabled_effects & EFFECT_VOLUMETRIC) != 0) {
+ grp = DRW_shgroup_create(e_data.volumetric_resolve_sh, psl->volumetric_accum_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, "inSceneDepth", &e_data.depth_src);
+ DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo);
+ DRW_shgroup_uniform_block(
+ grp, "renderpass_block", EEVEE_material_default_render_pass_ubo_get(sldata));
+ }
+ else {
+ /* There is no volumetrics in the scene. Use a shader to fill the accum textures with a default
+ * value. */
+ grp = DRW_shgroup_create(e_data.volumetric_accum_sh, psl->volumetric_accum_ps);
+ }
+ DRW_shgroup_call(grp, DRW_cache_fullscreen_quad_get(), NULL);
}
+
+void EEVEE_volumes_output_accumulate(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *vedata)
+{
+ EEVEE_FramebufferList *fbl = vedata->fbl;
+ EEVEE_PassList *psl = vedata->psl;
+
+ if (fbl->volumetric_accum_fb != NULL) {
+ /* Accum pass */
+ GPU_framebuffer_bind(fbl->volumetric_accum_fb);
+ DRW_draw_pass(psl->volumetric_accum_ps);
+
+ /* Restore */
+ GPU_framebuffer_bind(fbl->main_fb);
+ }
+}
+
+/* \} */
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 c4f815b5dd4..c3518198805 100644
--- a/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl
@@ -85,6 +85,37 @@ struct ShadowCascadeData {
#define sh_shadow_vec shadow_vec_id.xyz
#define sh_tex_index shadow_vec_id.w
+/* ------ Render Passes ----- */
+layout(std140) uniform renderpass_block
+{
+ bool renderPassDiffuse;
+ bool renderPassDiffuseLight;
+ bool renderPassGlossy;
+ bool renderPassGlossyLight;
+ bool renderPassEmit;
+ bool renderPassSSSColor;
+};
+
+vec3 render_pass_diffuse_mask(vec3 diffuse_color, vec3 diffuse_light)
+{
+ return renderPassDiffuse ? (renderPassDiffuseLight ? diffuse_light : diffuse_color) : vec3(0.0);
+}
+
+vec3 render_pass_sss_mask(vec3 sss_color)
+{
+ return renderPassSSSColor ? sss_color : vec3(0.0);
+}
+
+vec3 render_pass_glossy_mask(vec3 specular_color, vec3 specular_light)
+{
+ return renderPassGlossy ? (renderPassGlossyLight ? specular_light : specular_color) : vec3(0.0);
+}
+
+vec3 render_pass_emission_mask(vec3 emission_light)
+{
+ return renderPassEmit ? emission_light : vec3(0.0);
+}
+
/* ------- Convenience functions --------- */
vec3 mul(mat3 m, vec3 v)
@@ -833,11 +864,12 @@ void closure_load_sss_data(
cl.sss_radius = radius;
cl.sss_albedo = sss_albedo;
cl.flag |= CLOSURE_SSS_FLAG;
+ cl.radiance += render_pass_diffuse_mask(sss_albedo, vec3(0));
}
else
# endif
{
- cl.radiance += sss_irradiance * sss_albedo;
+ cl.radiance += render_pass_diffuse_mask(sss_albedo, sss_irradiance * sss_albedo);
}
}
diff --git a/source/blender/draw/engines/eevee/shaders/default_frag.glsl b/source/blender/draw/engines/eevee/shaders/default_frag.glsl
index a031ed193b6..1014b25033a 100644
--- a/source/blender/draw/engines/eevee/shaders/default_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/default_frag.glsl
@@ -34,7 +34,8 @@ Closure nodetree_exec(void)
eevee_closure_default(N, albedo, f0, f90, 1, roughness, 1.0, true, out_diff, out_spec, ssr_spec);
Closure cl = CLOSURE_DEFAULT;
- cl.radiance = out_spec + out_diff * albedo;
+ cl.radiance = render_pass_glossy_mask(vec3(1.0), out_spec) +
+ render_pass_diffuse_mask(albedo, out_diff * albedo);
closure_load_ssr_data(ssr_spec, roughness, N, viewCameraVec, 1, cl);
#ifdef LOOKDEV
diff --git a/source/blender/draw/engines/eevee/shaders/effect_bloom_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_bloom_frag.glsl
index 299cb2094c1..18f92c0dd33 100644
--- a/source/blender/draw/engines/eevee/shaders/effect_bloom_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/effect_bloom_frag.glsl
@@ -40,6 +40,7 @@ uniform float sampleScale;
/* Step Resolve */
uniform vec3 bloomColor;
+uniform bool bloomAddBase;
in vec4 uvcoordsvar;
@@ -201,9 +202,9 @@ vec4 step_resolve(void)
#else
vec3 blur = upsample_filter(sourceBuffer, uvcoordsvar.xy, sourceBufferTexelSize);
#endif
- vec4 base = textureLod(baseBuffer, uvcoordsvar.xy, 0.0);
- vec3 cout = base.rgb + blur * bloomColor;
- return vec4(cout, base.a);
+ vec3 base = bloomAddBase ? textureLod(baseBuffer, uvcoordsvar.xy, 0.0).rgb : vec3(0.0);
+ vec3 cout = base + blur * bloomColor;
+ return vec4(cout, 1.0);
}
void main(void)
diff --git a/source/blender/draw/engines/eevee/shaders/effect_subsurface_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_subsurface_frag.glsl
index 1241cf0e387..e9da49c9eb9 100644
--- a/source/blender/draw/engines/eevee/shaders/effect_subsurface_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/effect_subsurface_frag.glsl
@@ -20,13 +20,7 @@ uniform sampler2DArray utilTex;
# define texelfetch_noise_tex(coord) texelFetch(utilTex, ivec3(ivec2(coord) % LUT_SIZE, 2.0), 0)
#endif /* UTIL_TEX */
-#ifdef RESULT_ACCUM
-/* Render Passes Accumulation */
-layout(location = 0) out vec4 sssDirect;
-layout(location = 1) out vec4 sssColor;
-#else
layout(location = 0) out vec4 sssRadiance;
-#endif
float get_view_z_from_depth(float depth)
{
@@ -87,10 +81,7 @@ void main(void)
accum += kernel[i].rgb * mix(color, sss_irradiance, s);
}
-#ifdef RESULT_ACCUM
- sssDirect = vec4(accum, 1.0);
- sssColor = vec4(texture(sssAlbedo, uvs).rgb, 1.0);
-#elif defined(FIRST_PASS)
+#if defined(FIRST_PASS)
sssRadiance = vec4(accum, 1.0);
#else /* SECOND_PASS */
sssRadiance = vec4(accum * texture(sssAlbedo, uvs).rgb, 1.0);
diff --git a/source/blender/draw/engines/eevee/shaders/lights_lib.glsl b/source/blender/draw/engines/eevee/shaders/lights_lib.glsl
index 6427f02ed25..3b9d0a8f2bc 100644
--- a/source/blender/draw/engines/eevee/shaders/lights_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/lights_lib.glsl
@@ -173,19 +173,17 @@ float light_attenuation(LightData ld, vec4 l_vector)
return vis;
}
-float light_visibility(LightData ld,
- vec3 W,
+float light_shadowing(LightData ld,
+ vec3 W,
#ifndef VOLUMETRICS
- vec3 viewPosition,
- float tracing_depth,
- vec3 true_normal,
- float rand_x,
- const bool use_contact_shadows,
+ vec3 viewPosition,
+ float tracing_depth,
+ vec3 true_normal,
+ float rand_x,
+ const bool use_contact_shadows,
#endif
- vec4 l_vector)
+ float vis)
{
- float vis = light_attenuation(ld, l_vector);
-
#if !defined(VOLUMETRICS) || defined(VOLUME_SHADOW)
/* shadowing */
if (ld.l_shadowid >= 0.0 && vis > 0.001) {
@@ -236,6 +234,30 @@ float light_visibility(LightData ld,
return vis;
}
+float light_visibility(LightData ld,
+ vec3 W,
+#ifndef VOLUMETRICS
+ vec3 viewPosition,
+ float tracing_depth,
+ vec3 true_normal,
+ float rand_x,
+ const bool use_contact_shadows,
+#endif
+ vec4 l_vector)
+{
+ float l_atten = light_attenuation(ld, l_vector);
+ return light_shadowing(ld,
+ W,
+#ifndef VOLUMETRICS
+ viewPosition,
+ tracing_depth,
+ true_normal,
+ rand_x,
+ use_contact_shadows,
+#endif
+ l_atten);
+}
+
#ifdef USE_LTC
float light_diffuse(LightData ld, vec3 N, vec3 V, vec4 l_vector)
{
diff --git a/source/blender/draw/engines/eevee/shaders/renderpass_postprocess_frag.glsl b/source/blender/draw/engines/eevee/shaders/renderpass_postprocess_frag.glsl
index 35bfb411cb9..5214301bc03 100644
--- a/source/blender/draw/engines/eevee/shaders/renderpass_postprocess_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/renderpass_postprocess_frag.glsl
@@ -1,15 +1,17 @@
-#define SCE_PASS_Z (1 << 1)
-#define SCE_PASS_AO (1 << 6)
-#define SCE_PASS_NORMAL (1 << 8)
-#define SCE_PASS_MIST (1 << 14)
-#define SCE_PASS_SUBSURFACE_DIRECT (1 << 28)
-#define SCE_PASS_SUBSURFACE_COLOR (1 << 30)
+#define PASS_POST_UNDEFINED 0
+#define PASS_POST_ACCUMULATED_COLOR 1
+#define PASS_POST_ACCUMULATED_LIGHT 2
+#define PASS_POST_ACCUMULATED_VALUE 3
+#define PASS_POST_DEPTH 4
+#define PASS_POST_AO 5
+#define PASS_POST_NORMAL 6
+#define PASS_POST_TWO_LIGHT_BUFFERS 7
-#define ACCUMULATED_COLOR_PASSES (SCE_PASS_SUBSURFACE_DIRECT | SCE_PASS_SUBSURFACE_COLOR)
-#define ACCUMULATED_VALUE_PASSES (SCE_PASS_MIST)
-uniform int renderpassType;
+uniform int postProcessType;
uniform int currentSample;
uniform sampler2D inputBuffer;
+uniform sampler2D inputSecondLightBuffer;
+uniform sampler2D inputColorBuffer;
out vec4 fragColor;
@@ -17,7 +19,7 @@ void main()
{
ivec2 texel = ivec2(gl_FragCoord.xy);
- if (renderpassType == SCE_PASS_Z) {
+ if (postProcessType == PASS_POST_DEPTH) {
float depth = texelFetch(depthBuffer, texel, 0).r;
if (depth == 1.0f) {
depth = 1e10;
@@ -27,17 +29,15 @@ void main()
}
fragColor.r = depth;
}
-
- else if (renderpassType == SCE_PASS_AO) {
+ else if (postProcessType == PASS_POST_AO) {
float ao_accum = texelFetch(inputBuffer, texel, 0).r;
fragColor = vec4(vec3(min(1.0, ao_accum / currentSample)), 1.0);
}
-
- else if (renderpassType == SCE_PASS_NORMAL) {
+ else if (postProcessType == PASS_POST_NORMAL) {
float depth = texelFetch(depthBuffer, texel, 0).r;
vec2 encoded_normal = texelFetch(inputBuffer, texel, 0).rg;
- /* decode the normals only when they are valid. otherwise the result buffer will be filled with
- * NaN's */
+ /* decode the normals only when they are valid. otherwise the result buffer will be filled
+ * with NaN's */
if (depth != 1.0 && any(notEqual(encoded_normal, vec2(0.0)))) {
vec3 decoded_normal = normal_decode(texelFetch(inputBuffer, texel, 0).rg, vec3(0.0));
vec3 world_normal = mat3(ViewMatrixInverse) * decoded_normal;
@@ -47,18 +47,55 @@ void main()
fragColor = vec4(0.0, 0.0, 0.0, 1.0);
}
}
-
- else if ((renderpassType & ACCUMULATED_VALUE_PASSES) != 0) {
+ else if (postProcessType == PASS_POST_ACCUMULATED_VALUE) {
float accumulated_value = texelFetch(inputBuffer, texel, 0).r;
fragColor = vec4(vec3(accumulated_value / currentSample), 1.0);
}
-
- else if ((renderpassType & ACCUMULATED_COLOR_PASSES) != 0) {
+ else if (postProcessType == PASS_POST_ACCUMULATED_COLOR) {
vec3 accumulated_color = texelFetch(inputBuffer, texel, 0).rgb;
fragColor = vec4(accumulated_color / currentSample, 1.0);
}
+ else if (postProcessType == PASS_POST_ACCUMULATED_LIGHT) {
+ vec3 accumulated_light = texelFetch(inputBuffer, texel, 0).rgb;
+ vec3 accumulated_color = texelFetch(inputColorBuffer, texel, 0).rgb;
+ /* Fix INF in the case a color component is 0.0 */
+ if (accumulated_color.r == 0.0) {
+ accumulated_color.r = 1.0;
+ accumulated_light.r = 0.0;
+ }
+ if (accumulated_color.g == 0.0) {
+ accumulated_color.g = 1.0;
+ accumulated_light.g = 0.0;
+ }
+ if (accumulated_color.b == 0.0) {
+ accumulated_color.b = 1.0;
+ accumulated_light.b = 0.0;
+ }
+ fragColor = vec4(accumulated_light / accumulated_color, 1.0);
+ }
+ else if (postProcessType == PASS_POST_TWO_LIGHT_BUFFERS) {
+ vec3 accumulated_light = texelFetch(inputBuffer, texel, 0).rgb +
+ texelFetch(inputSecondLightBuffer, texel, 0).rgb;
+ vec3 accumulated_color = texelFetch(inputColorBuffer, texel, 0).rgb;
+
+ /* Fix INF in the case a color component is 0.0 */
+ if (accumulated_color.r == 0.0) {
+ accumulated_color.r = 1.0;
+ accumulated_light.r = 0.0;
+ }
+ if (accumulated_color.g == 0.0) {
+ accumulated_color.g = 1.0;
+ accumulated_light.g = 0.0;
+ }
+ if (accumulated_color.b == 0.0) {
+ accumulated_color.b = 1.0;
+ accumulated_light.b = 0.0;
+ }
+ fragColor = vec4(accumulated_light / accumulated_color, 1.0);
+ }
else {
+ /* Output error color: Unknown how to post process this pass. */
fragColor = vec4(1.0, 0.0, 1.0, 1.0);
}
}
diff --git a/source/blender/draw/engines/eevee/shaders/shadow_accum_frag.glsl b/source/blender/draw/engines/eevee/shaders/shadow_accum_frag.glsl
new file mode 100644
index 00000000000..fa02bee45b7
--- /dev/null
+++ b/source/blender/draw/engines/eevee/shaders/shadow_accum_frag.glsl
@@ -0,0 +1,58 @@
+
+out vec4 fragColor;
+
+#ifndef UTIL_TEX
+# define UTIL_TEX
+uniform sampler2DArray utilTex;
+# define texelfetch_noise_tex(coord) texelFetch(utilTex, ivec3(ivec2(coord) % LUT_SIZE, 2.0), 0)
+#endif /* UTIL_TEX */
+
+void main()
+{
+ if (laNumLight == 0) {
+ /* Early exit: No lights in scene */
+ fragColor.r = 0.0;
+ return;
+ }
+
+ ivec2 texel = ivec2(gl_FragCoord.xy);
+ float depth = texelFetch(depthBuffer, texel, 0).r;
+ if (depth == 1.0f) {
+ /* Early exit background does not receive shadows */
+ fragColor.r = 1.0;
+ return;
+ }
+
+ vec2 texel_size = 1.0 / vec2(textureSize(depthBuffer, 0)).xy;
+ vec2 uvs = saturate(gl_FragCoord.xy * texel_size);
+ vec4 rand = texelfetch_noise_tex(texel);
+
+ float accum_light = 0.0;
+ float tracing_depth = depth;
+ /* Constant bias (due to depth buffer precision) */
+ /* Magic numbers for 24bits of precision.
+ * From http://terathon.com/gdc07_lengyel.pdf (slide 26) */
+ tracing_depth -= mix(2.4e-7, 4.8e-7, depth);
+ /* Convert to view Z. */
+ tracing_depth = get_view_z_from_depth(tracing_depth);
+
+ vec3 viewPosition = get_view_space_from_depth(uvs, depth);
+ vec3 worldPosition = transform_point(ViewMatrixInverse, viewPosition);
+
+ vec3 true_normal = normalize(cross(dFdx(viewPosition), dFdy(viewPosition)));
+
+ for (int i = 0; i < MAX_LIGHT && i < laNumLight; i++) {
+ LightData ld = lights_data[i];
+
+ vec4 l_vector; /* Non-Normalized Light Vector with length in last component. */
+ l_vector.xyz = ld.l_position - worldPosition;
+ l_vector.w = length(l_vector.xyz);
+
+ float l_vis = light_shadowing(
+ ld, worldPosition, viewPosition, tracing_depth, true_normal, rand.x, true, 1.0);
+
+ accum_light += l_vis;
+ }
+
+ fragColor.r = accum_light / float(laNumLight);
+} \ No newline at end of file
diff --git a/source/blender/draw/engines/eevee/shaders/volumetric_accum_frag.glsl b/source/blender/draw/engines/eevee/shaders/volumetric_accum_frag.glsl
new file mode 100644
index 00000000000..1b6a7b33f42
--- /dev/null
+++ b/source/blender/draw/engines/eevee/shaders/volumetric_accum_frag.glsl
@@ -0,0 +1,11 @@
+
+/* This shader is used to add default values to the volume accum textures.
+ * so it looks similar (transmittance = 1, scattering = 0) */
+layout(location = 0, index = 0) out vec4 FragColor0;
+layout(location = 0, index = 1) out vec4 FragColor1;
+
+void main()
+{
+ FragColor0 = vec4(0.0);
+ FragColor1 = vec4(1.0);
+}
diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_diffuse.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_diffuse.glsl
index e029905a908..714792489f6 100644
--- a/source/blender/gpu/shaders/material/gpu_shader_material_diffuse.glsl
+++ b/source/blender/gpu/shaders/material/gpu_shader_material_diffuse.glsl
@@ -4,8 +4,8 @@ void node_bsdf_diffuse(vec4 color, float roughness, vec3 N, out Closure result)
N = normalize(N);
result = CLOSURE_DEFAULT;
eevee_closure_diffuse(N, color.rgb, 1.0, true, result.radiance);
+ result.radiance = render_pass_diffuse_mask(color.rgb, result.radiance * color.rgb);
closure_load_ssr_data(vec3(0.0), 0.0, N, viewCameraVec, -1, result);
- result.radiance *= color.rgb;
}
#else
/* Stub diffuse because it is not compatible with volumetrics. */
diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_eevee_specular.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_eevee_specular.glsl
index 34062cc8d02..747395857ee 100644
--- a/source/blender/gpu/shaders/material/gpu_shader_material_eevee_specular.glsl
+++ b/source/blender/gpu/shaders/material/gpu_shader_material_eevee_specular.glsl
@@ -32,7 +32,9 @@ void node_eevee_specular(vec4 diffuse,
float alpha = 1.0 - transp;
result = CLOSURE_DEFAULT;
- result.radiance = out_diff * diffuse.rgb + out_spec + emissive.rgb;
+ result.radiance = render_pass_diffuse_mask(diffuse.rgb, out_diff * diffuse.rgb);
+ result.radiance += render_pass_glossy_mask(vec3(1.0), out_spec);
+ result.radiance += render_pass_emission_mask(emissive.rgb);
result.radiance *= alpha;
result.transmittance = vec3(transp);
diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_emission.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_emission.glsl
index 092b9ed08bb..502bc7f92d6 100644
--- a/source/blender/gpu/shaders/material/gpu_shader_material_emission.glsl
+++ b/source/blender/gpu/shaders/material/gpu_shader_material_emission.glsl
@@ -2,7 +2,7 @@ void node_emission(vec4 color, float strength, vec3 vN, out Closure result)
{
result = CLOSURE_DEFAULT;
#ifndef VOLUMETRICS
- result.radiance = color.rgb * strength;
+ result.radiance = render_pass_emission_mask(color.rgb) * strength;
result.ssr_normal = normal_encode(vN, viewCameraVec);
#else
result.emission = color.rgb * strength;
diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_glass.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_glass.glsl
index 5038cb3892f..ece770f0e73 100644
--- a/source/blender/gpu/shaders/material/gpu_shader_material_glass.glsl
+++ b/source/blender/gpu/shaders/material/gpu_shader_material_glass.glsl
@@ -17,12 +17,12 @@ void node_bsdf_glass(
out_spec,
out_refr,
ssr_spec);
- out_refr *= refr_color;
- out_spec *= color.rgb;
float fresnel = F_eta(ior, dot(N, cameraVec));
vec3 vN = mat3(ViewMatrix) * N;
result = CLOSURE_DEFAULT;
- result.radiance = mix(out_refr, out_spec, fresnel);
+ result.radiance = render_pass_glossy_mask(refr_color, out_refr * refr_color) * (1.0 - fresnel);
+ result.radiance += render_pass_glossy_mask(color.rgb, out_spec * color.rgb) * fresnel;
+
closure_load_ssr_data(
ssr_spec * color.rgb * fresnel, roughness, N, viewCameraVec, int(ssr_id), result);
}
diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_glossy.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_glossy.glsl
index 75cc2e770c5..7513c3a4edb 100644
--- a/source/blender/gpu/shaders/material/gpu_shader_material_glossy.glsl
+++ b/source/blender/gpu/shaders/material/gpu_shader_material_glossy.glsl
@@ -7,7 +7,7 @@ void node_bsdf_glossy(vec4 color, float roughness, vec3 N, float ssr_id, out Clo
N, vec3(1.0), vec3(1.0), int(ssr_id), roughness, 1.0, true, out_spec, ssr_spec);
vec3 vN = mat3(ViewMatrix) * N;
result = CLOSURE_DEFAULT;
- result.radiance = out_spec * color.rgb;
+ result.radiance = render_pass_glossy_mask(vec3(1.0), out_spec) * color.rgb;
closure_load_ssr_data(ssr_spec * color.rgb, roughness, N, viewCameraVec, int(ssr_id), result);
}
#else
diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_principled.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_principled.glsl
index 7af409dd410..3c85dc6456c 100644
--- a/source/blender/gpu/shaders/material/gpu_shader_material_principled.glsl
+++ b/source/blender/gpu/shaders/material/gpu_shader_material_principled.glsl
@@ -18,15 +18,22 @@ void convert_metallic_to_specular_tinted(vec3 basecol,
diffuse = basecol * (1.0 - metallic);
}
-vec3 principled_sheen(float NV, vec3 basecol_tint, float sheen_tint)
+/* Output sheen is to be multiplied by sheen_color. */
+void principled_sheen(float NV,
+ vec3 basecol_tint,
+ float sheen,
+ float sheen_tint,
+ out float out_sheen,
+ out vec3 sheen_color)
{
float f = 1.0 - NV;
/* Temporary fix for T59784. Normal map seems to contain NaNs for tangent space normal maps,
* therefore we need to clamp value. */
f = clamp(f, 0.0, 1.0);
/* Empirical approximation (manual curve fitting). Can be refined. */
- float sheen = f * f * f * 0.077 + f * 0.01 + 0.00026;
- return sheen * mix(vec3(1.0), basecol_tint, sheen_tint);
+ out_sheen = f * f * f * 0.077 + f * 0.01 + 0.00026;
+
+ sheen_color = sheen * mix(vec3(1.0), basecol_tint, sheen_tint);
}
void node_bsdf_principled(vec4 base_color,
@@ -61,18 +68,23 @@ void node_bsdf_principled(vec4 base_color,
ior = max(ior, 1e-5);
metallic = saturate(metallic);
transmission = saturate(transmission);
+ float m_transmission = 1.0 - transmission;
+
float dielectric = 1.0 - metallic;
transmission *= dielectric;
sheen *= dielectric;
subsurface_color *= dielectric;
- vec3 diffuse, f0, out_diff, out_spec, out_refr, ssr_spec;
+ vec3 diffuse, f0, out_diff, out_spec, out_refr, ssr_spec, sheen_color;
+ float out_sheen;
vec3 ctint = tint_from_color(base_color.rgb);
convert_metallic_to_specular_tinted(
base_color.rgb, ctint, metallic, specular, specular_tint, diffuse, f0);
float NV = dot(N, cameraVec);
- vec3 out_sheen = sheen * principled_sheen(NV, ctint, sheen_tint);
+ principled_sheen(NV, ctint, sheen, sheen_tint, out_sheen, sheen_color);
+
+ vec3 f90 = mix(vec3(1.0), f0, (1.0 - specular) * metallic);
/* Far from being accurate, but 2 glossy evaluation is too expensive.
* Most noticeable difference is at grazing angles since the bsdf lut
@@ -81,8 +93,12 @@ void node_bsdf_principled(vec4 base_color,
float fresnel = F_eta(ior, NV);
vec3 spec_col = F_color_blend(ior, fresnel, f0_glass) * fresnel;
f0 = mix(f0, spec_col, transmission);
+ f90 = mix(f90, spec_col, transmission);
- vec3 f90 = mix(vec3(1.0), f0, (1.0 - specular) * metallic);
+ /* Really poor approximation but needed to workaround issues with renderpasses. */
+ spec_col = mix(vec3(1.0), spec_col, transmission);
+ /* Match cycles. */
+ spec_col += float(clearcoat > 1e-5);
vec3 mixed_ss_base_color = mix(diffuse, subsurface_color.rgb, subsurface);
@@ -108,19 +124,22 @@ void node_bsdf_principled(vec4 base_color,
vec3 refr_color = base_color.rgb;
refr_color *= (refractionDepth > 0.0) ? refr_color :
vec3(1.0); /* Simulate 2 transmission event */
- out_refr *= refr_color * (1.0 - fresnel) * transmission;
+ refr_color *= saturate(1.0 - fresnel) * transmission;
+
+ sheen_color *= m_transmission;
+ mixed_ss_base_color *= m_transmission;
result = CLOSURE_DEFAULT;
- result.radiance = out_spec + out_refr;
- result.radiance += out_diff * out_sheen; /* Coarse approx. */
- result.radiance += emission.rgb;
+ result.radiance = render_pass_glossy_mask(refr_color, out_refr * refr_color);
+ result.radiance += render_pass_glossy_mask(spec_col, out_spec);
+ /* Coarse approx. */
+ result.radiance += render_pass_diffuse_mask(sheen_color, out_diff * out_sheen * sheen_color);
+ result.radiance += render_pass_emission_mask(emission.rgb);
result.radiance *= alpha;
-
closure_load_ssr_data(ssr_spec * alpha, roughness, N, viewCameraVec, int(ssr_id), result);
- mixed_ss_base_color *= alpha * (1.0 - transmission);
+ mixed_ss_base_color *= alpha;
closure_load_sss_data(sss_scalef, out_diff, mixed_ss_base_color, int(sss_id), result);
-
result.transmittance = vec3(1.0 - alpha);
}
@@ -156,22 +175,26 @@ void node_bsdf_principled_dielectric(vec4 base_color,
metallic = saturate(metallic);
float dielectric = 1.0 - metallic;
- vec3 diffuse, f0, out_diff, out_spec, ssr_spec;
+ vec3 diffuse, f0, out_diff, out_spec, ssr_spec, sheen_color;
+ float out_sheen;
vec3 ctint = tint_from_color(base_color.rgb);
convert_metallic_to_specular_tinted(
base_color.rgb, ctint, metallic, specular, specular_tint, diffuse, f0);
+ vec3 f90 = mix(vec3(1.0), f0, (1.0 - specular) * metallic);
+
float NV = dot(N, cameraVec);
- vec3 out_sheen = sheen * principled_sheen(NV, ctint, sheen_tint);
+ principled_sheen(NV, ctint, sheen, sheen_tint, out_sheen, sheen_color);
eevee_closure_default(
- N, diffuse, f0, vec3(1.0), int(ssr_id), roughness, 1.0, true, out_diff, out_spec, ssr_spec);
+ N, diffuse, f0, f90, int(ssr_id), roughness, 1.0, true, out_diff, out_spec, ssr_spec);
result = CLOSURE_DEFAULT;
- result.radiance = out_spec + out_diff * (diffuse + out_sheen);
- result.radiance += emission.rgb;
+ result.radiance = render_pass_glossy_mask(vec3(1.0), out_spec);
+ result.radiance += render_pass_diffuse_mask(sheen_color, out_diff * out_sheen * sheen_color);
+ result.radiance += render_pass_diffuse_mask(diffuse, out_diff * diffuse);
+ result.radiance += render_pass_emission_mask(emission.rgb);
result.radiance *= alpha;
-
closure_load_ssr_data(ssr_spec * alpha, roughness, N, viewCameraVec, int(ssr_id), result);
result.transmittance = vec3(1.0 - alpha);
@@ -214,10 +237,9 @@ void node_bsdf_principled_metallic(vec4 base_color,
N, base_color.rgb, f90, int(ssr_id), roughness, 1.0, true, out_spec, ssr_spec);
result = CLOSURE_DEFAULT;
- result.radiance = out_spec;
- result.radiance += emission.rgb;
+ result.radiance = render_pass_glossy_mask(vec3(1.0), out_spec);
+ result.radiance += render_pass_emission_mask(emission.rgb);
result.radiance *= alpha;
-
closure_load_ssr_data(ssr_spec * alpha, roughness, N, viewCameraVec, int(ssr_id), result);
result.transmittance = vec3(1.0 - alpha);
@@ -268,10 +290,12 @@ void node_bsdf_principled_clearcoat(vec4 base_color,
true,
out_spec,
ssr_spec);
+ /* Match cycles. */
+ float spec_col = 1.0 + float(clearcoat > 1e-5);
result = CLOSURE_DEFAULT;
- result.radiance = out_spec;
- result.radiance += emission.rgb;
+ result.radiance = render_pass_glossy_mask(vec3(spec_col), out_spec);
+ result.radiance += render_pass_emission_mask(emission.rgb);
result.radiance *= alpha;
closure_load_ssr_data(ssr_spec * alpha, roughness, N, viewCameraVec, int(ssr_id), result);
@@ -310,7 +334,8 @@ void node_bsdf_principled_subsurface(vec4 base_color,
metallic = saturate(metallic);
N = normalize(N);
- vec3 diffuse, f0, out_diff, out_spec, ssr_spec;
+ vec3 diffuse, f0, out_diff, out_spec, ssr_spec, sheen_color;
+ float out_sheen;
vec3 ctint = tint_from_color(base_color.rgb);
convert_metallic_to_specular_tinted(
base_color.rgb, ctint, metallic, specular, specular_tint, diffuse, f0);
@@ -320,7 +345,7 @@ void node_bsdf_principled_subsurface(vec4 base_color,
float sss_scalef = avg(sss_scale) * subsurface;
float NV = dot(N, cameraVec);
- vec3 out_sheen = sheen * principled_sheen(NV, ctint, sheen_tint);
+ principled_sheen(NV, ctint, sheen, sheen_tint, out_sheen, sheen_color);
vec3 f90 = mix(vec3(1.0), base_color.rgb, (1.0 - specular) * metallic);
@@ -338,14 +363,14 @@ void node_bsdf_principled_subsurface(vec4 base_color,
ssr_spec);
result = CLOSURE_DEFAULT;
- result.radiance = out_spec;
- result.radiance += out_diff * out_sheen;
- result.radiance += emission.rgb;
+ result.radiance = render_pass_glossy_mask(vec3(1.0), out_spec);
+ result.radiance += render_pass_diffuse_mask(sheen_color, out_diff * out_sheen * sheen_color);
+ result.radiance += render_pass_emission_mask(emission.rgb);
result.radiance *= alpha;
closure_load_ssr_data(ssr_spec * alpha, roughness, N, viewCameraVec, int(ssr_id), result);
- mixed_ss_base_color *= alpha * (1.0 - transmission);
+ mixed_ss_base_color *= alpha;
closure_load_sss_data(sss_scalef, out_diff, mixed_ss_base_color, int(sss_id), result);
result.transmittance = vec3(1.0 - alpha);
@@ -400,16 +425,18 @@ void node_bsdf_principled_glass(vec4 base_color,
vec3 refr_color = base_color.rgb;
refr_color *= (refractionDepth > 0.0) ? refr_color :
vec3(1.0); /* Simulate 2 transmission events */
- out_refr *= refr_color;
float fresnel = F_eta(ior, dot(N, cameraVec));
vec3 spec_col = F_color_blend(ior, fresnel, f0);
- out_spec *= spec_col;
- ssr_spec *= spec_col * fresnel;
+ spec_col *= fresnel;
+ refr_color *= (1.0 - fresnel);
+
+ ssr_spec *= spec_col;
result = CLOSURE_DEFAULT;
- result.radiance = mix(out_refr, out_spec, fresnel);
- result.radiance += emission.rgb;
+ result.radiance = render_pass_glossy_mask(refr_color, out_refr * refr_color);
+ result.radiance += render_pass_glossy_mask(spec_col, out_spec * spec_col);
+ result.radiance += render_pass_emission_mask(emission.rgb);
result.radiance *= alpha;
closure_load_ssr_data(ssr_spec * alpha, roughness, N, viewCameraVec, int(ssr_id), result);
result.transmittance = vec3(1.0 - alpha);
diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_refraction.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_refraction.glsl
index 906964e1539..4088d6db06a 100644
--- a/source/blender/gpu/shaders/material/gpu_shader_material_refraction.glsl
+++ b/source/blender/gpu/shaders/material/gpu_shader_material_refraction.glsl
@@ -8,7 +8,7 @@ void node_bsdf_refraction(vec4 color, float roughness, float ior, vec3 N, out Cl
vec3 vN = mat3(ViewMatrix) * N;
result = CLOSURE_DEFAULT;
result.ssr_normal = normal_encode(vN, viewCameraVec);
- result.radiance = out_refr * color.rgb;
+ result.radiance = render_pass_glossy_mask(color.rgb, out_refr * color.rgb);
}
#else
/* Stub refraction because it is not compatible with volumetrics. */
diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_subsurface_scattering.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_subsurface_scattering.glsl
index 241228c0d4c..9bbbe71b206 100644
--- a/source/blender/gpu/shaders/material/gpu_shader_material_subsurface_scattering.glsl
+++ b/source/blender/gpu/shaders/material/gpu_shader_material_subsurface_scattering.glsl
@@ -19,6 +19,7 @@ void node_subsurface_scattering(vec4 color,
/* Not perfect for texture_blur not exactly equal to 0.0 or 1.0. */
vec3 sss_albedo = mix(color.rgb, vec3(1.0), texture_blur);
out_diff *= mix(vec3(1.0), color.rgb, texture_blur);
+ result.radiance = render_pass_sss_mask(sss_albedo);
closure_load_sss_data(scale, out_diff, sss_albedo, int(sss_id), result);
}
#else
diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_translucent.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_translucent.glsl
index 749b3a4c11f..5c3ed81410a 100644
--- a/source/blender/gpu/shaders/material/gpu_shader_material_translucent.glsl
+++ b/source/blender/gpu/shaders/material/gpu_shader_material_translucent.glsl
@@ -5,7 +5,7 @@ void node_bsdf_translucent(vec4 color, vec3 N, out Closure result)
result = CLOSURE_DEFAULT;
eevee_closure_diffuse(-N, color.rgb, 1.0, false, result.radiance);
closure_load_ssr_data(vec3(0.0), 0.0, N, viewCameraVec, -1, result);
- result.radiance *= color.rgb;
+ result.radiance = render_pass_diffuse_mask(color.rgb, result.radiance * color.rgb);
}
#else
/* Stub translucent because it is not compatible with volumetrics. */
diff --git a/source/blender/makesdna/DNA_layer_types.h b/source/blender/makesdna/DNA_layer_types.h
index 5480bed51e8..09d02e9a375 100644
--- a/source/blender/makesdna/DNA_layer_types.h
+++ b/source/blender/makesdna/DNA_layer_types.h
@@ -28,6 +28,26 @@ extern "C" {
#include "DNA_freestyle_types.h"
#include "DNA_listBase.h"
+/* Renderpasses for EEVEE.
+ * ViewLayerEEVEE.render_passes */
+typedef enum eViewLayerEEVEEPassType {
+ EEVEE_RENDER_PASS_COMBINED = (1 << 0),
+ EEVEE_RENDER_PASS_Z = (1 << 1),
+ EEVEE_RENDER_PASS_MIST = (1 << 2),
+ EEVEE_RENDER_PASS_NORMAL = (1 << 3),
+ EEVEE_RENDER_PASS_DIFFUSE_LIGHT = (1 << 4),
+ EEVEE_RENDER_PASS_DIFFUSE_COLOR = (1 << 5),
+ EEVEE_RENDER_PASS_SPECULAR_LIGHT = (1 << 6),
+ EEVEE_RENDER_PASS_SPECULAR_COLOR = (1 << 7),
+ EEVEE_RENDER_PASS_VOLUME_TRANSMITTANCE = (1 << 8),
+ EEVEE_RENDER_PASS_VOLUME_SCATTER = (1 << 9),
+ EEVEE_RENDER_PASS_EMIT = (1 << 10),
+ EEVEE_RENDER_PASS_ENVIRONMENT = (1 << 11),
+ EEVEE_RENDER_PASS_SHADOW = (1 << 12),
+ EEVEE_RENDER_PASS_AO = (1 << 13),
+ EEVEE_RENDER_PASS_BLOOM = (1 << 14),
+} eViewLayerEEVEEPassType;
+
typedef struct Base {
struct Base *next, *prev;
@@ -76,6 +96,12 @@ typedef struct LayerCollection {
short _pad2[3];
} LayerCollection;
+/* Type containing EEVEE settings per view-layer */
+typedef struct ViewLayerEEVEE {
+ int render_passes;
+ int _pad[1];
+} ViewLayerEEVEE;
+
typedef struct ViewLayer {
struct ViewLayer *next, *prev;
/** MAX_NAME. */
@@ -106,6 +132,7 @@ typedef struct ViewLayer {
struct IDProperty *id_properties;
struct FreestyleConfig freestyle_config;
+ struct ViewLayerEEVEE eevee;
/* Runtime data */
/** ViewLayerEngineData. */
diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h
index 7cd6b5f5013..0b5ab37b5ca 100644
--- a/source/blender/makesdna/DNA_scene_types.h
+++ b/source/blender/makesdna/DNA_scene_types.h
@@ -318,6 +318,9 @@ typedef enum eScenePassType {
#define RE_PASSNAME_SUBSURFACE_COLOR "SubsurfaceCol"
#define RE_PASSNAME_FREESTYLE "Freestyle"
+#define RE_PASSNAME_BLOOM "BloomCol"
+#define RE_PASSNAME_VOLUME_TRANSMITTANCE "VolumeTransmCol"
+#define RE_PASSNAME_VOLUME_SCATTER "VolumeScatterCol"
/* View - MultiView */
typedef struct SceneRenderView {
diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h
index 7d82b97868d..41858fffcf5 100644
--- a/source/blender/makesrna/RNA_access.h
+++ b/source/blender/makesrna/RNA_access.h
@@ -677,6 +677,7 @@ extern StructRNA RNA_View3DCursor;
extern StructRNA RNA_View3DOverlay;
extern StructRNA RNA_View3DShading;
extern StructRNA RNA_ViewLayer;
+extern StructRNA RNA_ViewLayerEEVEE;
extern StructRNA RNA_VoronoiTexture;
extern StructRNA RNA_WalkNavigation;
extern StructRNA RNA_WarpModifier;
diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c
index d2a17967de9..32c6239da5a 100644
--- a/source/blender/makesrna/intern/rna_scene.c
+++ b/source/blender/makesrna/intern/rna_scene.c
@@ -3756,6 +3756,30 @@ static void rna_def_unit_settings(BlenderRNA *brna)
RNA_def_property_update(prop, NC_WINDOW, NULL);
}
+static void rna_def_view_layer_eevee(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+ srna = RNA_def_struct(brna, "ViewLayerEEVEE", NULL);
+ RNA_def_struct_ui_text(srna, "EEVEE Settings", "View layer settings for EEVEE");
+
+ prop = RNA_def_property(srna, "use_pass_volume_scatter", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "render_passes", EEVEE_RENDER_PASS_VOLUME_SCATTER);
+ RNA_def_property_ui_text(prop, "Volume Scatter", "Deliver volume scattering pass");
+ RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_ViewLayer_pass_update");
+
+ prop = RNA_def_property(srna, "use_pass_volume_transmittance", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(
+ prop, NULL, "render_passes", EEVEE_RENDER_PASS_VOLUME_TRANSMITTANCE);
+ RNA_def_property_ui_text(prop, "Volume Transmittance", "Deliver volume transmittance pass");
+ RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_ViewLayer_pass_update");
+
+ prop = RNA_def_property(srna, "use_pass_bloom", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "render_passes", EEVEE_RENDER_PASS_BLOOM);
+ RNA_def_property_ui_text(prop, "Bloom", "Deliver bloom pass");
+ RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_ViewLayer_pass_update");
+}
+
void rna_def_view_layer_common(StructRNA *srna, const bool scene)
{
PropertyRNA *prop;
@@ -3801,6 +3825,11 @@ void rna_def_view_layer_common(StructRNA *srna, const bool scene)
"Z, Index, normal, UV and vector passes are only affected by surfaces with "
"alpha transparency equal to or higher than this threshold");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
+
+ prop = RNA_def_property(srna, "eevee", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
+ RNA_def_property_struct_type(prop, "ViewLayerEEVEE");
+ RNA_def_property_ui_text(prop, "EEVEE Settings", "View layer settings for EEVEE");
}
/* layer options */
@@ -7546,6 +7575,7 @@ void RNA_def_scene(BlenderRNA *brna)
rna_def_display_safe_areas(brna);
rna_def_scene_display(brna);
rna_def_scene_eevee(brna);
+ rna_def_view_layer_eevee(brna);
RNA_define_animate_sdna(true);
/* *** Animated *** */
rna_def_scene_render_data(brna);
diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c
index fdea081d8f1..975a3bdaf2e 100644
--- a/source/blender/makesrna/intern/rna_space.c
+++ b/source/blender/makesrna/intern/rna_space.c
@@ -382,14 +382,32 @@ static const EnumPropertyItem rna_enum_studio_light_items[] = {
};
static const EnumPropertyItem rna_enum_view3dshading_render_pass_type_items[] = {
- {SCE_PASS_COMBINED, "COMBINED", 0, "Combined", ""},
- /* {SCE_PASS_Z, "Z", 0, "Z", ""},*/
- {SCE_PASS_AO, "AO", 0, "Ambient Occlusion", ""},
- {SCE_PASS_NORMAL, "NORMAL", 0, "Normal", ""},
- {SCE_PASS_MIST, "MIST", 0, "Mist", ""},
- {SCE_PASS_SUBSURFACE_DIRECT, "SUBSURFACE_DIRECT", 0, "Subsurface Direct", ""},
- /* {SCE_PASS_SUBSURFACE_INDIRECT, "SUBSURFACE_INDIRECT", 0, "Subsurface Indirect", ""}, */
- {SCE_PASS_SUBSURFACE_COLOR, "SUBSURFACE_COLOR", 0, "Subsurface Color", ""},
+ {0, "", ICON_NONE, "General", ""},
+ {EEVEE_RENDER_PASS_COMBINED, "COMBINED", 0, "Combined", ""},
+ {EEVEE_RENDER_PASS_EMIT, "EMISSION", 0, "Emission", ""},
+ {EEVEE_RENDER_PASS_ENVIRONMENT, "ENVIRONMENT", 0, "Environment", ""},
+ {EEVEE_RENDER_PASS_AO, "AO", 0, "Ambient Occlusion", ""},
+ {EEVEE_RENDER_PASS_SHADOW, "SHADOW", 0, "Shadow", ""},
+
+ {0, "", ICON_NONE, "Light", ""},
+ {EEVEE_RENDER_PASS_DIFFUSE_LIGHT, "DIFFUSE_LIGHT", 0, "Diffuse Light", ""},
+ {EEVEE_RENDER_PASS_DIFFUSE_COLOR, "DIFFUSE_COLOR", 0, "Diffuse Color", ""},
+ {EEVEE_RENDER_PASS_SPECULAR_LIGHT, "SPECULAR_LIGHT", 0, "Specular Light", ""},
+ {EEVEE_RENDER_PASS_SPECULAR_COLOR, "SPECULAR_COLOR", 0, "Specular Color", ""},
+ {EEVEE_RENDER_PASS_VOLUME_TRANSMITTANCE,
+ "VOLUME_TRANSMITTANCE",
+ 0,
+ "Volume Transmittance",
+ ""},
+ {EEVEE_RENDER_PASS_VOLUME_SCATTER, "VOLUME_SCATTER", 0, "Volume Scattering", ""},
+
+ {0, "", ICON_NONE, "Effects", ""},
+ {EEVEE_RENDER_PASS_BLOOM, "BLOOM", 0, "Bloom", ""},
+
+ {0, "", ICON_NONE, "Data", ""},
+ {EEVEE_RENDER_PASS_NORMAL, "NORMAL", 0, "Normal", ""},
+ {EEVEE_RENDER_PASS_MIST, "MIST", 0, "Mist", ""},
+
{0, NULL, 0, NULL, NULL},
};
@@ -1242,6 +1260,30 @@ static const EnumPropertyItem *rna_View3DShading_studio_light_itemf(bContext *UN
return item;
}
+static const EnumPropertyItem *rna_3DViewShading_render_pass_itemf(bContext *C,
+ PointerRNA *UNUSED(ptr),
+ PropertyRNA *UNUSED(prop),
+ bool *r_free)
+{
+ Scene *scene = CTX_data_scene(C);
+
+ const bool ao_enabled = scene->eevee.flag & SCE_EEVEE_GTAO_ENABLED;
+ const bool bloom_enabled = scene->eevee.flag & SCE_EEVEE_BLOOM_ENABLED;
+
+ int totitem = 0;
+ EnumPropertyItem *result = NULL;
+ for (int i = 0; rna_enum_view3dshading_render_pass_type_items[i].identifier != NULL; i++) {
+ const EnumPropertyItem *item = &rna_enum_view3dshading_render_pass_type_items[i];
+ if (!((!ao_enabled && item->value == EEVEE_RENDER_PASS_AO) ||
+ (!bloom_enabled &&
+ (item->value == EEVEE_RENDER_PASS_BLOOM || STREQ(item->name, "Effects"))))) {
+ RNA_enum_item_add(&result, &totitem, item);
+ }
+ }
+ *r_free = true;
+ return result;
+}
+
static void rna_SpaceView3D_use_local_collections_update(bContext *C, PointerRNA *ptr)
{
Main *bmain = CTX_data_main(C);
@@ -3328,6 +3370,7 @@ static void rna_def_space_view3d_shading(BlenderRNA *brna)
RNA_def_property_enum_sdna(prop, NULL, "render_pass");
RNA_def_property_enum_items(prop, rna_enum_view3dshading_render_pass_type_items);
RNA_def_property_ui_text(prop, "Render Pass", "Render Pass to show in the viewport");
+ RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_3DViewShading_render_pass_itemf");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
}
diff --git a/source/blender/nodes/composite/node_composite_tree.c b/source/blender/nodes/composite/node_composite_tree.c
index 89349d91f94..93f2ba44a3a 100644
--- a/source/blender/nodes/composite/node_composite_tree.c
+++ b/source/blender/nodes/composite/node_composite_tree.c
@@ -281,8 +281,11 @@ void ntreeCompositUpdateRLayers(bNodeTree *ntree)
}
}
-void ntreeCompositRegisterPass(
- bNodeTree *ntree, Scene *scene, ViewLayer *view_layer, const char *name, int type)
+void ntreeCompositRegisterPass(bNodeTree *ntree,
+ Scene *scene,
+ ViewLayer *view_layer,
+ const char *name,
+ eNodeSocketDatatype type)
{
bNode *node;
diff --git a/source/blender/nodes/composite/nodes/node_composite_image.c b/source/blender/nodes/composite/nodes/node_composite_image.c
index b74f325a3fa..f8a97868959 100644
--- a/source/blender/nodes/composite/nodes/node_composite_image.c
+++ b/source/blender/nodes/composite/nodes/node_composite_image.c
@@ -72,13 +72,14 @@ static bNodeSocketTemplate cmp_node_rlayers_out[] = {
{SOCK_RGBA, 0, N_(RE_PASSNAME_SUBSURFACE_COLOR), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
{-1, 0, ""},
};
+#define MAX_LEGACY_SOCKET_INDEX 30
static void cmp_node_image_add_pass_output(bNodeTree *ntree,
bNode *node,
const char *name,
const char *passname,
int rres_index,
- int type,
+ eNodeSocketDatatype type,
int is_rlayers,
LinkNodePair *available_sockets,
int *prev_index)
@@ -94,8 +95,8 @@ static void cmp_node_image_add_pass_output(bNodeTree *ntree,
* New sockets are placed behind the previously traversed one,
* but always after the first 31. */
int after_index = *prev_index;
- if (is_rlayers && after_index < 30) {
- after_index = 30;
+ if (is_rlayers && after_index < MAX_LEGACY_SOCKET_INDEX) {
+ after_index = MAX_LEGACY_SOCKET_INDEX;
}
if (rres_index >= 0) {
@@ -238,8 +239,12 @@ typedef struct RLayerUpdateData {
int prev_index;
} RLayerUpdateData;
-void node_cmp_rlayers_register_pass(
- bNodeTree *ntree, bNode *node, Scene *scene, ViewLayer *view_layer, const char *name, int type)
+void node_cmp_rlayers_register_pass(bNodeTree *ntree,
+ bNode *node,
+ Scene *scene,
+ ViewLayer *view_layer,
+ const char *name,
+ eNodeSocketDatatype type)
{
RLayerUpdateData *data = node->storage;
@@ -389,7 +394,7 @@ static void cmp_node_image_verify_outputs(bNodeTree *ntree, bNode *node, bool rl
break;
}
}
- if (!link && (!rlayer || sock_index > 30)) {
+ if (!link && (!rlayer || sock_index > MAX_LEGACY_SOCKET_INDEX)) {
MEM_freeN(sock->storage);
nodeRemoveSocket(ntree, node, sock);
}
@@ -508,7 +513,7 @@ const char *node_cmp_rlayers_sock_to_pass(int sock_index)
RE_PASSNAME_SUBSURFACE_INDIRECT,
RE_PASSNAME_SUBSURFACE_COLOR,
};
- if (sock_index > 30) {
+ if (sock_index > MAX_LEGACY_SOCKET_INDEX) {
return NULL;
}
return sock_to_passname[sock_index];
diff --git a/source/blender/render/extern/include/RE_engine.h b/source/blender/render/extern/include/RE_engine.h
index 12e9123b5cb..88614de1641 100644
--- a/source/blender/render/extern/include/RE_engine.h
+++ b/source/blender/render/extern/include/RE_engine.h
@@ -26,6 +26,7 @@
#include "DNA_listBase.h"
#include "DNA_scene_types.h"
+#include "DNA_node_types.h"
#include "RNA_types.h"
#include "RE_bake.h"
@@ -117,7 +118,7 @@ typedef void (*update_render_passes_cb_t)(void *userdata,
const char *name,
int channels,
const char *chanid,
- int type);
+ eNodeSocketDatatype type);
typedef struct RenderEngine {
RenderEngineType *type;
@@ -212,7 +213,7 @@ void RE_engine_register_pass(struct RenderEngine *engine,
const char *name,
int channels,
const char *chanid,
- int type);
+ eNodeSocketDatatype type);
/* Engine Types */
diff --git a/source/blender/render/intern/source/external_engine.c b/source/blender/render/intern/source/external_engine.c
index 90058da5f0c..598f300cf86 100644
--- a/source/blender/render/intern/source/external_engine.c
+++ b/source/blender/render/intern/source/external_engine.c
@@ -863,7 +863,7 @@ void RE_engine_register_pass(struct RenderEngine *engine,
const char *name,
int channels,
const char *chanid,
- int type)
+ eNodeSocketDatatype type)
{
if (!(scene && view_layer && engine && engine->update_render_passes_cb)) {
return;
diff --git a/source/blender/render/intern/source/render_result.c b/source/blender/render/intern/source/render_result.c
index 120787a8d13..b2225d70eaf 100644
--- a/source/blender/render/intern/source/render_result.c
+++ b/source/blender/render/intern/source/render_result.c
@@ -442,6 +442,15 @@ RenderResult *render_result_new(Render *re,
if (view_layer->passflag & SCE_PASS_SUBSURFACE_COLOR) {
RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_SUBSURFACE_COLOR, view, "RGB");
}
+ if (view_layer->eevee.render_passes & EEVEE_RENDER_PASS_BLOOM) {
+ RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_BLOOM, view, "RGB");
+ }
+ if (view_layer->eevee.render_passes & EEVEE_RENDER_PASS_VOLUME_SCATTER) {
+ RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_VOLUME_SCATTER, view, "RGB");
+ }
+ if (view_layer->eevee.render_passes & EEVEE_RENDER_PASS_VOLUME_TRANSMITTANCE) {
+ RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_VOLUME_TRANSMITTANCE, view, "RGB");
+ }
#undef RENDER_LAYER_ADD_PASS_SAFE
}
}