diff options
author | Omar Emara <mail@OmarEmara.dev> | 2022-08-10 11:09:35 +0300 |
---|---|---|
committer | Omar Emara <mail@OmarEmara.dev> | 2022-08-10 11:09:35 +0300 |
commit | b5df7a02ac754de8e04fdeda4d1c3f0fcdf6a7a2 (patch) | |
tree | 20ae26a94770ed4f6286d191edf17d0cd619d94f /source | |
parent | 6109ad6cce9186bd6e8ff4dbfb281ae8f6742119 (diff) |
Realtime Compositor: Add basic convert and vector nodes
This patch implements the following nodes for the realtime compositor:
- Map range node.
- Map value node.
- Math node.
- Normal node.
- Alpha convert node.
- Separate color node.
- Combine color node.
- Separate XYZ node.
- Combine XYZ node.
- Separate RGBA node.
- Combine RGBA node.
- Separate HSVA node.
- Combine HSVA node.
- Separate YCCA node.
- Combine YUVA node.
- Set alpha node.
- Switch node.
- Switch view node.
- RGB to BW node.
- Color ramp node.
Differential Revision: https://developer.blender.org/D15229
Reviewed By: Clement Foucault
Diffstat (limited to 'source')
24 files changed, 1279 insertions, 77 deletions
diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt index 9c7fb8f290f..995771847c1 100644 --- a/source/blender/gpu/CMakeLists.txt +++ b/source/blender/gpu/CMakeLists.txt @@ -332,13 +332,18 @@ set(GLSL_SRC shaders/compositor/library/gpu_shader_compositor_bright_contrast.glsl shaders/compositor/library/gpu_shader_compositor_color_balance.glsl shaders/compositor/library/gpu_shader_compositor_color_correction.glsl + shaders/compositor/library/gpu_shader_compositor_color_to_luminance.glsl shaders/compositor/library/gpu_shader_compositor_exposure.glsl shaders/compositor/library/gpu_shader_compositor_gamma.glsl shaders/compositor/library/gpu_shader_compositor_hue_correct.glsl shaders/compositor/library/gpu_shader_compositor_hue_saturation_value.glsl shaders/compositor/library/gpu_shader_compositor_invert.glsl shaders/compositor/library/gpu_shader_compositor_main.glsl + shaders/compositor/library/gpu_shader_compositor_map_value.glsl + shaders/compositor/library/gpu_shader_compositor_normal.glsl shaders/compositor/library/gpu_shader_compositor_posterize.glsl + shaders/compositor/library/gpu_shader_compositor_separate_combine.glsl + shaders/compositor/library/gpu_shader_compositor_set_alpha.glsl shaders/compositor/library/gpu_shader_compositor_store_output.glsl shaders/compositor/library/gpu_shader_compositor_texture_utilities.glsl shaders/compositor/library/gpu_shader_compositor_type_conversion.glsl diff --git a/source/blender/gpu/shaders/common/gpu_shader_common_color_utils.glsl b/source/blender/gpu/shaders/common/gpu_shader_common_color_utils.glsl index 2ac0ff8c4bb..33108d3a989 100644 --- a/source/blender/gpu/shaders/common/gpu_shader_common_color_utils.glsl +++ b/source/blender/gpu/shaders/common/gpu_shader_common_color_utils.glsl @@ -140,6 +140,82 @@ void hsl_to_rgb(vec4 hsl, out vec4 outcol) outcol = vec4((nr - 0.5) * chroma + l, (ng - 0.5) * chroma + l, (nb - 0.5) * chroma + l, hsl.w); } +/* ** YCCA to RGBA ** */ + +void ycca_to_rgba_itu_601(vec4 ycca, out vec4 color) +{ + ycca.xyz *= 255.0; + ycca.xyz -= vec3(16.0, 128.0, 128.0); + color.rgb = mat3(vec3(1.164), 0.0, -0.392, 2.017, 1.596, -0.813, 0.0) * ycca.xyz; + color.rgb /= 255.0; + color.a = ycca.a; +} + +void ycca_to_rgba_itu_709(vec4 ycca, out vec4 color) +{ + ycca.xyz *= 255.0; + ycca.xyz -= vec3(16.0, 128.0, 128.0); + color.rgb = mat3(vec3(1.164), 0.0, -0.213, 2.115, 1.793, -0.534, 0.0) * ycca.xyz; + color.rgb /= 255.0; + color.a = ycca.a; +} + +void ycca_to_rgba_jpeg(vec4 ycca, out vec4 color) +{ + ycca.xyz *= 255.0; + color.rgb = mat3(vec3(1.0), 0.0, -0.34414, 1.772, 1.402, -0.71414, 0.0) * ycca.xyz; + color.rgb += vec3(-179.456, 135.45984, -226.816); + color.rgb /= 255.0; + color.a = ycca.a; +} + +/* ** RGBA to YCCA ** */ + +void rgba_to_ycca_itu_601(vec4 rgba, out vec4 ycca) +{ + rgba.rgb *= 255.0; + ycca.xyz = mat3(0.257, -0.148, 0.439, 0.504, -0.291, -0.368, 0.098, 0.439, -0.071) * rgba.rgb; + ycca.xyz += vec3(16.0, 128.0, 128.0); + ycca.xyz /= 255.0; + ycca.a = rgba.a; +} + +void rgba_to_ycca_itu_709(vec4 rgba, out vec4 ycca) +{ + rgba.rgb *= 255.0; + ycca.xyz = mat3(0.183, -0.101, 0.439, 0.614, -0.338, -0.399, 0.062, 0.439, -0.040) * rgba.rgb; + ycca.xyz += vec3(16.0, 128.0, 128.0); + ycca.xyz /= 255.0; + ycca.a = rgba.a; +} + +void rgba_to_ycca_jpeg(vec4 rgba, out vec4 ycca) +{ + rgba.rgb *= 255.0; + ycca.xyz = mat3(0.299, -0.16874, 0.5, 0.587, -0.33126, -0.41869, 0.114, 0.5, -0.08131) * + rgba.rgb; + ycca.xyz += vec3(0.0, 128.0, 128.0); + ycca.xyz /= 255.0; + ycca.a = rgba.a; +} + +/* ** YUVA to RGBA ** */ + +void yuva_to_rgba_itu_709(vec4 yuva, out vec4 color) +{ + color.rgb = mat3(vec3(1.0), 0.0, -0.21482, 2.12798, 1.28033, -0.38059, 0.0) * yuva.xyz; + color.a = yuva.a; +} + +/* ** RGBA to YUVA ** */ + +void rgba_to_yuva_itu_709(vec4 rgba, out vec4 yuva) +{ + yuva.xyz = mat3(0.2126, -0.09991, 0.615, 0.7152, -0.33609, -0.55861, 0.0722, 0.436, -0.05639) * + rgba.rgb; + yuva.a = rgba.a; +} + /* ** Alpha Handling ** */ void color_alpha_clear(vec4 color, out vec4 result) diff --git a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_color_to_luminance.glsl b/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_color_to_luminance.glsl new file mode 100644 index 00000000000..bcdd625bd4f --- /dev/null +++ b/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_color_to_luminance.glsl @@ -0,0 +1,6 @@ +#pragma BLENDER_REQUIRE(gpu_shader_common_color_utils.glsl) + +void color_to_luminance(vec4 color, const vec3 luminance_coefficients, out float result) +{ + result = get_luminance(color.rgb, luminance_coefficients); +} diff --git a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_map_value.glsl b/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_map_value.glsl new file mode 100644 index 00000000000..20874b4ef44 --- /dev/null +++ b/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_map_value.glsl @@ -0,0 +1,56 @@ +/* An arbitrary value determined by Blender. */ +#define BLENDER_ZMAX 10000.0 + +void node_composite_map_range(float value, + float from_min, + float from_max, + float to_min, + float to_max, + const float should_clamp, + out float result) +{ + if (abs(from_max - from_min) < 1e-6) { + result = 0.0; + } + else { + if (value >= -BLENDER_ZMAX && value <= BLENDER_ZMAX) { + result = (value - from_min) / (from_max - from_min); + result = to_min + result * (to_max - to_min); + } + else if (value > BLENDER_ZMAX) { + result = to_max; + } + else { + result = to_min; + } + + if (should_clamp != 0.0) { + if (to_max > to_min) { + result = clamp(result, to_min, to_max); + } + else { + result = clamp(result, to_max, to_min); + } + } + } +} + +void node_composite_map_value(float value, + float offset, + float size, + const float use_min, + float min, + const float use_max, + float max, + out float result) +{ + result = (value + offset) * size; + + if (use_min != 0.0 && result < min) { + result = min; + } + + if (use_max != 0.0 && result > max) { + result = max; + } +} diff --git a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_normal.glsl b/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_normal.glsl new file mode 100644 index 00000000000..a2e3b6c4aaa --- /dev/null +++ b/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_normal.glsl @@ -0,0 +1,9 @@ +void node_composite_normal(vec3 input_vector, + vec3 input_normal, + out vec3 result_normal, + out float result_dot) +{ + vec3 normal = normalize(input_normal); + result_normal = normal; + result_dot = -dot(input_vector, normal); +} diff --git a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_separate_combine.glsl b/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_separate_combine.glsl new file mode 100644 index 00000000000..d72d2260394 --- /dev/null +++ b/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_separate_combine.glsl @@ -0,0 +1,132 @@ +#pragma BLENDER_REQUIRE(gpu_shader_common_color_utils.glsl) + +/* ** Combine/Separate XYZ ** */ + +void node_composite_combine_xyz(float x, float y, float z, out vec3 vector) +{ + vector = vec3(x, y, z); +} + +void node_composite_separate_xyz(vec3 vector, out float x, out float y, out float z) +{ + x = vector.x; + y = vector.y; + z = vector.z; +} + +/* ** Combine/Separate RGBA ** */ + +void node_composite_combine_rgba(float r, float g, float b, float a, out vec4 color) +{ + color = vec4(r, g, b, a); +} + +void node_composite_separate_rgba(vec4 color, out float r, out float g, out float b, out float a) +{ + r = color.r; + g = color.g; + b = color.b; + a = color.a; +} + +/* ** Combine/Separate HSVA ** */ + +void node_composite_combine_hsva(float h, float s, float v, float a, out vec4 color) +{ + hsv_to_rgb(vec4(h, s, v, a), color); +} + +void node_composite_separate_hsva(vec4 color, out float h, out float s, out float v, out float a) +{ + vec4 hsva; + rgb_to_hsv(color, hsva); + h = hsva.x; + s = hsva.y; + v = hsva.z; + a = hsva.a; +} + +/* ** Combine/Separate HSLA ** */ + +void node_composite_combine_hsla(float h, float s, float l, float a, out vec4 color) +{ + hsl_to_rgb(vec4(h, s, l, a), color); +} + +void node_composite_separate_hsla(vec4 color, out float h, out float s, out float l, out float a) +{ + vec4 hsla; + rgb_to_hsl(color, hsla); + h = hsla.x; + s = hsla.y; + l = hsla.z; + a = hsla.a; +} + +/* ** Combine/Separate YCCA ** */ + +void node_composite_combine_ycca_itu_601(float y, float cb, float cr, float a, out vec4 color) +{ + ycca_to_rgba_itu_601(vec4(y, cb, cr, a), color); +} + +void node_composite_combine_ycca_itu_709(float y, float cb, float cr, float a, out vec4 color) +{ + ycca_to_rgba_itu_709(vec4(y, cb, cr, a), color); +} + +void node_composite_combine_ycca_jpeg(float y, float cb, float cr, float a, out vec4 color) +{ + ycca_to_rgba_jpeg(vec4(y, cb, cr, a), color); +} + +void node_composite_separate_ycca_itu_601( + vec4 color, out float y, out float cb, out float cr, out float a) +{ + vec4 ycca; + rgba_to_ycca_itu_601(color, ycca); + y = ycca.x; + cb = ycca.y; + cr = ycca.z; + a = ycca.a; +} + +void node_composite_separate_ycca_itu_709( + vec4 color, out float y, out float cb, out float cr, out float a) +{ + vec4 ycca; + rgba_to_ycca_itu_709(color, ycca); + y = ycca.x; + cb = ycca.y; + cr = ycca.z; + a = ycca.a; +} + +void node_composite_separate_ycca_jpeg( + vec4 color, out float y, out float cb, out float cr, out float a) +{ + vec4 ycca; + rgba_to_ycca_jpeg(color, ycca); + y = ycca.x; + cb = ycca.y; + cr = ycca.z; + a = ycca.a; +} + +/* ** Combine/Separate YUVA ** */ + +void node_composite_combine_yuva_itu_709(float y, float u, float v, float a, out vec4 color) +{ + yuva_to_rgba_itu_709(vec4(y, u, v, a), color); +} + +void node_composite_separate_yuva_itu_709( + vec4 color, out float y, out float u, out float v, out float a) +{ + vec4 yuva; + rgba_to_yuva_itu_709(color, yuva); + y = yuva.x; + u = yuva.y; + v = yuva.z; + a = yuva.a; +} diff --git a/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_set_alpha.glsl b/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_set_alpha.glsl new file mode 100644 index 00000000000..95380d1ed0f --- /dev/null +++ b/source/blender/gpu/shaders/compositor/library/gpu_shader_compositor_set_alpha.glsl @@ -0,0 +1,9 @@ +void node_composite_set_alpha_apply(vec4 color, float alpha, out vec4 result) +{ + result = color * alpha; +} + +void node_composite_set_alpha_replace(vec4 color, float alpha, out vec4 result) +{ + result = vec4(color.rgb, alpha); +} diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index a0e08267efe..b60d69bcd8a 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -1850,6 +1850,12 @@ typedef enum CMPNodeColorBalanceMethod { CMP_NODE_COLOR_BALANCE_ASC_CDL = 1, } CMPNodeColorBalanceMethod; +/* Alpha Convert Node. Stored in custom1. */ +typedef enum CMPNodeAlphaConvertMode { + CMP_NODE_ALPHA_CONVERT_PREMULTIPLY = 0, + CMP_NODE_ALPHA_CONVERT_UNPREMULTIPLY = 1, +} CMPNodeAlphaConvertMode; + /* Plane track deform node. */ enum { diff --git a/source/blender/nodes/composite/CMakeLists.txt b/source/blender/nodes/composite/CMakeLists.txt index 5034ddc4a30..2537e8e93cc 100644 --- a/source/blender/nodes/composite/CMakeLists.txt +++ b/source/blender/nodes/composite/CMakeLists.txt @@ -10,6 +10,7 @@ set(INC ../../blenlib ../../blentranslation ../../depsgraph + ../../functions ../../gpu ../../imbuf ../../makesdna diff --git a/source/blender/nodes/composite/nodes/node_composite_map_range.cc b/source/blender/nodes/composite/nodes/node_composite_map_range.cc index e52c6d096b9..e72869efa93 100644 --- a/source/blender/nodes/composite/nodes/node_composite_map_range.cc +++ b/source/blender/nodes/composite/nodes/node_composite_map_range.cc @@ -8,6 +8,10 @@ #include "UI_interface.h" #include "UI_resources.h" +#include "GPU_material.h" + +#include "COM_shader_node.hh" + #include "node_composite_util.hh" /* **************** Map Range ******************** */ @@ -16,11 +20,31 @@ namespace blender::nodes::node_composite_map_range_cc { static void cmp_node_map_range_declare(NodeDeclarationBuilder &b) { - b.add_input<decl::Float>(N_("Value")).default_value(1.0f).min(0.0f).max(1.0f); - b.add_input<decl::Float>(N_("From Min")).default_value(0.0f).min(-10000.0f).max(10000.0f); - b.add_input<decl::Float>(N_("From Max")).default_value(1.0f).min(-10000.0f).max(10000.0f); - b.add_input<decl::Float>(N_("To Min")).default_value(0.0f).min(-10000.0f).max(10000.0f); - b.add_input<decl::Float>(N_("To Max")).default_value(1.0f).min(-10000.0f).max(10000.0f); + b.add_input<decl::Float>(N_("Value")) + .default_value(1.0f) + .min(0.0f) + .max(1.0f) + .compositor_domain_priority(0); + b.add_input<decl::Float>(N_("From Min")) + .default_value(0.0f) + .min(-10000.0f) + .max(10000.0f) + .compositor_domain_priority(1); + b.add_input<decl::Float>(N_("From Max")) + .default_value(1.0f) + .min(-10000.0f) + .max(10000.0f) + .compositor_domain_priority(2); + b.add_input<decl::Float>(N_("To Min")) + .default_value(0.0f) + .min(-10000.0f) + .max(10000.0f) + .compositor_domain_priority(3); + b.add_input<decl::Float>(N_("To Max")) + .default_value(1.0f) + .min(-10000.0f) + .max(10000.0f) + .compositor_domain_priority(4); b.add_output<decl::Float>(N_("Value")); } @@ -32,6 +56,38 @@ static void node_composit_buts_map_range(uiLayout *layout, bContext *UNUSED(C), uiItemR(col, ptr, "use_clamp", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, ICON_NONE); } +using namespace blender::realtime_compositor; + +class MapRangeShaderNode : public ShaderNode { + public: + using ShaderNode::ShaderNode; + + void compile(GPUMaterial *material) override + { + GPUNodeStack *inputs = get_inputs_array(); + GPUNodeStack *outputs = get_outputs_array(); + + const float should_clamp = get_should_clamp(); + + GPU_stack_link(material, + &bnode(), + "node_composite_map_range", + inputs, + outputs, + GPU_constant(&should_clamp)); + } + + bool get_should_clamp() + { + return bnode().custom1; + } +}; + +static ShaderNode *get_compositor_shader_node(DNode node) +{ + return new MapRangeShaderNode(node); +} + } // namespace blender::nodes::node_composite_map_range_cc void register_node_type_cmp_map_range() @@ -43,6 +99,7 @@ void register_node_type_cmp_map_range() cmp_node_type_base(&ntype, CMP_NODE_MAP_RANGE, "Map Range", NODE_CLASS_OP_VECTOR); ntype.declare = file_ns::cmp_node_map_range_declare; ntype.draw_buttons = file_ns::node_composit_buts_map_range; + ntype.get_compositor_shader_node = file_ns::get_compositor_shader_node; nodeRegisterType(&ntype); } diff --git a/source/blender/nodes/composite/nodes/node_composite_map_value.cc b/source/blender/nodes/composite/nodes/node_composite_map_value.cc index bb42628ed3d..ec9b2d56636 100644 --- a/source/blender/nodes/composite/nodes/node_composite_map_value.cc +++ b/source/blender/nodes/composite/nodes/node_composite_map_value.cc @@ -12,6 +12,10 @@ #include "UI_interface.h" #include "UI_resources.h" +#include "GPU_material.h" + +#include "COM_shader_node.hh" + #include "node_composite_util.hh" /* **************** MAP VALUE ******************** */ @@ -20,7 +24,11 @@ namespace blender::nodes::node_composite_map_value_cc { static void cmp_node_map_value_declare(NodeDeclarationBuilder &b) { - b.add_input<decl::Float>(N_("Value")).default_value(1.0f).min(0.0f).max(1.0f); + b.add_input<decl::Float>(N_("Value")) + .default_value(1.0f) + .min(0.0f) + .max(1.0f) + .compositor_domain_priority(0); b.add_output<decl::Float>(N_("Value")); } @@ -50,6 +58,56 @@ static void node_composit_buts_map_value(uiLayout *layout, bContext *UNUSED(C), uiItemR(sub, ptr, "max", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE); } +using namespace blender::realtime_compositor; + +class MapValueShaderNode : public ShaderNode { + public: + using ShaderNode::ShaderNode; + + void compile(GPUMaterial *material) override + { + GPUNodeStack *inputs = get_inputs_array(); + GPUNodeStack *outputs = get_outputs_array(); + + const TexMapping *texture_mapping = get_texture_mapping(); + + const float use_min = get_use_min(); + const float use_max = get_use_max(); + + GPU_stack_link(material, + &bnode(), + "node_composite_map_value", + inputs, + outputs, + GPU_uniform(texture_mapping->loc), + GPU_uniform(texture_mapping->size), + GPU_constant(&use_min), + GPU_uniform(texture_mapping->min), + GPU_constant(&use_max), + GPU_uniform(texture_mapping->max)); + } + + TexMapping *get_texture_mapping() + { + return static_cast<TexMapping *>(bnode().storage); + } + + bool get_use_min() + { + return get_texture_mapping()->flag & TEXMAP_CLIP_MIN; + } + + bool get_use_max() + { + return get_texture_mapping()->flag & TEXMAP_CLIP_MAX; + } +}; + +static ShaderNode *get_compositor_shader_node(DNode node) +{ + return new MapValueShaderNode(node); +} + } // namespace blender::nodes::node_composite_map_value_cc void register_node_type_cmp_map_value() @@ -63,6 +121,7 @@ void register_node_type_cmp_map_value() ntype.draw_buttons = file_ns::node_composit_buts_map_value; node_type_init(&ntype, file_ns::node_composit_init_map_value); node_type_storage(&ntype, "TexMapping", node_free_standard_storage, node_copy_standard_storage); + ntype.get_compositor_shader_node = file_ns::get_compositor_shader_node; nodeRegisterType(&ntype); } diff --git a/source/blender/nodes/composite/nodes/node_composite_math.cc b/source/blender/nodes/composite/nodes/node_composite_math.cc index 7b2eadef2cb..4baf057913e 100644 --- a/source/blender/nodes/composite/nodes/node_composite_math.cc +++ b/source/blender/nodes/composite/nodes/node_composite_math.cc @@ -5,6 +5,12 @@ * \ingroup cmpnodes */ +#include "GPU_material.h" + +#include "COM_shader_node.hh" + +#include "NOD_math_functions.hh" + #include "node_composite_util.hh" /* **************** SCALAR MATH ******************** */ @@ -13,18 +19,72 @@ namespace blender::nodes::node_composite_math_cc { static void cmp_node_math_declare(NodeDeclarationBuilder &b) { - b.add_input<decl::Float>(N_("Value")).default_value(0.5f).min(-10000.0f).max(10000.0f); + b.add_input<decl::Float>(N_("Value")) + .default_value(0.5f) + .min(-10000.0f) + .max(10000.0f) + .compositor_domain_priority(0); b.add_input<decl::Float>(N_("Value"), "Value_001") .default_value(0.5f) .min(-10000.0f) - .max(10000.0f); + .max(10000.0f) + .compositor_domain_priority(1); b.add_input<decl::Float>(N_("Value"), "Value_002") .default_value(0.5f) .min(-10000.0f) - .max(10000.0f); + .max(10000.0f) + .compositor_domain_priority(2); b.add_output<decl::Float>(N_("Value")); } +using namespace blender::realtime_compositor; + +class MathShaderNode : public ShaderNode { + public: + using ShaderNode::ShaderNode; + + void compile(GPUMaterial *material) override + { + GPUNodeStack *inputs = get_inputs_array(); + GPUNodeStack *outputs = get_outputs_array(); + + GPU_stack_link(material, &bnode(), get_shader_function_name(), inputs, outputs); + + if (!get_should_clamp()) { + return; + } + + const float min = 0.0f; + const float max = 1.0f; + GPU_link(material, + "clamp_value", + get_output("Value").link, + GPU_constant(&min), + GPU_constant(&max), + &get_output("Value").link); + } + + NodeMathOperation get_operation() + { + return (NodeMathOperation)bnode().custom1; + } + + const char *get_shader_function_name() + { + return get_float_math_operation_info(get_operation())->shader_name.c_str(); + } + + bool get_should_clamp() + { + return bnode().custom2 & SHD_MATH_CLAMP; + } +}; + +static ShaderNode *get_compositor_shader_node(DNode node) +{ + return new MathShaderNode(node); +} + } // namespace blender::nodes::node_composite_math_cc void register_node_type_cmp_math() @@ -37,6 +97,7 @@ void register_node_type_cmp_math() ntype.declare = file_ns::cmp_node_math_declare; ntype.labelfunc = node_math_label; node_type_update(&ntype, node_math_update); + ntype.get_compositor_shader_node = file_ns::get_compositor_shader_node; nodeRegisterType(&ntype); } diff --git a/source/blender/nodes/composite/nodes/node_composite_normal.cc b/source/blender/nodes/composite/nodes/node_composite_normal.cc index b4dd0bbacd0..f61ace01cfd 100644 --- a/source/blender/nodes/composite/nodes/node_composite_normal.cc +++ b/source/blender/nodes/composite/nodes/node_composite_normal.cc @@ -5,6 +5,10 @@ * \ingroup cmpnodes */ +#include "GPU_material.h" + +#include "COM_shader_node.hh" + #include "node_composite_util.hh" /* **************** NORMAL ******************** */ @@ -17,7 +21,8 @@ static void cmp_node_normal_declare(NodeDeclarationBuilder &b) .default_value({0.0f, 0.0f, 1.0f}) .min(-1.0f) .max(1.0f) - .subtype(PROP_DIRECTION); + .subtype(PROP_DIRECTION) + .compositor_domain_priority(0); b.add_output<decl::Vector>(N_("Normal")) .default_value({0.0f, 0.0f, 1.0f}) .min(-1.0f) @@ -26,6 +31,37 @@ static void cmp_node_normal_declare(NodeDeclarationBuilder &b) b.add_output<decl::Float>(N_("Dot")); } +using namespace blender::realtime_compositor; + +class NormalShaderNode : public ShaderNode { + public: + using ShaderNode::ShaderNode; + + void compile(GPUMaterial *material) override + { + GPUNodeStack *inputs = get_inputs_array(); + GPUNodeStack *outputs = get_outputs_array(); + + GPU_stack_link(material, + &bnode(), + "node_composite_normal", + inputs, + outputs, + GPU_uniform(get_vector_value())); + } + + /* The vector value is stored in the default value of the output socket. */ + float *get_vector_value() + { + return node().output_by_identifier("Normal")->default_value<bNodeSocketValueVector>()->value; + } +}; + +static ShaderNode *get_compositor_shader_node(DNode node) +{ + return new NormalShaderNode(node); +} + } // namespace blender::nodes::node_composite_normal_cc void register_node_type_cmp_normal() @@ -36,6 +72,7 @@ void register_node_type_cmp_normal() cmp_node_type_base(&ntype, CMP_NODE_NORMAL, "Normal", NODE_CLASS_OP_VECTOR); ntype.declare = file_ns::cmp_node_normal_declare; + ntype.get_compositor_shader_node = file_ns::get_compositor_shader_node; nodeRegisterType(&ntype); } diff --git a/source/blender/nodes/composite/nodes/node_composite_premulkey.cc b/source/blender/nodes/composite/nodes/node_composite_premulkey.cc index 000cc9df90a..c814ea5f738 100644 --- a/source/blender/nodes/composite/nodes/node_composite_premulkey.cc +++ b/source/blender/nodes/composite/nodes/node_composite_premulkey.cc @@ -8,6 +8,10 @@ #include "UI_interface.h" #include "UI_resources.h" +#include "GPU_material.h" + +#include "COM_shader_node.hh" + #include "node_composite_util.hh" /* **************** Premul and Key Alpha Convert ******************** */ @@ -16,7 +20,9 @@ namespace blender::nodes::node_composite_premulkey_cc { static void cmp_node_premulkey_declare(NodeDeclarationBuilder &b) { - b.add_input<decl::Color>(N_("Image")).default_value({1.0f, 1.0f, 1.0f, 1.0f}); + b.add_input<decl::Color>(N_("Image")) + .default_value({1.0f, 1.0f, 1.0f, 1.0f}) + .compositor_domain_priority(0); b.add_output<decl::Color>(N_("Image")); } @@ -25,6 +31,36 @@ static void node_composit_buts_premulkey(uiLayout *layout, bContext *UNUSED(C), uiItemR(layout, ptr, "mapping", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE); } +using namespace blender::realtime_compositor; + +class AlphaConvertShaderNode : public ShaderNode { + public: + using ShaderNode::ShaderNode; + + void compile(GPUMaterial *material) override + { + GPUNodeStack *inputs = get_inputs_array(); + GPUNodeStack *outputs = get_outputs_array(); + + if (get_mode() == 0) { + GPU_stack_link(material, &bnode(), "color_alpha_premultiply", inputs, outputs); + return; + } + + GPU_stack_link(material, &bnode(), "color_alpha_unpremultiply", inputs, outputs); + } + + CMPNodeAlphaConvertMode get_mode() + { + return (CMPNodeAlphaConvertMode)bnode().custom1; + } +}; + +static ShaderNode *get_compositor_shader_node(DNode node) +{ + return new AlphaConvertShaderNode(node); +} + } // namespace blender::nodes::node_composite_premulkey_cc void register_node_type_cmp_premulkey() @@ -36,6 +72,7 @@ void register_node_type_cmp_premulkey() cmp_node_type_base(&ntype, CMP_NODE_PREMULKEY, "Alpha Convert", NODE_CLASS_CONVERTER); ntype.declare = file_ns::cmp_node_premulkey_declare; ntype.draw_buttons = file_ns::node_composit_buts_premulkey; + ntype.get_compositor_shader_node = file_ns::get_compositor_shader_node; nodeRegisterType(&ntype); } diff --git a/source/blender/nodes/composite/nodes/node_composite_sepcomb_color.cc b/source/blender/nodes/composite/nodes/node_composite_sepcomb_color.cc index b253656a628..d1f0b7977f8 100644 --- a/source/blender/nodes/composite/nodes/node_composite_sepcomb_color.cc +++ b/source/blender/nodes/composite/nodes/node_composite_sepcomb_color.cc @@ -1,5 +1,11 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */ +#include "BLI_assert.h" + +#include "GPU_material.h" + +#include "COM_shader_node.hh" + #include "node_composite_util.hh" static void node_cmp_combsep_color_init(bNodeTree *UNUSED(ntree), bNode *node) @@ -58,7 +64,9 @@ namespace blender::nodes::node_composite_separate_color_cc { static void cmp_node_separate_color_declare(NodeDeclarationBuilder &b) { - b.add_input<decl::Color>(N_("Image")).default_value({1.0f, 1.0f, 1.0f, 1.0f}); + b.add_input<decl::Color>(N_("Image")) + .default_value({1.0f, 1.0f, 1.0f, 1.0f}) + .compositor_domain_priority(0); b.add_output<decl::Float>(N_("Red")); b.add_output<decl::Float>(N_("Green")); b.add_output<decl::Float>(N_("Blue")); @@ -71,6 +79,57 @@ static void cmp_node_separate_color_update(bNodeTree *UNUSED(ntree), bNode *node node_cmp_combsep_color_label(&node->outputs, (CMPNodeCombSepColorMode)storage->mode); } +using namespace blender::realtime_compositor; + +class SeparateColorShaderNode : public ShaderNode { + public: + using ShaderNode::ShaderNode; + + void compile(GPUMaterial *material) override + { + GPUNodeStack *inputs = get_inputs_array(); + GPUNodeStack *outputs = get_outputs_array(); + + GPU_stack_link(material, &bnode(), get_shader_function_name(), inputs, outputs); + } + + NodeCMPCombSepColor *get_node_combine_separate_color() + { + return static_cast<NodeCMPCombSepColor *>(bnode().storage); + } + + const char *get_shader_function_name() + { + switch (get_node_combine_separate_color()->mode) { + case CMP_NODE_COMBSEP_COLOR_RGB: + return "node_composite_separate_rgba"; + case CMP_NODE_COMBSEP_COLOR_HSV: + return "node_composite_separate_hsva"; + case CMP_NODE_COMBSEP_COLOR_HSL: + return "node_composite_separate_hsla"; + case CMP_NODE_COMBSEP_COLOR_YUV: + return "node_composite_separate_yuva_itu_709"; + case CMP_NODE_COMBSEP_COLOR_YCC: + switch (get_node_combine_separate_color()->ycc_mode) { + case BLI_YCC_ITU_BT601: + return "node_composite_separate_ycca_itu_601"; + case BLI_YCC_ITU_BT709: + return "node_composite_separate_ycca_itu_709"; + case BLI_YCC_JFIF_0_255: + return "node_composite_separate_ycca_jpeg"; + } + } + + BLI_assert_unreachable(); + return nullptr; + } +}; + +static ShaderNode *get_compositor_shader_node(DNode node) +{ + return new SeparateColorShaderNode(node); +} + } // namespace blender::nodes::node_composite_separate_color_cc void register_node_type_cmp_separate_color() @@ -85,6 +144,7 @@ void register_node_type_cmp_separate_color() node_type_storage( &ntype, "NodeCMPCombSepColor", node_free_standard_storage, node_copy_standard_storage); node_type_update(&ntype, file_ns::cmp_node_separate_color_update); + ntype.get_compositor_shader_node = file_ns::get_compositor_shader_node; nodeRegisterType(&ntype); } @@ -95,22 +155,30 @@ namespace blender::nodes::node_composite_combine_color_cc { static void cmp_node_combine_color_declare(NodeDeclarationBuilder &b) { - b.add_input<decl::Float>(N_("Red")).default_value(0.0f).min(0.0f).max(1.0f).subtype(PROP_FACTOR); + b.add_input<decl::Float>(N_("Red")) + .default_value(0.0f) + .min(0.0f) + .max(1.0f) + .subtype(PROP_FACTOR) + .compositor_domain_priority(0); b.add_input<decl::Float>(N_("Green")) .default_value(0.0f) .min(0.0f) .max(1.0f) - .subtype(PROP_FACTOR); + .subtype(PROP_FACTOR) + .compositor_domain_priority(1); b.add_input<decl::Float>(N_("Blue")) .default_value(0.0f) .min(0.0f) .max(1.0f) - .subtype(PROP_FACTOR); + .subtype(PROP_FACTOR) + .compositor_domain_priority(2); b.add_input<decl::Float>(N_("Alpha")) .default_value(1.0f) .min(0.0f) .max(1.0f) - .subtype(PROP_FACTOR); + .subtype(PROP_FACTOR) + .compositor_domain_priority(3); b.add_output<decl::Color>(N_("Image")); } @@ -120,6 +188,57 @@ static void cmp_node_combine_color_update(bNodeTree *UNUSED(ntree), bNode *node) node_cmp_combsep_color_label(&node->inputs, (CMPNodeCombSepColorMode)storage->mode); } +using namespace blender::realtime_compositor; + +class CombineColorShaderNode : public ShaderNode { + public: + using ShaderNode::ShaderNode; + + void compile(GPUMaterial *material) override + { + GPUNodeStack *inputs = get_inputs_array(); + GPUNodeStack *outputs = get_outputs_array(); + + GPU_stack_link(material, &bnode(), get_shader_function_name(), inputs, outputs); + } + + NodeCMPCombSepColor *get_node_combine_separate_color() + { + return static_cast<NodeCMPCombSepColor *>(bnode().storage); + } + + const char *get_shader_function_name() + { + switch (get_node_combine_separate_color()->mode) { + case CMP_NODE_COMBSEP_COLOR_RGB: + return "node_composite_combine_rgba"; + case CMP_NODE_COMBSEP_COLOR_HSV: + return "node_composite_combine_hsva"; + case CMP_NODE_COMBSEP_COLOR_HSL: + return "node_composite_combine_hsla"; + case CMP_NODE_COMBSEP_COLOR_YUV: + return "node_composite_combine_yuva_itu_709"; + case CMP_NODE_COMBSEP_COLOR_YCC: + switch (get_node_combine_separate_color()->ycc_mode) { + case BLI_YCC_ITU_BT601: + return "node_composite_combine_ycca_itu_601"; + case BLI_YCC_ITU_BT709: + return "node_composite_combine_ycca_itu_709"; + case BLI_YCC_JFIF_0_255: + return "node_composite_combine_ycca_jpeg"; + } + } + + BLI_assert_unreachable(); + return nullptr; + } +}; + +static ShaderNode *get_compositor_shader_node(DNode node) +{ + return new CombineColorShaderNode(node); +} + } // namespace blender::nodes::node_composite_combine_color_cc void register_node_type_cmp_combine_color() @@ -134,6 +253,7 @@ void register_node_type_cmp_combine_color() node_type_storage( &ntype, "NodeCMPCombSepColor", node_free_standard_storage, node_copy_standard_storage); node_type_update(&ntype, file_ns::cmp_node_combine_color_update); + ntype.get_compositor_shader_node = file_ns::get_compositor_shader_node; nodeRegisterType(&ntype); } diff --git a/source/blender/nodes/composite/nodes/node_composite_sepcomb_hsva.cc b/source/blender/nodes/composite/nodes/node_composite_sepcomb_hsva.cc index a169f7e0dd3..b655c0db106 100644 --- a/source/blender/nodes/composite/nodes/node_composite_sepcomb_hsva.cc +++ b/source/blender/nodes/composite/nodes/node_composite_sepcomb_hsva.cc @@ -5,60 +5,112 @@ * \ingroup cmpnodes */ +#include "GPU_material.h" + +#include "COM_shader_node.hh" + #include "node_composite_util.hh" /* **************** SEPARATE HSVA ******************** */ -namespace blender::nodes::node_composite_sepcomb_hsva_cc { +namespace blender::nodes::node_composite_separate_hsva_cc { static void cmp_node_sephsva_declare(NodeDeclarationBuilder &b) { - b.add_input<decl::Color>(N_("Image")).default_value({1.0f, 1.0f, 1.0f, 1.0f}); + b.add_input<decl::Color>(N_("Image")) + .default_value({1.0f, 1.0f, 1.0f, 1.0f}) + .compositor_domain_priority(0); b.add_output<decl::Float>(N_("H")); b.add_output<decl::Float>(N_("S")); b.add_output<decl::Float>(N_("V")); b.add_output<decl::Float>(N_("A")); } -} // namespace blender::nodes::node_composite_sepcomb_hsva_cc +using namespace blender::realtime_compositor; + +class SeparateHSVAShaderNode : public ShaderNode { + public: + using ShaderNode::ShaderNode; + + void compile(GPUMaterial *material) override + { + GPUNodeStack *inputs = get_inputs_array(); + GPUNodeStack *outputs = get_outputs_array(); + + GPU_stack_link(material, &bnode(), "node_composite_separate_hsva", inputs, outputs); + } +}; + +static ShaderNode *get_compositor_shader_node(DNode node) +{ + return new SeparateHSVAShaderNode(node); +} + +} // namespace blender::nodes::node_composite_separate_hsva_cc void register_node_type_cmp_sephsva() { - namespace file_ns = blender::nodes::node_composite_sepcomb_hsva_cc; + namespace file_ns = blender::nodes::node_composite_separate_hsva_cc; static bNodeType ntype; cmp_node_type_base(&ntype, CMP_NODE_SEPHSVA_LEGACY, "Separate HSVA", NODE_CLASS_CONVERTER); ntype.declare = file_ns::cmp_node_sephsva_declare; ntype.gather_link_search_ops = nullptr; + ntype.get_compositor_shader_node = file_ns::get_compositor_shader_node; nodeRegisterType(&ntype); } /* **************** COMBINE HSVA ******************** */ -namespace blender::nodes::node_composite_sepcomb_hsva_cc { +namespace blender::nodes::node_composite_combine_hsva_cc { static void cmp_node_combhsva_declare(NodeDeclarationBuilder &b) { - b.add_input<decl::Float>(N_("H")).min(0.0f).max(1.0f); - b.add_input<decl::Float>(N_("S")).min(0.0f).max(1.0f); - b.add_input<decl::Float>(N_("V")).min(0.0f).max(1.0f); - b.add_input<decl::Float>(N_("A")).default_value(1.0f).min(0.0f).max(1.0f); + b.add_input<decl::Float>(N_("H")).min(0.0f).max(1.0f).compositor_domain_priority(0); + b.add_input<decl::Float>(N_("S")).min(0.0f).max(1.0f).compositor_domain_priority(1); + b.add_input<decl::Float>(N_("V")).min(0.0f).max(1.0f).compositor_domain_priority(2); + b.add_input<decl::Float>(N_("A")) + .default_value(1.0f) + .min(0.0f) + .max(1.0f) + .compositor_domain_priority(3); b.add_output<decl::Color>(N_("Image")); } -} // namespace blender::nodes::node_composite_sepcomb_hsva_cc +using namespace blender::realtime_compositor; + +class CombineHSVAShaderNode : public ShaderNode { + public: + using ShaderNode::ShaderNode; + + void compile(GPUMaterial *material) override + { + GPUNodeStack *inputs = get_inputs_array(); + GPUNodeStack *outputs = get_outputs_array(); + + GPU_stack_link(material, &bnode(), "node_composite_combine_hsva", inputs, outputs); + } +}; + +static ShaderNode *get_compositor_shader_node(DNode node) +{ + return new CombineHSVAShaderNode(node); +} + +} // namespace blender::nodes::node_composite_combine_hsva_cc void register_node_type_cmp_combhsva() { - namespace file_ns = blender::nodes::node_composite_sepcomb_hsva_cc; + namespace file_ns = blender::nodes::node_composite_combine_hsva_cc; static bNodeType ntype; cmp_node_type_base(&ntype, CMP_NODE_COMBHSVA_LEGACY, "Combine HSVA", NODE_CLASS_CONVERTER); ntype.declare = file_ns::cmp_node_combhsva_declare; ntype.gather_link_search_ops = nullptr; + ntype.get_compositor_shader_node = file_ns::get_compositor_shader_node; nodeRegisterType(&ntype); } diff --git a/source/blender/nodes/composite/nodes/node_composite_sepcomb_rgba.cc b/source/blender/nodes/composite/nodes/node_composite_sepcomb_rgba.cc index a243500b56d..1f4c9fd153f 100644 --- a/source/blender/nodes/composite/nodes/node_composite_sepcomb_rgba.cc +++ b/source/blender/nodes/composite/nodes/node_composite_sepcomb_rgba.cc @@ -5,59 +5,112 @@ * \ingroup cmpnodes */ +#include "GPU_material.h" + +#include "COM_shader_node.hh" + #include "node_composite_util.hh" /* **************** SEPARATE RGBA ******************** */ -namespace blender::nodes::node_composite_sepcomb_rgba_cc { + +namespace blender::nodes::node_composite_separate_rgba_cc { static void cmp_node_seprgba_declare(NodeDeclarationBuilder &b) { - b.add_input<decl::Color>(N_("Image")).default_value({1.0f, 1.0f, 1.0f, 1.0f}); + b.add_input<decl::Color>(N_("Image")) + .default_value({1.0f, 1.0f, 1.0f, 1.0f}) + .compositor_domain_priority(0); b.add_output<decl::Float>(N_("R")); b.add_output<decl::Float>(N_("G")); b.add_output<decl::Float>(N_("B")); b.add_output<decl::Float>(N_("A")); } -} // namespace blender::nodes::node_composite_sepcomb_rgba_cc +using namespace blender::realtime_compositor; + +class SeparateRGBAShaderNode : public ShaderNode { + public: + using ShaderNode::ShaderNode; + + void compile(GPUMaterial *material) override + { + GPUNodeStack *inputs = get_inputs_array(); + GPUNodeStack *outputs = get_outputs_array(); + + GPU_stack_link(material, &bnode(), "node_composite_separate_rgba", inputs, outputs); + } +}; + +static ShaderNode *get_compositor_shader_node(DNode node) +{ + return new SeparateRGBAShaderNode(node); +} + +} // namespace blender::nodes::node_composite_separate_rgba_cc void register_node_type_cmp_seprgba() { - namespace file_ns = blender::nodes::node_composite_sepcomb_rgba_cc; + namespace file_ns = blender::nodes::node_composite_separate_rgba_cc; static bNodeType ntype; cmp_node_type_base(&ntype, CMP_NODE_SEPRGBA_LEGACY, "Separate RGBA", NODE_CLASS_CONVERTER); ntype.declare = file_ns::cmp_node_seprgba_declare; ntype.gather_link_search_ops = nullptr; + ntype.get_compositor_shader_node = file_ns::get_compositor_shader_node; nodeRegisterType(&ntype); } /* **************** COMBINE RGBA ******************** */ -namespace blender::nodes::node_composite_sepcomb_rgba_cc { +namespace blender::nodes::node_composite_combine_rgba_cc { static void cmp_node_combrgba_declare(NodeDeclarationBuilder &b) { - b.add_input<decl::Float>(N_("R")).min(0.0f).max(1.0f); - b.add_input<decl::Float>(N_("G")).min(0.0f).max(1.0f); - b.add_input<decl::Float>(N_("B")).min(0.0f).max(1.0f); - b.add_input<decl::Float>(N_("A")).default_value(1.0f).min(0.0f).max(1.0f); + b.add_input<decl::Float>(N_("R")).min(0.0f).max(1.0f).compositor_domain_priority(0); + b.add_input<decl::Float>(N_("G")).min(0.0f).max(1.0f).compositor_domain_priority(1); + b.add_input<decl::Float>(N_("B")).min(0.0f).max(1.0f).compositor_domain_priority(2); + b.add_input<decl::Float>(N_("A")) + .default_value(1.0f) + .min(0.0f) + .max(1.0f) + .compositor_domain_priority(3); b.add_output<decl::Color>(N_("Image")); } -} // namespace blender::nodes::node_composite_sepcomb_rgba_cc +using namespace blender::realtime_compositor; + +class CombineRGBAShaderNode : public ShaderNode { + public: + using ShaderNode::ShaderNode; + + void compile(GPUMaterial *material) override + { + GPUNodeStack *inputs = get_inputs_array(); + GPUNodeStack *outputs = get_outputs_array(); + + GPU_stack_link(material, &bnode(), "node_composite_combine_rgba", inputs, outputs); + } +}; + +static ShaderNode *get_compositor_shader_node(DNode node) +{ + return new CombineRGBAShaderNode(node); +} + +} // namespace blender::nodes::node_composite_combine_rgba_cc void register_node_type_cmp_combrgba() { - namespace file_ns = blender::nodes::node_composite_sepcomb_rgba_cc; + namespace file_ns = blender::nodes::node_composite_combine_rgba_cc; static bNodeType ntype; cmp_node_type_base(&ntype, CMP_NODE_COMBRGBA_LEGACY, "Combine RGBA", NODE_CLASS_CONVERTER); ntype.declare = file_ns::cmp_node_combrgba_declare; ntype.gather_link_search_ops = nullptr; + ntype.get_compositor_shader_node = file_ns::get_compositor_shader_node; nodeRegisterType(&ntype); } diff --git a/source/blender/nodes/composite/nodes/node_composite_sepcomb_xyz.cc b/source/blender/nodes/composite/nodes/node_composite_sepcomb_xyz.cc index 4979c376cab..e288e698808 100644 --- a/source/blender/nodes/composite/nodes/node_composite_sepcomb_xyz.cc +++ b/source/blender/nodes/composite/nodes/node_composite_sepcomb_xyz.cc @@ -5,10 +5,15 @@ * \ingroup cmpnodes */ +#include "GPU_material.h" + +#include "COM_shader_node.hh" + #include "node_composite_util.hh" /* **************** SEPARATE XYZ ******************** */ -namespace blender::nodes { + +namespace blender::nodes::node_composite_separate_xyz_cc { static void cmp_node_separate_xyz_declare(NodeDeclarationBuilder &b) { @@ -18,21 +23,44 @@ static void cmp_node_separate_xyz_declare(NodeDeclarationBuilder &b) b.add_output<decl::Float>("Z"); } -} // namespace blender::nodes +using namespace blender::realtime_compositor; + +class SeparateXYZShaderNode : public ShaderNode { + public: + using ShaderNode::ShaderNode; + + void compile(GPUMaterial *material) override + { + GPUNodeStack *inputs = get_inputs_array(); + GPUNodeStack *outputs = get_outputs_array(); + + GPU_stack_link(material, &bnode(), "node_composite_separate_xyz", inputs, outputs); + } +}; + +static ShaderNode *get_compositor_shader_node(DNode node) +{ + return new SeparateXYZShaderNode(node); +} + +} // namespace blender::nodes::node_composite_separate_xyz_cc void register_node_type_cmp_separate_xyz() { + namespace file_ns = blender::nodes::node_composite_separate_xyz_cc; + static bNodeType ntype; cmp_node_type_base(&ntype, CMP_NODE_SEPARATE_XYZ, "Separate XYZ", NODE_CLASS_CONVERTER); - ntype.declare = blender::nodes::cmp_node_separate_xyz_declare; + ntype.declare = file_ns::cmp_node_separate_xyz_declare; + ntype.get_compositor_shader_node = file_ns::get_compositor_shader_node; nodeRegisterType(&ntype); } /* **************** COMBINE XYZ ******************** */ -namespace blender::nodes { +namespace blender::nodes::node_composite_combine_xyz_cc { static void cmp_node_combine_xyz_declare(NodeDeclarationBuilder &b) { @@ -42,14 +70,37 @@ static void cmp_node_combine_xyz_declare(NodeDeclarationBuilder &b) b.add_output<decl::Vector>("Vector"); } -} // namespace blender::nodes +using namespace blender::realtime_compositor; + +class CombineXYZShaderNode : public ShaderNode { + public: + using ShaderNode::ShaderNode; + + void compile(GPUMaterial *material) override + { + GPUNodeStack *inputs = get_inputs_array(); + GPUNodeStack *outputs = get_outputs_array(); + + GPU_stack_link(material, &bnode(), "node_composite_combine_xyz", inputs, outputs); + } +}; + +static ShaderNode *get_compositor_shader_node(DNode node) +{ + return new CombineXYZShaderNode(node); +} + +} // namespace blender::nodes::node_composite_combine_xyz_cc void register_node_type_cmp_combine_xyz() { + namespace file_ns = blender::nodes::node_composite_combine_xyz_cc; + static bNodeType ntype; cmp_node_type_base(&ntype, CMP_NODE_COMBINE_XYZ, "Combine XYZ", NODE_CLASS_CONVERTER); - ntype.declare = blender::nodes::cmp_node_combine_xyz_declare; + ntype.declare = file_ns::cmp_node_combine_xyz_declare; + ntype.get_compositor_shader_node = file_ns::get_compositor_shader_node; nodeRegisterType(&ntype); } diff --git a/source/blender/nodes/composite/nodes/node_composite_sepcomb_ycca.cc b/source/blender/nodes/composite/nodes/node_composite_sepcomb_ycca.cc index 51d3c18d238..bebe6abe115 100644 --- a/source/blender/nodes/composite/nodes/node_composite_sepcomb_ycca.cc +++ b/source/blender/nodes/composite/nodes/node_composite_sepcomb_ycca.cc @@ -5,15 +5,23 @@ * \ingroup cmpnodes */ +#include "BLI_assert.h" + +#include "GPU_material.h" + +#include "COM_shader_node.hh" + #include "node_composite_util.hh" /* **************** SEPARATE YCCA ******************** */ -namespace blender::nodes::node_composite_sepcomb_ycca_cc { +namespace blender::nodes::node_composite_separate_ycca_cc { static void cmp_node_sepycca_declare(NodeDeclarationBuilder &b) { - b.add_input<decl::Color>(N_("Image")).default_value({1.0f, 1.0f, 1.0f, 1.0f}); + b.add_input<decl::Color>(N_("Image")) + .default_value({1.0f, 1.0f, 1.0f, 1.0f}) + .compositor_domain_priority(0); b.add_output<decl::Float>(N_("Y")); b.add_output<decl::Float>(N_("Cb")); b.add_output<decl::Float>(N_("Cr")); @@ -25,11 +33,51 @@ static void node_composit_init_mode_sepycca(bNodeTree *UNUSED(ntree), bNode *nod node->custom1 = 1; /* BLI_YCC_ITU_BT709 */ } -} // namespace blender::nodes::node_composite_sepcomb_ycca_cc +using namespace blender::realtime_compositor; + +class SeparateYCCAShaderNode : public ShaderNode { + public: + using ShaderNode::ShaderNode; + + void compile(GPUMaterial *material) override + { + GPUNodeStack *inputs = get_inputs_array(); + GPUNodeStack *outputs = get_outputs_array(); + + GPU_stack_link(material, &bnode(), get_shader_function_name(), inputs, outputs); + } + + int get_mode() + { + return bnode().custom1; + } + + const char *get_shader_function_name() + { + switch (get_mode()) { + case BLI_YCC_ITU_BT601: + return "node_composite_separate_ycca_itu_601"; + case BLI_YCC_ITU_BT709: + return "node_composite_separate_ycca_itu_709"; + case BLI_YCC_JFIF_0_255: + return "node_composite_separate_ycca_jpeg"; + } + + BLI_assert_unreachable(); + return nullptr; + } +}; + +static ShaderNode *get_compositor_shader_node(DNode node) +{ + return new SeparateYCCAShaderNode(node); +} + +} // namespace blender::nodes::node_composite_separate_ycca_cc void register_node_type_cmp_sepycca() { - namespace file_ns = blender::nodes::node_composite_sepcomb_ycca_cc; + namespace file_ns = blender::nodes::node_composite_separate_ycca_cc; static bNodeType ntype; @@ -37,20 +85,33 @@ void register_node_type_cmp_sepycca() ntype.declare = file_ns::cmp_node_sepycca_declare; node_type_init(&ntype, file_ns::node_composit_init_mode_sepycca); ntype.gather_link_search_ops = nullptr; + ntype.get_compositor_shader_node = file_ns::get_compositor_shader_node; nodeRegisterType(&ntype); } /* **************** COMBINE YCCA ******************** */ -namespace blender::nodes::node_composite_sepcomb_ycca_cc { +namespace blender::nodes::node_composite_combine_ycca_cc { static void cmp_node_combycca_declare(NodeDeclarationBuilder &b) { - b.add_input<decl::Float>(N_("Y")).min(0.0f).max(1.0f); - b.add_input<decl::Float>(N_("Cb")).default_value(0.5f).min(0.0f).max(1.0f); - b.add_input<decl::Float>(N_("Cr")).default_value(0.5f).min(0.0f).max(1.0f); - b.add_input<decl::Float>(N_("A")).default_value(1.0f).min(0.0f).max(1.0f); + b.add_input<decl::Float>(N_("Y")).min(0.0f).max(1.0f).compositor_domain_priority(0); + b.add_input<decl::Float>(N_("Cb")) + .default_value(0.5f) + .min(0.0f) + .max(1.0f) + .compositor_domain_priority(1); + b.add_input<decl::Float>(N_("Cr")) + .default_value(0.5f) + .min(0.0f) + .max(1.0f) + .compositor_domain_priority(2); + b.add_input<decl::Float>(N_("A")) + .default_value(1.0f) + .min(0.0f) + .max(1.0f) + .compositor_domain_priority(3); b.add_output<decl::Color>(N_("Image")); } @@ -59,11 +120,51 @@ static void node_composit_init_mode_combycca(bNodeTree *UNUSED(ntree), bNode *no node->custom1 = 1; /* BLI_YCC_ITU_BT709 */ } -} // namespace blender::nodes::node_composite_sepcomb_ycca_cc +using namespace blender::realtime_compositor; + +class CombineYCCAShaderNode : public ShaderNode { + public: + using ShaderNode::ShaderNode; + + void compile(GPUMaterial *material) override + { + GPUNodeStack *inputs = get_inputs_array(); + GPUNodeStack *outputs = get_outputs_array(); + + GPU_stack_link(material, &bnode(), get_shader_function_name(), inputs, outputs); + } + + int get_mode() + { + return bnode().custom1; + } + + const char *get_shader_function_name() + { + switch (get_mode()) { + case BLI_YCC_ITU_BT601: + return "node_composite_combine_ycca_itu_601"; + case BLI_YCC_ITU_BT709: + return "node_composite_combine_ycca_itu_709"; + case BLI_YCC_JFIF_0_255: + return "node_composite_combine_ycca_jpeg"; + } + + BLI_assert_unreachable(); + return nullptr; + } +}; + +static ShaderNode *get_compositor_shader_node(DNode node) +{ + return new CombineYCCAShaderNode(node); +} + +} // namespace blender::nodes::node_composite_combine_ycca_cc void register_node_type_cmp_combycca() { - namespace file_ns = blender::nodes::node_composite_sepcomb_ycca_cc; + namespace file_ns = blender::nodes::node_composite_combine_ycca_cc; static bNodeType ntype; @@ -71,6 +172,7 @@ void register_node_type_cmp_combycca() ntype.declare = file_ns::cmp_node_combycca_declare; node_type_init(&ntype, file_ns::node_composit_init_mode_combycca); ntype.gather_link_search_ops = nullptr; + ntype.get_compositor_shader_node = file_ns::get_compositor_shader_node; nodeRegisterType(&ntype); } diff --git a/source/blender/nodes/composite/nodes/node_composite_sepcomb_yuva.cc b/source/blender/nodes/composite/nodes/node_composite_sepcomb_yuva.cc index 4acd2294114..1f0eb04cfc3 100644 --- a/source/blender/nodes/composite/nodes/node_composite_sepcomb_yuva.cc +++ b/source/blender/nodes/composite/nodes/node_composite_sepcomb_yuva.cc @@ -5,60 +5,112 @@ * \ingroup cmpnodes */ +#include "GPU_material.h" + +#include "COM_shader_node.hh" + #include "node_composite_util.hh" /* **************** SEPARATE YUVA ******************** */ -namespace blender::nodes::node_composite_sepcomb_yuva_cc { +namespace blender::nodes::node_composite_separate_yuva_cc { static void cmp_node_sepyuva_declare(NodeDeclarationBuilder &b) { - b.add_input<decl::Color>(N_("Image")).default_value({1.0f, 1.0f, 1.0f, 1.0f}); + b.add_input<decl::Color>(N_("Image")) + .default_value({1.0f, 1.0f, 1.0f, 1.0f}) + .compositor_domain_priority(0); b.add_output<decl::Float>(N_("Y")); b.add_output<decl::Float>(N_("U")); b.add_output<decl::Float>(N_("V")); b.add_output<decl::Float>(N_("A")); } -} // namespace blender::nodes::node_composite_sepcomb_yuva_cc +using namespace blender::realtime_compositor; + +class SeparateYUVAShaderNode : public ShaderNode { + public: + using ShaderNode::ShaderNode; + + void compile(GPUMaterial *material) override + { + GPUNodeStack *inputs = get_inputs_array(); + GPUNodeStack *outputs = get_outputs_array(); + + GPU_stack_link(material, &bnode(), "node_composite_separate_yuva_itu_709", inputs, outputs); + } +}; + +static ShaderNode *get_compositor_shader_node(DNode node) +{ + return new SeparateYUVAShaderNode(node); +} + +} // namespace blender::nodes::node_composite_separate_yuva_cc void register_node_type_cmp_sepyuva() { - namespace file_ns = blender::nodes::node_composite_sepcomb_yuva_cc; + namespace file_ns = blender::nodes::node_composite_separate_yuva_cc; static bNodeType ntype; cmp_node_type_base(&ntype, CMP_NODE_SEPYUVA_LEGACY, "Separate YUVA", NODE_CLASS_CONVERTER); ntype.declare = file_ns::cmp_node_sepyuva_declare; ntype.gather_link_search_ops = nullptr; + ntype.get_compositor_shader_node = file_ns::get_compositor_shader_node; nodeRegisterType(&ntype); } /* **************** COMBINE YUVA ******************** */ -namespace blender::nodes::node_composite_sepcomb_yuva_cc { +namespace blender::nodes::node_composite_combine_yuva_cc { static void cmp_node_combyuva_declare(NodeDeclarationBuilder &b) { - b.add_input<decl::Float>(N_("Y")).min(0.0f).max(1.0f); - b.add_input<decl::Float>(N_("U")).min(0.0f).max(1.0f); - b.add_input<decl::Float>(N_("V")).min(0.0f).max(1.0f); - b.add_input<decl::Float>(N_("A")).default_value(1.0f).min(0.0f).max(1.0f); + b.add_input<decl::Float>(N_("Y")).min(0.0f).max(1.0f).compositor_domain_priority(0); + b.add_input<decl::Float>(N_("U")).min(0.0f).max(1.0f).compositor_domain_priority(1); + b.add_input<decl::Float>(N_("V")).min(0.0f).max(1.0f).compositor_domain_priority(2); + b.add_input<decl::Float>(N_("A")) + .default_value(1.0f) + .min(0.0f) + .max(1.0f) + .compositor_domain_priority(3); b.add_output<decl::Color>(N_("Image")); } -} // namespace blender::nodes::node_composite_sepcomb_yuva_cc +using namespace blender::realtime_compositor; + +class CombineYUVAShaderNode : public ShaderNode { + public: + using ShaderNode::ShaderNode; + + void compile(GPUMaterial *material) override + { + GPUNodeStack *inputs = get_inputs_array(); + GPUNodeStack *outputs = get_outputs_array(); + + GPU_stack_link(material, &bnode(), "node_composite_combine_yuva_itu_709", inputs, outputs); + } +}; + +static ShaderNode *get_compositor_shader_node(DNode node) +{ + return new CombineYUVAShaderNode(node); +} + +} // namespace blender::nodes::node_composite_combine_yuva_cc void register_node_type_cmp_combyuva() { - namespace file_ns = blender::nodes::node_composite_sepcomb_yuva_cc; + namespace file_ns = blender::nodes::node_composite_combine_yuva_cc; static bNodeType ntype; cmp_node_type_base(&ntype, CMP_NODE_COMBYUVA_LEGACY, "Combine YUVA", NODE_CLASS_CONVERTER); ntype.declare = file_ns::cmp_node_combyuva_declare; ntype.gather_link_search_ops = nullptr; + ntype.get_compositor_shader_node = file_ns::get_compositor_shader_node; nodeRegisterType(&ntype); } diff --git a/source/blender/nodes/composite/nodes/node_composite_setalpha.cc b/source/blender/nodes/composite/nodes/node_composite_setalpha.cc index 8aeaafbbf67..9930125aa70 100644 --- a/source/blender/nodes/composite/nodes/node_composite_setalpha.cc +++ b/source/blender/nodes/composite/nodes/node_composite_setalpha.cc @@ -8,6 +8,10 @@ #include "UI_interface.h" #include "UI_resources.h" +#include "GPU_material.h" + +#include "COM_shader_node.hh" + #include "node_composite_util.hh" /* **************** SET ALPHA ******************** */ @@ -16,8 +20,14 @@ namespace blender::nodes::node_composite_setalpha_cc { static void cmp_node_setalpha_declare(NodeDeclarationBuilder &b) { - b.add_input<decl::Color>(N_("Image")).default_value({1.0f, 1.0f, 1.0f, 1.0f}); - b.add_input<decl::Float>(N_("Alpha")).default_value(1.0f).min(0.0f).max(1.0f); + b.add_input<decl::Color>(N_("Image")) + .default_value({1.0f, 1.0f, 1.0f, 1.0f}) + .compositor_domain_priority(0); + b.add_input<decl::Float>(N_("Alpha")) + .default_value(1.0f) + .min(0.0f) + .max(1.0f) + .compositor_domain_priority(1); b.add_output<decl::Color>(N_("Image")); } @@ -33,6 +43,36 @@ static void node_composit_buts_set_alpha(uiLayout *layout, bContext *UNUSED(C), uiItemR(layout, ptr, "mode", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, ICON_NONE); } +using namespace blender::realtime_compositor; + +class SetAlphaShaderNode : public ShaderNode { + public: + using ShaderNode::ShaderNode; + + void compile(GPUMaterial *material) override + { + GPUNodeStack *inputs = get_inputs_array(); + GPUNodeStack *outputs = get_outputs_array(); + + if (get_node_set_alpha()->mode == CMP_NODE_SETALPHA_MODE_APPLY) { + GPU_stack_link(material, &bnode(), "node_composite_set_alpha_apply", inputs, outputs); + return; + } + + GPU_stack_link(material, &bnode(), "node_composite_set_alpha_replace", inputs, outputs); + } + + NodeSetAlpha *get_node_set_alpha() + { + return static_cast<NodeSetAlpha *>(bnode().storage); + } +}; + +static ShaderNode *get_compositor_shader_node(DNode node) +{ + return new SetAlphaShaderNode(node); +} + } // namespace blender::nodes::node_composite_setalpha_cc void register_node_type_cmp_setalpha() @@ -47,6 +87,7 @@ void register_node_type_cmp_setalpha() node_type_init(&ntype, file_ns::node_composit_init_setalpha); node_type_storage( &ntype, "NodeSetAlpha", node_free_standard_storage, node_copy_standard_storage); + ntype.get_compositor_shader_node = file_ns::get_compositor_shader_node; nodeRegisterType(&ntype); } diff --git a/source/blender/nodes/composite/nodes/node_composite_switch.cc b/source/blender/nodes/composite/nodes/node_composite_switch.cc index bda490572e9..767802cc442 100644 --- a/source/blender/nodes/composite/nodes/node_composite_switch.cc +++ b/source/blender/nodes/composite/nodes/node_composite_switch.cc @@ -8,6 +8,8 @@ #include "UI_interface.h" #include "UI_resources.h" +#include "COM_node_operation.hh" + #include "node_composite_util.hh" /* **************** Switch ******************** */ @@ -26,6 +28,30 @@ static void node_composit_buts_switch(uiLayout *layout, bContext *UNUSED(C), Poi uiItemR(layout, ptr, "check", UI_ITEM_R_SPLIT_EMPTY_NAME, nullptr, ICON_NONE); } +using namespace blender::realtime_compositor; + +class SwitchOperation : public NodeOperation { + public: + using NodeOperation::NodeOperation; + + void execute() override + { + Result &input = get_input(get_condition() ? "On" : "Off"); + Result &result = get_result("Image"); + input.pass_through(result); + } + + bool get_condition() + { + return bnode().custom1; + } +}; + +static NodeOperation *get_compositor_operation(Context &context, DNode node) +{ + return new SwitchOperation(context, node); +} + } // namespace blender::nodes::node_composite_switch_cc void register_node_type_cmp_switch() @@ -38,5 +64,7 @@ void register_node_type_cmp_switch() ntype.declare = file_ns::cmp_node_switch_declare; ntype.draw_buttons = file_ns::node_composit_buts_switch; node_type_size_preset(&ntype, NODE_SIZE_SMALL); + ntype.get_compositor_operation = file_ns::get_compositor_operation; + nodeRegisterType(&ntype); } diff --git a/source/blender/nodes/composite/nodes/node_composite_switchview.cc b/source/blender/nodes/composite/nodes/node_composite_switchview.cc index 2cf3da03a05..e74c3b6007a 100644 --- a/source/blender/nodes/composite/nodes/node_composite_switchview.cc +++ b/source/blender/nodes/composite/nodes/node_composite_switchview.cc @@ -11,6 +11,8 @@ #include "UI_interface.h" #include "UI_resources.h" +#include "COM_node_operation.hh" + #include "node_composite_util.hh" /* **************** SWITCH VIEW ******************** */ @@ -140,6 +142,25 @@ static void node_composit_buts_switch_view_ex(uiLayout *layout, nullptr); } +using namespace blender::realtime_compositor; + +class SwitchViewOperation : public NodeOperation { + public: + using NodeOperation::NodeOperation; + + void execute() override + { + Result &input = get_input(context().get_view_name()); + Result &result = get_result("Image"); + input.pass_through(result); + } +}; + +static NodeOperation *get_compositor_operation(Context &context, DNode node) +{ + return new SwitchViewOperation(context, node); +} + } // namespace blender::nodes::node_composite_switchview_cc void register_node_type_cmp_switch_view() @@ -153,6 +174,7 @@ void register_node_type_cmp_switch_view() ntype.draw_buttons_ex = file_ns::node_composit_buts_switch_view_ex; ntype.initfunc_api = file_ns::init_switch_view; node_type_update(&ntype, file_ns::cmp_node_switch_view_update); + ntype.get_compositor_operation = file_ns::get_compositor_operation; nodeRegisterType(&ntype); } diff --git a/source/blender/nodes/composite/nodes/node_composite_val_to_rgb.cc b/source/blender/nodes/composite/nodes/node_composite_val_to_rgb.cc index df669d5beda..03a7bc61924 100644 --- a/source/blender/nodes/composite/nodes/node_composite_val_to_rgb.cc +++ b/source/blender/nodes/composite/nodes/node_composite_val_to_rgb.cc @@ -5,18 +5,33 @@ * \ingroup cmpnodes */ +#include "BLI_assert.h" + +#include "IMB_colormanagement.h" + +#include "BKE_colorband.h" + +#include "GPU_material.h" + +#include "COM_shader_node.hh" + #include "node_composite_util.hh" #include "BKE_colorband.h" /* **************** VALTORGB ******************** */ -namespace blender::nodes::node_composite_val_to_rgb_cc { +namespace blender::nodes::node_composite_color_ramp_cc { static void cmp_node_valtorgb_declare(NodeDeclarationBuilder &b) { - b.add_input<decl::Float>(N_("Fac")).default_value(0.5f).min(0.0f).max(1.0f).subtype(PROP_FACTOR); - b.add_output<decl::Color>(N_("Image")); + b.add_input<decl::Float>(N_("Fac")) + .default_value(0.5f) + .min(0.0f) + .max(1.0f) + .subtype(PROP_FACTOR) + .compositor_domain_priority(1); + b.add_output<decl::Color>(N_("Image")).compositor_domain_priority(0); b.add_output<decl::Float>(N_("Alpha")); } @@ -25,11 +40,94 @@ static void node_composit_init_valtorgb(bNodeTree *UNUSED(ntree), bNode *node) node->storage = BKE_colorband_add(true); } -} // namespace blender::nodes::node_composite_val_to_rgb_cc +using namespace blender::realtime_compositor; + +class ColorRampShaderNode : public ShaderNode { + public: + using ShaderNode::ShaderNode; + + void compile(GPUMaterial *material) override + { + GPUNodeStack *inputs = get_inputs_array(); + GPUNodeStack *outputs = get_outputs_array(); + + struct ColorBand *color_band = get_color_band(); + + /* Common / easy case optimization. */ + if ((color_band->tot <= 2) && (color_band->color_mode == COLBAND_BLEND_RGB)) { + float mul_bias[2]; + switch (color_band->ipotype) { + case COLBAND_INTERP_LINEAR: + mul_bias[0] = 1.0f / (color_band->data[1].pos - color_band->data[0].pos); + mul_bias[1] = -mul_bias[0] * color_band->data[0].pos; + GPU_stack_link(material, + &bnode(), + "valtorgb_opti_linear", + inputs, + outputs, + GPU_uniform(mul_bias), + GPU_uniform(&color_band->data[0].r), + GPU_uniform(&color_band->data[1].r)); + return; + case COLBAND_INTERP_CONSTANT: + mul_bias[1] = max_ff(color_band->data[0].pos, color_band->data[1].pos); + GPU_stack_link(material, + &bnode(), + "valtorgb_opti_constant", + inputs, + outputs, + GPU_uniform(&mul_bias[1]), + GPU_uniform(&color_band->data[0].r), + GPU_uniform(&color_band->data[1].r)); + return; + case COLBAND_INTERP_EASE: + mul_bias[0] = 1.0f / (color_band->data[1].pos - color_band->data[0].pos); + mul_bias[1] = -mul_bias[0] * color_band->data[0].pos; + GPU_stack_link(material, + &bnode(), + "valtorgb_opti_ease", + inputs, + outputs, + GPU_uniform(mul_bias), + GPU_uniform(&color_band->data[0].r), + GPU_uniform(&color_band->data[1].r)); + return; + default: + BLI_assert_unreachable(); + return; + } + } + + float *array, layer; + int size; + BKE_colorband_evaluate_table_rgba(color_band, &array, &size); + GPUNodeLink *tex = GPU_color_band(material, size, array, &layer); + + if (color_band->ipotype == COLBAND_INTERP_CONSTANT) { + GPU_stack_link( + material, &bnode(), "valtorgb_nearest", inputs, outputs, tex, GPU_constant(&layer)); + return; + } + + GPU_stack_link(material, &bnode(), "valtorgb", inputs, outputs, tex, GPU_constant(&layer)); + } + + struct ColorBand *get_color_band() + { + return static_cast<struct ColorBand *>(bnode().storage); + } +}; + +static ShaderNode *get_compositor_shader_node(DNode node) +{ + return new ColorRampShaderNode(node); +} + +} // namespace blender::nodes::node_composite_color_ramp_cc void register_node_type_cmp_valtorgb() { - namespace file_ns = blender::nodes::node_composite_val_to_rgb_cc; + namespace file_ns = blender::nodes::node_composite_color_ramp_cc; static bNodeType ntype; @@ -38,31 +136,63 @@ void register_node_type_cmp_valtorgb() node_type_size(&ntype, 240, 200, 320); node_type_init(&ntype, file_ns::node_composit_init_valtorgb); node_type_storage(&ntype, "ColorBand", node_free_standard_storage, node_copy_standard_storage); + ntype.get_compositor_shader_node = file_ns::get_compositor_shader_node; nodeRegisterType(&ntype); } /* **************** RGBTOBW ******************** */ -namespace blender::nodes::node_composite_val_to_rgb_cc { +namespace blender::nodes::node_composite_rgb_to_bw_cc { static void cmp_node_rgbtobw_declare(NodeDeclarationBuilder &b) { - b.add_input<decl::Color>(N_("Image")).default_value({0.8f, 0.8f, 0.8f, 1.0f}); + b.add_input<decl::Color>(N_("Image")) + .default_value({0.8f, 0.8f, 0.8f, 1.0f}) + .compositor_domain_priority(0); b.add_output<decl::Float>(N_("Val")); } -} // namespace blender::nodes::node_composite_val_to_rgb_cc +using namespace blender::realtime_compositor; + +class RGBToBWShaderNode : public ShaderNode { + public: + using ShaderNode::ShaderNode; + + void compile(GPUMaterial *material) override + { + GPUNodeStack *inputs = get_inputs_array(); + GPUNodeStack *outputs = get_outputs_array(); + + float luminance_coefficients[3]; + IMB_colormanagement_get_luminance_coefficients(luminance_coefficients); + + GPU_stack_link(material, + &bnode(), + "color_to_luminance", + inputs, + outputs, + GPU_constant(luminance_coefficients)); + } +}; + +static ShaderNode *get_compositor_shader_node(DNode node) +{ + return new RGBToBWShaderNode(node); +} + +} // namespace blender::nodes::node_composite_rgb_to_bw_cc void register_node_type_cmp_rgbtobw() { - namespace file_ns = blender::nodes::node_composite_val_to_rgb_cc; + namespace file_ns = blender::nodes::node_composite_rgb_to_bw_cc; static bNodeType ntype; cmp_node_type_base(&ntype, CMP_NODE_RGBTOBW, "RGB to BW", NODE_CLASS_CONVERTER); ntype.declare = file_ns::cmp_node_rgbtobw_declare; node_type_size_preset(&ntype, NODE_SIZE_SMALL); + ntype.get_compositor_shader_node = file_ns::get_compositor_shader_node; nodeRegisterType(&ntype); } |