From 18cf8eaeef39ca5b5ae1b11cfbda67024f4874bf Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Fri, 9 Jun 2023 14:29:12 +0200 Subject: [PATCH] Compositor: add passes for non-viewport realtime compositor --- .../infos/compositor_read_pass_info.hh | 14 +++- .../composite/nodes/node_composite_image.cc | 72 +++++++------------ 2 files changed, 37 insertions(+), 49 deletions(-) diff --git a/source/blender/compositor/realtime_compositor/shaders/infos/compositor_read_pass_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_read_pass_info.hh index 9c6181a65a9..15e00fd1fb6 100644 --- a/source/blender/compositor/realtime_compositor/shaders/infos/compositor_read_pass_info.hh +++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_read_pass_info.hh @@ -10,7 +10,19 @@ GPU_SHADER_CREATE_INFO(compositor_read_pass_shared) .sampler(0, ImageType::FLOAT_2D, "input_tx") .compute_source("compositor_read_pass.glsl"); -GPU_SHADER_CREATE_INFO(compositor_read_pass) +GPU_SHADER_CREATE_INFO(compositor_read_pass_float) + .additional_info("compositor_read_pass_shared") + .image(0, GPU_R16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img") + .define("READ_EXPRESSION(pass_color)", "vec4(pass_color.r, vec3(0.0))") + .do_static_compilation(true); + +GPU_SHADER_CREATE_INFO(compositor_read_pass_vector) + .additional_info("compositor_read_pass_shared") + .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img") + .define("READ_EXPRESSION(pass_color)", "pass_color") + .do_static_compilation(true); + +GPU_SHADER_CREATE_INFO(compositor_read_pass_color) .additional_info("compositor_read_pass_shared") .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img") .define("READ_EXPRESSION(pass_color)", "pass_color") diff --git a/source/blender/nodes/composite/nodes/node_composite_image.cc b/source/blender/nodes/composite/nodes/node_composite_image.cc index 8364f7f275b..c699c09a986 100644 --- a/source/blender/nodes/composite/nodes/node_composite_image.cc +++ b/source/blender/nodes/composite/nodes/node_composite_image.cc @@ -825,36 +825,47 @@ class RenderLayerOperation : public NodeOperation { void execute() override { const int view_layer = bnode().custom1; - GPUTexture *pass_texture = context().get_input_texture(view_layer, RE_PASSNAME_COMBINED); + GPUTexture *combined_texture = context().get_input_texture(view_layer, RE_PASSNAME_COMBINED); - execute_image(pass_texture); - execute_alpha(pass_texture); + execute_pass("Image", combined_texture, "compositor_read_pass_color"); + execute_pass("Alpha", combined_texture, "compositor_read_pass_alpha"); /* Other output passes are not supported for now, so allocate them as invalid. */ for (const bNodeSocket *output : this->node()->output_sockets()) { - if (!STR_ELEM(output->identifier, "Image", "Alpha")) { - Result &unsupported_result = get_result(output->identifier); - if (unsupported_result.should_compute()) { - unsupported_result.allocate_invalid(); - context().set_info_message("Viewport compositor setup not fully supported"); - } + if (STR_ELEM(output->identifier, "Image", "Alpha")) { + continue; + } + + GPUTexture *pass_texture = context().get_input_texture(view_layer, output->identifier); + if (output->type == SOCK_FLOAT) { + execute_pass(output->identifier, pass_texture, "compositor_read_pass_float"); + } + else if (output->type == SOCK_VECTOR) { + execute_pass(output->identifier, pass_texture, "compositor_read_pass_vector"); + } + else if (output->type == SOCK_RGBA) { + execute_pass(output->identifier, pass_texture, "compositor_read_pass_color"); + } + else { + BLI_assert_unreachable(); } } } - void execute_image(GPUTexture *pass_texture) + void execute_pass(const char *pass_name, GPUTexture *pass_texture, const char *shader_name) { - Result &image_result = get_result("Image"); + Result &image_result = get_result(pass_name); if (!image_result.should_compute()) { return; } if (pass_texture == nullptr) { - /* Pass not rendered (yet). */ + /* Pass not rendered yet, or not supported by viewport. */ image_result.allocate_invalid(); + context().set_info_message("Viewport compositor setup not fully supported"); return; } - GPUShader *shader = shader_manager().get("compositor_read_pass"); + GPUShader *shader = shader_manager().get(shader_name); GPU_shader_bind(shader); /* The compositing space might be limited to a subset of the pass texture, so only read that @@ -876,41 +887,6 @@ class RenderLayerOperation : public NodeOperation { GPU_texture_unbind(pass_texture); image_result.unbind_as_image(); } - - void execute_alpha(GPUTexture *pass_texture) - { - Result &alpha_result = get_result("Alpha"); - if (!alpha_result.should_compute()) { - return; - } - if (pass_texture == nullptr) { - /* Pass not rendered (yet). */ - alpha_result.allocate_invalid(); - return; - } - - GPUShader *shader = shader_manager().get("compositor_read_pass_alpha"); - GPU_shader_bind(shader); - - /* The compositing space might be limited to a subset of the pass texture, so only read that - * compositing region into an appropriately sized texture. */ - const rcti compositing_region = context().get_compositing_region(); - const int2 lower_bound = int2(compositing_region.xmin, compositing_region.ymin); - GPU_shader_uniform_2iv(shader, "compositing_region_lower_bound", lower_bound); - - const int input_unit = GPU_shader_get_sampler_binding(shader, "input_tx"); - GPU_texture_bind(pass_texture, input_unit); - - const int2 compositing_region_size = context().get_compositing_region_size(); - alpha_result.allocate_texture(Domain(compositing_region_size)); - alpha_result.bind_as_image(shader, "output_img"); - - compute_dispatch_threads_at_least(shader, compositing_region_size); - - GPU_shader_unbind(); - GPU_texture_unbind(pass_texture); - alpha_result.unbind_as_image(); - } }; static NodeOperation *get_compositor_operation(Context &context, DNode node) -- 2.30.2