Realtime Compositor: Implement ID Mask node #106593

Merged
Omar Emara merged 5 commits from OmarEmaraDev/blender:id-mask-node into main 2023-04-20 07:21:11 +02:00
5 changed files with 85 additions and 8 deletions
Showing only changes of commit dffd210fbb - Show all commits

View File

@ -115,6 +115,7 @@ set(GLSL_SRC
shaders/compositor_glare_simple_star_vertical_pass.glsl
shaders/compositor_glare_streaks_accumulate.glsl
shaders/compositor_glare_streaks_filter.glsl
shaders/compositor_id_mask.glsl
shaders/compositor_image_crop.glsl
shaders/compositor_morphological_distance.glsl
shaders/compositor_morphological_distance_feather.glsl
@ -207,6 +208,7 @@ set(SRC_SHADER_CREATE_INFOS
shaders/infos/compositor_filter_info.hh
shaders/infos/compositor_flip_info.hh
shaders/infos/compositor_glare_info.hh
shaders/infos/compositor_id_mask_info.hh
shaders/infos/compositor_image_crop_info.hh
shaders/infos/compositor_morphological_distance_feather_info.hh
shaders/infos/compositor_morphological_distance_info.hh

View File

@ -13,8 +13,8 @@ namespace blender::realtime_compositor {
void smaa(Context &context,
Result &input,
Result &output,
float threshold,
float local_contrast_adaptation_factor,
int corner_rounding);
float threshold = 0.1f,
float local_contrast_adaptation_factor = 2.0,
int corner_rounding = 25);
} // namespace blender::realtime_compositor

View File

@ -0,0 +1,11 @@
#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl)
void main()
{
ivec2 texel = ivec2(gl_GlobalInvocationID.xy);
float input_mask_value = texture_load(input_mask_tx, texel).x;
float mask = int(round(input_mask_value)) == index ? 1.0 : 0.0;
imageStore(output_mask_img, texel, vec4(mask));
}

View File

@ -0,0 +1,11 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#include "gpu_shader_create_info.hh"
GPU_SHADER_CREATE_INFO(compositor_id_mask)
.local_group_size(16, 16)
.push_constant(Type::INT, "index")
.sampler(0, ImageType::FLOAT_2D, "input_mask_tx")
.image(0, GPU_R16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_mask_img")
.compute_source("compositor_id_mask.glsl")
.do_static_compilation(true);

View File

@ -5,11 +5,14 @@
* \ingroup cmpnodes
*/
#include <cmath>
#include "BLT_translation.h"
#include "UI_interface.h"
#include "UI_resources.h"
#include "COM_algorithm_smaa.hh"
#include "COM_node_operation.hh"
#include "node_composite_util.hh"
@ -20,7 +23,11 @@ namespace blender::nodes::node_composite_id_mask_cc {
static void cmp_node_idmask_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Float>(N_("ID value")).default_value(1.0f).min(0.0f).max(1.0f);
b.add_input<decl::Float>(N_("ID value"))
.default_value(1.0f)
.min(0.0f)
.max(1.0f)
.compositor_domain_priority(0);
b.add_output<decl::Float>(N_("Alpha"));
}
@ -38,8 +45,56 @@ class IDMaskOperation : public NodeOperation {
void execute() override
{
get_input("ID value").pass_through(get_result("Alpha"));
context().set_info_message("Viewport compositor setup not fully supported");
const Result &input_mask = get_input("ID value");
if (input_mask.is_single_value()) {
execute_single_value();
return;
}
GPUShader *shader = shader_manager().get("compositor_id_mask");
GPU_shader_bind(shader);
GPU_shader_uniform_1i(shader, "index", get_index());
input_mask.bind_as_texture(shader, "input_mask_tx");
/* If anti-aliasing is disabled, write to the output directly, otherwise, write to a temporary
* result to later perform anti-aliasing. */
Result non_anti_aliased_mask = Result::Temporary(ResultType::Float, texture_pool());
Result &output_mask = use_anti_aliasing() ? non_anti_aliased_mask : get_result("Alpha");
const Domain domain = compute_domain();
output_mask.allocate_texture(domain);
output_mask.bind_as_image(shader, "output_mask_img");
compute_dispatch_threads_at_least(shader, domain.size);
input_mask.unbind_as_texture();
output_mask.unbind_as_image();
GPU_shader_unbind();
if (use_anti_aliasing()) {
smaa(context(), non_anti_aliased_mask, get_result("Alpha"));
non_anti_aliased_mask.release();
}
}
void execute_single_value()
{
const float input_mask_value = get_input("ID value").get_float_value();
const float mask = int(round(input_mask_value)) == get_index() ? 1.0f : 0.0f;
get_result("Alpha").allocate_single_value();
get_result("Alpha").set_float_value(mask);
}
int get_index()
{
return bnode().custom1;
}
bool use_anti_aliasing()
{
return bnode().custom2 != 0;
}
};
@ -60,8 +115,6 @@ void register_node_type_cmp_idmask()
ntype.declare = file_ns::cmp_node_idmask_declare;
ntype.draw_buttons = file_ns::node_composit_buts_id_mask;
ntype.get_compositor_operation = file_ns::get_compositor_operation;
ntype.realtime_compositor_unsupported_message = N_(
"Node not supported in the Viewport compositor");
nodeRegisterType(&ntype);
}