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_data.c3
-rw-r--r--source/blender/draw/engines/eevee/eevee_materials.c119
-rw-r--r--source/blender/draw/engines/eevee/eevee_private.h19
-rw-r--r--source/blender/draw/engines/eevee/eevee_render.c60
-rw-r--r--source/blender/draw/engines/eevee/eevee_renderpasses.c53
-rw-r--r--source/blender/draw/engines/eevee/shaders/renderpass_lib.glsl13
-rw-r--r--source/blender/draw/engines/eevee/shaders/renderpass_postprocess_frag.glsl37
7 files changed, 251 insertions, 53 deletions
diff --git a/source/blender/draw/engines/eevee/eevee_data.c b/source/blender/draw/engines/eevee/eevee_data.c
index 5c4ee015c86..47068d0b843 100644
--- a/source/blender/draw/engines/eevee/eevee_data.c
+++ b/source/blender/draw/engines/eevee/eevee_data.c
@@ -240,6 +240,9 @@ void EEVEE_view_layer_data_free(void *storage)
DRW_UBO_FREE_SAFE(sldata->renderpass_ubo.spec_light);
DRW_UBO_FREE_SAFE(sldata->renderpass_ubo.emit);
DRW_UBO_FREE_SAFE(sldata->renderpass_ubo.environment);
+ for (int aov_index = 0; aov_index < MAX_AOVS; aov_index++) {
+ DRW_UBO_FREE_SAFE(sldata->renderpass_ubo.aovs[aov_index]);
+ }
if (sldata->material_cache) {
BLI_memblock_destroy(sldata->material_cache, NULL);
diff --git a/source/blender/draw/engines/eevee/eevee_materials.c b/source/blender/draw/engines/eevee/eevee_materials.c
index 58f182ecf8d..c7a8f7729eb 100644
--- a/source/blender/draw/engines/eevee/eevee_materials.c
+++ b/source/blender/draw/engines/eevee/eevee_materials.c
@@ -244,31 +244,31 @@ void EEVEE_materials_init(EEVEE_ViewLayerData *sldata,
/* Create RenderPass UBO */
if (sldata->renderpass_ubo.combined == NULL) {
EEVEE_RenderPassData data;
- data = (EEVEE_RenderPassData){true, true, true, true, true, false, false};
+ data = (EEVEE_RenderPassData){true, true, true, true, true, false, false, false, 0};
sldata->renderpass_ubo.combined = GPU_uniformbuf_create_ex(
sizeof(data), &data, "renderpass_ubo.combined");
- data = (EEVEE_RenderPassData){true, false, false, false, false, true, false};
+ data = (EEVEE_RenderPassData){true, false, false, false, false, true, false, false, 0};
sldata->renderpass_ubo.diff_color = GPU_uniformbuf_create_ex(
sizeof(data), &data, "renderpass_ubo.diff_color");
- data = (EEVEE_RenderPassData){true, true, false, false, false, false, false};
+ data = (EEVEE_RenderPassData){true, true, false, false, false, false, false, false, 0};
sldata->renderpass_ubo.diff_light = GPU_uniformbuf_create_ex(
sizeof(data), &data, "renderpass_ubo.diff_light");
- data = (EEVEE_RenderPassData){false, false, true, false, false, false, false};
+ data = (EEVEE_RenderPassData){false, false, true, false, false, false, false, false, 0};
sldata->renderpass_ubo.spec_color = GPU_uniformbuf_create_ex(
sizeof(data), &data, "renderpass_ubo.spec_color");
- data = (EEVEE_RenderPassData){false, false, true, true, false, false, false};
+ data = (EEVEE_RenderPassData){false, false, true, true, false, false, false, false, 0};
sldata->renderpass_ubo.spec_light = GPU_uniformbuf_create_ex(
sizeof(data), &data, "renderpass_ubo.spec_light");
- data = (EEVEE_RenderPassData){false, false, false, false, true, false, false};
+ data = (EEVEE_RenderPassData){false, false, false, false, true, false, false, false, 0};
sldata->renderpass_ubo.emit = GPU_uniformbuf_create_ex(
sizeof(data), &data, "renderpass_ubo.emit");
- data = (EEVEE_RenderPassData){true, true, true, true, true, false, true};
+ data = (EEVEE_RenderPassData){true, true, true, true, true, false, true, false, 0};
sldata->renderpass_ubo.environment = GPU_uniformbuf_create_ex(
sizeof(data), &data, "renderpass_ubo.environment");
}
@@ -276,6 +276,51 @@ void EEVEE_materials_init(EEVEE_ViewLayerData *sldata,
/* Used combined pass by default. */
g_data->renderpass_ubo = sldata->renderpass_ubo.combined;
+ {
+ g_data->num_aovs_used = 0;
+ if ((stl->g_data->render_passes & EEVEE_RENDER_PASS_AOV) != 0) {
+ EEVEE_RenderPassData data = {true, true, true, true, true, false, false, true, 0};
+ if (stl->g_data->aov_hash == EEVEE_AOV_HASH_ALL) {
+ ViewLayer *view_layer = draw_ctx->view_layer;
+ int aov_index = 0;
+ LISTBASE_FOREACH (ViewLayerAOV *, aov, &view_layer->aovs) {
+ if ((aov->flag & AOV_CONFLICT) != 0) {
+ continue;
+ }
+ if (aov_index == MAX_AOVS) {
+ break;
+ }
+ data.renderPassAOVActive = EEVEE_renderpasses_aov_hash(aov);
+ if (sldata->renderpass_ubo.aovs[aov_index]) {
+ GPU_uniformbuf_update(sldata->renderpass_ubo.aovs[aov_index], &data);
+ }
+ else {
+ sldata->renderpass_ubo.aovs[aov_index] = GPU_uniformbuf_create_ex(
+ sizeof(data), &data, "renderpass_ubo.aovs");
+ }
+ aov_index++;
+ }
+ g_data->num_aovs_used = aov_index;
+ }
+ else {
+ /* Rendering a single AOV in the 3d viewport */
+ data.renderPassAOVActive = stl->g_data->aov_hash;
+ if (sldata->renderpass_ubo.aovs[0]) {
+ GPU_uniformbuf_update(sldata->renderpass_ubo.aovs[0], &data);
+ }
+ else {
+ sldata->renderpass_ubo.aovs[0] = GPU_uniformbuf_create_ex(
+ sizeof(data), &data, "renderpass_ubo.aovs");
+ }
+ g_data->num_aovs_used = 1;
+ }
+ }
+ /* Free AOV UBO's that are not in use. */
+ for (int aov_index = g_data->num_aovs_used; aov_index < MAX_AOVS; aov_index++) {
+ DRW_UBO_FREE_SAFE(sldata->renderpass_ubo.aovs[aov_index]);
+ }
+ }
+
/* HACK: EEVEE_material_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
@@ -949,6 +994,11 @@ void EEVEE_material_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata,
if (pd->render_passes & EEVEE_RENDER_PASS_SPECULAR_COLOR) {
material_renderpass_init(fbl, &txl->spec_color_accum, texture_format, do_clear);
}
+ if (pd->render_passes & EEVEE_RENDER_PASS_AOV) {
+ for (int aov_index = 0; aov_index < pd->num_aovs_used; aov_index++) {
+ material_renderpass_init(fbl, &txl->aov_surface_accum[aov_index], texture_format, do_clear);
+ }
+ }
if (pd->render_passes & EEVEE_RENDER_PASS_SPECULAR_LIGHT) {
material_renderpass_init(fbl, &txl->spec_light_accum, texture_format, do_clear);
@@ -960,6 +1010,7 @@ void EEVEE_material_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata,
static void material_renderpass_accumulate(EEVEE_FramebufferList *fbl,
DRWPass *renderpass,
+ DRWPass *renderpass2,
EEVEE_PrivateData *pd,
GPUTexture *output_tx,
struct GPUUniformBuf *renderpass_option_ubo)
@@ -969,6 +1020,9 @@ static void material_renderpass_accumulate(EEVEE_FramebufferList *fbl,
pd->renderpass_ubo = renderpass_option_ubo;
DRW_draw_pass(renderpass);
+ if (renderpass2) {
+ DRW_draw_pass(renderpass2);
+ }
GPU_framebuffer_texture_detach(fbl->material_accum_fb, output_tx);
}
@@ -983,38 +1037,69 @@ void EEVEE_material_output_accumulate(EEVEE_ViewLayerData *sldata, EEVEE_Data *v
if (fbl->material_accum_fb != NULL) {
DRWPass *material_accum_ps = psl->material_accum_ps;
+ DRWPass *background_accum_ps = psl->background_accum_ps;
if (pd->render_passes & EEVEE_RENDER_PASS_ENVIRONMENT) {
material_renderpass_accumulate(
- fbl, psl->background_accum_ps, pd, txl->env_accum, sldata->renderpass_ubo.environment);
+ fbl, background_accum_ps, NULL, pd, txl->env_accum, sldata->renderpass_ubo.environment);
}
if (pd->render_passes & EEVEE_RENDER_PASS_EMIT) {
material_renderpass_accumulate(
- fbl, material_accum_ps, pd, txl->emit_accum, sldata->renderpass_ubo.emit);
+ fbl, material_accum_ps, NULL, pd, txl->emit_accum, sldata->renderpass_ubo.emit);
}
if (pd->render_passes & EEVEE_RENDER_PASS_DIFFUSE_COLOR) {
- material_renderpass_accumulate(
- fbl, material_accum_ps, pd, txl->diff_color_accum, sldata->renderpass_ubo.diff_color);
+ material_renderpass_accumulate(fbl,
+ material_accum_ps,
+ NULL,
+ pd,
+ txl->diff_color_accum,
+ sldata->renderpass_ubo.diff_color);
}
if (pd->render_passes & EEVEE_RENDER_PASS_DIFFUSE_LIGHT) {
- material_renderpass_accumulate(
- fbl, material_accum_ps, pd, txl->diff_light_accum, sldata->renderpass_ubo.diff_light);
+ material_renderpass_accumulate(fbl,
+ material_accum_ps,
+ NULL,
+ pd,
+ txl->diff_light_accum,
+ sldata->renderpass_ubo.diff_light);
if (effects->enabled_effects & EFFECT_SSS) {
EEVEE_subsurface_output_accumulate(sldata, vedata);
}
}
if (pd->render_passes & EEVEE_RENDER_PASS_SPECULAR_COLOR) {
- material_renderpass_accumulate(
- fbl, material_accum_ps, pd, txl->spec_color_accum, sldata->renderpass_ubo.spec_color);
+ material_renderpass_accumulate(fbl,
+ material_accum_ps,
+ NULL,
+ pd,
+ txl->spec_color_accum,
+ sldata->renderpass_ubo.spec_color);
}
if (pd->render_passes & EEVEE_RENDER_PASS_SPECULAR_LIGHT) {
- material_renderpass_accumulate(
- fbl, material_accum_ps, pd, txl->spec_light_accum, sldata->renderpass_ubo.spec_light);
+ material_renderpass_accumulate(fbl,
+ material_accum_ps,
+ NULL,
+ pd,
+ txl->spec_light_accum,
+ sldata->renderpass_ubo.spec_light);
if (effects->enabled_effects & EFFECT_SSR) {
EEVEE_reflection_output_accumulate(sldata, vedata);
}
}
+ if (pd->render_passes & EEVEE_RENDER_PASS_AOV) {
+ for (int aov_index = 0; aov_index < pd->num_aovs_used; aov_index++) {
+ material_renderpass_accumulate(fbl,
+ material_accum_ps,
+ background_accum_ps,
+ pd,
+ txl->aov_surface_accum[aov_index],
+ sldata->renderpass_ubo.aovs[aov_index]);
+ }
+ }
+ /* Free unused aov textures. */
+ for (int aov_index = pd->num_aovs_used; aov_index < MAX_AOVS; aov_index++) {
+ DRW_TEXTURE_FREE_SAFE(txl->aov_surface_accum[aov_index]);
+ }
/* Restore default. */
pd->renderpass_ubo = sldata->renderpass_ubo.combined;
diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h
index f5cef8f3c25..1385721a569 100644
--- a/source/blender/draw/engines/eevee/eevee_private.h
+++ b/source/blender/draw/engines/eevee/eevee_private.h
@@ -53,6 +53,7 @@ extern struct DrawEngineType draw_engine_eevee_type;
#define MAX_SHADOW_CASCADE 8
#define MAX_SHADOW_CUBE (MAX_SHADOW - MAX_CASCADE_NUM * MAX_SHADOW_CASCADE)
#define MAX_BLOOM_STEP 16
+#define MAX_AOVS 64
// #define DEBUG_SHADOW_DISTRIBUTION
@@ -163,8 +164,9 @@ BLI_INLINE bool eevee_hdri_preview_overlay_enabled(const View3D *v3d)
#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)
-
+ EEVEE_RENDER_PASS_ENVIRONMENT | EEVEE_RENDER_PASS_AOV)
+#define EEVEE_AOV_HASH_ALL -1
+#define EEVEE_AOV_HASH_COLOR_TYPE_MASK 1
/* Material shader variations */
enum {
VAR_MAT_MESH = (1 << 0),
@@ -376,6 +378,7 @@ typedef struct EEVEE_TextureList {
struct GPUTexture *diff_light_accum;
struct GPUTexture *spec_color_accum;
struct GPUTexture *spec_light_accum;
+ struct GPUTexture *aov_surface_accum[MAX_AOVS];
struct GPUTexture *emit_accum;
struct GPUTexture *bloom_accum;
struct GPUTexture *ssr_accum;
@@ -430,7 +433,9 @@ typedef struct EEVEE_RenderPassData {
int renderPassEmit;
int renderPassSSSColor;
int renderPassEnvironment;
- int _pad[1];
+ int renderPassAOV;
+ int renderPassAOVActive;
+ int _pad[3];
} EEVEE_RenderPassData;
/* ************ LIGHT UBO ************* */
@@ -860,6 +865,7 @@ typedef struct EEVEE_ViewLayerData {
struct GPUUniformBuf *spec_color;
struct GPUUniformBuf *spec_light;
struct GPUUniformBuf *emit;
+ struct GPUUniformBuf *aovs[MAX_AOVS];
} renderpass_ubo;
/* Common Uniform Buffer */
@@ -959,6 +965,9 @@ typedef struct EEVEE_PrivateData {
/* Renderpasses */
/* Bitmask containing the active render_passes */
eViewLayerEEVEEPassType render_passes;
+ int aov_hash;
+ int num_aovs_used;
+
/* Uniform references that are referenced inside the `renderpass_pass`. They are updated
* to reuse the drawing pass and the shading group. */
int renderpass_type;
@@ -1284,10 +1293,12 @@ void EEVEE_renderpasses_output_accumulate(EEVEE_ViewLayerData *sldata,
bool post_effect);
void EEVEE_renderpasses_postprocess(EEVEE_ViewLayerData *sldata,
EEVEE_Data *vedata,
- eViewLayerEEVEEPassType renderpass_type);
+ eViewLayerEEVEEPassType renderpass_type,
+ int aov_index);
void EEVEE_renderpasses_draw(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_renderpasses_draw_debug(EEVEE_Data *vedata);
bool EEVEE_renderpasses_only_first_sample_pass_active(EEVEE_Data *vedata);
+int EEVEE_renderpasses_aov_hash(const ViewLayerAOV *aov);
/* 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 504e4e1d336..32e6eac2402 100644
--- a/source/blender/draw/engines/eevee/eevee_render.c
+++ b/source/blender/draw/engines/eevee/eevee_render.c
@@ -301,7 +301,7 @@ static void eevee_render_result_normal(RenderLayer *rl,
}
if ((vedata->stl->g_data->render_passes & EEVEE_RENDER_PASS_NORMAL) != 0) {
- EEVEE_renderpasses_postprocess(sldata, vedata, EEVEE_RENDER_PASS_NORMAL);
+ EEVEE_renderpasses_postprocess(sldata, vedata, EEVEE_RENDER_PASS_NORMAL, 0);
eevee_render_color_result(
rl, viewname, rect, RE_PASSNAME_NORMAL, 3, vedata->fbl->renderpass_fb, vedata);
}
@@ -321,7 +321,7 @@ static void eevee_render_result_z(RenderLayer *rl,
}
if ((vedata->stl->g_data->render_passes & EEVEE_RENDER_PASS_Z) != 0) {
- EEVEE_renderpasses_postprocess(sldata, vedata, EEVEE_RENDER_PASS_Z);
+ EEVEE_renderpasses_postprocess(sldata, vedata, EEVEE_RENDER_PASS_Z, 0);
eevee_render_color_result(
rl, viewname, rect, RE_PASSNAME_Z, 1, vedata->fbl->renderpass_fb, vedata);
}
@@ -334,7 +334,7 @@ static void eevee_render_result_mist(RenderLayer *rl,
EEVEE_ViewLayerData *sldata)
{
if ((vedata->stl->g_data->render_passes & EEVEE_RENDER_PASS_MIST) != 0) {
- EEVEE_renderpasses_postprocess(sldata, vedata, EEVEE_RENDER_PASS_MIST);
+ EEVEE_renderpasses_postprocess(sldata, vedata, EEVEE_RENDER_PASS_MIST, 0);
eevee_render_color_result(
rl, viewname, rect, RE_PASSNAME_MIST, 1, vedata->fbl->renderpass_fb, vedata);
}
@@ -347,7 +347,7 @@ static void eevee_render_result_shadow(RenderLayer *rl,
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_renderpasses_postprocess(sldata, vedata, EEVEE_RENDER_PASS_SHADOW, 0);
eevee_render_color_result(
rl, viewname, rect, RE_PASSNAME_SHADOW, 3, vedata->fbl->renderpass_fb, vedata);
}
@@ -360,7 +360,7 @@ static void eevee_render_result_occlusion(RenderLayer *rl,
EEVEE_ViewLayerData *sldata)
{
if ((vedata->stl->g_data->render_passes & EEVEE_RENDER_PASS_AO) != 0) {
- EEVEE_renderpasses_postprocess(sldata, vedata, EEVEE_RENDER_PASS_AO);
+ EEVEE_renderpasses_postprocess(sldata, vedata, EEVEE_RENDER_PASS_AO, 0);
eevee_render_color_result(
rl, viewname, rect, RE_PASSNAME_AO, 3, vedata->fbl->renderpass_fb, vedata);
}
@@ -378,7 +378,7 @@ static void eevee_render_result_bloom(RenderLayer *rl,
}
if ((vedata->stl->g_data->render_passes & EEVEE_RENDER_PASS_BLOOM) != 0) {
- EEVEE_renderpasses_postprocess(sldata, vedata, EEVEE_RENDER_PASS_BLOOM);
+ EEVEE_renderpasses_postprocess(sldata, vedata, EEVEE_RENDER_PASS_BLOOM, 0);
eevee_render_color_result(
rl, viewname, rect, RE_PASSNAME_BLOOM, 3, vedata->fbl->renderpass_fb, vedata);
}
@@ -386,7 +386,7 @@ static void eevee_render_result_bloom(RenderLayer *rl,
#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_renderpasses_postprocess(sldata, vedata, EEVEE_RENDER_PASS_##eevee_pass_type, 0); \
eevee_render_color_result( \
rl, viewname, rect, RE_PASSNAME_##pass_name, 3, vedata->fbl->renderpass_fb, vedata); \
}
@@ -462,6 +462,35 @@ static void eevee_render_result_volume_transmittance(RenderLayer *rl,
EEVEE_RENDER_RESULT_MATERIAL_PASS(VOLUME_TRANSMITTANCE, VOLUME_TRANSMITTANCE)
}
+static void eevee_render_result_aovs(RenderLayer *rl,
+ const char *viewname,
+ const rcti *rect,
+ EEVEE_Data *vedata,
+ EEVEE_ViewLayerData *sldata)
+{
+ if ((vedata->stl->g_data->render_passes & EEVEE_RENDER_PASS_AOV) != 0) {
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ ViewLayer *view_layer = draw_ctx->view_layer;
+ int aov_index = 0;
+ LISTBASE_FOREACH (ViewLayerAOV *, aov, &view_layer->aovs) {
+ if ((aov->flag & AOV_CONFLICT) != 0) {
+ continue;
+ }
+ EEVEE_renderpasses_postprocess(sldata, vedata, EEVEE_RENDER_PASS_AOV, aov_index);
+ switch (aov->type) {
+ case AOV_TYPE_COLOR:
+ eevee_render_color_result(
+ rl, viewname, rect, aov->name, 4, vedata->fbl->renderpass_fb, vedata);
+ break;
+ case AOV_TYPE_VALUE:
+ eevee_render_color_result(
+ rl, viewname, rect, aov->name, 1, vedata->fbl->renderpass_fb, vedata);
+ }
+ aov_index++;
+ }
+ }
+}
+
#undef EEVEE_RENDER_RESULT_MATERIAL_PASS
static void eevee_render_draw_background(EEVEE_Data *vedata)
@@ -641,6 +670,7 @@ void EEVEE_render_read_result(EEVEE_Data *vedata,
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);
+ eevee_render_result_aovs(rl, viewname, rect, vedata, sldata);
}
void EEVEE_render_update_passes(RenderEngine *engine, Scene *scene, ViewLayer *view_layer)
@@ -675,6 +705,22 @@ void EEVEE_render_update_passes(RenderEngine *engine, Scene *scene, ViewLayer *v
CHECK_PASS_EEVEE(VOLUME_TRANSMITTANCE, SOCK_RGBA, 3, "RGB");
CHECK_PASS_EEVEE(BLOOM, SOCK_RGBA, 3, "RGB");
+ LISTBASE_FOREACH (ViewLayerAOV *, aov, &view_layer->aovs) {
+ if ((aov->flag & AOV_CONFLICT) != 0) {
+ continue;
+ }
+ switch (aov->type) {
+ case AOV_TYPE_COLOR:
+ RE_engine_register_pass(engine, scene, view_layer, aov->name, 4, "RGBA", SOCK_RGBA);
+ break;
+ case AOV_TYPE_VALUE:
+ RE_engine_register_pass(engine, scene, view_layer, aov->name, 1, "X", SOCK_FLOAT);
+ break;
+ default:
+ break;
+ }
+ }
+
#undef CHECK_PASS_LEGACY
#undef CHECK_PASS_EEVEE
}
diff --git a/source/blender/draw/engines/eevee/eevee_renderpasses.c b/source/blender/draw/engines/eevee/eevee_renderpasses.c
index be73225b348..3f75f10b204 100644
--- a/source/blender/draw/engines/eevee/eevee_renderpasses.c
+++ b/source/blender/draw/engines/eevee/eevee_renderpasses.c
@@ -27,6 +27,7 @@
#include "BKE_global.h" /* for G.debug_value */
+#include "BLI_hash.h"
#include "BLI_string_utils.h"
#include "DEG_depsgraph_query.h"
@@ -36,12 +37,13 @@
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,
+ PASS_POST_ACCUMULATED_COLOR_ALPHA = 2,
+ PASS_POST_ACCUMULATED_LIGHT = 3,
+ PASS_POST_ACCUMULATED_VALUE = 4,
+ PASS_POST_DEPTH = 5,
+ PASS_POST_AO = 6,
+ PASS_POST_NORMAL = 7,
+ PASS_POST_TWO_LIGHT_BUFFERS = 8,
} eRenderPassPostProcessType;
/* bitmask containing all renderpasses that need post-processing */
@@ -70,6 +72,15 @@ bool EEVEE_renderpasses_only_first_sample_pass_active(EEVEE_Data *vedata)
return (g_data->render_passes & ~EEVEE_RENDERPASSES_POST_PROCESS_ON_FIRST_SAMPLE) == 0;
}
+/* Calculate the hash for an AOV. The least significant bit is used to store the AOV
+ * type the rest of the bits are used for the name hash. */
+int EEVEE_renderpasses_aov_hash(const ViewLayerAOV *aov)
+{
+ int hash = BLI_hash_string(aov->name);
+ SET_FLAG_FROM_TEST(hash, aov->type == AOV_TYPE_COLOR, EEVEE_AOV_HASH_COLOR_TYPE_MASK);
+ return hash;
+}
+
void EEVEE_renderpasses_init(EEVEE_Data *vedata)
{
const DRWContextState *draw_ctx = DRW_context_state_get();
@@ -81,10 +92,24 @@ void EEVEE_renderpasses_init(EEVEE_Data *vedata)
if (v3d) {
const Scene *scene = draw_ctx->scene;
eViewLayerEEVEEPassType render_pass = v3d->shading.render_pass;
+ g_data->aov_hash = 0;
+
if (render_pass == EEVEE_RENDER_PASS_BLOOM &&
((scene->eevee.flag & SCE_EEVEE_BLOOM_ENABLED) == 0)) {
render_pass = EEVEE_RENDER_PASS_COMBINED;
}
+ if (render_pass == EEVEE_RENDER_PASS_AOV) {
+ ViewLayerAOV *aov = BLI_findstring(
+ &view_layer->aovs, v3d->shading.aov_name, offsetof(ViewLayerAOV, name));
+ if (aov != NULL) {
+ g_data->aov_hash = EEVEE_renderpasses_aov_hash(aov);
+ }
+ else {
+ /* AOV not found in view layer. */
+ render_pass = EEVEE_RENDER_PASS_COMBINED;
+ }
+ }
+
g_data->render_passes = render_pass;
}
else {
@@ -110,10 +135,14 @@ void EEVEE_renderpasses_init(EEVEE_Data *vedata)
ENABLE_FROM_LEGACY(ENVIRONMENT, ENVIRONMENT)
#undef ENABLE_FROM_LEGACY
+ if (DRW_state_is_image_render() && !BLI_listbase_is_empty(&view_layer->aovs)) {
+ enabled_render_passes |= EEVEE_RENDER_PASS_AOV;
+ g_data->aov_hash = EEVEE_AOV_HASH_ALL;
+ }
+
g_data->render_passes = (enabled_render_passes & EEVEE_RENDERPASSES_ALL) |
EEVEE_RENDER_PASS_COMBINED;
}
-
EEVEE_material_renderpasses_init(vedata);
}
@@ -216,7 +245,8 @@ void EEVEE_renderpasses_cache_finish(EEVEE_ViewLayerData *sldata, EEVEE_Data *ve
* After invoking this function the active frame-buffer is set to `vedata->fbl->renderpass_fb`. */
void EEVEE_renderpasses_postprocess(EEVEE_ViewLayerData *UNUSED(sldata),
EEVEE_Data *vedata,
- eViewLayerEEVEEPassType renderpass_type)
+ eViewLayerEEVEEPassType renderpass_type,
+ int aov_index)
{
EEVEE_PassList *psl = vedata->psl;
EEVEE_TextureList *txl = vedata->txl;
@@ -311,6 +341,11 @@ void EEVEE_renderpasses_postprocess(EEVEE_ViewLayerData *UNUSED(sldata),
}
break;
}
+ case EEVEE_RENDER_PASS_AOV: {
+ g_data->renderpass_postprocess = PASS_POST_ACCUMULATED_COLOR_ALPHA;
+ g_data->renderpass_input = txl->aov_surface_accum[aov_index];
+ break;
+ }
case EEVEE_RENDER_PASS_BLOOM: {
g_data->renderpass_postprocess = PASS_POST_ACCUMULATED_COLOR;
g_data->renderpass_input = txl->bloom_accum;
@@ -392,7 +427,7 @@ void EEVEE_renderpasses_draw(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
}
if (is_valid) {
- EEVEE_renderpasses_postprocess(sldata, vedata, render_pass);
+ EEVEE_renderpasses_postprocess(sldata, vedata, render_pass, 0);
GPU_framebuffer_bind(dfbl->default_fb);
DRW_transform_none(txl->renderpass);
}
diff --git a/source/blender/draw/engines/eevee/shaders/renderpass_lib.glsl b/source/blender/draw/engines/eevee/shaders/renderpass_lib.glsl
index 36cf3cecf40..3e0a5e76d00 100644
--- a/source/blender/draw/engines/eevee/shaders/renderpass_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/renderpass_lib.glsl
@@ -1,3 +1,4 @@
+#define EEVEE_AOV_HASH_COLOR_TYPE_MASK 1
/* ---------------------------------------------------------------------- */
/** \name Resources
@@ -12,6 +13,8 @@ layout(std140) uniform renderpass_block
bool renderPassEmit;
bool renderPassSSSColor;
bool renderPassEnvironment;
+ bool renderPassAOV;
+ int renderPassAOVActive;
};
/** \} */
@@ -40,4 +43,14 @@ vec3 render_pass_emission_mask(vec3 emission_light)
return renderPassEmit ? emission_light : vec3(0.0);
}
+bool render_pass_aov_is_color()
+{
+ return (renderPassAOVActive & EEVEE_AOV_HASH_COLOR_TYPE_MASK) != 0;
+}
+
+int render_pass_aov_hash()
+{
+ return renderPassAOVActive & ~EEVEE_AOV_HASH_COLOR_TYPE_MASK;
+}
+
/** \} */
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 89a411bc7cb..eb6ca4b9de8 100644
--- a/source/blender/draw/engines/eevee/shaders/renderpass_postprocess_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/renderpass_postprocess_frag.glsl
@@ -4,12 +4,13 @@
#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 PASS_POST_ACCUMULATED_COLOR_ALPHA 2
+#define PASS_POST_ACCUMULATED_LIGHT 3
+#define PASS_POST_ACCUMULATED_VALUE 4
+#define PASS_POST_DEPTH 5
+#define PASS_POST_AO 6
+#define PASS_POST_NORMAL 7
+#define PASS_POST_TWO_LIGHT_BUFFERS 8
uniform int postProcessType;
uniform int currentSample;
@@ -55,7 +56,7 @@ vec3 safe_divide_even_color(vec3 a, vec3 b)
void main()
{
- vec3 color;
+ vec4 color = vec4(0.0, 0.0, 0.0, 1.0);
ivec2 texel = ivec2(gl_FragCoord.xy);
if (postProcessType == PASS_POST_DEPTH) {
@@ -66,11 +67,11 @@ void main()
else {
depth = -get_view_z_from_depth(depth);
}
- color = vec3(depth);
+ color.rgb = vec3(depth);
}
else if (postProcessType == PASS_POST_AO) {
float ao_accum = texelFetch(inputBuffer, texel, 0).r;
- color = vec3(min(1.0, ao_accum / currentSample));
+ color.rgb = vec3(min(1.0, ao_accum / currentSample));
}
else if (postProcessType == PASS_POST_NORMAL) {
float depth = texelFetch(depthBuffer, texel, 0).r;
@@ -80,35 +81,39 @@ void main()
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;
- color = world_normal;
+ color.rgb = world_normal;
}
else {
- color = vec3(0.0);
+ color.rgb = vec3(0.0);
}
}
else if (postProcessType == PASS_POST_ACCUMULATED_VALUE) {
float accumulated_value = texelFetch(inputBuffer, texel, 0).r;
- color = vec3(accumulated_value / currentSample);
+ color.rgb = vec3(accumulated_value / currentSample);
}
else if (postProcessType == PASS_POST_ACCUMULATED_COLOR) {
vec3 accumulated_color = texelFetch(inputBuffer, texel, 0).rgb;
+ color.rgb = (accumulated_color / currentSample);
+ }
+ else if (postProcessType == PASS_POST_ACCUMULATED_COLOR_ALPHA) {
+ vec4 accumulated_color = texelFetch(inputBuffer, texel, 0);
color = (accumulated_color / currentSample);
}
else if (postProcessType == PASS_POST_ACCUMULATED_LIGHT) {
vec3 accumulated_light = texelFetch(inputBuffer, texel, 0).rgb;
vec3 accumulated_color = texelFetch(inputColorBuffer, texel, 0).rgb;
- color = safe_divide_even_color(accumulated_light, accumulated_color);
+ color.rgb = safe_divide_even_color(accumulated_light, accumulated_color);
}
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;
- color = safe_divide_even_color(accumulated_light, accumulated_color);
+ color.rgb = safe_divide_even_color(accumulated_light, accumulated_color);
}
else {
/* Output error color: Unknown how to post process this pass. */
- color = vec3(1.0, 0.0, 1.0);
+ color.rgb = vec3(1.0, 0.0, 1.0);
}
- fragColor = vec4(color, 1.0);
+ fragColor = color;
}