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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClément Foucault <foucault.clem@gmail.com>2019-12-02 03:40:58 +0300
committerClément Foucault <foucault.clem@gmail.com>2019-12-02 03:40:58 +0300
commita35c635edb3db548e11555024ec3a384f93ce352 (patch)
treeae0c0c9435c2e7daed4cbd916e0be90df7898b51 /source/blender/draw/engines/eevee
parent7164e63fefcfa26caf387a2ad04a8c51b533c32b (diff)
parentf1ac64921b49eaea8658d144754a1a532198c720 (diff)
Merge branch 'master' into tmp-overlay-enginetmp-overlay-engine
# Conflicts: # source/blender/draw/modes/paint_texture_mode.c
Diffstat (limited to 'source/blender/draw/engines/eevee')
-rw-r--r--source/blender/draw/engines/eevee/eevee_effects.c4
-rw-r--r--source/blender/draw/engines/eevee/eevee_engine.c36
-rw-r--r--source/blender/draw/engines/eevee/eevee_mist.c7
-rw-r--r--source/blender/draw/engines/eevee/eevee_occlusion.c12
-rw-r--r--source/blender/draw/engines/eevee/eevee_private.h29
-rw-r--r--source/blender/draw/engines/eevee/eevee_render.c271
-rw-r--r--source/blender/draw/engines/eevee/eevee_renderpasses.c278
-rw-r--r--source/blender/draw/engines/eevee/eevee_subsurface.c21
-rw-r--r--source/blender/draw/engines/eevee/eevee_temporal_sampling.c4
-rw-r--r--source/blender/draw/engines/eevee/shaders/renderpass_postprocess_frag.glsl64
10 files changed, 497 insertions, 229 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 a1096390bce..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) {
@@ -483,6 +504,7 @@ static void eevee_engine_free(void)
EEVEE_screen_raytrace_free();
EEVEE_subsurface_free();
EEVEE_volumes_free();
+ EEVEE_renderpasses_free();
}
static const DrawEngineDataSize eevee_data_size = DRW_VIEWPORT_DATA_SIZE(EEVEE_Data);
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 48e9b5bcc13..6ba518b3a28 100644
--- a/source/blender/draw/engines/eevee/eevee_occlusion.c
+++ b/source/blender/draw/engines/eevee/eevee_occlusion.c
@@ -131,7 +131,7 @@ int EEVEE_occlusion_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
return 0;
}
-void EEVEE_occlusion_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
+void EEVEE_occlusion_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, uint tot_samples)
{
EEVEE_FramebufferList *fbl = vedata->fbl;
EEVEE_TextureList *txl = vedata->txl;
@@ -143,18 +143,22 @@ void EEVEE_occlusion_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata
const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph);
if (scene_eval->eevee.flag & SCE_EEVEE_GTAO_ENABLED) {
+ const eGPUTextureFormat texture_format = (tot_samples > 128) ? GPU_R32F : GPU_R16F;
+
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
float clear[4] = {0.0f, 0.0f, 0.0f, 0.0f};
/* Should be enough precision for many samples. */
- DRW_texture_ensure_fullscreen_2d(&txl->ao_accum, GPU_R32F, 0);
+ DRW_texture_ensure_fullscreen_2d(&txl->ao_accum, texture_format, 0);
GPU_framebuffer_ensure_config(&fbl->ao_accum_fb,
{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 7d02aacfac7..97bde2e5f2e 100644
--- a/source/blender/draw/engines/eevee/eevee_private.h
+++ b/source/blender/draw/engines/eevee/eevee_private.h
@@ -271,6 +271,7 @@ typedef struct EEVEE_PassList {
struct DRWPass *update_noise_pass;
struct DRWPass *lookdev_glossy_pass;
struct DRWPass *lookdev_diffuse_pass;
+ struct DRWPass *renderpass_pass;
} EEVEE_PassList;
typedef struct EEVEE_FramebufferList {
@@ -295,6 +296,7 @@ typedef struct EEVEE_FramebufferList {
struct GPUFrameBuffer *screen_tracing_fb;
struct GPUFrameBuffer *refract_fb;
struct GPUFrameBuffer *mist_accum_fb;
+ struct GPUFrameBuffer *renderpass_fb;
struct GPUFrameBuffer *ao_accum_fb;
struct GPUFrameBuffer *velocity_resolve_fb;
@@ -341,6 +343,8 @@ typedef struct EEVEE_TextureList {
struct GPUTexture *maxzbuffer;
+ struct GPUTexture *renderpass;
+
struct GPUTexture *color; /* R16_G16_B16 */
struct GPUTexture *color_double_buffer;
struct GPUTexture *depth_double_buffer;
@@ -799,6 +803,10 @@ typedef struct EEVEE_PrivateData {
float studiolight_glossy_clamp;
float studiolight_filter_quality;
+ /* Renderpasses */
+ /* Bitmask containing the active render_passes */
+ eScenePassType render_passes;
+
/** For rendering shadows. */
struct DRWView *cube_views[6];
/** For rendering probes. */
@@ -988,7 +996,9 @@ void EEVEE_bloom_free(void);
/* eevee_occlusion.c */
int EEVEE_occlusion_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
-void EEVEE_occlusion_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
+void EEVEE_occlusion_output_init(EEVEE_ViewLayerData *sldata,
+ EEVEE_Data *vedata,
+ uint tot_samples);
void EEVEE_occlusion_output_accumulate(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_occlusion_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_occlusion_compute(EEVEE_ViewLayerData *sldata,
@@ -1009,7 +1019,9 @@ void EEVEE_screen_raytrace_free(void);
void EEVEE_subsurface_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_subsurface_draw_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_subsurface_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
-void EEVEE_subsurface_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
+void EEVEE_subsurface_output_init(EEVEE_ViewLayerData *sldata,
+ EEVEE_Data *vedata,
+ uint tot_samples);
void EEVEE_subsurface_add_pass(EEVEE_ViewLayerData *sldata,
EEVEE_Data *vedata,
uint sss_id,
@@ -1035,6 +1047,19 @@ void EEVEE_mist_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_mist_output_accumulate(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_mist_free(void);
+/* eevee_renderpasses.c */
+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);
int EEVEE_temporal_sampling_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
diff --git a/source/blender/draw/engines/eevee/eevee_render.c b/source/blender/draw/engines/eevee/eevee_render.c
index 75e837f140b..ba5704f14e5 100644
--- a/source/blender/draw/engines/eevee/eevee_render.c
+++ b/source/blender/draw/engines/eevee/eevee_render.c
@@ -130,7 +130,9 @@ void EEVEE_render_init(EEVEE_Data *ved, RenderEngine *engine, struct Depsgraph *
DRW_view_default_set(view);
DRW_view_set_active(view);
- /* 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, ob_camera_eval, false);
EEVEE_materials_init(sldata, stl, fbl);
EEVEE_shadows_init(sldata);
@@ -202,79 +204,60 @@ void EEVEE_render_cache(void *vedata,
}
}
-static void eevee_render_result_combined(RenderLayer *rl,
- const char *viewname,
- const rcti *rect,
- EEVEE_Data *vedata,
- EEVEE_ViewLayerData *UNUSED(sldata))
+static void eevee_render_color_result(RenderLayer *rl,
+ const char *viewname,
+ const rcti *rect,
+ const char *render_pass_name,
+ int num_channels,
+ GPUFrameBuffer *framebuffer,
+ EEVEE_Data *vedata)
{
- RenderPass *rp = RE_pass_find_by_name(rl, RE_PASSNAME_COMBINED, viewname);
-
- GPU_framebuffer_bind(vedata->stl->effects->final_fb);
- GPU_framebuffer_read_color(vedata->stl->effects->final_fb,
+ RenderPass *rp = RE_pass_find_by_name(rl, render_pass_name, viewname);
+ GPU_framebuffer_bind(framebuffer);
+ GPU_framebuffer_read_color(framebuffer,
vedata->stl->g_data->overscan_pixels + rect->xmin,
vedata->stl->g_data->overscan_pixels + rect->ymin,
BLI_rcti_size_x(rect),
BLI_rcti_size_y(rect),
- 4,
+ num_channels,
0,
rp->rect);
}
+static void eevee_render_result_combined(RenderLayer *rl,
+ const char *viewname,
+ const rcti *rect,
+ EEVEE_Data *vedata,
+ EEVEE_ViewLayerData *UNUSED(sldata))
+{
+ eevee_render_color_result(
+ 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 *UNUSED(sldata),
- int render_samples)
+ EEVEE_ViewLayerData *sldata)
{
- const DRWContextState *draw_ctx = DRW_context_state_get();
- ViewLayer *view_layer = draw_ctx->view_layer;
-
if (vedata->fbl->sss_accum_fb == NULL) {
/* SSS is not enabled. */
return;
}
- if ((view_layer->passflag & SCE_PASS_SUBSURFACE_COLOR) != 0) {
- RenderPass *rp = RE_pass_find_by_name(rl, RE_PASSNAME_SUBSURFACE_COLOR, viewname);
-
- GPU_framebuffer_bind(vedata->fbl->sss_accum_fb);
- GPU_framebuffer_read_color(vedata->fbl->sss_accum_fb,
- vedata->stl->g_data->overscan_pixels + rect->xmin,
- vedata->stl->g_data->overscan_pixels + rect->ymin,
- BLI_rcti_size_x(rect),
- BLI_rcti_size_y(rect),
- 3,
- 1,
- rp->rect);
-
- /* This is the accumulated color. Divide by the number of samples. */
- for (int i = 0; i < rp->rectx * rp->recty * 3; i++) {
- rp->rect[i] /= (float)render_samples;
- }
+ 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 ((view_layer->passflag & SCE_PASS_SUBSURFACE_DIRECT) != 0) {
- RenderPass *rp = RE_pass_find_by_name(rl, RE_PASSNAME_SUBSURFACE_DIRECT, viewname);
-
- GPU_framebuffer_bind(vedata->fbl->sss_accum_fb);
- GPU_framebuffer_read_color(vedata->fbl->sss_accum_fb,
- vedata->stl->g_data->overscan_pixels + rect->xmin,
- vedata->stl->g_data->overscan_pixels + rect->ymin,
- BLI_rcti_size_x(rect),
- BLI_rcti_size_y(rect),
- 3,
- 0,
- rp->rect);
-
- /* This is the accumulated color. Divide by the number of samples. */
- for (int i = 0; i < rp->rectx * rp->recty * 3; i++) {
- rp->rect[i] /= (float)render_samples;
- }
+ 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 ((view_layer->passflag & SCE_PASS_SUBSURFACE_INDIRECT) != 0) {
+ 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. */
}
@@ -284,54 +267,19 @@ static void eevee_render_result_normal(RenderLayer *rl,
const char *viewname,
const rcti *rect,
EEVEE_Data *vedata,
- EEVEE_ViewLayerData *UNUSED(sldata))
+ EEVEE_ViewLayerData *sldata)
{
- const DRWContextState *draw_ctx = DRW_context_state_get();
- ViewLayer *view_layer = draw_ctx->view_layer;
- EEVEE_StorageList *stl = vedata->stl;
- EEVEE_PrivateData *g_data = stl->g_data;
+ const int current_sample = vedata->stl->effects->taa_current_sample;
/* Only read the center texel. */
- if (stl->effects->taa_current_sample > 1) {
+ if (current_sample > 1) {
return;
}
- if ((view_layer->passflag & SCE_PASS_NORMAL) != 0) {
- RenderPass *rp = RE_pass_find_by_name(rl, RE_PASSNAME_NORMAL, viewname);
-
- GPU_framebuffer_bind(vedata->fbl->main_fb);
- GPU_framebuffer_read_color(vedata->fbl->main_fb,
- g_data->overscan_pixels + rect->xmin,
- g_data->overscan_pixels + rect->ymin,
- BLI_rcti_size_x(rect),
- BLI_rcti_size_y(rect),
- 3,
- 1,
- rp->rect);
-
- float viewinv[4][4];
- DRW_view_viewmat_get(NULL, viewinv, true);
-
- /* Convert Eevee encoded normals to Blender normals. */
- for (int i = 0; i < rp->rectx * rp->recty * 3; i += 3) {
- if (rp->rect[i] == 0.0f && rp->rect[i + 1] == 0.0f) {
- /* If normal is not correct then do not produce NANs. */
- continue;
- }
-
- float fenc[2];
- fenc[0] = rp->rect[i + 0] * 4.0f - 2.0f;
- fenc[1] = rp->rect[i + 1] * 4.0f - 2.0f;
-
- float f = dot_v2v2(fenc, fenc);
- float g = sqrtf(1.0f - f / 4.0f);
-
- rp->rect[i + 0] = fenc[0] * g;
- rp->rect[i + 1] = fenc[1] * g;
- rp->rect[i + 2] = 1.0f - f / 2.0f;
-
- mul_mat3_m4_v3(viewinv, &rp->rect[i]);
- }
+ if ((vedata->stl->g_data->render_passes & SCE_PASS_NORMAL) != 0) {
+ EEVEE_renderpasses_postprocess(sldata, vedata, SCE_PASS_NORMAL);
+ eevee_render_color_result(
+ rl, viewname, rect, RE_PASSNAME_NORMAL, 3, vedata->fbl->renderpass_fb, vedata);
}
}
@@ -341,49 +289,17 @@ static void eevee_render_result_z(RenderLayer *rl,
EEVEE_Data *vedata,
EEVEE_ViewLayerData *sldata)
{
- const DRWContextState *draw_ctx = DRW_context_state_get();
- ViewLayer *view_layer = draw_ctx->view_layer;
- EEVEE_CommonUniformBuffer *common_data = &sldata->common_data;
- EEVEE_StorageList *stl = vedata->stl;
- EEVEE_PrivateData *g_data = stl->g_data;
+ const int current_sample = vedata->stl->effects->taa_current_sample;
/* Only read the center texel. */
- if (stl->effects->taa_current_sample > 1) {
+ if (current_sample > 1) {
return;
}
- if ((view_layer->passflag & SCE_PASS_Z) != 0) {
- RenderPass *rp = RE_pass_find_by_name(rl, RE_PASSNAME_Z, viewname);
-
- GPU_framebuffer_bind(vedata->fbl->main_fb);
- GPU_framebuffer_read_depth(vedata->fbl->main_fb,
- g_data->overscan_pixels + rect->xmin,
- g_data->overscan_pixels + rect->ymin,
- BLI_rcti_size_x(rect),
- BLI_rcti_size_y(rect),
- rp->rect);
-
- bool is_persp = DRW_view_is_persp_get(NULL);
-
- float winmat[4][4];
- DRW_view_winmat_get(NULL, winmat, false);
-
- /* Convert ogl depth [0..1] to view Z [near..far] */
- for (int i = 0; i < rp->rectx * rp->recty; i++) {
- if (rp->rect[i] == 1.0f) {
- rp->rect[i] = 1e10f; /* Background */
- }
- else {
- if (is_persp) {
- rp->rect[i] = rp->rect[i] * 2.0f - 1.0f;
- rp->rect[i] = winmat[3][2] / (rp->rect[i] + winmat[2][2]);
- }
- else {
- rp->rect[i] = -common_data->view_vecs[0][2] +
- rp->rect[i] * -common_data->view_vecs[1][2];
- }
- }
- }
+ if ((vedata->stl->g_data->render_passes & SCE_PASS_Z) != 0) {
+ EEVEE_renderpasses_postprocess(sldata, vedata, SCE_PASS_Z);
+ eevee_render_color_result(
+ rl, viewname, rect, RE_PASSNAME_Z, 1, vedata->fbl->renderpass_fb, vedata);
}
}
@@ -391,29 +307,12 @@ static void eevee_render_result_mist(RenderLayer *rl,
const char *viewname,
const rcti *rect,
EEVEE_Data *vedata,
- EEVEE_ViewLayerData *UNUSED(sldata),
- int render_samples)
+ EEVEE_ViewLayerData *sldata)
{
- const DRWContextState *draw_ctx = DRW_context_state_get();
- ViewLayer *view_layer = draw_ctx->view_layer;
-
- if ((view_layer->passflag & SCE_PASS_MIST) != 0) {
- RenderPass *rp = RE_pass_find_by_name(rl, RE_PASSNAME_MIST, viewname);
-
- GPU_framebuffer_bind(vedata->fbl->mist_accum_fb);
- GPU_framebuffer_read_color(vedata->fbl->mist_accum_fb,
- vedata->stl->g_data->overscan_pixels + rect->xmin,
- vedata->stl->g_data->overscan_pixels + rect->ymin,
- BLI_rcti_size_x(rect),
- BLI_rcti_size_y(rect),
- 1,
- 0,
- rp->rect);
-
- /* This is the accumulated color. Divide by the number of samples. */
- for (int i = 0; i < rp->rectx * rp->recty; i++) {
- rp->rect[i] /= (float)render_samples;
- }
+ if ((vedata->stl->g_data->render_passes & SCE_PASS_MIST) != 0) {
+ EEVEE_renderpasses_postprocess(sldata, vedata, SCE_PASS_MIST);
+ eevee_render_color_result(
+ rl, viewname, rect, RE_PASSNAME_MIST, 1, vedata->fbl->renderpass_fb, vedata);
}
}
@@ -421,35 +320,17 @@ static void eevee_render_result_occlusion(RenderLayer *rl,
const char *viewname,
const rcti *rect,
EEVEE_Data *vedata,
- EEVEE_ViewLayerData *UNUSED(sldata),
- int render_samples)
+ EEVEE_ViewLayerData *sldata)
{
- const DRWContextState *draw_ctx = DRW_context_state_get();
- ViewLayer *view_layer = draw_ctx->view_layer;
-
if (vedata->fbl->ao_accum_fb == NULL) {
/* AO is not enabled. */
return;
}
- if ((view_layer->passflag & SCE_PASS_AO) != 0) {
- RenderPass *rp = RE_pass_find_by_name(rl, RE_PASSNAME_AO, viewname);
-
- GPU_framebuffer_bind(vedata->fbl->ao_accum_fb);
- GPU_framebuffer_read_color(vedata->fbl->ao_accum_fb,
- vedata->stl->g_data->overscan_pixels + rect->xmin,
- vedata->stl->g_data->overscan_pixels + rect->ymin,
- BLI_rcti_size_x(rect),
- BLI_rcti_size_y(rect),
- 3,
- 0,
- rp->rect);
-
- /* This is the accumulated color. Divide by the number of samples. */
- for (int i = 0; i < rp->rectx * rp->recty * 3; i += 3) {
- rp->rect[i] = rp->rect[i + 1] = rp->rect[i + 2] = min_ff(
- 1.0f, rp->rect[i] / (float)render_samples);
- }
+ if ((vedata->stl->g_data->render_passes & SCE_PASS_AO) != 0) {
+ EEVEE_renderpasses_postprocess(sldata, vedata, SCE_PASS_AO);
+ eevee_render_color_result(
+ rl, viewname, rect, RE_PASSNAME_AO, 3, vedata->fbl->renderpass_fb, vedata);
}
}
@@ -488,7 +369,6 @@ void EEVEE_render_draw(EEVEE_Data *vedata, RenderEngine *engine, RenderLayer *rl
{
const DRWContextState *draw_ctx = DRW_context_state_get();
const Scene *scene_eval = DEG_get_evaluated_scene(draw_ctx->depsgraph);
- ViewLayer *view_layer = draw_ctx->view_layer;
const char *viewname = RE_GetActiveRenderView(engine->re);
EEVEE_PassList *psl = vedata->psl;
EEVEE_StorageList *stl = vedata->stl;
@@ -517,31 +397,20 @@ void EEVEE_render_draw(EEVEE_Data *vedata, RenderEngine *engine, RenderLayer *rl
GPU_framebuffer_bind(fbl->main_fb);
DRW_hair_update();
- if ((view_layer->passflag & (SCE_PASS_SUBSURFACE_COLOR | SCE_PASS_SUBSURFACE_DIRECT |
- SCE_PASS_SUBSURFACE_INDIRECT)) != 0) {
- EEVEE_subsurface_output_init(sldata, vedata);
- }
-
- if ((view_layer->passflag & SCE_PASS_MIST) != 0) {
- EEVEE_mist_output_init(sldata, vedata);
- }
-
- if ((view_layer->passflag & SCE_PASS_AO) != 0) {
- EEVEE_occlusion_output_init(sldata, vedata);
- }
-
uint tot_sample = scene_eval->eevee.taa_render_samples;
uint render_samples = 0;
- if (RE_engine_test_break(engine)) {
- return;
- }
-
/* SSR needs one iteration to start properly. */
if (stl->effects->enabled_effects & EFFECT_SSR) {
tot_sample += 1;
}
+ EEVEE_renderpasses_output_init(sldata, vedata, tot_sample);
+
+ if (RE_engine_test_break(engine)) {
+ return;
+ }
+
while (render_samples < tot_sample && !RE_engine_test_break(engine)) {
float clear_col[4] = {0.0f, 0.0f, 0.0f, 0.0f};
float clear_depth = 1.0f;
@@ -616,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);
@@ -644,9 +509,9 @@ 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, render_samples);
- eevee_render_result_mist(rl, viewname, rect, vedata, sldata, render_samples);
- eevee_render_result_occlusion(rl, viewname, rect, vedata, sldata, render_samples);
+ 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);
/* Restore original viewport size. */
DRW_render_viewport_size_set((int[2]){g_data->size_orig[0], g_data->size_orig[1]});
diff --git a/source/blender/draw/engines/eevee/eevee_renderpasses.c b/source/blender/draw/engines/eevee/eevee_renderpasses.c
new file mode 100644
index 00000000000..927ff70a52b
--- /dev/null
+++ b/source/blender/draw/engines/eevee/eevee_renderpasses.c
@@ -0,0 +1,278 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Copyright 2019, Blender Foundation.
+ */
+
+/** \file
+ * \ingroup draw_engine
+ */
+
+#include "DRW_engine.h"
+#include "DRW_render.h"
+
+#include "BLI_string_utils.h"
+
+#include "DEG_depsgraph_query.h"
+
+#include "eevee_private.h"
+
+extern char datatoc_common_view_lib_glsl[];
+extern char datatoc_common_uniforms_lib_glsl[];
+extern char datatoc_bsdf_common_lib_glsl[];
+extern char datatoc_renderpass_postprocess_frag_glsl[];
+
+static struct {
+ struct GPUShader *postprocess_sh;
+} e_data = {NULL}; /* Engine data */
+
+/* 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)
+
+#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;
+
+ 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,
+ EEVEE_Data *vedata,
+ uint tot_samples)
+{
+ EEVEE_FramebufferList *fbl = vedata->fbl;
+ EEVEE_TextureList *txl = vedata->txl;
+ EEVEE_PassList *psl = vedata->psl;
+ EEVEE_StorageList *stl = vedata->stl;
+ EEVEE_PrivateData *g_data = stl->g_data;
+
+ const bool needs_post_processing = (g_data->render_passes &
+ EEVEE_RENDERPASSES_WITH_POST_PROCESSING) > 0;
+ if (needs_post_processing) {
+ if (e_data.postprocess_sh == NULL) {
+ char *frag_str = BLI_string_joinN(datatoc_common_view_lib_glsl,
+ datatoc_common_uniforms_lib_glsl,
+ datatoc_bsdf_common_lib_glsl,
+ datatoc_renderpass_postprocess_frag_glsl);
+ e_data.postprocess_sh = DRW_shader_create_fullscreen(frag_str, NULL);
+ MEM_freeN(frag_str);
+ }
+
+ /* Create FrameBuffer. */
+
+ /* 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 */
+ 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 & SCE_PASS_MIST) != 0) {
+ EEVEE_mist_output_init(sldata, vedata);
+ }
+
+ if ((g_data->render_passes & SCE_PASS_AO) != 0) {
+ EEVEE_occlusion_output_init(sldata, vedata, tot_samples);
+ }
+
+ /* Create Pass. */
+ DRW_PASS_CREATE(psl->renderpass_pass, DRW_STATE_WRITE_COLOR);
+ }
+ else {
+ /* Free unneeded memory */
+ DRW_TEXTURE_FREE_SAFE(txl->renderpass);
+ GPU_FRAMEBUFFER_FREE_SAFE(fbl->renderpass_fb);
+ psl->renderpass_pass = NULL;
+ }
+}
+
+/* Postprocess data to construct a specific renderpass
+ *
+ * This method will create a shading group to perform the post-processing for the given
+ * `renderpass_type`. The post-processing will be done and the result will be stored in the
+ * `vedata->txl->renderpass` texture.
+ *
+ * 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 *sldata,
+ EEVEE_Data *vedata,
+ eScenePassType renderpass_type)
+{
+ EEVEE_PassList *psl = vedata->psl;
+ EEVEE_TextureList *txl = vedata->txl;
+ EEVEE_StorageList *stl = vedata->stl;
+ EEVEE_FramebufferList *fbl = vedata->fbl;
+ EEVEE_EffectsInfo *effects = stl->effects;
+ DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
+
+ const int current_sample = effects->taa_current_sample;
+
+ DRWShadingGroup *shgrp = DRW_shgroup_create(e_data.postprocess_sh, psl->renderpass_pass);
+ DRW_shgroup_uniform_int_copy(shgrp, "renderpassType", renderpass_type);
+
+ switch (renderpass_type) {
+ case SCE_PASS_Z: {
+ DRW_shgroup_uniform_block(shgrp, "common_block", sldata->common_ubo);
+ DRW_shgroup_uniform_texture_ref(shgrp, "depthBuffer", &dtxl->depth);
+ break;
+ }
+
+ 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;
+ }
+
+ case SCE_PASS_SUBSURFACE_DIRECT: {
+ DRW_shgroup_uniform_texture_ref(shgrp, "inputBuffer", &txl->sss_dir_accum);
+ DRW_shgroup_uniform_int_copy(shgrp, "currentSample", current_sample);
+ break;
+ }
+
+ case SCE_PASS_SUBSURFACE_COLOR: {
+ DRW_shgroup_uniform_texture_ref(shgrp, "inputBuffer", &txl->sss_col_accum);
+ DRW_shgroup_uniform_int_copy(shgrp, "currentSample", current_sample);
+ break;
+ }
+
+ default: {
+ break;
+ }
+ }
+
+ DRW_shgroup_call(shgrp, DRW_cache_fullscreen_quad_get(), NULL);
+
+ /* only draw the shading group that has been added. This function can be called multiple times
+ * and the pass still hold the previous shading groups.*/
+ GPU_framebuffer_bind(fbl->renderpass_fb);
+ 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 = (render_pass & EEVEE_RENDERPASSES_ALL) > 0;
+ 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 8376b8c67b8..e94fc903694 100644
--- a/source/blender/draw/engines/eevee/eevee_subsurface.c
+++ b/source/blender/draw/engines/eevee/eevee_subsurface.c
@@ -156,7 +156,9 @@ 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)
+void EEVEE_subsurface_output_init(EEVEE_ViewLayerData *UNUSED(sldata),
+ EEVEE_Data *vedata,
+ uint tot_samples)
{
EEVEE_FramebufferList *fbl = vedata->fbl;
EEVEE_TextureList *txl = vedata->txl;
@@ -164,8 +166,10 @@ void EEVEE_subsurface_output_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Dat
EEVEE_EffectsInfo *effects = stl->effects;
if (effects->enabled_effects & EFFECT_SSS) {
- DRW_texture_ensure_fullscreen_2d(&txl->sss_dir_accum, GPU_RGBA16F, 0);
- DRW_texture_ensure_fullscreen_2d(&txl->sss_col_accum, GPU_RGBA16F, 0);
+ 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;
@@ -183,9 +187,11 @@ void EEVEE_subsurface_output_init(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Dat
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 |
@@ -253,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
new file mode 100644
index 00000000000..5a738d0f130
--- /dev/null
+++ b/source/blender/draw/engines/eevee/shaders/renderpass_postprocess_frag.glsl
@@ -0,0 +1,64 @@
+#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 ACCUMULATED_COLOR_PASSES (SCE_PASS_SUBSURFACE_DIRECT | SCE_PASS_SUBSURFACE_COLOR)
+#define ACCUMULATED_VALUE_PASSES (SCE_PASS_MIST)
+uniform int renderpassType;
+uniform int currentSample;
+uniform sampler2D inputBuffer;
+
+out vec4 fragColor;
+
+void main()
+{
+ ivec2 texel = ivec2(gl_FragCoord.xy);
+
+ if (renderpassType == SCE_PASS_Z) {
+ float depth = texelFetch(depthBuffer, texel, 0).r;
+ if (depth == 1.0f) {
+ depth = 1e10;
+ }
+ else {
+ depth = -get_view_z_from_depth(depth);
+ }
+ fragColor.r = depth;
+ }
+
+ else if (renderpassType == SCE_PASS_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) {
+ 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 (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, 1.0);
+ }
+ else {
+ 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 = vec4(vec3(accumulated_value / currentSample), 1.0);
+ }
+
+ else if ((renderpassType & ACCUMULATED_COLOR_PASSES) != 0) {
+ vec3 accumulated_color = texelFetch(inputBuffer, texel, 0).rgb;
+ fragColor = vec4(accumulated_color / currentSample, 1.0);
+ }
+
+ else {
+ fragColor = vec4(1.0, 0.0, 1.0, 1.0);
+ }
+} \ No newline at end of file