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
This commit is contained in:
Omar Emara 2022-08-10 10:09:35 +02:00
parent 6109ad6cce
commit b5df7a02ac
24 changed files with 1279 additions and 77 deletions

View File

@ -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

View File

@ -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)

View File

@ -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);
}

View File

@ -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;
}
}

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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 {

View File

@ -10,6 +10,7 @@ set(INC
../../blenlib
../../blentranslation
../../depsgraph
../../functions
../../gpu
../../imbuf
../../makesdna

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}