From 960b53dbbba9076f2703cd60288baafbc99c0fbd Mon Sep 17 00:00:00 2001 From: Miguel Pozo Date: Tue, 30 May 2023 15:20:52 +0200 Subject: [PATCH] EEVEE Next: Image rendering and render passes fixes/improvements * Fix image rendering. * Fix AOV rendering. * Merge all render passes and AOV textures into 2 arrays (one for colors and one for values). * Make AOVsInfoData std140 compliant. * Remove surface color from Diffuse Light and Specular Light passes. * Add Environment pass support. * Add Shadow pass support. Pull Request: https://projects.blender.org/blender/blender/pulls/108239 --- .../draw/engines/eevee_next/eevee_defines.hh | 23 +++--- .../draw/engines/eevee_next/eevee_film.cc | 26 +++---- .../draw/engines/eevee_next/eevee_instance.cc | 31 ++++++++ .../draw/engines/eevee_next/eevee_pipeline.cc | 48 ++++--------- .../engines/eevee_next/eevee_renderbuffers.cc | 69 +++++++++--------- .../engines/eevee_next/eevee_renderbuffers.hh | 17 ++--- .../draw/engines/eevee_next/eevee_shader.cc | 1 - .../engines/eevee_next/eevee_shader_shared.hh | 39 ++++++---- .../shaders/eevee_deferred_light_frag.glsl | 33 ++++++--- .../eevee_next/shaders/eevee_film_lib.glsl | 72 +++++++++---------- .../shaders/eevee_light_eval_lib.glsl | 13 ++-- .../shaders/eevee_nodetree_lib.glsl | 47 ++++++++++-- .../shaders/eevee_surf_deferred_frag.glsl | 13 ++-- .../shaders/eevee_surf_forward_frag.glsl | 32 +++++---- .../shaders/eevee_surf_world_frag.glsl | 33 ++++++--- .../shaders/infos/eevee_deferred_info.hh | 7 +- .../shaders/infos/eevee_film_info.hh | 20 ++---- .../shaders/infos/eevee_material_info.hh | 34 ++------- 18 files changed, 301 insertions(+), 257 deletions(-) diff --git a/source/blender/draw/engines/eevee_next/eevee_defines.hh b/source/blender/draw/engines/eevee_next/eevee_defines.hh index fd7fd7b55b6..a59e5804acc 100644 --- a/source/blender/draw/engines/eevee_next/eevee_defines.hh +++ b/source/blender/draw/engines/eevee_next/eevee_defines.hh @@ -97,17 +97,11 @@ #define RBUFS_UTILITY_TEX_SLOT 14 /* Images. */ -#define RBUFS_NORMAL_SLOT 0 -#define RBUFS_LIGHT_SLOT 1 -#define RBUFS_DIFF_COLOR_SLOT 2 -#define RBUFS_SPEC_COLOR_SLOT 3 -#define RBUFS_EMISSION_SLOT 4 -#define RBUFS_AOV_COLOR_SLOT 5 -#define RBUFS_AOV_VALUE_SLOT 6 -#define RBUFS_CRYPTOMATTE_SLOT 7 -/* G-buffer reuses render passes slots. */ -#define GBUF_CLOSURE_SLOT RBUFS_LIGHT_SLOT -#define GBUF_COLOR_SLOT RBUFS_DIFF_COLOR_SLOT +#define RBUFS_COLOR_SLOT 0 +#define RBUFS_VALUE_SLOT 1 +#define RBUFS_CRYPTOMATTE_SLOT 2 +#define GBUF_CLOSURE_SLOT 3 +#define GBUF_COLOR_SLOT 4 /* Uniform Buffers. */ /* Only during pre-pass. */ @@ -116,17 +110,16 @@ #define VELOCITY_CAMERA_NEXT_BUF 5 #define CAMERA_BUF_SLOT 6 +#define RBUFS_BUF_SLOT 7 /* Storage Buffers. */ #define LIGHT_CULL_BUF_SLOT 0 #define LIGHT_BUF_SLOT 1 #define LIGHT_ZBIN_BUF_SLOT 2 #define LIGHT_TILE_BUF_SLOT 3 -/* Only during surface shading. */ -#define RBUFS_AOV_BUF_SLOT 5 /* Only during shadow rendering. */ -#define SHADOW_PAGE_INFO_SLOT 5 -#define SAMPLING_BUF_SLOT 6 +#define SHADOW_PAGE_INFO_SLOT 4 +#define SAMPLING_BUF_SLOT 5 #define CRYPTOMATTE_BUF_SLOT 7 /* Only during pre-pass. */ diff --git a/source/blender/draw/engines/eevee_next/eevee_film.cc b/source/blender/draw/engines/eevee_next/eevee_film.cc index 8484c0e4642..5cd3ed02c0a 100644 --- a/source/blender/draw/engines/eevee_next/eevee_film.cc +++ b/source/blender/draw/engines/eevee_next/eevee_film.cc @@ -75,7 +75,7 @@ void Film::init_aovs() for (ViewLayerAOV *aov : aovs) { bool is_value = (aov->type == AOV_TYPE_VALUE); uint &index = is_value ? aovs_info.value_len : aovs_info.color_len; - uint &hash = is_value ? aovs_info.hash_value[index] : aovs_info.hash_color[index]; + uint &hash = is_value ? aovs_info.hash_value[index].x : aovs_info.hash_color[index].x; hash = BLI_hash_string(aov->name); index++; } @@ -86,14 +86,14 @@ float *Film::read_aov(ViewLayerAOV *aov) bool is_value = (aov->type == AOV_TYPE_VALUE); Texture &accum_tx = is_value ? value_accum_tx_ : color_accum_tx_; - Span aovs_hash(is_value ? aovs_info.hash_value : aovs_info.hash_color, - is_value ? aovs_info.value_len : aovs_info.color_len); + Span aovs_hash(is_value ? aovs_info.hash_value : aovs_info.hash_color, + is_value ? aovs_info.value_len : aovs_info.color_len); /* Find AOV index. */ uint hash = BLI_hash_string(aov->name); int aov_index = -1; int i = 0; - for (uint candidate_hash : aovs_hash) { - if (candidate_hash == hash) { + for (uint4 candidate_hash : aovs_hash) { + if (candidate_hash.x == hash) { aov_index = i; break; } @@ -105,6 +105,8 @@ float *Film::read_aov(ViewLayerAOV *aov) int index = aov_index + (is_value ? data_.aov_value_id : data_.aov_color_id); GPUTexture *pass_tx = accum_tx.layer_view(index); + GPU_memory_barrier(GPU_BARRIER_TEXTURE_UPDATE); + return (float *)GPU_texture_read(pass_tx, GPU_DATA_FLOAT, 0); } @@ -431,18 +433,9 @@ void Film::sync() accumulate_ps_.bind_ubo("camera_next", &(*velocity.camera_steps[step_next])); accumulate_ps_.bind_texture("depth_tx", &rbuffers.depth_tx); accumulate_ps_.bind_texture("combined_tx", &combined_final_tx_); - accumulate_ps_.bind_texture("normal_tx", &rbuffers.normal_tx); accumulate_ps_.bind_texture("vector_tx", &rbuffers.vector_tx); - accumulate_ps_.bind_texture("light_tx", &rbuffers.light_tx); - accumulate_ps_.bind_texture("diffuse_color_tx", &rbuffers.diffuse_color_tx); - accumulate_ps_.bind_texture("specular_color_tx", &rbuffers.specular_color_tx); - accumulate_ps_.bind_texture("volume_light_tx", &rbuffers.volume_light_tx); - accumulate_ps_.bind_texture("emission_tx", &rbuffers.emission_tx); - accumulate_ps_.bind_texture("environment_tx", &rbuffers.environment_tx); - accumulate_ps_.bind_texture("shadow_tx", &rbuffers.shadow_tx); - accumulate_ps_.bind_texture("ambient_occlusion_tx", &rbuffers.ambient_occlusion_tx); - accumulate_ps_.bind_texture("aov_color_tx", &rbuffers.aov_color_tx); - accumulate_ps_.bind_texture("aov_value_tx", &rbuffers.aov_value_tx); + accumulate_ps_.bind_texture("rp_color_tx", &rbuffers.rp_color_tx); + accumulate_ps_.bind_texture("rp_value_tx", &rbuffers.rp_value_tx); accumulate_ps_.bind_texture("cryptomatte_tx", &rbuffers.cryptomatte_tx); /* NOTE(@fclem): 16 is the max number of sampled texture in many implementations. * If we need more, we need to pack more of the similar passes in the same textures as arrays or @@ -455,6 +448,7 @@ void Film::sync() accumulate_ps_.bind_image("color_accum_img", &color_accum_tx_); accumulate_ps_.bind_image("value_accum_img", &value_accum_tx_); accumulate_ps_.bind_image("cryptomatte_img", &cryptomatte_tx_); + accumulate_ps_.bind_ubo(RBUFS_BUF_SLOT, &inst_.render_buffers.data); /* Sync with rendering passes. */ accumulate_ps_.barrier(GPU_BARRIER_TEXTURE_FETCH | GPU_BARRIER_SHADER_IMAGE_ACCESS); if (use_compute) { diff --git a/source/blender/draw/engines/eevee_next/eevee_instance.cc b/source/blender/draw/engines/eevee_next/eevee_instance.cc index 575ef7a086d..547d6a9d097 100644 --- a/source/blender/draw/engines/eevee_next/eevee_instance.cc +++ b/source/blender/draw/engines/eevee_next/eevee_instance.cc @@ -118,6 +118,7 @@ void Instance::begin_sync() main_view.sync(); world.sync(); film.sync(); + render_buffers.sync(); irradiance_cache.sync(); } @@ -211,13 +212,20 @@ void Instance::end_sync() void Instance::render_sync() { + /* TODO: Remove old draw manager calls. */ DRW_cache_restart(); + manager->begin_sync(); + begin_sync(); DRW_render_object_iter(this, render, depsgraph, object_sync_render); end_sync(); + manager->end_sync(); + + /* TODO: Remove old draw manager calls. */ DRW_render_instance_buffer_finish(); + /* Also we weed to have a correct FBO bound for #DRW_hair_update */ // GPU_framebuffer_bind(); // DRW_hair_update(); @@ -282,6 +290,29 @@ void Instance::render_read_result(RenderLayer *render_layer, const char *view_na } } + /* AOVs. */ + LISTBASE_FOREACH (ViewLayerAOV *, aov, &view_layer->aovs) { + if ((aov->flag & AOV_CONFLICT) != 0) { + continue; + } + RenderPass *rp = RE_pass_find_by_name(render_layer, aov->name, view_name); + if (!rp) { + continue; + } + float *result = film.read_aov(aov); + + if (result) { + BLI_mutex_lock(&render->update_render_passes_mutex); + /* WORKAROUND: We use texture read to avoid using a framebuffer to get the render result. + * However, on some implementation, we need a buffer with a few extra bytes for the read to + * happen correctly (see GLTexture::read()). So we need a custom memory allocation. */ + /* Avoid memcpy(), replace the pointer directly. */ + MEM_SAFE_FREE(rp->rect); + rp->rect = result; + BLI_mutex_unlock(&render->update_render_passes_mutex); + } + } + /* The vector pass is initialized to weird values. Set it to neutral value if not rendered. */ if ((pass_bits & EEVEE_RENDER_PASS_VECTOR) == 0) { for (std::string vector_pass_name : diff --git a/source/blender/draw/engines/eevee_next/eevee_pipeline.cc b/source/blender/draw/engines/eevee_next/eevee_pipeline.cc index 78ff35136aa..d6ce123cf03 100644 --- a/source/blender/draw/engines/eevee_next/eevee_pipeline.cc +++ b/source/blender/draw/engines/eevee_next/eevee_pipeline.cc @@ -34,21 +34,15 @@ void WorldPipeline::sync(GPUMaterial *gpumat) world_ps_.material_set(manager, gpumat); world_ps_.push_constant("world_opacity_fade", inst_.film.background_opacity_get()); world_ps_.bind_texture("utility_tx", inst_.pipelines.utility_tx); - /* AOVs. */ - world_ps_.bind_image("aov_color_img", &rbufs.aov_color_tx); - world_ps_.bind_image("aov_value_img", &rbufs.aov_value_tx); - world_ps_.bind_ssbo("aov_buf", &inst_.film.aovs_info); - /* RenderPasses. Cleared by background (even if bad practice). */ - world_ps_.bind_image("rp_normal_img", &rbufs.normal_tx); - world_ps_.bind_image("rp_light_img", &rbufs.light_tx); - world_ps_.bind_image("rp_diffuse_color_img", &rbufs.diffuse_color_tx); - world_ps_.bind_image("rp_specular_color_img", &rbufs.specular_color_tx); - world_ps_.bind_image("rp_emission_img", &rbufs.emission_tx); + /* RenderPasses & AOVs. Cleared by background (even if bad practice). */ + world_ps_.bind_image("rp_color_img", &rbufs.rp_color_tx); + world_ps_.bind_image("rp_value_img", &rbufs.rp_value_tx); world_ps_.bind_image("rp_cryptomatte_img", &rbufs.cryptomatte_tx); /* Required by validation layers. */ inst_.cryptomatte.bind_resources(&world_ps_); world_ps_.bind_ubo(CAMERA_BUF_SLOT, inst_.camera.ubo_get()); + world_ps_.bind_ubo(RBUFS_BUF_SLOT, &inst_.render_buffers.data); world_ps_.draw(DRW_cache_fullscreen_quad_get(), handle); /* To allow opaque pass rendering over it. */ @@ -140,24 +134,16 @@ void ForwardPipeline::sync() { /* Common resources. */ - - /* RenderPasses. */ - opaque_ps_.bind_image(RBUFS_NORMAL_SLOT, &inst_.render_buffers.normal_tx); - opaque_ps_.bind_image(RBUFS_LIGHT_SLOT, &inst_.render_buffers.light_tx); - opaque_ps_.bind_image(RBUFS_DIFF_COLOR_SLOT, &inst_.render_buffers.diffuse_color_tx); - opaque_ps_.bind_image(RBUFS_SPEC_COLOR_SLOT, &inst_.render_buffers.specular_color_tx); - opaque_ps_.bind_image(RBUFS_EMISSION_SLOT, &inst_.render_buffers.emission_tx); - /* AOVs. */ - opaque_ps_.bind_image(RBUFS_AOV_COLOR_SLOT, &inst_.render_buffers.aov_color_tx); - opaque_ps_.bind_image(RBUFS_AOV_VALUE_SLOT, &inst_.render_buffers.aov_value_tx); + /* RenderPasses & AOVs. */ + opaque_ps_.bind_image(RBUFS_COLOR_SLOT, &inst_.render_buffers.rp_color_tx); + opaque_ps_.bind_image(RBUFS_VALUE_SLOT, &inst_.render_buffers.rp_value_tx); /* Cryptomatte. */ opaque_ps_.bind_image(RBUFS_CRYPTOMATTE_SLOT, &inst_.render_buffers.cryptomatte_tx); - /* Storage Buffer. */ - opaque_ps_.bind_ssbo(RBUFS_AOV_BUF_SLOT, &inst_.film.aovs_info); /* Textures. */ opaque_ps_.bind_texture(RBUFS_UTILITY_TEX_SLOT, inst_.pipelines.utility_tx); /* Uniform Buffer. */ opaque_ps_.bind_ubo(CAMERA_BUF_SLOT, inst_.camera.ubo_get()); + opaque_ps_.bind_ubo(RBUFS_BUF_SLOT, &inst_.render_buffers.data); inst_.lights.bind_resources(&opaque_ps_); inst_.shadows.bind_resources(&opaque_ps_); @@ -327,23 +313,17 @@ void DeferredLayer::begin_sync() /* G-buffer. */ gbuffer_ps_.bind_image(GBUF_CLOSURE_SLOT, &inst_.gbuffer.closure_tx); gbuffer_ps_.bind_image(GBUF_COLOR_SLOT, &inst_.gbuffer.color_tx); - /* RenderPasses. */ - gbuffer_ps_.bind_image(RBUFS_NORMAL_SLOT, &inst_.render_buffers.normal_tx); - /* TODO(fclem): Pack all render pass into the same texture. */ - // gbuffer_ps_.bind_image(RBUFS_DIFF_COLOR_SLOT, &inst_.render_buffers.diffuse_color_tx); - gbuffer_ps_.bind_image(RBUFS_SPEC_COLOR_SLOT, &inst_.render_buffers.specular_color_tx); - gbuffer_ps_.bind_image(RBUFS_EMISSION_SLOT, &inst_.render_buffers.emission_tx); - /* AOVs. */ - gbuffer_ps_.bind_image(RBUFS_AOV_COLOR_SLOT, &inst_.render_buffers.aov_color_tx); - gbuffer_ps_.bind_image(RBUFS_AOV_VALUE_SLOT, &inst_.render_buffers.aov_value_tx); + /* RenderPasses & AOVs. */ + gbuffer_ps_.bind_image(RBUFS_COLOR_SLOT, &inst_.render_buffers.rp_color_tx); + gbuffer_ps_.bind_image(RBUFS_VALUE_SLOT, &inst_.render_buffers.rp_value_tx); /* Cryptomatte. */ gbuffer_ps_.bind_image(RBUFS_CRYPTOMATTE_SLOT, &inst_.render_buffers.cryptomatte_tx); /* Storage Buffer. */ - gbuffer_ps_.bind_ssbo(RBUFS_AOV_BUF_SLOT, &inst_.film.aovs_info); /* Textures. */ gbuffer_ps_.bind_texture(RBUFS_UTILITY_TEX_SLOT, inst_.pipelines.utility_tx); /* Uniform Buffer. */ gbuffer_ps_.bind_ubo(CAMERA_BUF_SLOT, inst_.camera.ubo_get()); + gbuffer_ps_.bind_ubo(RBUFS_BUF_SLOT, &inst_.render_buffers.data); inst_.sampling.bind_resources(&gbuffer_ps_); inst_.cryptomatte.bind_resources(&gbuffer_ps_); @@ -380,8 +360,10 @@ void DeferredLayer::end_sync() eval_light_ps_.bind_texture("gbuffer_closure_tx", &inst_.gbuffer.closure_tx); eval_light_ps_.bind_texture("gbuffer_color_tx", &inst_.gbuffer.color_tx); eval_light_ps_.push_constant("is_last_eval_pass", is_last_eval_pass); - eval_light_ps_.bind_image(RBUFS_LIGHT_SLOT, &inst_.render_buffers.light_tx); + eval_light_ps_.bind_image(RBUFS_COLOR_SLOT, &inst_.render_buffers.rp_color_tx); + eval_light_ps_.bind_image(RBUFS_VALUE_SLOT, &inst_.render_buffers.rp_value_tx); eval_light_ps_.bind_texture(RBUFS_UTILITY_TEX_SLOT, inst_.pipelines.utility_tx); + eval_light_ps_.bind_ubo(RBUFS_BUF_SLOT, &inst_.render_buffers.data); inst_.lights.bind_resources(&eval_light_ps_); inst_.shadows.bind_resources(&eval_light_ps_); diff --git a/source/blender/draw/engines/eevee_next/eevee_renderbuffers.cc b/source/blender/draw/engines/eevee_next/eevee_renderbuffers.cc index 29a5484f438..947b95f9d87 100644 --- a/source/blender/draw/engines/eevee_next/eevee_renderbuffers.cc +++ b/source/blender/draw/engines/eevee_next/eevee_renderbuffers.cc @@ -24,6 +24,36 @@ namespace blender::eevee { +void RenderBuffers::sync() +{ + const eViewLayerEEVEEPassType enabled_passes = inst_.film.enabled_passes_get(); + + data.color_len = 0; + data.value_len = 0; + + auto pass_index_get = [&](eViewLayerEEVEEPassType pass_type) { + if (enabled_passes & pass_type) { + return inst_.film.pass_storage_type(pass_type) == PASS_STORAGE_COLOR ? data.color_len++ : + data.value_len++; + } + return -1; + }; + + data.normal_id = pass_index_get(EEVEE_RENDER_PASS_NORMAL); + data.diffuse_light_id = pass_index_get(EEVEE_RENDER_PASS_DIFFUSE_LIGHT); + data.diffuse_color_id = pass_index_get(EEVEE_RENDER_PASS_DIFFUSE_COLOR); + data.specular_light_id = pass_index_get(EEVEE_RENDER_PASS_SPECULAR_LIGHT); + data.specular_color_id = pass_index_get(EEVEE_RENDER_PASS_SPECULAR_COLOR); + data.volume_light_id = pass_index_get(EEVEE_RENDER_PASS_VOLUME_LIGHT); + data.emission_id = pass_index_get(EEVEE_RENDER_PASS_EMIT); + data.environment_id = pass_index_get(EEVEE_RENDER_PASS_ENVIRONMENT); + data.shadow_id = pass_index_get(EEVEE_RENDER_PASS_SHADOW); + data.ambient_occlusion_id = pass_index_get(EEVEE_RENDER_PASS_AO); + + data.aovs = inst_.film.aovs_info; + data.push_update(); +} + void RenderBuffers::acquire(int2 extent) { const eViewLayerEEVEEPassType enabled_passes = inst_.film.enabled_passes_get(); @@ -42,36 +72,19 @@ void RenderBuffers::acquire(int2 extent) bool do_vector_render_pass = (enabled_passes & EEVEE_RENDER_PASS_VECTOR) || (inst_.motion_blur.postfx_enabled() && !inst_.is_viewport()); - uint32_t max_light_color_layer = max_ii(enabled_passes & EEVEE_RENDER_PASS_DIFFUSE_LIGHT ? - int(RENDER_PASS_LAYER_DIFFUSE_LIGHT) : - -1, - enabled_passes & EEVEE_RENDER_PASS_SPECULAR_LIGHT ? - int(RENDER_PASS_LAYER_SPECULAR_LIGHT) : - -1) + - 1; + /* Only RG16F when only doing only reprojection or motion blur. */ eGPUTextureFormat vector_format = do_vector_render_pass ? GPU_RGBA16F : GPU_RG16F; /* TODO(fclem): Make vector pass allocation optional if no TAA or motion blur is needed. */ vector_tx.acquire(extent, vector_format); - normal_tx.acquire(pass_extent(EEVEE_RENDER_PASS_NORMAL), color_format); - diffuse_color_tx.acquire(pass_extent(EEVEE_RENDER_PASS_DIFFUSE_COLOR), color_format); - specular_color_tx.acquire(pass_extent(EEVEE_RENDER_PASS_SPECULAR_COLOR), color_format); - volume_light_tx.acquire(pass_extent(EEVEE_RENDER_PASS_VOLUME_LIGHT), color_format); - emission_tx.acquire(pass_extent(EEVEE_RENDER_PASS_EMIT), color_format); - environment_tx.acquire(pass_extent(EEVEE_RENDER_PASS_ENVIRONMENT), color_format); - shadow_tx.acquire(pass_extent(EEVEE_RENDER_PASS_SHADOW), float_format); - ambient_occlusion_tx.acquire(pass_extent(EEVEE_RENDER_PASS_AO), float_format); + int color_len = data.color_len + data.aovs.color_len; + int value_len = data.value_len + data.aovs.value_len; - light_tx.ensure_2d_array(color_format, - max_light_color_layer > 0 ? extent : int2(1), - max_ii(1, max_light_color_layer)); - - const AOVsInfoData &aovs = inst_.film.aovs_info; - aov_color_tx.ensure_2d_array( - color_format, (aovs.color_len > 0) ? extent : int2(1), max_ii(1, aovs.color_len)); - aov_value_tx.ensure_2d_array( - float_format, (aovs.value_len > 0) ? extent : int2(1), max_ii(1, aovs.value_len)); + rp_color_tx.ensure_2d_array( + color_format, (color_len > 0) ? extent : int2(1), math::max(1, color_len)); + rp_value_tx.ensure_2d_array( + float_format, (value_len > 0) ? extent : int2(1), math::max(1, value_len)); eGPUTextureFormat cryptomatte_format = GPU_R32F; const int cryptomatte_layer_len = inst_.film.cryptomatte_layer_max_get(); @@ -93,15 +106,7 @@ void RenderBuffers::release() depth_tx.release(); combined_tx.release(); - normal_tx.release(); vector_tx.release(); - diffuse_color_tx.release(); - specular_color_tx.release(); - volume_light_tx.release(); - emission_tx.release(); - environment_tx.release(); - shadow_tx.release(); - ambient_occlusion_tx.release(); cryptomatte_tx.release(); } diff --git a/source/blender/draw/engines/eevee_next/eevee_renderbuffers.hh b/source/blender/draw/engines/eevee_next/eevee_renderbuffers.hh index ae5d7fbae5c..878cf740ec8 100644 --- a/source/blender/draw/engines/eevee_next/eevee_renderbuffers.hh +++ b/source/blender/draw/engines/eevee_next/eevee_renderbuffers.hh @@ -22,24 +22,17 @@ class Instance; class RenderBuffers { public: + UniformBuffer data; + TextureFromPool depth_tx; TextureFromPool combined_tx; // TextureFromPool mist_tx; /* Derived from depth_tx during accumulation. */ - TextureFromPool normal_tx; TextureFromPool vector_tx; - TextureFromPool diffuse_color_tx; - TextureFromPool specular_color_tx; - TextureFromPool volume_light_tx; - TextureFromPool emission_tx; - TextureFromPool environment_tx; - TextureFromPool shadow_tx; - TextureFromPool ambient_occlusion_tx; TextureFromPool cryptomatte_tx; /* TODO(fclem): Use texture from pool once they support texture array. */ - Texture light_tx; - Texture aov_color_tx; - Texture aov_value_tx; + Texture rp_color_tx; + Texture rp_value_tx; private: Instance &inst_; @@ -47,6 +40,8 @@ class RenderBuffers { public: RenderBuffers(Instance &inst) : inst_(inst){}; + void sync(); + /* Acquires (also ensures) the render buffer before rendering to them. */ void acquire(int2 extent); void release(); diff --git a/source/blender/draw/engines/eevee_next/eevee_shader.cc b/source/blender/draw/engines/eevee_next/eevee_shader.cc index 26d9642a525..6b5deeee5c1 100644 --- a/source/blender/draw/engines/eevee_next/eevee_shader.cc +++ b/source/blender/draw/engines/eevee_next/eevee_shader.cc @@ -260,7 +260,6 @@ void ShaderModule::material_create_info_ammend(GPUMaterial *gpumat, GPUCodegenOu pipeline_type == MAT_PIPE_FORWARD) { /* Opaque forward do support AOVs and render pass if not using transparency. */ - info.additional_info("eevee_aov_out"); info.additional_info("eevee_render_pass_out"); info.additional_info("eevee_cryptomatte_out"); } diff --git a/source/blender/draw/engines/eevee_next/eevee_shader_shared.hh b/source/blender/draw/engines/eevee_next/eevee_shader_shared.hh index 5e3c183eda6..3bb62dbf02d 100644 --- a/source/blender/draw/engines/eevee_next/eevee_shader_shared.hh +++ b/source/blender/draw/engines/eevee_next/eevee_shader_shared.hh @@ -307,18 +307,7 @@ static inline float film_filter_weight(float filter_radius, float sample_distanc /** \} */ /* -------------------------------------------------------------------- */ -/** \name Render passes - * \{ */ - -enum eRenderPassLayerIndex : uint32_t { - RENDER_PASS_LAYER_DIFFUSE_LIGHT = 0u, - RENDER_PASS_LAYER_SPECULAR_LIGHT = 1u, -}; - -/** \} */ - -/* -------------------------------------------------------------------- */ -/** \name Arbitrary Output Variables +/** \name RenderBuffers * \{ */ /* Theoretical max is 128 as we are using texture array and VRAM usage. @@ -326,10 +315,11 @@ enum eRenderPassLayerIndex : uint32_t { * If we find a way to avoid this we could bump this number up. */ #define AOV_MAX 16 -/* NOTE(@fclem): Needs to be used in #StorageBuffer because of arrays of scalar. */ struct AOVsInfoData { - uint hash_value[AOV_MAX]; - uint hash_color[AOV_MAX]; + /* Use uint4 to workaround std140 packing rules. + * Only the x value is used. */ + uint4 hash_value[AOV_MAX]; + uint4 hash_color[AOV_MAX]; /* Length of used data. */ uint color_len; uint value_len; @@ -340,6 +330,25 @@ struct AOVsInfoData { }; BLI_STATIC_ASSERT_ALIGN(AOVsInfoData, 16) +struct RenderBuffersInfoData { + AOVsInfoData aovs; + /* Color. */ + int color_len; + int normal_id; + int diffuse_light_id; + int diffuse_color_id; + int specular_light_id; + int specular_color_id; + int volume_light_id; + int emission_id; + int environment_id; + /* Value */ + int value_len; + int shadow_id; + int ambient_occlusion_id; +}; +BLI_STATIC_ASSERT_ALIGN(RenderBuffersInfoData, 16) + /** \} */ /* -------------------------------------------------------------------- */ diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_deferred_light_frag.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_deferred_light_frag.glsl index 80dcaaf67cb..9653fe630bf 100644 --- a/source/blender/draw/engines/eevee_next/shaders/eevee_deferred_light_frag.glsl +++ b/source/blender/draw/engines/eevee_next/shaders/eevee_deferred_light_frag.glsl @@ -51,9 +51,18 @@ void main() vec3 diffuse_light = vec3(0.0); vec3 reflection_light = vec3(0.0); + float shadow = 1.0; - light_eval( - diffuse_data, reflection_data, P, Ng, V, vP_z, thickness, diffuse_light, reflection_light); + light_eval(diffuse_data, + reflection_data, + P, + Ng, + V, + vP_z, + thickness, + diffuse_light, + reflection_light, + shadow); if (is_last_eval_pass) { /* Apply color and output lighting to render-passes. */ @@ -67,13 +76,21 @@ void main() diffuse_data.color = vec3(0.0); } - reflection_light *= reflection_data.color; + /* Light passes. */ + if (rp_buf.diffuse_light_id >= 0) { + imageStore(rp_color_img, ivec3(texel, rp_buf.diffuse_light_id), vec4(diffuse_light, 1.0)); + } + if (rp_buf.specular_light_id >= 0) { + imageStore( + rp_color_img, ivec3(texel, rp_buf.specular_light_id), vec4(reflection_light, 1.0)); + } + if (rp_buf.shadow_id >= 0) { + imageStore(rp_value_img, ivec3(texel, rp_buf.shadow_id), vec4(shadow)); + } + /* TODO: AO. */ + diffuse_light *= diffuse_data.color; - /* Add radiance to light pass. */ - imageStore( - rp_light_img, ivec3(texel, RENDER_PASS_LAYER_DIFFUSE_LIGHT), vec4(diffuse_light, 1.0)); - imageStore( - rp_light_img, ivec3(texel, RENDER_PASS_LAYER_SPECULAR_LIGHT), vec4(reflection_light, 1.0)); + reflection_light *= reflection_data.color; /* Add radiance to combined pass. */ out_radiance = vec4(diffuse_light + reflection_light, 0.0); out_transmittance = vec4(1.0); diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_film_lib.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_film_lib.glsl index 980c7165809..cb3285f7266 100644 --- a/source/blender/draw/engines/eevee_next/shaders/eevee_film_lib.glsl +++ b/source/blender/draw/engines/eevee_next/shaders/eevee_film_lib.glsl @@ -90,42 +90,22 @@ float film_weight_accumulation(ivec2 texel_film) return film_buf.samples_weight_total; } -void film_sample_accum(FilmSample samp, int pass_id, sampler2D tex, inout vec4 accum) -{ - if (pass_id == -1) { - return; - } - accum += texelFetch(tex, samp.texel, 0) * samp.weight; -} - -void film_sample_accum(FilmSample samp, int pass_id, sampler2D tex, inout float accum) -{ - if (pass_id == -1) { - return; - } - accum += texelFetch(tex, samp.texel, 0).x * samp.weight; -} - void film_sample_accum( - FilmSample samp, int pass_id, uint layer, sampler2DArray tex, inout vec4 accum) + FilmSample samp, int pass_id, int layer, sampler2DArray tex, inout vec4 accum) { - if (pass_id == -1) { + if (pass_id < 0 || layer < 0) { return; } accum += texelFetch(tex, ivec3(samp.texel, layer), 0) * samp.weight; } -void film_sample_accum(FilmSample samp, int pass_id, sampler2DArray tex, inout vec4 accum) +void film_sample_accum( + FilmSample samp, int pass_id, int layer, sampler2DArray tex, inout float accum) { - film_sample_accum(samp, pass_id, pass_id, tex, accum); -} - -void film_sample_accum(FilmSample samp, int pass_id, sampler2DArray tex, inout float accum) -{ - if (pass_id == -1) { + if (pass_id < 0 || layer < 0) { return; } - accum += texelFetch(tex, ivec3(samp.texel, pass_id), 0).x * samp.weight; + accum += texelFetch(tex, ivec3(samp.texel, layer), 0).x * samp.weight; } void film_sample_accum_mist(FilmSample samp, inout float accum) @@ -662,7 +642,7 @@ void film_process_data(ivec2 texel_film, out vec4 out_color, out float out_depth FilmSample film_sample = film_sample_get(0, texel_film); if (film_buf.use_reprojection || film_sample.weight < film_distance) { - vec4 normal = texelFetch(normal_tx, film_sample.texel, 0); + vec4 normal = texelFetch(rp_color_tx, ivec3(film_sample.texel, rp_buf.normal_id), 0); float depth = texelFetch(depth_tx, film_sample.texel, 0).x; vec4 vector = velocity_resolve(vector_tx, film_sample.texel, depth); /* Transform to pixel space. */ @@ -688,16 +668,18 @@ void film_process_data(ivec2 texel_film, out vec4 out_color, out float out_depth FilmSample src = film_sample_get(i, texel_film); film_sample_accum(src, film_buf.diffuse_light_id, - RENDER_PASS_LAYER_DIFFUSE_LIGHT, - light_tx, + rp_buf.diffuse_light_id, + rp_color_tx, diffuse_light_accum); film_sample_accum(src, film_buf.specular_light_id, - RENDER_PASS_LAYER_SPECULAR_LIGHT, - light_tx, + rp_buf.specular_light_id, + rp_color_tx, specular_light_accum); - film_sample_accum(src, film_buf.volume_light_id, volume_light_tx, volume_light_accum); - film_sample_accum(src, film_buf.emission_id, emission_tx, emission_accum); + film_sample_accum( + src, film_buf.volume_light_id, rp_buf.volume_light_id, rp_color_tx, volume_light_accum); + film_sample_accum( + src, film_buf.emission_id, rp_buf.emission_id, rp_color_tx, emission_accum); } film_store_color(dst, film_buf.diffuse_light_id, diffuse_light_accum, out_color); film_store_color(dst, film_buf.specular_light_id, specular_light_accum, out_color); @@ -715,11 +697,21 @@ void film_process_data(ivec2 texel_film, out vec4 out_color, out float out_depth for (int i = 0; i < film_buf.samples_len; i++) { FilmSample src = film_sample_get(i, texel_film); - film_sample_accum(src, film_buf.diffuse_color_id, diffuse_color_tx, diffuse_color_accum); - film_sample_accum(src, film_buf.specular_color_id, specular_color_tx, specular_color_accum); - film_sample_accum(src, film_buf.environment_id, environment_tx, environment_accum); - film_sample_accum(src, film_buf.shadow_id, shadow_tx, shadow_accum); - film_sample_accum(src, film_buf.ambient_occlusion_id, ambient_occlusion_tx, ao_accum); + film_sample_accum(src, + film_buf.diffuse_color_id, + rp_buf.diffuse_color_id, + rp_color_tx, + diffuse_color_accum); + film_sample_accum(src, + film_buf.specular_color_id, + rp_buf.specular_color_id, + rp_color_tx, + specular_color_accum); + film_sample_accum( + src, film_buf.environment_id, rp_buf.environment_id, rp_color_tx, environment_accum); + film_sample_accum(src, film_buf.shadow_id, rp_buf.shadow_id, rp_value_tx, shadow_accum); + film_sample_accum( + src, film_buf.ambient_occlusion_id, rp_buf.ambient_occlusion_id, rp_value_tx, ao_accum); film_sample_accum_mist(src, mist_accum); } film_store_color(dst, film_buf.diffuse_color_id, diffuse_color_accum, out_color); @@ -735,7 +727,7 @@ void film_process_data(ivec2 texel_film, out vec4 out_color, out float out_depth for (int i = 0; i < film_buf.samples_len; i++) { FilmSample src = film_sample_get(i, texel_film); - film_sample_accum(src, aov, aov_color_tx, aov_accum); + film_sample_accum(src, 0, rp_buf.color_len + aov, rp_color_tx, aov_accum); } film_store_color(dst, film_buf.aov_color_id + aov, aov_accum, out_color); } @@ -745,7 +737,7 @@ void film_process_data(ivec2 texel_film, out vec4 out_color, out float out_depth for (int i = 0; i < film_buf.samples_len; i++) { FilmSample src = film_sample_get(i, texel_film); - film_sample_accum(src, aov, aov_value_tx, aov_accum); + film_sample_accum(src, 0, rp_buf.value_len + aov, rp_value_tx, aov_accum); } film_store_value(dst, film_buf.aov_value_id + aov, aov_accum, out_color); } diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_light_eval_lib.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_light_eval_lib.glsl index 4a57a850d34..d530f28c04c 100644 --- a/source/blender/draw/engines/eevee_next/shaders/eevee_light_eval_lib.glsl +++ b/source/blender/draw/engines/eevee_next/shaders/eevee_light_eval_lib.glsl @@ -27,7 +27,8 @@ void light_eval_ex(ClosureDiffuse diffuse, vec4 ltc_mat, uint l_idx, inout vec3 out_diffuse, - inout vec3 out_specular) + inout vec3 out_specular, + inout float out_shadow) { LightData light = light_buf[l_idx]; vec3 L; @@ -61,6 +62,7 @@ void light_eval_ex(ClosureDiffuse diffuse, } #endif visibility *= float(samp.occluder_delta + samp.bias >= 0.0); + out_shadow *= float(samp.occluder_delta + samp.bias >= 0.0); } if (visibility < 1e-6) { @@ -89,7 +91,8 @@ void light_eval(ClosureDiffuse diffuse, float vP_z, float thickness, inout vec3 out_diffuse, - inout vec3 out_specular) + inout vec3 out_specular, + inout float out_shadow) { vec2 uv = vec2(reflection.roughness, safe_sqrt(1.0 - dot(reflection.N, V))); uv = uv * UTIL_TEX_UV_SCALE + UTIL_TEX_UV_BIAS; @@ -107,7 +110,8 @@ void light_eval(ClosureDiffuse diffuse, ltc_mat, l_idx, out_diffuse, - out_specular); + out_specular, + out_shadow); } LIGHT_FOREACH_END @@ -124,7 +128,8 @@ void light_eval(ClosureDiffuse diffuse, ltc_mat, l_idx, out_diffuse, - out_specular); + out_specular, + out_shadow); } LIGHT_FOREACH_END } diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_nodetree_lib.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_nodetree_lib.glsl index ea37188553e..957b2b01c1a 100644 --- a/source/blender/draw/engines/eevee_next/shaders/eevee_nodetree_lib.glsl +++ b/source/blender/draw/engines/eevee_next/shaders/eevee_nodetree_lib.glsl @@ -237,18 +237,51 @@ float F_eta(float a, float b) { return a; } + +void output_renderpass_color(int id, vec4 color) +{ +#if defined(MAT_RENDER_PASS_SUPPORT) && defined(GPU_FRAGMENT_SHADER) + if (id >= 0) { + ivec2 texel = ivec2(gl_FragCoord.xy); + imageStore(rp_color_img, ivec3(texel, id), color); + } +#endif +}; + +void output_renderpass_value(int id, float value) +{ +#if defined(MAT_RENDER_PASS_SUPPORT) && defined(GPU_FRAGMENT_SHADER) + if (id >= 0) { + ivec2 texel = ivec2(gl_FragCoord.xy); + imageStore(rp_value_img, ivec3(texel, id), vec4(value)); + } +#endif +}; + +void clear_aovs() +{ +#if defined(MAT_RENDER_PASS_SUPPORT) && defined(GPU_FRAGMENT_SHADER) + for (int i = 0; i < AOV_MAX && i < rp_buf.aovs.color_len; i++) { + output_renderpass_color(rp_buf.color_len + i, vec4(0)); + } + for (int i = 0; i < AOV_MAX && i < rp_buf.aovs.value_len; i++) { + output_renderpass_value(rp_buf.value_len + i, 0.0); + } +#endif +} + void output_aov(vec4 color, float value, uint hash) { -#if defined(MAT_AOV_SUPPORT) && defined(GPU_FRAGMENT_SHADER) - for (uint i = 0; i < AOV_MAX && i < aov_buf.color_len; i++) { - if (aov_buf.hash_color[i] == hash) { - imageStore(aov_color_img, ivec3(ivec2(gl_FragCoord.xy), i), color); +#if defined(MAT_RENDER_PASS_SUPPORT) && defined(GPU_FRAGMENT_SHADER) + for (uint i = 0; i < AOV_MAX && i < rp_buf.aovs.color_len; i++) { + if (rp_buf.aovs.hash_color[i].x == hash) { + imageStore(rp_color_img, ivec3(ivec2(gl_FragCoord.xy), rp_buf.color_len + i), color); return; } } - for (uint i = 0; i < AOV_MAX && i < aov_buf.value_len; i++) { - if (aov_buf.hash_value[i] == hash) { - imageStore(aov_value_img, ivec3(ivec2(gl_FragCoord.xy), i), vec4(value)); + for (uint i = 0; i < AOV_MAX && i < rp_buf.aovs.value_len; i++) { + if (rp_buf.aovs.hash_value[i].x == hash) { + imageStore(rp_value_img, ivec3(ivec2(gl_FragCoord.xy), rp_buf.value_len + i), vec4(value)); return; } } diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_surf_deferred_frag.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_surf_deferred_frag.glsl index d84d0a030e2..b7fdca6374c 100644 --- a/source/blender/draw/engines/eevee_next/shaders/eevee_surf_deferred_frag.glsl +++ b/source/blender/draw/engines/eevee_next/shaders/eevee_surf_deferred_frag.glsl @@ -28,6 +28,9 @@ vec4 closure_to_rgba(Closure cl) void main() { + /* Clear AOVs first. In case the material renders to them. */ + clear_aovs(); + init_globals(); float noise = utility_tx_fetch(utility_tx, gl_FragCoord.xy, UTIL_BLUE_NOISE_LAYER).r; @@ -66,12 +69,10 @@ void main() /* Some render pass can be written during the gbuffer pass. Light passes are written later. */ vec4 cryptomatte_output = vec4(cryptomatte_object_buf[resource_id], node_tree.crypto_hash, 0.0); imageStore(rp_cryptomatte_img, out_texel, cryptomatte_output); - imageStore(rp_normal_img, out_texel, vec4(out_normal, 1.0)); - /* TODO(fclem): For now, just don't do anything. In the future all render passes should be in an - * array texture and have a UBO with indirection to the correct layer. */ - // imageStore(rp_diffuse_color_img, out_texel, vec4(g_diffuse_data.color, 1.0)); - imageStore(rp_specular_color_img, out_texel, vec4(specular_color, 1.0)); - imageStore(rp_emission_img, out_texel, vec4(g_emission, 1.0)); + output_renderpass_color(rp_buf.normal_id, vec4(out_normal, 1.0)); + output_renderpass_color(rp_buf.diffuse_color_id, vec4(g_diffuse_data.color, 1.0)); + output_renderpass_color(rp_buf.specular_color_id, vec4(specular_color, 1.0)); + output_renderpass_color(rp_buf.emission_id, vec4(g_emission, 1.0)); #endif /* ----- GBuffer output ----- */ diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_surf_forward_frag.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_surf_forward_frag.glsl index dad1faad0b4..49764e5219d 100644 --- a/source/blender/draw/engines/eevee_next/shaders/eevee_surf_forward_frag.glsl +++ b/source/blender/draw/engines/eevee_next/shaders/eevee_surf_forward_frag.glsl @@ -18,6 +18,7 @@ vec4 closure_to_rgba(Closure cl) vec3 diffuse_light = vec3(0.0); vec3 reflection_light = vec3(0.0); vec3 refraction_light = vec3(0.0); + float shadow = 1.0; float vP_z = dot(cameraForward, g_data.P) - dot(cameraForward, cameraPos); @@ -29,7 +30,8 @@ vec4 closure_to_rgba(Closure cl) vP_z, 0.01 /* TODO(fclem) thickness. */, diffuse_light, - reflection_light); + reflection_light, + shadow); vec4 out_color; out_color.rgb = g_emission; @@ -47,6 +49,9 @@ vec4 closure_to_rgba(Closure cl) void main() { + /* Clear AOVs first. In case the material renders to them. */ + clear_aovs(); + init_globals(); float noise = utility_tx_fetch(utility_tx, gl_FragCoord.xy, UTIL_BLUE_NOISE_LAYER).r; @@ -61,6 +66,7 @@ void main() vec3 diffuse_light = vec3(0.0); vec3 reflection_light = vec3(0.0); vec3 refraction_light = vec3(0.0); + float shadow = 1.0; float vP_z = dot(cameraForward, g_data.P) - dot(cameraForward, cameraPos); @@ -72,7 +78,8 @@ void main() vP_z, 0.01 /* TODO(fclem) thickness. */, diffuse_light, - reflection_light); + reflection_light, + shadow); g_diffuse_data.color *= g_diffuse_data.weight; g_reflection_data.color *= g_reflection_data.weight; @@ -101,17 +108,16 @@ void main() #ifdef MAT_RENDER_PASS_SUPPORT ivec2 out_texel = ivec2(gl_FragCoord.xy); - imageStore(rp_normal_img, out_texel, vec4(out_normal, 1.0)); - imageStore( - rp_light_img, ivec3(out_texel, RENDER_PASS_LAYER_DIFFUSE_LIGHT), vec4(diffuse_light, 1.0)); - imageStore( - rp_light_img, ivec3(out_texel, RENDER_PASS_LAYER_SPECULAR_LIGHT), vec4(specular_light, 1.0)); - imageStore(rp_diffuse_color_img, out_texel, vec4(g_diffuse_data.color, 1.0)); - imageStore(rp_specular_color_img, out_texel, vec4(specular_color, 1.0)); - imageStore(rp_emission_img, out_texel, vec4(g_emission, 1.0)); - imageStore(rp_cryptomatte_img, - out_texel, - vec4(cryptomatte_object_buf[resource_id], node_tree.crypto_hash, 0.0)); + vec4 cryptomatte_output = vec4(cryptomatte_object_buf[resource_id], node_tree.crypto_hash, 0.0); + imageStore(rp_cryptomatte_img, out_texel, cryptomatte_output); + output_renderpass_color(rp_buf.normal_id, vec4(out_normal, 1.0)); + output_renderpass_color(rp_buf.diffuse_color_id, vec4(g_diffuse_data.color, 1.0)); + output_renderpass_color(rp_buf.diffuse_light_id, vec4(diffuse_light, 1.0)); + output_renderpass_color(rp_buf.specular_color_id, vec4(specular_color, 1.0)); + output_renderpass_color(rp_buf.specular_light_id, vec4(specular_light, 1.0)); + output_renderpass_color(rp_buf.emission_id, vec4(g_emission, 1.0)); + output_renderpass_value(rp_buf.shadow_id, shadow); + /* TODO: AO. */ #endif out_radiance.rgb *= 1.0 - g_holdout; diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_surf_world_frag.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_surf_world_frag.glsl index 442c2579c84..0c53451cda3 100644 --- a/source/blender/draw/engines/eevee_next/shaders/eevee_surf_world_frag.glsl +++ b/source/blender/draw/engines/eevee_next/shaders/eevee_surf_world_frag.glsl @@ -13,6 +13,9 @@ void main() { + /* Clear AOVs first. In case the material renders to them. */ + clear_aovs(); + init_globals(); /* View position is passed to keep accuracy. */ g_data.N = normal_view_to_world(viewCameraVec(interp.P)); @@ -24,20 +27,28 @@ void main() g_holdout = saturate(g_holdout); - ivec2 out_texel = ivec2(gl_FragCoord.xy); - imageStore(rp_normal_img, out_texel, vec4(0.0, 0.0, 0.0, 1.0)); - imageStore( - rp_light_img, ivec3(out_texel, RENDER_PASS_LAYER_DIFFUSE_LIGHT), vec4(0.0, 0.0, 0.0, 1.0)); - imageStore( - rp_light_img, ivec3(out_texel, RENDER_PASS_LAYER_SPECULAR_LIGHT), vec4(0.0, 0.0, 0.0, 1.0)); - imageStore(rp_diffuse_color_img, out_texel, vec4(0.0, 0.0, 0.0, 1.0)); - imageStore(rp_specular_color_img, out_texel, vec4(0.0, 0.0, 0.0, 1.0)); - imageStore(rp_emission_img, out_texel, vec4(0.0, 0.0, 0.0, 1.0)); - imageStore(rp_cryptomatte_img, out_texel, vec4(0.0)); - out_background.rgb = safe_color(g_emission) * (1.0 - g_holdout); out_background.a = saturate(avg(g_transmittance)) * g_holdout; /* World opacity. */ out_background = mix(vec4(0.0, 0.0, 0.0, 1.0), out_background, world_opacity_fade); + + /* Clear Render Buffers. */ + ivec2 texel = ivec2(gl_FragCoord.xy); + + vec4 environment = out_background; + environment.a = 1.0 - environment.a; + environment.rgb *= environment.a; + output_renderpass_color(rp_buf.environment_id, environment); + + vec4 clear_color = vec4(0.0, 0.0, 0.0, 1.0); + output_renderpass_color(rp_buf.normal_id, clear_color); + output_renderpass_color(rp_buf.diffuse_light_id, clear_color); + output_renderpass_color(rp_buf.specular_light_id, clear_color); + output_renderpass_color(rp_buf.diffuse_color_id, clear_color); + output_renderpass_color(rp_buf.specular_color_id, clear_color); + output_renderpass_color(rp_buf.emission_id, clear_color); + output_renderpass_value(rp_buf.shadow_id, 1.0); + output_renderpass_value(rp_buf.ambient_occlusion_id, 0.0); + imageStore(rp_cryptomatte_img, texel, vec4(0.0)); } diff --git a/source/blender/draw/engines/eevee_next/shaders/infos/eevee_deferred_info.hh b/source/blender/draw/engines/eevee_next/shaders/infos/eevee_deferred_info.hh index f5bc967e5b6..a1ccdb4d882 100644 --- a/source/blender/draw/engines/eevee_next/shaders/infos/eevee_deferred_info.hh +++ b/source/blender/draw/engines/eevee_next/shaders/infos/eevee_deferred_info.hh @@ -24,11 +24,9 @@ GPU_SHADER_CREATE_INFO(eevee_deferred_base) /* Combined pass output. */ .fragment_out(0, Type::VEC4, "out_radiance", DualBlend::SRC_0) .fragment_out(0, Type::VEC4, "out_transmittance", DualBlend::SRC_1) - /* Light pass output. */ - .image_array_out(RBUFS_LIGHT_SLOT, Qualifier::READ_WRITE, GPU_RGBA16F, "rp_light_img") /* Chaining to next pass. */ - .image_out(2, Qualifier::READ_WRITE, GPU_RGBA16F, "out_diffuse_light_img") - .image_out(3, Qualifier::READ_WRITE, GPU_RGBA16F, "out_specular_light_img"); + .image_out(2, Qualifier::WRITE, GPU_RGBA16F, "out_diffuse_light_img") + .image_out(3, Qualifier::WRITE, GPU_RGBA16F, "out_specular_light_img"); GPU_SHADER_CREATE_INFO(eevee_deferred_light) .fragment_source("eevee_deferred_light_frag.glsl") @@ -40,6 +38,7 @@ GPU_SHADER_CREATE_INFO(eevee_deferred_light) "eevee_shadow_data", "eevee_deferred_base", "eevee_hiz_data", + "eevee_render_pass_out", "draw_view", "draw_fullscreen") .do_static_compilation(true); diff --git a/source/blender/draw/engines/eevee_next/shaders/infos/eevee_film_info.hh b/source/blender/draw/engines/eevee_next/shaders/infos/eevee_film_info.hh index 1b37547e703..54370a06a46 100644 --- a/source/blender/draw/engines/eevee_next/shaders/infos/eevee_film_info.hh +++ b/source/blender/draw/engines/eevee_next/shaders/infos/eevee_film_info.hh @@ -7,21 +7,12 @@ GPU_SHADER_CREATE_INFO(eevee_film) .uniform_buf(6, "FilmData", "film_buf") .sampler(0, ImageType::DEPTH_2D, "depth_tx") .sampler(1, ImageType::FLOAT_2D, "combined_tx") - .sampler(2, ImageType::FLOAT_2D, "normal_tx") - .sampler(3, ImageType::FLOAT_2D, "vector_tx") - .sampler(4, ImageType::FLOAT_2D_ARRAY, "light_tx") - .sampler(5, ImageType::FLOAT_2D, "diffuse_color_tx") - .sampler(6, ImageType::FLOAT_2D, "specular_color_tx") - .sampler(7, ImageType::FLOAT_2D, "volume_light_tx") - .sampler(8, ImageType::FLOAT_2D, "emission_tx") - .sampler(9, ImageType::FLOAT_2D, "environment_tx") - .sampler(10, ImageType::FLOAT_2D, "shadow_tx") - .sampler(11, ImageType::FLOAT_2D, "ambient_occlusion_tx") - .sampler(12, ImageType::FLOAT_2D_ARRAY, "aov_color_tx") - .sampler(13, ImageType::FLOAT_2D_ARRAY, "aov_value_tx") + .sampler(2, ImageType::FLOAT_2D, "vector_tx") + .sampler(3, ImageType::FLOAT_2D_ARRAY, "rp_color_tx") + .sampler(4, ImageType::FLOAT_2D_ARRAY, "rp_value_tx") /* Color History for TAA needs to be sampler to leverage bilinear sampling. */ - .sampler(14, ImageType::FLOAT_2D, "in_combined_tx") - .sampler(15, ImageType::FLOAT_2D, "cryptomatte_tx") + .sampler(5, ImageType::FLOAT_2D, "in_combined_tx") + .sampler(6, ImageType::FLOAT_2D, "cryptomatte_tx") .image(0, GPU_R32F, Qualifier::READ, ImageType::FLOAT_2D_ARRAY, "in_weight_img") .image(1, GPU_R32F, Qualifier::WRITE, ImageType::FLOAT_2D_ARRAY, "out_weight_img") /* Color History for TAA needs to be sampler to leverage bilinear sampling. */ @@ -31,6 +22,7 @@ GPU_SHADER_CREATE_INFO(eevee_film) .image(5, GPU_RGBA16F, Qualifier::READ_WRITE, ImageType::FLOAT_2D_ARRAY, "color_accum_img") .image(6, GPU_R16F, Qualifier::READ_WRITE, ImageType::FLOAT_2D_ARRAY, "value_accum_img") .image(7, GPU_RGBA32F, Qualifier::READ_WRITE, ImageType::FLOAT_2D_ARRAY, "cryptomatte_img") + .uniform_buf(RBUFS_BUF_SLOT, "RenderBuffersInfoData", "rp_buf") .additional_info("eevee_shared") .additional_info("eevee_velocity_camera") .additional_info("draw_view"); diff --git a/source/blender/draw/engines/eevee_next/shaders/infos/eevee_material_info.hh b/source/blender/draw/engines/eevee_next/shaders/infos/eevee_material_info.hh index f16113a5efc..7fb9cf8975b 100644 --- a/source/blender/draw/engines/eevee_next/shaders/infos/eevee_material_info.hh +++ b/source/blender/draw/engines/eevee_next/shaders/infos/eevee_material_info.hh @@ -80,19 +80,11 @@ GPU_SHADER_INTERFACE_INFO(eevee_surf_iface, "interp") #define image_array_out(slot, qualifier, format, name) \ image(slot, format, qualifier, ImageType::FLOAT_2D_ARRAY, name, Frequency::PASS) -GPU_SHADER_CREATE_INFO(eevee_aov_out) - .define("MAT_AOV_SUPPORT") - .image_array_out(RBUFS_AOV_COLOR_SLOT, Qualifier::WRITE, GPU_RGBA16F, "aov_color_img") - .image_array_out(RBUFS_AOV_VALUE_SLOT, Qualifier::WRITE, GPU_R16F, "aov_value_img") - .storage_buf(RBUFS_AOV_BUF_SLOT, Qualifier::READ, "AOVsInfoData", "aov_buf"); - GPU_SHADER_CREATE_INFO(eevee_render_pass_out) .define("MAT_RENDER_PASS_SUPPORT") - .image_out(RBUFS_NORMAL_SLOT, Qualifier::WRITE, GPU_RGBA16F, "rp_normal_img") - .image_array_out(RBUFS_LIGHT_SLOT, Qualifier::WRITE, GPU_RGBA16F, "rp_light_img") - .image_out(RBUFS_DIFF_COLOR_SLOT, Qualifier::WRITE, GPU_RGBA16F, "rp_diffuse_color_img") - .image_out(RBUFS_SPEC_COLOR_SLOT, Qualifier::WRITE, GPU_RGBA16F, "rp_specular_color_img") - .image_out(RBUFS_EMISSION_SLOT, Qualifier::WRITE, GPU_RGBA16F, "rp_emission_img"); + .image_array_out(RBUFS_COLOR_SLOT, Qualifier::WRITE, GPU_RGBA16F, "rp_color_img") + .image_array_out(RBUFS_VALUE_SLOT, Qualifier::WRITE, GPU_R16F, "rp_value_img") + .uniform_buf(RBUFS_BUF_SLOT, "RenderBuffersInfoData", "rp_buf"); GPU_SHADER_CREATE_INFO(eevee_cryptomatte_out) .storage_buf(CRYPTOMATTE_BUF_SLOT, Qualifier::READ, "vec2", "cryptomatte_object_buf[]") @@ -109,22 +101,12 @@ GPU_SHADER_CREATE_INFO(eevee_surf_deferred) * limitation of the number of images we can bind on a single shader. */ .image_array_out(GBUF_CLOSURE_SLOT, Qualifier::WRITE, GPU_RGBA16, "out_gbuff_closure_img") .image_array_out(GBUF_COLOR_SLOT, Qualifier::WRITE, GPU_RGB10_A2, "out_gbuff_color_img") - /* Render-passes need to be declared manually to avoid overlap with the G-buffer which reuse - * some of binding points. */ - .image_out(RBUFS_NORMAL_SLOT, Qualifier::WRITE, GPU_RGBA16F, "rp_normal_img") - // .image_array_out(RBUFS_LIGHT_SLOT, Qualifier::WRITE, GPU_RGBA16F, "rp_light_img") - /* TODO(fclem): Merge all render-pass into the same texture array. */ - // .image_out(RBUFS_DIFF_COLOR_SLOT, Qualifier::WRITE, GPU_RGBA16F, "rp_diffuse_color_img") - .image_out(RBUFS_SPEC_COLOR_SLOT, Qualifier::WRITE, GPU_RGBA16F, "rp_specular_color_img") - .image_out(RBUFS_EMISSION_SLOT, Qualifier::WRITE, GPU_RGBA16F, "rp_emission_img") .fragment_source("eevee_surf_deferred_frag.glsl") .additional_info("eevee_camera", "eevee_utility_texture", "eevee_sampling_data", - /* Added manually to avoid overlap. */ - // "eevee_render_pass_out", - "eevee_cryptomatte_out", - "eevee_aov_out"); + "eevee_render_pass_out", + "eevee_cryptomatte_out"); GPU_SHADER_CREATE_INFO(eevee_surf_forward) .vertex_out(eevee_surf_iface) @@ -140,11 +122,10 @@ GPU_SHADER_CREATE_INFO(eevee_surf_forward) "eevee_sampling_data", "eevee_shadow_data" /* Optionally added depending on the material. */ + // "eevee_render_pass_out", // "eevee_cryptomatte_out", // "eevee_raytrace_data", // "eevee_transmittance_data", - // "eevee_aov_out", - // "eevee_render_pass_out", ); GPU_SHADER_CREATE_INFO(eevee_surf_depth) @@ -157,9 +138,8 @@ GPU_SHADER_CREATE_INFO(eevee_surf_world) .push_constant(Type::FLOAT, "world_opacity_fade") .fragment_out(0, Type::VEC4, "out_background") .fragment_source("eevee_surf_world_frag.glsl") - .additional_info("eevee_aov_out", + .additional_info("eevee_render_pass_out", "eevee_cryptomatte_out", - "eevee_render_pass_out", "eevee_camera", "eevee_utility_texture");