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:
Diffstat (limited to 'source/blender/draw')
-rw-r--r--source/blender/draw/engines/eevee/eevee_effects.c4
-rw-r--r--source/blender/draw/engines/eevee/eevee_engine.c35
-rw-r--r--source/blender/draw/engines/eevee/eevee_mist.c7
-rw-r--r--source/blender/draw/engines/eevee/eevee_occlusion.c6
-rw-r--r--source/blender/draw/engines/eevee/eevee_private.h11
-rw-r--r--source/blender/draw/engines/eevee/eevee_render.c8
-rw-r--r--source/blender/draw/engines/eevee/eevee_renderpasses.c90
-rw-r--r--source/blender/draw/engines/eevee/eevee_subsurface.c11
-rw-r--r--source/blender/draw/engines/eevee/eevee_temporal_sampling.c4
-rw-r--r--source/blender/draw/engines/eevee/shaders/renderpass_postprocess_frag.glsl11
10 files changed, 156 insertions, 31 deletions
diff --git a/source/blender/draw/engines/eevee/eevee_effects.c b/source/blender/draw/engines/eevee/eevee_effects.c
index d59d1f56e92..824ea69ea73 100644
--- a/source/blender/draw/engines/eevee/eevee_effects.c
+++ b/source/blender/draw/engines/eevee/eevee_effects.c
@@ -136,8 +136,6 @@ void EEVEE_effects_init(EEVEE_ViewLayerData *sldata,
EEVEE_TextureList *txl = vedata->txl;
EEVEE_EffectsInfo *effects;
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
- const DRWContextState *draw_ctx = DRW_context_state_get();
- ViewLayer *view_layer = draw_ctx->view_layer;
const float *viewport_size = DRW_viewport_size_get();
int size_fs[2] = {(int)viewport_size[0], (int)viewport_size[1]};
@@ -172,7 +170,7 @@ void EEVEE_effects_init(EEVEE_ViewLayerData *sldata,
EEVEE_subsurface_init(sldata, vedata);
/* Force normal buffer creation. */
- if (DRW_state_is_image_render() && !minimal && (view_layer->passflag & SCE_PASS_NORMAL) != 0) {
+ if (!minimal && (stl->g_data->render_passes & SCE_PASS_NORMAL) != 0) {
effects->enabled_effects |= EFFECT_NORMAL_BUFFER;
}
diff --git a/source/blender/draw/engines/eevee/eevee_engine.c b/source/blender/draw/engines/eevee/eevee_engine.c
index 173b7ff57a1..603a4787dba 100644
--- a/source/blender/draw/engines/eevee/eevee_engine.c
+++ b/source/blender/draw/engines/eevee/eevee_engine.c
@@ -27,6 +27,8 @@
#include "BKE_object.h"
#include "BKE_global.h" /* for G.debug_value */
+#include "DEG_depsgraph_query.h"
+
#include "DNA_world_types.h"
#include "eevee_private.h"
@@ -81,7 +83,9 @@ static void eevee_engine_init(void *ved)
&sldata->common_data);
}
- /* EEVEE_effects_init needs to go first for TAA */
+ /* `EEVEE_renderpasses_init` will set the active render passes used by `EEVEE_effects_init`.
+ * `EEVEE_effects_init` needs to go second for TAA. */
+ EEVEE_renderpasses_init(vedata);
EEVEE_effects_init(sldata, vedata, camera, false);
EEVEE_materials_init(sldata, stl, fbl);
EEVEE_shadows_init(sldata);
@@ -147,6 +151,8 @@ 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;
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph);
EEVEE_volumes_cache_finish(sldata, vedata);
EEVEE_materials_cache_finish(sldata, vedata);
@@ -156,6 +162,14 @@ static void eevee_cache_finish(void *vedata)
EEVEE_effects_draw_init(sldata, vedata);
EEVEE_volumes_draw_init(sldata, vedata);
+ uint tot_samples = scene_eval->eevee.taa_render_samples;
+ if (tot_samples == 0) {
+ /* use a high number of samples so the outputs accum buffers
+ * will have the highest possible precision */
+ tot_samples = 1024;
+ }
+ EEVEE_renderpasses_output_init(sldata, vedata, tot_samples);
+
/* Restart taa if a shader has finish compiling. */
/* HACK We should use notification of some sort from the compilation job instead. */
if (g_data->queued_shaders_count != g_data->queued_shaders_count_prev) {
@@ -306,6 +320,8 @@ static void eevee_draw_background(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) &&
@@ -319,14 +335,19 @@ static void eevee_draw_background(void *vedata)
}
}
- /* Tonemapping and transfer result to default framebuffer. */
- bool use_render_settings = stl->g_data->use_color_render_settings;
+ if ((stl->g_data->render_passes & SCE_PASS_COMBINED) > 0) {
+ /* Tonemapping and transfer result to default framebuffer. */
+ bool use_render_settings = stl->g_data->use_color_render_settings;
- GPU_framebuffer_bind(dfbl->default_fb);
- DRW_transform_to_display(stl->effects->final_tx, true, use_render_settings);
+ GPU_framebuffer_bind(dfbl->default_fb);
+ DRW_transform_to_display(stl->effects->final_tx, true, use_render_settings);
- /* Draw checkerboard with alpha under. */
- EEVEE_draw_alpha_checker(vedata);
+ /* Draw checkerboard with alpha under. */
+ EEVEE_draw_alpha_checker(vedata);
+ }
+ else {
+ EEVEE_renderpasses_draw(sldata, vedata);
+ }
/* Debug : Output buffer to view. */
switch (G.debug_value) {
diff --git a/source/blender/draw/engines/eevee/eevee_mist.c b/source/blender/draw/engines/eevee/eevee_mist.c
index 7209651a1d4..c9b56a6d551 100644
--- a/source/blender/draw/engines/eevee/eevee_mist.c
+++ b/source/blender/draw/engines/eevee/eevee_mist.c
@@ -49,6 +49,7 @@ void EEVEE_mist_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
EEVEE_TextureList *txl = vedata->txl;
EEVEE_StorageList *stl = vedata->stl;
EEVEE_PassList *psl = vedata->psl;
+ EEVEE_EffectsInfo *effects = stl->effects;
EEVEE_PrivateData *g_data = stl->g_data;
Scene *scene = draw_ctx->scene;
@@ -74,8 +75,10 @@ void EEVEE_mist_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
{GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(txl->mist_accum)});
/* Clear texture. */
- GPU_framebuffer_bind(fbl->mist_accum_fb);
- GPU_framebuffer_clear_color(fbl->mist_accum_fb, clear);
+ if (DRW_state_is_image_render() || effects->taa_current_sample == 1) {
+ GPU_framebuffer_bind(fbl->mist_accum_fb);
+ GPU_framebuffer_clear_color(fbl->mist_accum_fb, clear);
+ }
/* Mist settings. */
if (scene && scene->world) {
diff --git a/source/blender/draw/engines/eevee/eevee_occlusion.c b/source/blender/draw/engines/eevee/eevee_occlusion.c
index 0a7d1db1061..6ba518b3a28 100644
--- a/source/blender/draw/engines/eevee/eevee_occlusion.c
+++ b/source/blender/draw/engines/eevee/eevee_occlusion.c
@@ -155,8 +155,10 @@ void EEVEE_occlusion_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata
{GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(txl->ao_accum)});
/* Clear texture. */
- GPU_framebuffer_bind(fbl->ao_accum_fb);
- GPU_framebuffer_clear_color(fbl->ao_accum_fb, clear);
+ if (DRW_state_is_image_render() || effects->taa_current_sample == 1) {
+ GPU_framebuffer_bind(fbl->ao_accum_fb);
+ GPU_framebuffer_clear_color(fbl->ao_accum_fb, clear);
+ }
/* Accumulation pass */
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ADD;
diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h
index b49328d90ab..bbe68aec190 100644
--- a/source/blender/draw/engines/eevee/eevee_private.h
+++ b/source/blender/draw/engines/eevee/eevee_private.h
@@ -63,6 +63,14 @@ extern struct DrawEngineType draw_engine_eevee_type;
# define SHADER_IRRADIANCE "#define IRRADIANCE_HL2\n"
#endif
+#define EEVEE_RENDERPASSES_SUPPORTED \
+ (SCE_PASS_COMBINED | SCE_PASS_Z | SCE_PASS_MIST | SCE_PASS_NORMAL | SCE_PASS_AO | \
+ SCE_PASS_SUBSURFACE_COLOR | SCE_PASS_SUBSURFACE_DIRECT)
+
+#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)
+
/* Macro causes over indentation. */
/* clang-format off */
#define SHADER_DEFINES \
@@ -1052,10 +1060,13 @@ 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_postprocess(EEVEE_ViewLayerData *sldata,
EEVEE_Data *vedata,
eScenePassType renderpass_type);
+void EEVEE_renderpasses_draw(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_renderpasses_free(void);
+bool EEVEE_renderpasses_only_first_sample_pass_active(EEVEE_Data *vedata);
/* eevee_temporal_sampling.c */
void EEVEE_temporal_sampling_reset(EEVEE_Data *vedata);
diff --git a/source/blender/draw/engines/eevee/eevee_render.c b/source/blender/draw/engines/eevee/eevee_render.c
index 9a7d170c9ea..ba5704f14e5 100644
--- a/source/blender/draw/engines/eevee/eevee_render.c
+++ b/source/blender/draw/engines/eevee/eevee_render.c
@@ -485,16 +485,12 @@ void EEVEE_render_draw(EEVEE_Data *vedata, RenderEngine *engine, RenderLayer *rl
DRW_draw_pass(psl->refract_depth_pass);
DRW_draw_pass(psl->refract_depth_pass_cull);
DRW_draw_pass(psl->refract_pass);
- /* Subsurface output */
- EEVEE_subsurface_output_accumulate(sldata, vedata);
- /* Occlusion output */
- EEVEE_occlusion_output_accumulate(sldata, vedata);
/* Result NORMAL */
eevee_render_result_normal(rl, viewname, rect, vedata, sldata);
/* Volumetrics Resolve Opaque */
EEVEE_volumes_resolve(sldata, vedata);
- /* Mist output */
- EEVEE_mist_output_accumulate(sldata, vedata);
+ /* Subsurface output, Occlusion output, Mist output */
+ EEVEE_renderpasses_output_accumulate(sldata, vedata);
/* Transparent */
GPU_framebuffer_texture_attach(fbl->main_color_fb, dtxl->depth, 0, 0);
GPU_framebuffer_bind(fbl->main_color_fb);
diff --git a/source/blender/draw/engines/eevee/eevee_renderpasses.c b/source/blender/draw/engines/eevee/eevee_renderpasses.c
index 17f1f8c96d6..b83216ee6d0 100644
--- a/source/blender/draw/engines/eevee/eevee_renderpasses.c
+++ b/source/blender/draw/engines/eevee/eevee_renderpasses.c
@@ -25,6 +25,8 @@
#include "BLI_string_utils.h"
+#include "DEG_depsgraph_query.h"
+
#include "eevee_private.h"
extern char datatoc_common_view_lib_glsl[];
@@ -46,14 +48,31 @@ static struct {
#define EEVEE_RENDERPASSES_ALL (EEVEE_RENDERPASSES_WITH_POST_PROCESSING | SCE_PASS_COMBINED)
+#define EEVEE_RENDERPASSES_POST_PROCESS_ON_FIRST_SAMPLE (SCE_PASS_Z | SCE_PASS_NORMAL)
+
+#define EEVEE_RENDERPASSES_COLOR_PASS (SCE_PASS_SUBSURFACE_COLOR | SCE_PASS_SUBSURFACE_DIRECT)
+
+bool EEVEE_renderpasses_only_first_sample_pass_active(EEVEE_Data *vedata)
+{
+ EEVEE_StorageList *stl = vedata->stl;
+ EEVEE_PrivateData *g_data = stl->g_data;
+ return (g_data->render_passes & ~EEVEE_RENDERPASSES_POST_PROCESS_ON_FIRST_SAMPLE) == 0;
+}
+
void EEVEE_renderpasses_init(EEVEE_Data *vedata)
{
const DRWContextState *draw_ctx = DRW_context_state_get();
EEVEE_StorageList *stl = vedata->stl;
EEVEE_PrivateData *g_data = stl->g_data;
ViewLayer *view_layer = draw_ctx->view_layer;
+ View3D *v3d = draw_ctx->v3d;
- g_data->render_passes = (view_layer->passflag & EEVEE_RENDERPASSES_ALL) | SCE_PASS_COMBINED;
+ if (v3d) {
+ g_data->render_passes = v3d->shading.render_pass;
+ }
+ else {
+ g_data->render_passes = (view_layer->passflag & EEVEE_RENDERPASSES_ALL) | SCE_PASS_COMBINED;
+ }
}
void EEVEE_renderpasses_output_init(EEVEE_ViewLayerData *sldata,
@@ -143,17 +162,21 @@ void EEVEE_renderpasses_postprocess(EEVEE_ViewLayerData *sldata,
}
case SCE_PASS_AO: {
+ DRW_shgroup_uniform_block(shgrp, "common_block", sldata->common_ubo);
DRW_shgroup_uniform_texture_ref(shgrp, "inputBuffer", &txl->ao_accum);
DRW_shgroup_uniform_int_copy(shgrp, "currentSample", current_sample);
break;
}
case SCE_PASS_NORMAL: {
+ DRW_shgroup_uniform_block(shgrp, "common_block", sldata->common_ubo);
DRW_shgroup_uniform_texture_ref(shgrp, "inputBuffer", &effects->ssr_normal_input);
+ DRW_shgroup_uniform_texture_ref(shgrp, "depthBuffer", &dtxl->depth);
break;
}
case SCE_PASS_MIST: {
+ DRW_shgroup_uniform_block(shgrp, "common_block", sldata->common_ubo);
DRW_shgroup_uniform_texture_ref(shgrp, "inputBuffer", &txl->mist_accum);
DRW_shgroup_uniform_int_copy(shgrp, "currentSample", current_sample);
break;
@@ -184,6 +207,71 @@ void EEVEE_renderpasses_postprocess(EEVEE_ViewLayerData *sldata,
DRW_draw_pass_subset(psl->renderpass_pass, shgrp, shgrp);
}
+void EEVEE_renderpasses_output_accumulate(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
+{
+ EEVEE_StorageList *stl = vedata->stl;
+ EEVEE_EffectsInfo *effects = stl->effects;
+ eScenePassType 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 ((render_pass & SCE_PASS_AO) != 0) {
+ EEVEE_occlusion_output_accumulate(sldata, vedata);
+ }
+}
+
+void EEVEE_renderpasses_draw(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
+{
+ EEVEE_FramebufferList *fbl = vedata->fbl;
+ EEVEE_TextureList *txl = vedata->txl;
+ 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;
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph);
+
+ bool is_valid = true;
+ bool needs_color_transfer = (render_pass & EEVEE_RENDERPASSES_COLOR_PASS) > 0 &&
+ DRW_state_is_opengl_render();
+
+ /* 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) {
+ 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) {
+ is_valid = false;
+ }
+
+ const int current_sample = stl->effects->taa_current_sample;
+ const int total_samples = stl->effects->taa_total_sample;
+ if ((render_pass & EEVEE_RENDERPASSES_POST_PROCESS_ON_FIRST_SAMPLE) &&
+ (current_sample > 1 && total_samples != 1)) {
+ return;
+ }
+
+ if (is_valid) {
+ EEVEE_renderpasses_postprocess(sldata, vedata, render_pass);
+ GPU_framebuffer_bind(dfbl->default_fb);
+ DRW_transform_to_display(txl->renderpass, needs_color_transfer, false);
+ }
+ 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};
+ GPU_framebuffer_bind(dfbl->default_fb);
+ GPU_framebuffer_clear_color(dfbl->default_fb, clear_color);
+ }
+ GPU_framebuffer_bind(fbl->main_fb);
+}
+
void EEVEE_renderpasses_free(void)
{
DRW_SHADER_FREE_SAFE(e_data.postprocess_sh);
diff --git a/source/blender/draw/engines/eevee/eevee_subsurface.c b/source/blender/draw/engines/eevee/eevee_subsurface.c
index a7c28347c15..e94fc903694 100644
--- a/source/blender/draw/engines/eevee/eevee_subsurface.c
+++ b/source/blender/draw/engines/eevee/eevee_subsurface.c
@@ -187,9 +187,11 @@ void EEVEE_subsurface_output_init(EEVEE_ViewLayerData *UNUSED(sldata),
GPU_ATTACHMENT_TEXTURE(txl->sss_col_accum)});
/* Clear texture. */
- 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);
+ 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);
+ }
/* Make the opaque refraction pass mask the sss. */
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL | DRW_STATE_CLIP_PLANES |
@@ -257,7 +259,8 @@ void EEVEE_subsurface_add_pass(EEVEE_ViewLayerData *sldata,
DRW_shgroup_stencil_mask(grp, sss_id);
DRW_shgroup_call(grp, quad, NULL);
- if (DRW_state_is_image_render()) {
+ 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);
diff --git a/source/blender/draw/engines/eevee/eevee_temporal_sampling.c b/source/blender/draw/engines/eevee/eevee_temporal_sampling.c
index e5f89aab4d1..0f0b4a3e0a9 100644
--- a/source/blender/draw/engines/eevee/eevee_temporal_sampling.c
+++ b/source/blender/draw/engines/eevee/eevee_temporal_sampling.c
@@ -234,7 +234,9 @@ int EEVEE_temporal_sampling_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data
view_is_valid = view_is_valid && (ED_screen_animation_no_scrub(wm) == NULL);
}
- effects->taa_total_sample = scene_eval->eevee.taa_samples;
+ effects->taa_total_sample = EEVEE_renderpasses_only_first_sample_pass_active(vedata) ?
+ 1 :
+ scene_eval->eevee.taa_samples;
MAX2(effects->taa_total_sample, 0);
DRW_view_persmat_get(NULL, persmat, false);
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 8a543f13fbc..5a738d0f130 100644
--- a/source/blender/draw/engines/eevee/shaders/renderpass_postprocess_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/renderpass_postprocess_frag.glsl
@@ -34,27 +34,28 @@ void main()
}
else if (renderpassType == SCE_PASS_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 */
- if (any(notEqual(encoded_normal, vec2(0.0)))) {
+ 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;
- fragColor = vec4(world_normal, 0.0);
+ fragColor = vec4(world_normal, 1.0);
}
else {
- fragColor = vec4(0.0);
+ fragColor = vec4(0.0, 0.0, 0.0, 1.0);
}
}
else if ((renderpassType & ACCUMULATED_VALUE_PASSES) != 0) {
float accumulated_value = texelFetch(inputBuffer, texel, 0).r;
- fragColor.r = accumulated_value / currentSample;
+ fragColor = vec4(vec3(accumulated_value / currentSample), 1.0);
}
else if ((renderpassType & ACCUMULATED_COLOR_PASSES) != 0) {
vec3 accumulated_color = texelFetch(inputBuffer, texel, 0).rgb;
- fragColor.rgb = accumulated_color / currentSample;
+ fragColor = vec4(accumulated_color / currentSample, 1.0);
}
else {