Nodes: Add general Combine/Separate Color nodes

Inspired by D12936 and D12929, this patch adds general purpose
"Combine Color" and "Separate Color" nodes to Geometry, Compositor,
Shader and Texture nodes.
- Within Geometry Nodes, it replaces the existing "Combine RGB" and
  "Separate RGB" nodes.
- Within Compositor Nodes, it replaces the existing
  "Combine RGBA/HSVA/YCbCrA/YUVA" and "Separate RGBA/HSVA/YCbCrA/YUVA"
  nodes.
- Within Texture Nodes, it replaces the existing "Combine RGBA" and
  "Separate RGBA" nodes.
- Within Shader Nodes, it replaces the existing "Combine RGB/HSV" and
  "Separate RGB/HSV" nodes.

Python addons have not been updated to the new nodes yet.

**New shader code**
In node_color.h, color.h and gpu_shader_material_color_util.glsl,
missing methods hsl_to_rgb and rgb_to_hsl are added by directly
converting existing C code. They always produce the same result.

**Old code**
As requested by T96219, old nodes still exist but are not displayed in
the add menu. This means Python scripts can still create them as usual.
Otherwise, versioning replaces the old nodes with the new nodes when
opening .blend files.

Differential Revision: https://developer.blender.org/D14034
This commit is contained in:
Hallam Roberts 2022-05-04 18:44:03 +02:00 committed by Hans Goudey
parent 7d41e1ed40
commit 82df48227b
62 changed files with 2252 additions and 196 deletions

View File

@ -355,6 +355,18 @@ static ShaderNode *add_node(Scene *scene,
else if (b_node.is_a(&RNA_ShaderNodeCombineHSV)) {
node = graph->create_node<CombineHSVNode>();
}
else if (b_node.is_a(&RNA_ShaderNodeSeparateColor)) {
BL::ShaderNodeSeparateColor b_separate_node(b_node);
SeparateColorNode *separate_node = graph->create_node<SeparateColorNode>();
separate_node->set_color_type((NodeCombSepColorType)b_separate_node.mode());
node = separate_node;
}
else if (b_node.is_a(&RNA_ShaderNodeCombineColor)) {
BL::ShaderNodeCombineColor b_combine_node(b_node);
CombineColorNode *combine_node = graph->create_node<CombineColorNode>();
combine_node->set_color_type((NodeCombSepColorType)b_combine_node.mode());
node = combine_node;
}
else if (b_node.is_a(&RNA_ShaderNodeSeparateXYZ)) {
node = graph->create_node<SeparateXYZNode>();
}

View File

@ -145,6 +145,7 @@ set(SRC_KERNEL_SVM_HEADERS
svm/normal.h
svm/ramp.h
svm/ramp_util.h
svm/sepcomb_color.h
svm/sepcomb_hsv.h
svm/sepcomb_vector.h
svm/sky.h

View File

@ -16,6 +16,7 @@ set(SRC_OSL
node_camera.osl
node_checker_texture.osl
node_clamp.osl
node_combine_color.osl
node_combine_rgb.osl
node_combine_hsv.osl
node_combine_xyz.osl
@ -68,6 +69,7 @@ set(SRC_OSL
node_refraction_bsdf.osl
node_rgb_curves.osl
node_rgb_ramp.osl
node_separate_color.osl
node_separate_rgb.osl
node_separate_hsv.osl
node_separate_xyz.osl

View File

@ -148,3 +148,53 @@ color hsv_to_rgb(color hsv)
return rgb;
}
color rgb_to_hsl(color rgb)
{
float cmax, cmin, h, s, l;
cmax = max(rgb[0], max(rgb[1], rgb[2]));
cmin = min(rgb[0], min(rgb[1], rgb[2]));
l = min(1.0, (cmax + cmin) / 2.0);
if (cmax == cmin) {
h = s = 0.0; /* achromatic */
}
else {
float cdelta = cmax - cmin;
s = l > 0.5 ? cdelta / (2.0 - cmax - cmin) : cdelta / (cmax + cmin);
if (cmax == rgb[0]) {
h = (rgb[1] - rgb[2]) / cdelta + (rgb[1] < rgb[2] ? 6.0 : 0.0);
}
else if (cmax == rgb[1]) {
h = (rgb[2] - rgb[0]) / cdelta + 2.0;
}
else {
h = (rgb[0] - rgb[1]) / cdelta + 4.0;
}
}
h /= 6.0;
return color(h, s, l);
}
color hsl_to_rgb(color hsl)
{
float nr, ng, nb, chroma, h, s, l;
h = hsl[0];
s = hsl[1];
l = hsl[2];
nr = abs(h * 6.0 - 3.0) - 1.0;
ng = 2.0 - abs(h * 6.0 - 2.0);
nb = 2.0 - abs(h * 6.0 - 4.0);
nr = clamp(nr, 0.0, 1.0);
nb = clamp(nb, 0.0, 1.0);
ng = clamp(ng, 0.0, 1.0);
chroma = (1.0 - abs(2.0 * l - 1.0)) * s;
return color((nr - 0.5) * chroma + l, (ng - 0.5) * chroma + l, (nb - 0.5) * chroma + l);
}

View File

@ -0,0 +1,12 @@
/* SPDX-License-Identifier: Apache-2.0
* Copyright 2011-2022 Blender Foundation */
#include "stdcycles.h"
shader node_combine_color(string color_type = "rgb", float Red = 0.0, float Green = 0.0, float Blue = 0.0, output color Color = 0.8)
{
if (color_type == "rgb" || color_type == "hsv" || color_type == "hsl")
Color = color(color_type, Red, Green, Blue);
else
warning("%s", "Unknown color space!");
}

View File

@ -0,0 +1,26 @@
/* SPDX-License-Identifier: Apache-2.0
* Copyright 2011-2022 Blender Foundation */
#include "node_color.h"
#include "stdcycles.h"
shader node_separate_color(string color_type = "rgb",
color Color = 0.8,
output float Red = 0.0,
output float Green = 0.0,
output float Blue = 0.0)
{
color col;
if (color_type == "rgb")
col = Color;
else if (color_type == "hsv")
col = rgb_to_hsv(Color);
else if (color_type == "hsl")
col = rgb_to_hsl(Color);
else
warning("%s", "Unknown color space!");
Red = col[0];
Green = col[1];
Blue = col[2];
}

View File

@ -307,4 +307,30 @@ ccl_device_inline float3 svm_brightness_contrast(float3 color, float brightness,
return color;
}
ccl_device float3 svm_combine_color(NodeCombSepColorType type, float3 color)
{
switch (type) {
case NODE_COMBSEP_COLOR_HSV:
return hsv_to_rgb(color);
case NODE_COMBSEP_COLOR_HSL:
return hsl_to_rgb(color);
case NODE_COMBSEP_COLOR_RGB:
default:
return color;
}
}
ccl_device float3 svm_separate_color(NodeCombSepColorType type, float3 color)
{
switch (type) {
case NODE_COMBSEP_COLOR_HSV:
return rgb_to_hsv(color);
case NODE_COMBSEP_COLOR_HSL:
return rgb_to_hsl(color);
case NODE_COMBSEP_COLOR_RGB:
default:
return color;
}
}
CCL_NAMESPACE_END

View File

@ -0,0 +1,53 @@
/* SPDX-License-Identifier: Apache-2.0
* Copyright 2011-2022 Blender Foundation */
#pragma once
CCL_NAMESPACE_BEGIN
ccl_device_noinline void svm_node_combine_color(KernelGlobals kg,
ccl_private ShaderData *sd,
ccl_private float *stack,
uint color_type,
uint inputs_stack_offsets,
uint result_stack_offset)
{
uint red_stack_offset, green_stack_offset, blue_stack_offset;
svm_unpack_node_uchar3(inputs_stack_offsets, &red_stack_offset, &green_stack_offset, &blue_stack_offset);
float r = stack_load_float(stack, red_stack_offset);
float g = stack_load_float(stack, green_stack_offset);
float b = stack_load_float(stack, blue_stack_offset);
/* Combine, and convert back to RGB */
float3 color = svm_combine_color((NodeCombSepColorType)color_type, make_float3(r, g, b));
if (stack_valid(result_stack_offset))
stack_store_float3(stack, result_stack_offset, color);
}
ccl_device_noinline void svm_node_separate_color(KernelGlobals kg,
ccl_private ShaderData *sd,
ccl_private float *stack,
uint color_type,
uint input_stack_offset,
uint results_stack_offsets)
{
float3 color = stack_load_float3(stack, input_stack_offset);
/* Convert color space */
color = svm_separate_color((NodeCombSepColorType)color_type, color);
uint red_stack_offset, green_stack_offset, blue_stack_offset;
svm_unpack_node_uchar3(
results_stack_offsets, &red_stack_offset, &green_stack_offset, &blue_stack_offset);
if (stack_valid(red_stack_offset))
stack_store_float(stack, red_stack_offset, color.x);
if (stack_valid(green_stack_offset))
stack_store_float(stack, green_stack_offset, color.y);
if (stack_valid(blue_stack_offset))
stack_store_float(stack, blue_stack_offset, color.z);
}
CCL_NAMESPACE_END

View File

@ -181,6 +181,7 @@ CCL_NAMESPACE_END
#include "kernel/svm/noisetex.h"
#include "kernel/svm/normal.h"
#include "kernel/svm/ramp.h"
#include "kernel/svm/sepcomb_color.h"
#include "kernel/svm/sepcomb_hsv.h"
#include "kernel/svm/sepcomb_vector.h"
#include "kernel/svm/sky.h"
@ -520,6 +521,12 @@ ccl_device void svm_eval_nodes(KernelGlobals kg,
case NODE_MIX:
offset = svm_node_mix(kg, sd, stack, node.y, node.z, node.w, offset);
break;
case NODE_SEPARATE_COLOR:
svm_node_separate_color(kg, sd, stack, node.y, node.z, node.w);
break;
case NODE_COMBINE_COLOR:
svm_node_combine_color(kg, sd, stack, node.y, node.z, node.w);
break;
case NODE_SEPARATE_VECTOR:
svm_node_separate_vector(sd, stack, node.y, node.z, node.w);
break;

View File

@ -92,6 +92,8 @@ typedef enum ShaderNodeType {
NODE_NORMAL_MAP,
NODE_INVERT,
NODE_MIX,
NODE_SEPARATE_COLOR,
NODE_COMBINE_COLOR,
NODE_SEPARATE_VECTOR,
NODE_COMBINE_VECTOR,
NODE_SEPARATE_HSV,
@ -487,6 +489,12 @@ typedef enum NodePrincipledHairParametrization {
NODE_PRINCIPLED_HAIR_NUM,
} NodePrincipledHairParametrization;
typedef enum NodeCombSepColorType {
NODE_COMBSEP_COLOR_RGB,
NODE_COMBSEP_COLOR_HSV,
NODE_COMBSEP_COLOR_HSL,
} NodeCombSepColorType;
/* Closure */
typedef enum ClosureType {

View File

@ -5010,6 +5010,63 @@ void MixNode::constant_fold(const ConstantFolder &folder)
}
}
/* Combine Color */
NODE_DEFINE(CombineColorNode)
{
NodeType *type = NodeType::add("combine_color", create, NodeType::SHADER);
static NodeEnum type_enum;
type_enum.insert("rgb", NODE_COMBSEP_COLOR_RGB);
type_enum.insert("hsv", NODE_COMBSEP_COLOR_HSV);
type_enum.insert("hsl", NODE_COMBSEP_COLOR_HSL);
SOCKET_ENUM(color_type, "Type", type_enum, NODE_COMBSEP_COLOR_RGB);
SOCKET_IN_FLOAT(r, "Red", 0.0f);
SOCKET_IN_FLOAT(g, "Green", 0.0f);
SOCKET_IN_FLOAT(b, "Blue", 0.0f);
SOCKET_OUT_COLOR(color, "Color");
return type;
}
CombineColorNode::CombineColorNode() : ShaderNode(get_node_type())
{
}
void CombineColorNode::constant_fold(const ConstantFolder &folder)
{
if (folder.all_inputs_constant()) {
folder.make_constant(svm_combine_color(color_type, make_float3(r, g, b)));
}
}
void CombineColorNode::compile(SVMCompiler &compiler)
{
ShaderInput *red_in = input("Red");
ShaderInput *green_in = input("Green");
ShaderInput *blue_in = input("Blue");
ShaderOutput *color_out = output("Color");
int red_stack_offset = compiler.stack_assign(red_in);
int green_stack_offset = compiler.stack_assign(green_in);
int blue_stack_offset = compiler.stack_assign(blue_in);
int color_stack_offset = compiler.stack_assign(color_out);
compiler.add_node(
NODE_COMBINE_COLOR,
color_type,
compiler.encode_uchar4(red_stack_offset, green_stack_offset, blue_stack_offset),
color_stack_offset);
}
void CombineColorNode::compile(OSLCompiler &compiler)
{
compiler.parameter(this, "color_type");
compiler.add(this, "node_combine_color");
}
/* Combine RGB */
NODE_DEFINE(CombineRGBNode)
@ -5250,6 +5307,70 @@ void BrightContrastNode::compile(OSLCompiler &compiler)
compiler.add(this, "node_brightness");
}
/* Separate Color */
NODE_DEFINE(SeparateColorNode)
{
NodeType *type = NodeType::add("separate_color", create, NodeType::SHADER);
static NodeEnum type_enum;
type_enum.insert("rgb", NODE_COMBSEP_COLOR_RGB);
type_enum.insert("hsv", NODE_COMBSEP_COLOR_HSV);
type_enum.insert("hsl", NODE_COMBSEP_COLOR_HSL);
SOCKET_ENUM(color_type, "Type", type_enum, NODE_COMBSEP_COLOR_RGB);
SOCKET_IN_COLOR(color, "Color", zero_float3());
SOCKET_OUT_FLOAT(r, "Red");
SOCKET_OUT_FLOAT(g, "Green");
SOCKET_OUT_FLOAT(b, "Blue");
return type;
}
SeparateColorNode::SeparateColorNode() : ShaderNode(get_node_type())
{
}
void SeparateColorNode::constant_fold(const ConstantFolder &folder)
{
if (folder.all_inputs_constant()) {
float3 col = svm_separate_color(color_type, color);
for (int channel = 0; channel < 3; channel++) {
if (outputs[channel] == folder.output) {
folder.make_constant(col[channel]);
return;
}
}
}
}
void SeparateColorNode::compile(SVMCompiler &compiler)
{
ShaderInput *color_in = input("Color");
ShaderOutput *red_out = output("Red");
ShaderOutput *green_out = output("Green");
ShaderOutput *blue_out = output("Blue");
int color_stack_offset = compiler.stack_assign(color_in);
int red_stack_offset = compiler.stack_assign(red_out);
int green_stack_offset = compiler.stack_assign(green_out);
int blue_stack_offset = compiler.stack_assign(blue_out);
compiler.add_node(
NODE_SEPARATE_COLOR,
color_type,
color_stack_offset,
compiler.encode_uchar4(red_stack_offset, green_stack_offset, blue_stack_offset));
}
void SeparateColorNode::compile(OSLCompiler &compiler)
{
compiler.parameter(this, "color_type");
compiler.add(this, "node_separate_color");
}
/* Separate RGB */
NODE_DEFINE(SeparateRGBNode)

View File

@ -1101,6 +1101,17 @@ class MixNode : public ShaderNode {
NODE_SOCKET_API(float, fac)
};
class CombineColorNode : public ShaderNode {
public:
SHADER_NODE_CLASS(CombineColorNode)
void constant_fold(const ConstantFolder &folder);
NODE_SOCKET_API(NodeCombSepColorType, color_type)
NODE_SOCKET_API(float, r)
NODE_SOCKET_API(float, g)
NODE_SOCKET_API(float, b)
};
class CombineRGBNode : public ShaderNode {
public:
SHADER_NODE_CLASS(CombineRGBNode)
@ -1150,6 +1161,15 @@ class BrightContrastNode : public ShaderNode {
NODE_SOCKET_API(float, contrast)
};
class SeparateColorNode : public ShaderNode {
public:
SHADER_NODE_CLASS(SeparateColorNode)
void constant_fold(const ConstantFolder &folder);
NODE_SOCKET_API(NodeCombSepColorType, color_type)
NODE_SOCKET_API(float3, color)
};
class SeparateRGBNode : public ShaderNode {
public:
SHADER_NODE_CLASS(SeparateRGBNode)

View File

@ -152,6 +152,55 @@ ccl_device float3 hsv_to_rgb(float3 hsv)
return rgb;
}
ccl_device float3 rgb_to_hsl(float3 rgb)
{
float cmax, cmin, h, s, l;
cmax = fmaxf(rgb.x, fmaxf(rgb.y, rgb.z));
cmin = min(rgb.x, min(rgb.y, rgb.z));
l = min(1.0f, (cmax + cmin) / 2.0f);
if (cmax == cmin) {
h = s = 0.0f; /* achromatic */
} else {
float cdelta = cmax - cmin;
s = l > 0.5f ? cdelta / (2.0f - cmax - cmin) : cdelta / (cmax + cmin);
if (cmax == rgb.x) {
h = (rgb.y - rgb.z) / cdelta + (rgb.y < rgb.z ? 6.0f : 0.0f);
}
else if (cmax == rgb.y) {
h = (rgb.z - rgb.x) / cdelta + 2.0f;
}
else {
h = (rgb.x - rgb.y) / cdelta + 4.0f;
}
}
h /= 6.0f;
return make_float3(h, s, l);
}
ccl_device float3 hsl_to_rgb(float3 hsl)
{
float nr, ng, nb, chroma, h, s, l;
h = hsl.x;
s = hsl.y;
l = hsl.z;
nr = fabsf(h * 6.0f - 3.0f) - 1.0f;
ng = 2.0f - fabsf(h * 6.0f - 2.0f);
nb = 2.0f - fabsf(h * 6.0f - 4.0f);
nr = clamp(nr, 0.0f, 1.0f);
nb = clamp(nb, 0.0f, 1.0f);
ng = clamp(ng, 0.0f, 1.0f);
chroma = (1.0f - fabsf(2.0f * l - 1.0f)) * s;
return make_float3((nr - 0.5f) * chroma + l, (ng - 0.5f) * chroma + l, (nb - 0.5f) * chroma + l);
}
ccl_device float3 xyY_to_xyz(float x, float y, float Y)
{
float X, Z;

View File

@ -419,12 +419,10 @@ shader_node_categories = [
NodeItem("ShaderNodeRGBToBW"),
NodeItem("ShaderNodeShaderToRGB", poll=object_eevee_shader_nodes_poll),
NodeItem("ShaderNodeVectorMath"),
NodeItem("ShaderNodeSeparateRGB"),
NodeItem("ShaderNodeCombineRGB"),
NodeItem("ShaderNodeSeparateColor"),
NodeItem("ShaderNodeCombineColor"),
NodeItem("ShaderNodeSeparateXYZ"),
NodeItem("ShaderNodeCombineXYZ"),
NodeItem("ShaderNodeSeparateHSV"),
NodeItem("ShaderNodeCombineHSV"),
NodeItem("ShaderNodeWavelength"),
NodeItem("ShaderNodeBlackbody"),
]),
@ -483,14 +481,8 @@ compositor_node_categories = [
NodeItem("CompositorNodePremulKey"),
NodeItem("CompositorNodeIDMask"),
NodeItem("CompositorNodeRGBToBW"),
NodeItem("CompositorNodeSepRGBA"),
NodeItem("CompositorNodeCombRGBA"),
NodeItem("CompositorNodeSepHSVA"),
NodeItem("CompositorNodeCombHSVA"),
NodeItem("CompositorNodeSepYUVA"),
NodeItem("CompositorNodeCombYUVA"),
NodeItem("CompositorNodeSepYCCA"),
NodeItem("CompositorNodeCombYCCA"),
NodeItem("CompositorNodeSeparateColor"),
NodeItem("CompositorNodeCombineColor"),
NodeItem("CompositorNodeSeparateXYZ"),
NodeItem("CompositorNodeCombineXYZ"),
NodeItem("CompositorNodeSwitchView"),
@ -576,8 +568,8 @@ texture_node_categories = [
NodeItem("TextureNodeCurveRGB"),
NodeItem("TextureNodeInvert"),
NodeItem("TextureNodeHueSaturation"),
NodeItem("TextureNodeCompose"),
NodeItem("TextureNodeDecompose"),
NodeItem("TextureNodeCombineColor"),
NodeItem("TextureNodeSeparateColor"),
]),
TextureNodeCategory("TEX_PATTERN", "Pattern", items=[
NodeItem("TextureNodeChecker"),
@ -629,8 +621,8 @@ geometry_node_categories = [
NodeItem("ShaderNodeMixRGB"),
NodeItem("ShaderNodeRGBCurve"),
NodeItem("ShaderNodeValToRGB"),
NodeItem("ShaderNodeSeparateRGB"),
NodeItem("ShaderNodeCombineRGB"),
NodeItem("FunctionNodeSeparateColor"),
NodeItem("FunctionNodeCombineColor"),
]),
GeometryNodeCategory("GEO_CURVE", "Curve", items=curve_node_items),
GeometryNodeCategory("GEO_PRIMITIVES_CURVE", "Curve Primitives", items=[

View File

@ -1090,8 +1090,8 @@ void BKE_nodetree_remove_layer_n(struct bNodeTree *ntree, struct Scene *scene, i
#define SH_NODE_SQUEEZE 117
//#define SH_NODE_MATERIAL_EXT 118
#define SH_NODE_INVERT 119
#define SH_NODE_SEPRGB 120
#define SH_NODE_COMBRGB 121
#define SH_NODE_SEPRGB_LEGACY 120
#define SH_NODE_COMBRGB_LEGACY 121
#define SH_NODE_HUE_SAT 122
#define SH_NODE_OUTPUT_MATERIAL 124
@ -1147,8 +1147,8 @@ void BKE_nodetree_remove_layer_n(struct bNodeTree *ntree, struct Scene *scene, i
#define SH_NODE_WAVELENGTH 180
#define SH_NODE_BLACKBODY 181
#define SH_NODE_VECT_TRANSFORM 182
#define SH_NODE_SEPHSV 183
#define SH_NODE_COMBHSV 184
#define SH_NODE_SEPHSV_LEGACY 183
#define SH_NODE_COMBHSV_LEGACY 184
#define SH_NODE_BSDF_HAIR 185
// #define SH_NODE_LAMP 186
#define SH_NODE_UVMAP 187
@ -1175,6 +1175,8 @@ void BKE_nodetree_remove_layer_n(struct bNodeTree *ntree, struct Scene *scene, i
#define SH_NODE_VECTOR_ROTATE 708
#define SH_NODE_CURVE_FLOAT 709
#define SH_NODE_POINT_INFO 710
#define SH_NODE_COMBINE_COLOR 711
#define SH_NODE_SEPARATE_COLOR 712
/** \} */
@ -1202,8 +1204,8 @@ void BKE_nodetree_remove_layer_n(struct bNodeTree *ntree, struct Scene *scene, i
#define CMP_NODE_MAP_VALUE 213
#define CMP_NODE_TIME 214
#define CMP_NODE_VECBLUR 215
#define CMP_NODE_SEPRGBA 216
#define CMP_NODE_SEPHSVA 217
#define CMP_NODE_SEPRGBA_LEGACY 216
#define CMP_NODE_SEPHSVA_LEGACY 217
#define CMP_NODE_SETALPHA 218
#define CMP_NODE_HUE_SAT 219
#define CMP_NODE_IMAGE 220
@ -1213,14 +1215,14 @@ void BKE_nodetree_remove_layer_n(struct bNodeTree *ntree, struct Scene *scene, i
#define CMP_NODE_TEXTURE 224
#define CMP_NODE_TRANSLATE 225
#define CMP_NODE_ZCOMBINE 226
#define CMP_NODE_COMBRGBA 227
#define CMP_NODE_COMBRGBA_LEGACY 227
#define CMP_NODE_DILATEERODE 228
#define CMP_NODE_ROTATE 229
#define CMP_NODE_SCALE 230
#define CMP_NODE_SEPYCCA 231
#define CMP_NODE_COMBYCCA 232
#define CMP_NODE_SEPYUVA 233
#define CMP_NODE_COMBYUVA 234
#define CMP_NODE_SEPYCCA_LEGACY 231
#define CMP_NODE_COMBYCCA_LEGACY 232
#define CMP_NODE_SEPYUVA_LEGACY 233
#define CMP_NODE_COMBYUVA_LEGACY 234
#define CMP_NODE_DIFF_MATTE 235
#define CMP_NODE_COLOR_SPILL 236
#define CMP_NODE_CHROMA_MATTE 237
@ -1232,7 +1234,7 @@ void BKE_nodetree_remove_layer_n(struct bNodeTree *ntree, struct Scene *scene, i
#define CMP_NODE_ID_MASK 243
#define CMP_NODE_DEFOCUS 244
#define CMP_NODE_DISPLACE 245
#define CMP_NODE_COMBHSVA 246
#define CMP_NODE_COMBHSVA_LEGACY 246
#define CMP_NODE_MATH 247
#define CMP_NODE_LUMA_MATTE 248
#define CMP_NODE_BRIGHTCONTRAST 249
@ -1289,6 +1291,8 @@ void BKE_nodetree_remove_layer_n(struct bNodeTree *ntree, struct Scene *scene, i
#define CMP_NODE_SCENE_TIME 329
#define CMP_NODE_SEPARATE_XYZ 330
#define CMP_NODE_COMBINE_XYZ 331
#define CMP_NODE_COMBINE_COLOR 332
#define CMP_NODE_SEPARATE_COLOR 333
/* channel toggles */
#define CMP_CHAN_RGB 1
@ -1354,11 +1358,13 @@ struct TexResult;
#define TEX_NODE_TRANSLATE 416
#define TEX_NODE_COORD 417
#define TEX_NODE_DISTANCE 418
#define TEX_NODE_COMPOSE 419
#define TEX_NODE_DECOMPOSE 420
#define TEX_NODE_COMPOSE_LEGACY 419
#define TEX_NODE_DECOMPOSE_LEGACY 420
#define TEX_NODE_VALTONOR 421
#define TEX_NODE_SCALE 422
#define TEX_NODE_AT 423
#define TEX_NODE_COMBINE_COLOR 424
#define TEX_NODE_SEPARATE_COLOR 425
/* 501-599 reserved. Use like this: TEX_NODE_PROC + TEX_CLOUDS, etc */
#define TEX_NODE_PROC 500
@ -1511,6 +1517,8 @@ struct TexResult;
#define FN_NODE_REPLACE_STRING 1218
#define FN_NODE_INPUT_BOOL 1219
#define FN_NODE_INPUT_INT 1220
#define FN_NODE_SEPARATE_COLOR 1221
#define FN_NODE_COMBINE_COLOR 1222
/** \} */

View File

@ -4502,6 +4502,8 @@ static void registerCompositNodes()
register_node_type_cmp_premulkey();
register_node_type_cmp_separate_xyz();
register_node_type_cmp_combine_xyz();
register_node_type_cmp_separate_color();
register_node_type_cmp_combine_color();
register_node_type_cmp_diff_matte();
register_node_type_cmp_distance_matte();
@ -4574,6 +4576,8 @@ static void registerShaderNodes()
register_node_type_sh_vect_transform();
register_node_type_sh_squeeze();
register_node_type_sh_invert();
register_node_type_sh_sepcolor();
register_node_type_sh_combcolor();
register_node_type_sh_seprgb();
register_node_type_sh_combrgb();
register_node_type_sh_sephsv();
@ -4660,6 +4664,8 @@ static void registerTextureNodes()
register_node_type_tex_distance();
register_node_type_tex_compose();
register_node_type_tex_decompose();
register_node_type_tex_combine_color();
register_node_type_tex_separate_color();
register_node_type_tex_output();
register_node_type_tex_viewer();
@ -4821,6 +4827,7 @@ static void registerFunctionNodes()
{
register_node_type_fn_align_euler_to_vector();
register_node_type_fn_boolean_math();
register_node_type_fn_combine_color();
register_node_type_fn_compare();
register_node_type_fn_float_to_int();
register_node_type_fn_input_bool();
@ -4832,6 +4839,7 @@ static void registerFunctionNodes()
register_node_type_fn_random_value();
register_node_type_fn_replace_string();
register_node_type_fn_rotate_euler();
register_node_type_fn_separate_color();
register_node_type_fn_slice_string();
register_node_type_fn_string_length();
register_node_type_fn_value_to_string();

View File

@ -238,7 +238,7 @@ void rgb_to_hsl(float r, float g, float b, float *r_h, float *r_s, float *r_l)
{
const float cmax = max_fff(r, g, b);
const float cmin = min_fff(r, g, b);
float h, s, l = min_ff(1.0, (cmax + cmin) / 2.0f);
float h, s, l = min_ff(1.0f, (cmax + cmin) / 2.0f);
if (cmax == cmin) {
h = s = 0.0f; /* achromatic */

View File

@ -2772,5 +2772,250 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain)
*/
{
/* Keep this block, even when empty. */
/* Replace legacy combine/separate color nodes */
FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
/* In geometry nodes, replace shader combine/separate color nodes with function nodes */
if (ntree->type == NTREE_GEOMETRY) {
version_node_input_socket_name(ntree, SH_NODE_COMBRGB_LEGACY, "R", "Red");
version_node_input_socket_name(ntree, SH_NODE_COMBRGB_LEGACY, "G", "Green");
version_node_input_socket_name(ntree, SH_NODE_COMBRGB_LEGACY, "B", "Blue");
version_node_output_socket_name(ntree, SH_NODE_COMBRGB_LEGACY, "Image", "Color");
version_node_output_socket_name(ntree, SH_NODE_SEPRGB_LEGACY, "R", "Red");
version_node_output_socket_name(ntree, SH_NODE_SEPRGB_LEGACY, "G", "Green");
version_node_output_socket_name(ntree, SH_NODE_SEPRGB_LEGACY, "B", "Blue");
version_node_input_socket_name(ntree, SH_NODE_SEPRGB_LEGACY, "Image", "Color");
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
switch (node->type) {
case SH_NODE_COMBRGB_LEGACY: {
node->type = FN_NODE_COMBINE_COLOR;
NodeCombSepColor *storage = (NodeCombSepColor *)MEM_callocN(sizeof(NodeCombSepColor),
__func__);
storage->mode = NODE_COMBSEP_COLOR_RGB;
strcpy(node->idname, "FunctionNodeCombineColor");
node->storage = storage;
break;
}
case SH_NODE_SEPRGB_LEGACY: {
node->type = FN_NODE_SEPARATE_COLOR;
NodeCombSepColor *storage = (NodeCombSepColor *)MEM_callocN(sizeof(NodeCombSepColor),
__func__);
storage->mode = NODE_COMBSEP_COLOR_RGB;
strcpy(node->idname, "FunctionNodeSeparateColor");
node->storage = storage;
break;
}
}
}
}
/* In compositing nodes, replace combine/separate RGBA/HSVA/YCbCrA/YCCA nodes with
* combine/separate color */
if (ntree->type == NTREE_COMPOSIT) {
version_node_input_socket_name(ntree, CMP_NODE_COMBRGBA_LEGACY, "R", "Red");
version_node_input_socket_name(ntree, CMP_NODE_COMBRGBA_LEGACY, "G", "Green");
version_node_input_socket_name(ntree, CMP_NODE_COMBRGBA_LEGACY, "B", "Blue");
version_node_input_socket_name(ntree, CMP_NODE_COMBRGBA_LEGACY, "A", "Alpha");
version_node_input_socket_name(ntree, CMP_NODE_COMBHSVA_LEGACY, "H", "Red");
version_node_input_socket_name(ntree, CMP_NODE_COMBHSVA_LEGACY, "S", "Green");
version_node_input_socket_name(ntree, CMP_NODE_COMBHSVA_LEGACY, "V", "Blue");
version_node_input_socket_name(ntree, CMP_NODE_COMBHSVA_LEGACY, "A", "Alpha");
version_node_input_socket_name(ntree, CMP_NODE_COMBYCCA_LEGACY, "Y", "Red");
version_node_input_socket_name(ntree, CMP_NODE_COMBYCCA_LEGACY, "Cb", "Green");
version_node_input_socket_name(ntree, CMP_NODE_COMBYCCA_LEGACY, "Cr", "Blue");
version_node_input_socket_name(ntree, CMP_NODE_COMBYCCA_LEGACY, "A", "Alpha");
version_node_input_socket_name(ntree, CMP_NODE_COMBYUVA_LEGACY, "Y", "Red");
version_node_input_socket_name(ntree, CMP_NODE_COMBYUVA_LEGACY, "U", "Green");
version_node_input_socket_name(ntree, CMP_NODE_COMBYUVA_LEGACY, "V", "Blue");
version_node_input_socket_name(ntree, CMP_NODE_COMBYUVA_LEGACY, "A", "Alpha");
version_node_output_socket_name(ntree, CMP_NODE_SEPRGBA_LEGACY, "R", "Red");
version_node_output_socket_name(ntree, CMP_NODE_SEPRGBA_LEGACY, "G", "Green");
version_node_output_socket_name(ntree, CMP_NODE_SEPRGBA_LEGACY, "B", "Blue");
version_node_output_socket_name(ntree, CMP_NODE_SEPRGBA_LEGACY, "A", "Alpha");
version_node_output_socket_name(ntree, CMP_NODE_SEPHSVA_LEGACY, "H", "Red");
version_node_output_socket_name(ntree, CMP_NODE_SEPHSVA_LEGACY, "S", "Green");
version_node_output_socket_name(ntree, CMP_NODE_SEPHSVA_LEGACY, "V", "Blue");
version_node_output_socket_name(ntree, CMP_NODE_SEPHSVA_LEGACY, "A", "Alpha");
version_node_output_socket_name(ntree, CMP_NODE_SEPYCCA_LEGACY, "Y", "Red");
version_node_output_socket_name(ntree, CMP_NODE_SEPYCCA_LEGACY, "Cb", "Green");
version_node_output_socket_name(ntree, CMP_NODE_SEPYCCA_LEGACY, "Cr", "Blue");
version_node_output_socket_name(ntree, CMP_NODE_SEPYCCA_LEGACY, "A", "Alpha");
version_node_output_socket_name(ntree, CMP_NODE_SEPYUVA_LEGACY, "Y", "Red");
version_node_output_socket_name(ntree, CMP_NODE_SEPYUVA_LEGACY, "U", "Green");
version_node_output_socket_name(ntree, CMP_NODE_SEPYUVA_LEGACY, "V", "Blue");
version_node_output_socket_name(ntree, CMP_NODE_SEPYUVA_LEGACY, "A", "Alpha");
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
switch (node->type) {
case CMP_NODE_COMBRGBA_LEGACY: {
node->type = CMP_NODE_COMBINE_COLOR;
NodeCMPCombSepColor *storage = (NodeCMPCombSepColor *)MEM_callocN(
sizeof(NodeCMPCombSepColor), __func__);
storage->mode = CMP_NODE_COMBSEP_COLOR_RGB;
strcpy(node->idname, "CompositorNodeCombineColor");
node->storage = storage;
break;
}
case CMP_NODE_COMBHSVA_LEGACY: {
node->type = CMP_NODE_COMBINE_COLOR;
NodeCMPCombSepColor *storage = (NodeCMPCombSepColor *)MEM_callocN(
sizeof(NodeCMPCombSepColor), __func__);
storage->mode = CMP_NODE_COMBSEP_COLOR_HSV;
strcpy(node->idname, "CompositorNodeCombineColor");
node->storage = storage;
break;
}
case CMP_NODE_COMBYCCA_LEGACY: {
node->type = CMP_NODE_COMBINE_COLOR;
NodeCMPCombSepColor *storage = (NodeCMPCombSepColor *)MEM_callocN(
sizeof(NodeCMPCombSepColor), __func__);
storage->mode = CMP_NODE_COMBSEP_COLOR_YCC;
storage->ycc_mode = node->custom1;
strcpy(node->idname, "CompositorNodeCombineColor");
node->storage = storage;
break;
}
case CMP_NODE_COMBYUVA_LEGACY: {
node->type = CMP_NODE_COMBINE_COLOR;
NodeCMPCombSepColor *storage = (NodeCMPCombSepColor *)MEM_callocN(
sizeof(NodeCMPCombSepColor), __func__);
storage->mode = CMP_NODE_COMBSEP_COLOR_YUV;
strcpy(node->idname, "CompositorNodeCombineColor");
node->storage = storage;
break;
}
case CMP_NODE_SEPRGBA_LEGACY: {
node->type = CMP_NODE_SEPARATE_COLOR;
NodeCMPCombSepColor *storage = (NodeCMPCombSepColor *)MEM_callocN(
sizeof(NodeCMPCombSepColor), __func__);
storage->mode = CMP_NODE_COMBSEP_COLOR_RGB;
strcpy(node->idname, "CompositorNodeSeparateColor");
node->storage = storage;
break;
}
case CMP_NODE_SEPHSVA_LEGACY: {
node->type = CMP_NODE_SEPARATE_COLOR;
NodeCMPCombSepColor *storage = (NodeCMPCombSepColor *)MEM_callocN(
sizeof(NodeCMPCombSepColor), __func__);
storage->mode = CMP_NODE_COMBSEP_COLOR_HSV;
strcpy(node->idname, "CompositorNodeSeparateColor");
node->storage = storage;
break;
}
case CMP_NODE_SEPYCCA_LEGACY: {
node->type = CMP_NODE_SEPARATE_COLOR;
NodeCMPCombSepColor *storage = (NodeCMPCombSepColor *)MEM_callocN(
sizeof(NodeCMPCombSepColor), __func__);
storage->mode = CMP_NODE_COMBSEP_COLOR_YCC;
storage->ycc_mode = node->custom1;
strcpy(node->idname, "CompositorNodeSeparateColor");
node->storage = storage;
break;
}
case CMP_NODE_SEPYUVA_LEGACY: {
node->type = CMP_NODE_SEPARATE_COLOR;
NodeCMPCombSepColor *storage = (NodeCMPCombSepColor *)MEM_callocN(
sizeof(NodeCMPCombSepColor), __func__);
storage->mode = CMP_NODE_COMBSEP_COLOR_YUV;
strcpy(node->idname, "CompositorNodeSeparateColor");
node->storage = storage;
break;
}
}
}
}
/* In texture nodes, replace combine/separate RGBA with combine/separate color */
if (ntree->type == NTREE_TEXTURE) {
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
switch (node->type) {
case TEX_NODE_COMPOSE_LEGACY: {
node->type = TEX_NODE_COMBINE_COLOR;
node->custom1 = NODE_COMBSEP_COLOR_RGB;
strcpy(node->idname, "TextureNodeCombineColor");
break;
}
case TEX_NODE_DECOMPOSE_LEGACY: {
node->type = TEX_NODE_SEPARATE_COLOR;
node->custom1 = NODE_COMBSEP_COLOR_RGB;
strcpy(node->idname, "TextureNodeSeparateColor");
break;
}
}
}
}
/* In shader nodes, replace combine/separate RGB/HSV with combine/separate color */
if (ntree->type == NTREE_SHADER) {
version_node_input_socket_name(ntree, SH_NODE_COMBRGB_LEGACY, "R", "Red");
version_node_input_socket_name(ntree, SH_NODE_COMBRGB_LEGACY, "G", "Green");
version_node_input_socket_name(ntree, SH_NODE_COMBRGB_LEGACY, "B", "Blue");
version_node_output_socket_name(ntree, SH_NODE_COMBRGB_LEGACY, "Image", "Color");
version_node_input_socket_name(ntree, SH_NODE_COMBHSV_LEGACY, "H", "Red");
version_node_input_socket_name(ntree, SH_NODE_COMBHSV_LEGACY, "S", "Green");
version_node_input_socket_name(ntree, SH_NODE_COMBHSV_LEGACY, "V", "Blue");
version_node_output_socket_name(ntree, SH_NODE_SEPRGB_LEGACY, "R", "Red");
version_node_output_socket_name(ntree, SH_NODE_SEPRGB_LEGACY, "G", "Green");
version_node_output_socket_name(ntree, SH_NODE_SEPRGB_LEGACY, "B", "Blue");
version_node_input_socket_name(ntree, SH_NODE_SEPRGB_LEGACY, "Image", "Color");
version_node_output_socket_name(ntree, SH_NODE_SEPHSV_LEGACY, "H", "Red");
version_node_output_socket_name(ntree, SH_NODE_SEPHSV_LEGACY, "S", "Green");
version_node_output_socket_name(ntree, SH_NODE_SEPHSV_LEGACY, "V", "Blue");
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
switch (node->type) {
case SH_NODE_COMBRGB_LEGACY: {
node->type = SH_NODE_COMBINE_COLOR;
NodeCombSepColor *storage = (NodeCombSepColor *)MEM_callocN(sizeof(NodeCombSepColor),
__func__);
storage->mode = NODE_COMBSEP_COLOR_RGB;
strcpy(node->idname, "ShaderNodeCombineColor");
node->storage = storage;
break;
}
case SH_NODE_COMBHSV_LEGACY: {
node->type = SH_NODE_COMBINE_COLOR;
NodeCombSepColor *storage = (NodeCombSepColor *)MEM_callocN(sizeof(NodeCombSepColor),
__func__);
storage->mode = NODE_COMBSEP_COLOR_HSV;
strcpy(node->idname, "ShaderNodeCombineColor");
node->storage = storage;
break;
}
case SH_NODE_SEPRGB_LEGACY: {
node->type = SH_NODE_SEPARATE_COLOR;
NodeCombSepColor *storage = (NodeCombSepColor *)MEM_callocN(sizeof(NodeCombSepColor),
__func__);
storage->mode = NODE_COMBSEP_COLOR_RGB;
strcpy(node->idname, "ShaderNodeSeparateColor");
node->storage = storage;
break;
}
case SH_NODE_SEPHSV_LEGACY: {
node->type = SH_NODE_SEPARATE_COLOR;
NodeCombSepColor *storage = (NodeCombSepColor *)MEM_callocN(sizeof(NodeCombSepColor),
__func__);
storage->mode = NODE_COMBSEP_COLOR_HSV;
strcpy(node->idname, "ShaderNodeSeparateColor");
node->storage = storage;
break;
}
}
}
}
}
FOREACH_NODETREE_END;
}
}

View File

@ -259,12 +259,16 @@ set(SRC
# converter nodes
nodes/COM_CombineColorNode.cc
nodes/COM_CombineColorNode.h
nodes/COM_CombineColorNodeLegacy.cc
nodes/COM_CombineColorNodeLegacy.h
nodes/COM_CombineXYZNode.cc
nodes/COM_CombineXYZNode.h
nodes/COM_IDMaskNode.cc
nodes/COM_IDMaskNode.h
nodes/COM_SeparateColorNode.cc
nodes/COM_SeparateColorNode.h
nodes/COM_SeparateColorNodeLegacy.cc
nodes/COM_SeparateColorNodeLegacy.h
nodes/COM_SeparateXYZNode.cc
nodes/COM_SeparateXYZNode.h

View File

@ -29,6 +29,7 @@
#include "COM_ColorSpillNode.h"
#include "COM_ColorToBWNode.h"
#include "COM_CombineColorNode.h"
#include "COM_CombineColorNodeLegacy.h"
#include "COM_CombineXYZNode.h"
#include "COM_CompositorNode.h"
#include "COM_ConvertAlphaNode.h"
@ -82,6 +83,7 @@
#include "COM_ScaleOperation.h"
#include "COM_SceneTimeNode.h"
#include "COM_SeparateColorNode.h"
#include "COM_SeparateColorNodeLegacy.h"
#include "COM_SeparateXYZNode.h"
#include "COM_SetAlphaNode.h"
#include "COM_SetValueOperation.h"
@ -169,28 +171,34 @@ Node *COM_convert_bnode(bNode *b_node)
case CMP_NODE_BRIGHTCONTRAST:
node = new BrightnessNode(b_node);
break;
case CMP_NODE_SEPRGBA:
case CMP_NODE_SEPARATE_COLOR:
node = new SeparateColorNode(b_node);
break;
case CMP_NODE_COMBINE_COLOR:
node = new CombineColorNode(b_node);
break;
case CMP_NODE_SEPRGBA_LEGACY:
node = new SeparateRGBANode(b_node);
break;
case CMP_NODE_COMBRGBA:
case CMP_NODE_COMBRGBA_LEGACY:
node = new CombineRGBANode(b_node);
break;
case CMP_NODE_SEPHSVA:
case CMP_NODE_SEPHSVA_LEGACY:
node = new SeparateHSVANode(b_node);
break;
case CMP_NODE_COMBHSVA:
case CMP_NODE_COMBHSVA_LEGACY:
node = new CombineHSVANode(b_node);
break;
case CMP_NODE_SEPYUVA:
case CMP_NODE_SEPYUVA_LEGACY:
node = new SeparateYUVANode(b_node);
break;
case CMP_NODE_COMBYUVA:
case CMP_NODE_COMBYUVA_LEGACY:
node = new CombineYUVANode(b_node);
break;
case CMP_NODE_SEPYCCA:
case CMP_NODE_SEPYCCA_LEGACY:
node = new SeparateYCCANode(b_node);
break;
case CMP_NODE_COMBYCCA:
case CMP_NODE_COMBYCCA_LEGACY:
node = new CombineYCCANode(b_node);
break;
case CMP_NODE_ALPHAOVER:

View File

@ -40,7 +40,39 @@ void CombineColorNode::convert_to_operations(NodeConverter &converter,
converter.map_input_socket(input_bsocket, operation->get_input_socket(2));
converter.map_input_socket(input_asocket, operation->get_input_socket(3));
NodeOperation *color_conv = get_color_converter(context);
bNode *editor_node = this->get_bnode();
NodeCMPCombSepColor *storage = (NodeCMPCombSepColor *)editor_node->storage;
NodeOperation *color_conv = nullptr;
switch (storage->mode) {
case CMP_NODE_COMBSEP_COLOR_RGB: {
/* Pass */
break;
}
case CMP_NODE_COMBSEP_COLOR_HSV: {
color_conv = new ConvertHSVToRGBOperation();
break;
}
case CMP_NODE_COMBSEP_COLOR_HSL: {
color_conv = new ConvertHSLToRGBOperation();
break;
}
case CMP_NODE_COMBSEP_COLOR_YCC: {
ConvertYCCToRGBOperation *operation = new ConvertYCCToRGBOperation();
operation->set_mode(storage->ycc_mode);
color_conv = operation;
break;
}
case CMP_NODE_COMBSEP_COLOR_YUV: {
color_conv = new ConvertYUVToRGBOperation();
break;
}
default: {
BLI_assert_unreachable();
break;
}
}
if (color_conv) {
converter.add_operation(color_conv);
@ -52,27 +84,4 @@ void CombineColorNode::convert_to_operations(NodeConverter &converter,
}
}
NodeOperation *CombineRGBANode::get_color_converter(const CompositorContext & /*context*/) const
{
return nullptr; /* no conversion needed */
}
NodeOperation *CombineHSVANode::get_color_converter(const CompositorContext & /*context*/) const
{
return new ConvertHSVToRGBOperation();
}
NodeOperation *CombineYCCANode::get_color_converter(const CompositorContext & /*context*/) const
{
ConvertYCCToRGBOperation *operation = new ConvertYCCToRGBOperation();
bNode *editor_node = this->get_bnode();
operation->set_mode(editor_node->custom1);
return operation;
}
NodeOperation *CombineYUVANode::get_color_converter(const CompositorContext & /*context*/) const
{
return new ConvertYUVToRGBOperation();
}
} // namespace blender::compositor

View File

@ -12,45 +12,6 @@ class CombineColorNode : public Node {
CombineColorNode(bNode *editor_node);
void convert_to_operations(NodeConverter &converter,
const CompositorContext &context) const override;
protected:
virtual NodeOperation *get_color_converter(const CompositorContext &context) const = 0;
};
class CombineRGBANode : public CombineColorNode {
public:
CombineRGBANode(bNode *editor_node) : CombineColorNode(editor_node)
{
}
NodeOperation *get_color_converter(const CompositorContext &context) const override;
};
class CombineHSVANode : public CombineColorNode {
public:
CombineHSVANode(bNode *editor_node) : CombineColorNode(editor_node)
{
}
NodeOperation *get_color_converter(const CompositorContext &context) const override;
};
class CombineYCCANode : public CombineColorNode {
public:
CombineYCCANode(bNode *editor_node) : CombineColorNode(editor_node)
{
}
NodeOperation *get_color_converter(const CompositorContext &context) const override;
};
class CombineYUVANode : public CombineColorNode {
public:
CombineYUVANode(bNode *editor_node) : CombineColorNode(editor_node)
{
}
NodeOperation *get_color_converter(const CompositorContext &context) const override;
};
} // namespace blender::compositor

View File

@ -0,0 +1,78 @@
/* SPDX-License-Identifier: GPL-2.0-or-later
* Copyright 2011 Blender Foundation. */
#include "COM_CombineColorNodeLegacy.h"
#include "COM_ConvertOperation.h"
namespace blender::compositor {
CombineColorNodeLegacy::CombineColorNodeLegacy(bNode *editor_node) : Node(editor_node)
{
}
void CombineColorNodeLegacy::convert_to_operations(NodeConverter &converter,
const CompositorContext &context) const
{
NodeInput *input_rsocket = this->get_input_socket(0);
NodeInput *input_gsocket = this->get_input_socket(1);
NodeInput *input_bsocket = this->get_input_socket(2);
NodeInput *input_asocket = this->get_input_socket(3);
NodeOutput *output_socket = this->get_output_socket(0);
CombineChannelsOperation *operation = new CombineChannelsOperation();
if (input_rsocket->is_linked()) {
operation->set_canvas_input_index(0);
}
else if (input_gsocket->is_linked()) {
operation->set_canvas_input_index(1);
}
else if (input_bsocket->is_linked()) {
operation->set_canvas_input_index(2);
}
else {
operation->set_canvas_input_index(3);
}
converter.add_operation(operation);
converter.map_input_socket(input_rsocket, operation->get_input_socket(0));
converter.map_input_socket(input_gsocket, operation->get_input_socket(1));
converter.map_input_socket(input_bsocket, operation->get_input_socket(2));
converter.map_input_socket(input_asocket, operation->get_input_socket(3));
NodeOperation *color_conv = get_color_converter(context);
if (color_conv) {
converter.add_operation(color_conv);
converter.add_link(operation->get_output_socket(), color_conv->get_input_socket(0));
converter.map_output_socket(output_socket, color_conv->get_output_socket());
}
else {
converter.map_output_socket(output_socket, operation->get_output_socket());
}
}
NodeOperation *CombineRGBANode::get_color_converter(const CompositorContext & /*context*/) const
{
return nullptr; /* no conversion needed */
}
NodeOperation *CombineHSVANode::get_color_converter(const CompositorContext & /*context*/) const
{
return new ConvertHSVToRGBOperation();
}
NodeOperation *CombineYCCANode::get_color_converter(const CompositorContext & /*context*/) const
{
ConvertYCCToRGBOperation *operation = new ConvertYCCToRGBOperation();
bNode *editor_node = this->get_bnode();
operation->set_mode(editor_node->custom1);
return operation;
}
NodeOperation *CombineYUVANode::get_color_converter(const CompositorContext & /*context*/) const
{
return new ConvertYUVToRGBOperation();
}
} // namespace blender::compositor

View File

@ -0,0 +1,56 @@
/* SPDX-License-Identifier: GPL-2.0-or-later
* Copyright 2011 Blender Foundation. */
#pragma once
#include "COM_Node.h"
namespace blender::compositor {
class CombineColorNodeLegacy : public Node {
public:
CombineColorNodeLegacy(bNode *editor_node);
void convert_to_operations(NodeConverter &converter,
const CompositorContext &context) const override;
protected:
virtual NodeOperation *get_color_converter(const CompositorContext &context) const = 0;
};
class CombineRGBANode : public CombineColorNodeLegacy {
public:
CombineRGBANode(bNode *editor_node) : CombineColorNodeLegacy(editor_node)
{
}
NodeOperation *get_color_converter(const CompositorContext &context) const override;
};
class CombineHSVANode : public CombineColorNodeLegacy {
public:
CombineHSVANode(bNode *editor_node) : CombineColorNodeLegacy(editor_node)
{
}
NodeOperation *get_color_converter(const CompositorContext &context) const override;
};
class CombineYCCANode : public CombineColorNodeLegacy {
public:
CombineYCCANode(bNode *editor_node) : CombineColorNodeLegacy(editor_node)
{
}
NodeOperation *get_color_converter(const CompositorContext &context) const override;
};
class CombineYUVANode : public CombineColorNodeLegacy {
public:
CombineYUVANode(bNode *editor_node) : CombineColorNodeLegacy(editor_node)
{
}
NodeOperation *get_color_converter(const CompositorContext &context) const override;
};
} // namespace blender::compositor

View File

@ -20,7 +20,39 @@ void SeparateColorNode::convert_to_operations(NodeConverter &converter,
NodeOutput *output_bsocket = this->get_output_socket(2);
NodeOutput *output_asocket = this->get_output_socket(3);
NodeOperation *color_conv = get_color_converter(context);
bNode *editor_node = this->get_bnode();
NodeCMPCombSepColor *storage = (NodeCMPCombSepColor *)editor_node->storage;
NodeOperation *color_conv = nullptr;
switch (storage->mode) {
case CMP_NODE_COMBSEP_COLOR_RGB: {
/* Pass */
break;
}
case CMP_NODE_COMBSEP_COLOR_HSV: {
color_conv = new ConvertRGBToHSVOperation();
break;
}
case CMP_NODE_COMBSEP_COLOR_HSL: {
color_conv = new ConvertRGBToHSLOperation();
break;
}
case CMP_NODE_COMBSEP_COLOR_YCC: {
ConvertRGBToYCCOperation *operation = new ConvertRGBToYCCOperation();
operation->set_mode(storage->ycc_mode);
color_conv = operation;
break;
}
case CMP_NODE_COMBSEP_COLOR_YUV: {
color_conv = new ConvertRGBToYUVOperation();
break;
}
default: {
BLI_assert_unreachable();
break;
}
}
if (color_conv) {
converter.add_operation(color_conv);
@ -84,27 +116,4 @@ void SeparateColorNode::convert_to_operations(NodeConverter &converter,
}
}
NodeOperation *SeparateRGBANode::get_color_converter(const CompositorContext & /*context*/) const
{
return nullptr; /* no conversion needed */
}
NodeOperation *SeparateHSVANode::get_color_converter(const CompositorContext & /*context*/) const
{
return new ConvertRGBToHSVOperation();
}
NodeOperation *SeparateYCCANode::get_color_converter(const CompositorContext & /*context*/) const
{
ConvertRGBToYCCOperation *operation = new ConvertRGBToYCCOperation();
bNode *editor_node = this->get_bnode();
operation->set_mode(editor_node->custom1);
return operation;
}
NodeOperation *SeparateYUVANode::get_color_converter(const CompositorContext & /*context*/) const
{
return new ConvertRGBToYUVOperation();
}
} // namespace blender::compositor

View File

@ -12,45 +12,6 @@ class SeparateColorNode : public Node {
SeparateColorNode(bNode *editor_node);
void convert_to_operations(NodeConverter &converter,
const CompositorContext &context) const override;
protected:
virtual NodeOperation *get_color_converter(const CompositorContext &context) const = 0;
};
class SeparateRGBANode : public SeparateColorNode {
public:
SeparateRGBANode(bNode *editor_node) : SeparateColorNode(editor_node)
{
}
NodeOperation *get_color_converter(const CompositorContext &context) const override;
};
class SeparateHSVANode : public SeparateColorNode {
public:
SeparateHSVANode(bNode *editor_node) : SeparateColorNode(editor_node)
{
}
NodeOperation *get_color_converter(const CompositorContext &context) const override;
};
class SeparateYCCANode : public SeparateColorNode {
public:
SeparateYCCANode(bNode *editor_node) : SeparateColorNode(editor_node)
{
}
NodeOperation *get_color_converter(const CompositorContext &context) const override;
};
class SeparateYUVANode : public SeparateColorNode {
public:
SeparateYUVANode(bNode *editor_node) : SeparateColorNode(editor_node)
{
}
NodeOperation *get_color_converter(const CompositorContext &context) const override;
};
} // namespace blender::compositor

View File

@ -0,0 +1,110 @@
/* SPDX-License-Identifier: GPL-2.0-or-later
* Copyright 2011 Blender Foundation. */
#include "COM_SeparateColorNodeLegacy.h"
#include "COM_ConvertOperation.h"
namespace blender::compositor {
SeparateColorNodeLegacy::SeparateColorNodeLegacy(bNode *editor_node) : Node(editor_node)
{
}
void SeparateColorNodeLegacy::convert_to_operations(NodeConverter &converter,
const CompositorContext &context) const
{
NodeInput *image_socket = this->get_input_socket(0);
NodeOutput *output_rsocket = this->get_output_socket(0);
NodeOutput *output_gsocket = this->get_output_socket(1);
NodeOutput *output_bsocket = this->get_output_socket(2);
NodeOutput *output_asocket = this->get_output_socket(3);
NodeOperation *color_conv = get_color_converter(context);
if (color_conv) {
converter.add_operation(color_conv);
converter.map_input_socket(image_socket, color_conv->get_input_socket(0));
}
{
SeparateChannelOperation *operation = new SeparateChannelOperation();
operation->set_channel(0);
converter.add_operation(operation);
if (color_conv) {
converter.add_link(color_conv->get_output_socket(), operation->get_input_socket(0));
}
else {
converter.map_input_socket(image_socket, operation->get_input_socket(0));
}
converter.map_output_socket(output_rsocket, operation->get_output_socket(0));
}
{
SeparateChannelOperation *operation = new SeparateChannelOperation();
operation->set_channel(1);
converter.add_operation(operation);
if (color_conv) {
converter.add_link(color_conv->get_output_socket(), operation->get_input_socket(0));
}
else {
converter.map_input_socket(image_socket, operation->get_input_socket(0));
}
converter.map_output_socket(output_gsocket, operation->get_output_socket(0));
}
{
SeparateChannelOperation *operation = new SeparateChannelOperation();
operation->set_channel(2);
converter.add_operation(operation);
if (color_conv) {
converter.add_link(color_conv->get_output_socket(), operation->get_input_socket(0));
}
else {
converter.map_input_socket(image_socket, operation->get_input_socket(0));
}
converter.map_output_socket(output_bsocket, operation->get_output_socket(0));
}
{
SeparateChannelOperation *operation = new SeparateChannelOperation();
operation->set_channel(3);
converter.add_operation(operation);
if (color_conv) {
converter.add_link(color_conv->get_output_socket(), operation->get_input_socket(0));
}
else {
converter.map_input_socket(image_socket, operation->get_input_socket(0));
}
converter.map_output_socket(output_asocket, operation->get_output_socket(0));
}
}
NodeOperation *SeparateRGBANode::get_color_converter(const CompositorContext & /*context*/) const
{
return nullptr; /* no conversion needed */
}
NodeOperation *SeparateHSVANode::get_color_converter(const CompositorContext & /*context*/) const
{
return new ConvertRGBToHSVOperation();
}
NodeOperation *SeparateYCCANode::get_color_converter(const CompositorContext & /*context*/) const
{
ConvertRGBToYCCOperation *operation = new ConvertRGBToYCCOperation();
bNode *editor_node = this->get_bnode();
operation->set_mode(editor_node->custom1);
return operation;
}
NodeOperation *SeparateYUVANode::get_color_converter(const CompositorContext & /*context*/) const
{
return new ConvertRGBToYUVOperation();
}
} // namespace blender::compositor

View File

@ -0,0 +1,56 @@
/* SPDX-License-Identifier: GPL-2.0-or-later
* Copyright 2011 Blender Foundation. */
#pragma once
#include "COM_Node.h"
namespace blender::compositor {
class SeparateColorNodeLegacy : public Node {
public:
SeparateColorNodeLegacy(bNode *editor_node);
void convert_to_operations(NodeConverter &converter,
const CompositorContext &context) const override;
protected:
virtual NodeOperation *get_color_converter(const CompositorContext &context) const = 0;
};
class SeparateRGBANode : public SeparateColorNodeLegacy {
public:
SeparateRGBANode(bNode *editor_node) : SeparateColorNodeLegacy(editor_node)
{
}
NodeOperation *get_color_converter(const CompositorContext &context) const override;
};
class SeparateHSVANode : public SeparateColorNodeLegacy {
public:
SeparateHSVANode(bNode *editor_node) : SeparateColorNodeLegacy(editor_node)
{
}
NodeOperation *get_color_converter(const CompositorContext &context) const override;
};
class SeparateYCCANode : public SeparateColorNodeLegacy {
public:
SeparateYCCANode(bNode *editor_node) : SeparateColorNodeLegacy(editor_node)
{
}
NodeOperation *get_color_converter(const CompositorContext &context) const override;
};
class SeparateYUVANode : public SeparateColorNodeLegacy {
public:
SeparateYUVANode(bNode *editor_node) : SeparateColorNodeLegacy(editor_node)
{
}
NodeOperation *get_color_converter(const CompositorContext &context) const override;
};
} // namespace blender::compositor

View File

@ -464,6 +464,68 @@ void ConvertHSVToRGBOperation::update_memory_buffer_partial(BuffersIterator<floa
}
}
/* ******** RGB to HSL ******** */
ConvertRGBToHSLOperation::ConvertRGBToHSLOperation() : ConvertBaseOperation()
{
this->add_input_socket(DataType::Color);
this->add_output_socket(DataType::Color);
}
void ConvertRGBToHSLOperation::execute_pixel_sampled(float output[4],
float x,
float y,
PixelSampler sampler)
{
float input_color[4];
input_operation_->read_sampled(input_color, x, y, sampler);
rgb_to_hsl_v(input_color, output);
output[3] = input_color[3];
}
void ConvertRGBToHSLOperation::update_memory_buffer_partial(BuffersIterator<float> &it)
{
for (; !it.is_end(); ++it) {
const float *in = it.in(0);
rgb_to_hsl_v(in, it.out);
it.out[3] = in[3];
}
}
/* ******** HSL to RGB ******** */
ConvertHSLToRGBOperation::ConvertHSLToRGBOperation() : ConvertBaseOperation()
{
this->add_input_socket(DataType::Color);
this->add_output_socket(DataType::Color);
}
void ConvertHSLToRGBOperation::execute_pixel_sampled(float output[4],
float x,
float y,
PixelSampler sampler)
{
float input_color[4];
input_operation_->read_sampled(input_color, x, y, sampler);
hsl_to_rgb_v(input_color, output);
output[0] = max_ff(output[0], 0.0f);
output[1] = max_ff(output[1], 0.0f);
output[2] = max_ff(output[2], 0.0f);
output[3] = input_color[3];
}
void ConvertHSLToRGBOperation::update_memory_buffer_partial(BuffersIterator<float> &it)
{
for (; !it.is_end(); ++it) {
const float *in = it.in(0);
hsl_to_rgb_v(in, it.out);
it.out[0] = max_ff(it.out[0], 0.0f);
it.out[1] = max_ff(it.out[1], 0.0f);
it.out[2] = max_ff(it.out[2], 0.0f);
it.out[3] = in[3];
}
}
/* ******** Premul to Straight ******** */
ConvertPremulToStraightOperation::ConvertPremulToStraightOperation() : ConvertBaseOperation()

View File

@ -172,6 +172,26 @@ class ConvertHSVToRGBOperation : public ConvertBaseOperation {
void update_memory_buffer_partial(BuffersIterator<float> &it) override;
};
class ConvertRGBToHSLOperation : public ConvertBaseOperation {
public:
ConvertRGBToHSLOperation();
void execute_pixel_sampled(float output[4], float x, float y, PixelSampler sampler) override;
protected:
void update_memory_buffer_partial(BuffersIterator<float> &it) override;
};
class ConvertHSLToRGBOperation : public ConvertBaseOperation {
public:
ConvertHSLToRGBOperation();
void execute_pixel_sampled(float output[4], float x, float y, PixelSampler sampler) override;
protected:
void update_memory_buffer_partial(BuffersIterator<float> &it) override;
};
class ConvertPremulToStraightOperation : public ConvertBaseOperation {
public:
ConvertPremulToStraightOperation();

View File

@ -213,6 +213,11 @@ static void node_buts_math(uiLayout *layout, bContext *UNUSED(C), PointerRNA *pt
uiItemR(layout, ptr, "use_clamp", DEFAULT_FLAGS, nullptr, ICON_NONE);
}
static void node_buts_combsep_color(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiItemR(layout, ptr, "mode", DEFAULT_FLAGS, "", ICON_NONE);
}
NodeResizeDirection node_get_resize_direction(const bNode *node, const int x, const int y)
{
if (node->type == NODE_FRAME) {
@ -480,6 +485,10 @@ static void node_shader_set_butfunc(bNodeType *ntype)
case SH_NODE_MATH:
ntype->draw_buttons = node_buts_math;
break;
case SH_NODE_COMBINE_COLOR:
case SH_NODE_SEPARATE_COLOR:
ntype->draw_buttons = node_buts_combsep_color;
break;
case SH_NODE_TEX_IMAGE:
ntype->draw_buttons = node_shader_buts_tex_image;
ntype->draw_buttons_ex = node_shader_buts_tex_image_ex;
@ -589,6 +598,19 @@ static void node_composit_buts_ycc(uiLayout *layout, bContext *UNUSED(C), Pointe
uiItemR(layout, ptr, "mode", DEFAULT_FLAGS, "", ICON_NONE);
}
static void node_composit_buts_combsep_color(uiLayout *layout,
bContext *UNUSED(C),
PointerRNA *ptr)
{
bNode *node = (bNode *)ptr->data;
NodeCMPCombSepColor *storage = (NodeCMPCombSepColor *)node->storage;
uiItemR(layout, ptr, "mode", DEFAULT_FLAGS, "", ICON_NONE);
if (storage->mode == CMP_NODE_COMBSEP_COLOR_YCC) {
uiItemR(layout, ptr, "ycc_mode", DEFAULT_FLAGS, "", ICON_NONE);
}
}
static void node_composit_backdrop_viewer(
SpaceNode *snode, ImBuf *backdrop, bNode *node, int x, int y)
{
@ -821,8 +843,12 @@ static void node_composit_set_butfunc(bNodeType *ntype)
case CMP_NODE_HUECORRECT:
ntype->draw_buttons = node_composit_buts_huecorrect;
break;
case CMP_NODE_COMBYCCA:
case CMP_NODE_SEPYCCA:
case CMP_NODE_COMBINE_COLOR:
case CMP_NODE_SEPARATE_COLOR:
ntype->draw_buttons = node_composit_buts_combsep_color;
break;
case CMP_NODE_COMBYCCA_LEGACY:
case CMP_NODE_SEPYCCA_LEGACY:
ntype->draw_buttons = node_composit_buts_ycc;
break;
case CMP_NODE_MASK_BOX:
@ -975,6 +1001,11 @@ static void node_texture_buts_output(uiLayout *layout, bContext *UNUSED(C), Poin
uiItemR(layout, ptr, "filepath", DEFAULT_FLAGS, "", ICON_NONE);
}
static void node_texture_buts_combsep_color(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiItemR(layout, ptr, "mode", DEFAULT_FLAGS, "", ICON_NONE);
}
/* only once called */
static void node_texture_set_butfunc(bNodeType *ntype)
{
@ -1020,6 +1051,11 @@ static void node_texture_set_butfunc(bNodeType *ntype)
case TEX_NODE_OUTPUT:
ntype->draw_buttons = node_texture_buts_output;
break;
case TEX_NODE_COMBINE_COLOR:
case TEX_NODE_SEPARATE_COLOR:
ntype->draw_buttons = node_texture_buts_combsep_color;
break;
}
}
}

View File

@ -317,6 +317,7 @@ set(GLSL_SRC
shaders/material/gpu_shader_material_clamp.glsl
shaders/material/gpu_shader_material_color_ramp.glsl
shaders/material/gpu_shader_material_color_util.glsl
shaders/material/gpu_shader_material_combine_color.glsl
shaders/material/gpu_shader_material_combine_hsv.glsl
shaders/material/gpu_shader_material_combine_rgb.glsl
shaders/material/gpu_shader_material_combine_xyz.glsl
@ -359,6 +360,7 @@ set(GLSL_SRC
shaders/material/gpu_shader_material_refraction.glsl
shaders/material/gpu_shader_material_rgb_curves.glsl
shaders/material/gpu_shader_material_rgb_to_bw.glsl
shaders/material/gpu_shader_material_separate_color.glsl
shaders/material/gpu_shader_material_separate_hsv.glsl
shaders/material/gpu_shader_material_separate_rgb.glsl
shaders/material/gpu_shader_material_separate_xyz.glsl

View File

@ -90,6 +90,56 @@ void hsv_to_rgb(vec4 hsv, out vec4 outcol)
outcol = vec4(rgb, hsv.w);
}
void rgb_to_hsl(vec4 rgb, out vec4 outcol)
{
float cmax, cmin, h, s, l;
cmax = max(rgb[0], max(rgb[1], rgb[2]));
cmin = min(rgb[0], min(rgb[1], rgb[2]));
l = min(1.0, (cmax + cmin) / 2.0);
if (cmax == cmin) {
h = s = 0.0; /* achromatic */
}
else {
float cdelta = cmax - cmin;
s = l > 0.5 ? cdelta / (2.0 - cmax - cmin) : cdelta / (cmax + cmin);
if (cmax == rgb[0]) {
h = (rgb[1] - rgb[2]) / cdelta + (rgb[1] < rgb[2] ? 6.0 : 0.0);
}
else if (cmax == rgb[1]) {
h = (rgb[2] - rgb[0]) / cdelta + 2.0;
}
else {
h = (rgb[0] - rgb[1]) / cdelta + 4.0;
}
}
h /= 6.0;
outcol = vec4(h, s, l, rgb.w);
}
void hsl_to_rgb(vec4 hsl, out vec4 outcol)
{
float nr, ng, nb, chroma, h, s, l;
h = hsl[0];
s = hsl[1];
l = hsl[2];
nr = abs(h * 6.0 - 3.0) - 1.0;
ng = 2.0 - abs(h * 6.0 - 2.0);
nb = 2.0 - abs(h * 6.0 - 4.0);
nr = clamp(nr, 0.0, 1.0);
nb = clamp(nb, 0.0, 1.0);
ng = clamp(ng, 0.0, 1.0);
chroma = (1.0 - abs(2.0 * l - 1.0)) * s;
outcol = vec4((nr - 0.5) * chroma + l, (ng - 0.5) * chroma + l, (nb - 0.5) * chroma + l, hsl.w);
}
void color_alpha_clear(vec4 color, out vec4 result)
{
result = vec4(color.rgb, 1.0);

View File

@ -0,0 +1,16 @@
#pragma BLENDER_REQUIRE(gpu_shader_material_color_util.glsl)
void combine_color_rgb(float r, float g, float b, out vec4 col)
{
col = vec4(r, g, b, 1.0);
}
void combine_color_hsv(float h, float s, float v, out vec4 col)
{
hsv_to_rgb(vec4(h, s, v, 1.0), col);
}
void combine_color_hsl(float h, float s, float l, out vec4 col)
{
hsl_to_rgb(vec4(h, s, l, 1.0), col);
}

View File

@ -0,0 +1,28 @@
#pragma BLENDER_REQUIRE(gpu_shader_material_color_util.glsl)
void separate_color_rgb(vec4 col, out float r, out float g, out float b)
{
r = col.r;
g = col.g;
b = col.b;
}
void separate_color_hsv(vec4 col, out float r, out float g, out float b)
{
vec4 hsv;
rgb_to_hsv(col, hsv);
r = hsv[0];
g = hsv[1];
b = hsv[2];
}
void separate_color_hsl(vec4 col, out float r, out float g, out float b)
{
vec4 hsl;
rgb_to_hsl(col, hsl);
r = hsl[0];
g = hsl[1];
b = hsl[2];
}

View File

@ -855,6 +855,12 @@ typedef struct NodeVertexCol {
char name[64];
} NodeVertexCol;
typedef struct NodeCMPCombSepColor {
/* CMPNodeCombSepColorMode */
uint8_t mode;
uint8_t ycc_mode;
} NodeCMPCombSepColor;
/** Defocus blur node. */
typedef struct NodeDefocus {
char bktype, _pad0, preview, gamco;
@ -1485,6 +1491,11 @@ typedef struct NodeFunctionCompare {
char _pad[1];
} NodeFunctionCompare;
typedef struct NodeCombSepColor {
/* NodeCombSepColorMode */
int8_t mode;
} NodeCombSepColor;
/* script node mode */
#define NODE_SCRIPT_INTERNAL 0
#define NODE_SCRIPT_EXTERNAL 1
@ -1877,6 +1888,16 @@ typedef enum CMPNodeDenoisePrefilter {
CMP_NODE_DENOISE_PREFILTER_ACCURATE = 2
} CMPNodeDenoisePrefilter;
/* Color combine/separate modes */
typedef enum CMPNodeCombSepColorMode {
CMP_NODE_COMBSEP_COLOR_RGB = 0,
CMP_NODE_COMBSEP_COLOR_HSV = 1,
CMP_NODE_COMBSEP_COLOR_HSL = 2,
CMP_NODE_COMBSEP_COLOR_YCC = 3,
CMP_NODE_COMBSEP_COLOR_YUV = 4,
} CMPNodeCombSepColorMode;
#define CMP_NODE_PLANETRACKDEFORM_MBLUR_SAMPLES_MAX 64
/* Point Density shader node */
@ -2135,6 +2156,12 @@ typedef enum GeometryNodeScaleElementsMode {
GEO_NODE_SCALE_ELEMENTS_SINGLE_AXIS = 1,
} GeometryNodeScaleElementsMode;
typedef enum NodeCombSepColorMode {
NODE_COMBSEP_COLOR_RGB = 0,
NODE_COMBSEP_COLOR_HSV = 1,
NODE_COMBSEP_COLOR_HSL = 2,
} NodeCombSepColorMode;
#ifdef __cplusplus
}
#endif

View File

@ -489,6 +489,13 @@ static const EnumPropertyItem rna_node_geometry_curve_handle_side_items[] = {
{GEO_NODE_CURVE_HANDLE_RIGHT, "RIGHT", ICON_NONE, "Right", "Use the right handles"},
{0, NULL, 0, NULL, NULL}};
static const EnumPropertyItem rna_node_combsep_color_items[] = {
{NODE_COMBSEP_COLOR_RGB, "RGB", ICON_NONE, "RGB", "Use RGB color processing"},
{NODE_COMBSEP_COLOR_HSV, "HSV", ICON_NONE, "HSV", "Use HSV color processing"},
{NODE_COMBSEP_COLOR_HSL, "HSL", ICON_NONE, "HSL", "Use HSL color processing"},
{0, NULL, 0, NULL, NULL},
};
#ifndef RNA_RUNTIME
static const EnumPropertyItem node_sampler_type_items[] = {
{0, "NEAREST", 0, "Nearest", ""},
@ -5050,6 +5057,18 @@ static void def_fn_input_string(StructRNA *srna)
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
}
static void def_fn_combsep_color(StructRNA *srna)
{
PropertyRNA *prop;
RNA_def_struct_sdna_from(srna, "NodeCombSepColor", "storage");
prop = RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, rna_node_combsep_color_items);
RNA_def_property_ui_text(prop, "Mode", "Mode of color processing");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
}
/* -- Shader Nodes ---------------------------------------------------------- */
static void def_sh_output(StructRNA *srna)
@ -5401,6 +5420,17 @@ static void def_sh_tex_image(StructRNA *srna)
RNA_def_property_update(prop, 0, "rna_Node_update");
}
static void def_tex_combsep_color(StructRNA *srna)
{
PropertyRNA *prop;
prop = RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "custom1");
RNA_def_property_enum_items(prop, rna_node_combsep_color_items);
RNA_def_property_ui_text(prop, "Mode", "Mode of color processing");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
}
static void def_geo_image_texture(StructRNA *srna)
{
static const EnumPropertyItem fn_tex_prop_interpolation_items[] = {
@ -6308,6 +6338,25 @@ static void def_sh_output_aov(StructRNA *srna)
RNA_def_struct_sdna_from(srna, "bNode", NULL);
}
static void def_sh_combsep_color(StructRNA *srna)
{
static const EnumPropertyItem type_items[] = {
{NODE_COMBSEP_COLOR_RGB, "RGB", ICON_NONE, "RGB", "Use RGB color processing"},
{NODE_COMBSEP_COLOR_HSV, "HSV", ICON_NONE, "HSV", "Use HSV color processing"},
{NODE_COMBSEP_COLOR_HSL, "HSL", ICON_NONE, "HSL", "Use HSL color processing"},
{0, NULL, 0, NULL, NULL},
};
PropertyRNA *prop;
RNA_def_struct_sdna_from(srna, "NodeCombSepColor", "storage");
prop = RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, type_items);
RNA_def_property_ui_text(prop, "Mode", "Mode of color processing");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
}
static void def_sh_script(StructRNA *srna)
{
PropertyRNA *prop;
@ -8071,6 +8120,32 @@ static void def_cmp_ycc(StructRNA *srna)
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
}
static void def_cmp_combsep_color(StructRNA *srna)
{
static const EnumPropertyItem mode_items[] = {
{CMP_NODE_COMBSEP_COLOR_RGB, "RGB", ICON_NONE, "RGB", "Use RGB color processing"},
{CMP_NODE_COMBSEP_COLOR_HSV, "HSV", ICON_NONE, "HSV", "Use HSV color processing"},
{CMP_NODE_COMBSEP_COLOR_HSL, "HSL", ICON_NONE, "HSL", "Use HSL color processing"},
{CMP_NODE_COMBSEP_COLOR_YCC, "YCC", ICON_NONE, "YCbCr", "Use YCbCr color processing"},
{CMP_NODE_COMBSEP_COLOR_YUV, "YUV", ICON_NONE, "YUV", "Use YUV color processing"},
{0, NULL, 0, NULL, NULL},
};
PropertyRNA *prop;
RNA_def_struct_sdna_from(srna, "NodeCMPCombSepColor", "storage");
prop = RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, mode_items);
RNA_def_property_ui_text(prop, "Mode", "Mode of color processing");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update");
prop = RNA_def_property(srna, "ycc_mode", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, node_ycc_items);
RNA_def_property_ui_text(prop, "Color Space", "Color space used for YCbCrA processing");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
}
static void def_cmp_movieclip(StructRNA *srna)
{
PropertyRNA *prop;

View File

@ -126,6 +126,8 @@ void register_node_type_cmp_planetrackdeform(void);
void register_node_type_cmp_cornerpin(void);
void register_node_type_cmp_separate_xyz(void);
void register_node_type_cmp_combine_xyz(void);
void register_node_type_cmp_separate_color(void);
void register_node_type_cmp_combine_color(void);
void node_cmp_rlayers_outputs(struct bNodeTree *ntree, struct bNode *node);
void node_cmp_rlayers_register_pass(struct bNodeTree *ntree,

View File

@ -8,6 +8,7 @@ extern "C" {
void register_node_type_fn_align_euler_to_vector(void);
void register_node_type_fn_boolean_math(void);
void register_node_type_fn_combine_color(void);
void register_node_type_fn_compare(void);
void register_node_type_fn_float_to_int(void);
void register_node_type_fn_input_bool(void);
@ -19,6 +20,7 @@ void register_node_type_fn_input_vector(void);
void register_node_type_fn_random_value(void);
void register_node_type_fn_replace_string(void);
void register_node_type_fn_rotate_euler(void);
void register_node_type_fn_separate_color(void);
void register_node_type_fn_slice_string(void);
void register_node_type_fn_string_length(void);
void register_node_type_fn_value_to_string(void);

View File

@ -43,6 +43,8 @@ void register_node_type_sh_vect_math(void);
void register_node_type_sh_squeeze(void);
void register_node_type_sh_dynamic(void);
void register_node_type_sh_invert(void);
void register_node_type_sh_sepcolor(void);
void register_node_type_sh_combcolor(void);
void register_node_type_sh_seprgb(void);
void register_node_type_sh_combrgb(void);
void register_node_type_sh_sephsv(void);

View File

@ -42,8 +42,8 @@ DefNode(ShaderNode, SH_NODE_MATH, def_math, "MATH",
DefNode(ShaderNode, SH_NODE_VECTOR_MATH, def_vector_math, "VECT_MATH", VectorMath, "Vector Math", "" )
DefNode(ShaderNode, SH_NODE_SQUEEZE, 0, "SQUEEZE", Squeeze, "Squeeze Value", "" )
DefNode(ShaderNode, SH_NODE_INVERT, 0, "INVERT", Invert, "Invert", "" )
DefNode(ShaderNode, SH_NODE_SEPRGB, 0, "SEPRGB", SeparateRGB, "Separate RGB", "" )
DefNode(ShaderNode, SH_NODE_COMBRGB, 0, "COMBRGB", CombineRGB, "Combine RGB", "" )
DefNode(ShaderNode, SH_NODE_SEPRGB_LEGACY, 0, "SEPRGB", SeparateRGB, "Separate RGB", "" )
DefNode(ShaderNode, SH_NODE_COMBRGB_LEGACY, 0, "COMBRGB", CombineRGB, "Combine RGB", "" )
DefNode(ShaderNode, SH_NODE_HUE_SAT, 0, "HUE_SAT", HueSaturation, "Hue/Saturation", "" )
DefNode(ShaderNode, SH_NODE_OUTPUT_MATERIAL, def_sh_output, "OUTPUT_MATERIAL", OutputMaterial, "Material Output", "" )
@ -106,8 +106,8 @@ DefNode(ShaderNode, SH_NODE_TEX_POINTDENSITY, def_sh_tex_pointdensity,"TEX
DefNode(ShaderNode, SH_NODE_TEX_COORD, def_sh_tex_coord, "TEX_COORD", TexCoord, "Texture Coordinate","" )
DefNode(ShaderNode, SH_NODE_VECTOR_ROTATE, def_sh_vector_rotate, "VECTOR_ROTATE", VectorRotate, "Vector Rotate", "" )
DefNode(ShaderNode, SH_NODE_VECT_TRANSFORM, def_sh_vect_transform, "VECT_TRANSFORM", VectorTransform, "Vector Transform", "" )
DefNode(ShaderNode, SH_NODE_SEPHSV, 0, "SEPHSV", SeparateHSV, "Separate HSV", "" )
DefNode(ShaderNode, SH_NODE_COMBHSV, 0, "COMBHSV", CombineHSV, "Combine HSV", "" )
DefNode(ShaderNode, SH_NODE_SEPHSV_LEGACY, 0, "SEPHSV", SeparateHSV, "Separate HSV", "" )
DefNode(ShaderNode, SH_NODE_COMBHSV_LEGACY, 0, "COMBHSV", CombineHSV, "Combine HSV", "" )
DefNode(ShaderNode, SH_NODE_UVMAP, def_sh_uvmap, "UVMAP", UVMap, "UV Map", "" )
DefNode(ShaderNode, SH_NODE_VERTEX_COLOR, def_sh_vertex_color, "VERTEX_COLOR", VertexColor, "Color Attribute", "" )
DefNode(ShaderNode, SH_NODE_UVALONGSTROKE, def_sh_uvalongstroke, "UVALONGSTROKE", UVAlongStroke, "UV Along Stroke", "" )
@ -120,6 +120,8 @@ DefNode(ShaderNode, SH_NODE_TEX_IES, def_sh_tex_ies, "TEX
DefNode(ShaderNode, SH_NODE_TEX_WHITE_NOISE, def_sh_tex_white_noise, "TEX_WHITE_NOISE", TexWhiteNoise, "White Noise", "" )
DefNode(ShaderNode, SH_NODE_OUTPUT_AOV, def_sh_output_aov, "OUTPUT_AOV", OutputAOV, "AOV Output", "" )
DefNode(ShaderNode, SH_NODE_CURVE_FLOAT, def_float_curve, "CURVE_FLOAT", FloatCurve, "Float Curve", "" )
DefNode(ShaderNode, SH_NODE_COMBINE_COLOR, def_sh_combsep_color, "COMBINE_COLOR", CombineColor, "Combine Color", "" )
DefNode(ShaderNode, SH_NODE_SEPARATE_COLOR, def_sh_combsep_color, "SEPARATE_COLOR", SeparateColor, "Separate Color", "" )
DefNode(CompositorNode, CMP_NODE_VIEWER, def_cmp_viewer, "VIEWER", Viewer, "Viewer", "" )
DefNode(CompositorNode, CMP_NODE_RGB, 0, "RGB", RGB, "RGB", "" )
@ -137,8 +139,8 @@ DefNode(CompositorNode, CMP_NODE_MAP_VALUE, def_cmp_map_value, "MAP_VA
DefNode(CompositorNode, CMP_NODE_MAP_RANGE, def_cmp_map_range, "MAP_RANGE", MapRange, "Map Range", "" )
DefNode(CompositorNode, CMP_NODE_TIME, def_time, "TIME", Time, "Time Curve", "" )
DefNode(CompositorNode, CMP_NODE_VECBLUR, def_cmp_vector_blur, "VECBLUR", VecBlur, "Vector Blur", "" )
DefNode(CompositorNode, CMP_NODE_SEPRGBA, 0, "SEPRGBA", SepRGBA, "Separate RGBA", "" )
DefNode(CompositorNode, CMP_NODE_SEPHSVA, 0, "SEPHSVA", SepHSVA, "Separate HSVA", "" )
DefNode(CompositorNode, CMP_NODE_SEPRGBA_LEGACY, 0, "SEPRGBA", SepRGBA, "Separate RGBA", "" )
DefNode(CompositorNode, CMP_NODE_SEPHSVA_LEGACY, 0, "SEPHSVA", SepHSVA, "Separate HSVA", "" )
DefNode(CompositorNode, CMP_NODE_SETALPHA, def_cmp_set_alpha, "SETALPHA", SetAlpha, "Set Alpha", "" )
DefNode(CompositorNode, CMP_NODE_HUE_SAT, 0, "HUE_SAT", HueSat, "Hue Saturation Value","" )
DefNode(CompositorNode, CMP_NODE_IMAGE, def_cmp_image, "IMAGE", Image, "Image", "" )
@ -149,16 +151,16 @@ DefNode(CompositorNode, CMP_NODE_OUTPUT_FILE, 0, "OUTPUT
DefNode(CompositorNode, CMP_NODE_TEXTURE, def_texture, "TEXTURE", Texture, "Texture", "" )
DefNode(CompositorNode, CMP_NODE_TRANSLATE, def_cmp_translate, "TRANSLATE", Translate, "Translate", "" )
DefNode(CompositorNode, CMP_NODE_ZCOMBINE, def_cmp_zcombine, "ZCOMBINE", Zcombine, "Z Combine", "" )
DefNode(CompositorNode, CMP_NODE_COMBRGBA, 0, "COMBRGBA", CombRGBA, "Combine RGBA", "" )
DefNode(CompositorNode, CMP_NODE_COMBRGBA_LEGACY,0, "COMBRGBA", CombRGBA, "Combine RGBA", "" )
DefNode(CompositorNode, CMP_NODE_DILATEERODE, def_cmp_dilate_erode, "DILATEERODE", DilateErode, "Dilate/Erode", "" )
DefNode(CompositorNode, CMP_NODE_INPAINT, def_cmp_inpaint, "INPAINT", Inpaint, "Inpaint", "" )
DefNode(CompositorNode, CMP_NODE_DESPECKLE, def_cmp_despeckle, "DESPECKLE", Despeckle, "Despeckle", "" )
DefNode(CompositorNode, CMP_NODE_ROTATE, def_cmp_rotate, "ROTATE", Rotate, "Rotate", "" )
DefNode(CompositorNode, CMP_NODE_SCALE, def_cmp_scale, "SCALE", Scale, "Scale", "" )
DefNode(CompositorNode, CMP_NODE_SEPYCCA, def_cmp_ycc, "SEPYCCA", SepYCCA, "Separate YCbCrA", "" )
DefNode(CompositorNode, CMP_NODE_COMBYCCA, def_cmp_ycc, "COMBYCCA", CombYCCA, "Combine YCbCrA", "" )
DefNode(CompositorNode, CMP_NODE_SEPYUVA, 0, "SEPYUVA", SepYUVA, "Separate YUVA", "" )
DefNode(CompositorNode, CMP_NODE_COMBYUVA, 0, "COMBYUVA", CombYUVA, "Combine YUVA", "" )
DefNode(CompositorNode, CMP_NODE_SEPYCCA_LEGACY, def_cmp_ycc, "SEPYCCA", SepYCCA, "Separate YCbCrA", "" )
DefNode(CompositorNode, CMP_NODE_COMBYCCA_LEGACY,def_cmp_ycc, "COMBYCCA", CombYCCA, "Combine YCbCrA", "" )
DefNode(CompositorNode, CMP_NODE_SEPYUVA_LEGACY, 0, "SEPYUVA", SepYUVA, "Separate YUVA", "" )
DefNode(CompositorNode, CMP_NODE_COMBYUVA_LEGACY,0, "COMBYUVA", CombYUVA, "Combine YUVA", "" )
DefNode(CompositorNode, CMP_NODE_DIFF_MATTE, def_cmp_diff_matte, "DIFF_MATTE", DiffMatte, "Difference Key", "" )
DefNode(CompositorNode, CMP_NODE_COLOR_SPILL, def_cmp_color_spill, "COLOR_SPILL", ColorSpill, "Color Spill", "" )
DefNode(CompositorNode, CMP_NODE_CHROMA_MATTE, def_cmp_chroma_matte, "CHROMA_MATTE", ChromaMatte, "Chroma Key", "" )
@ -170,7 +172,7 @@ DefNode(CompositorNode, CMP_NODE_ID_MASK, def_cmp_id_mask, "ID_MAS
DefNode(CompositorNode, CMP_NODE_DOUBLEEDGEMASK, def_cmp_double_edge_mask,"DOUBLEEDGEMASK", DoubleEdgeMask, "Double Edge Mask", "" )
DefNode(CompositorNode, CMP_NODE_DEFOCUS, def_cmp_defocus, "DEFOCUS", Defocus, "Defocus", "" )
DefNode(CompositorNode, CMP_NODE_DISPLACE, 0, "DISPLACE", Displace, "Displace", "" )
DefNode(CompositorNode, CMP_NODE_COMBHSVA, 0, "COMBHSVA", CombHSVA, "Combine HSVA", "" )
DefNode(CompositorNode, CMP_NODE_COMBHSVA_LEGACY,0, "COMBHSVA", CombHSVA, "Combine HSVA", "" )
DefNode(CompositorNode, CMP_NODE_MATH, def_math, "MATH", Math, "Math", "" )
DefNode(CompositorNode, CMP_NODE_LUMA_MATTE, def_cmp_luma_matte, "LUMA_MATTE", LumaMatte, "Luminance Key", "" )
DefNode(CompositorNode, CMP_NODE_BRIGHTCONTRAST, def_cmp_brightcontrast, "BRIGHTCONTRAST", BrightContrast, "Bright/Contrast", "" )
@ -215,9 +217,11 @@ DefNode(CompositorNode, CMP_NODE_EXPOSURE, 0, "EXPOSU
DefNode(CompositorNode, CMP_NODE_ANTIALIASING, def_cmp_antialiasing, "ANTIALIASING", AntiAliasing, "Anti-Aliasing", "" )
DefNode(CompositorNode, CMP_NODE_POSTERIZE, 0, "POSTERIZE", Posterize, "Posterize", "" )
DefNode(CompositorNode, CMP_NODE_CONVERT_COLOR_SPACE,def_cmp_convert_color_space, "CONVERT_COLORSPACE", ConvertColorSpace, "Color Space","" )
DefNode(CompositorNode, CMP_NODE_SCENE_TIME, 0, "SCENE_TIME", SceneTime, "Scene Time", "" )
DefNode(CompositorNode, CMP_NODE_SCENE_TIME, 0, "SCENE_TIME", SceneTime, "Scene Time", "" )
DefNode(CompositorNode, CMP_NODE_COMBINE_XYZ, 0, "COMBINE_XYZ", CombineXYZ, "Combine XYZ", "" )
DefNode(CompositorNode, CMP_NODE_SEPARATE_XYZ, 0, "SEPARATE_XYZ", SeparateXYZ, "Separate XYZ", "" )
DefNode(CompositorNode, CMP_NODE_SEPARATE_COLOR, def_cmp_combsep_color, "SEPARATE_COLOR", SeparateColor, "Separate Color", "" )
DefNode(CompositorNode, CMP_NODE_COMBINE_COLOR, def_cmp_combsep_color, "COMBINE_COLOR", CombineColor, "Combine Color", "" )
DefNode(TextureNode, TEX_NODE_OUTPUT, def_tex_output, "OUTPUT", Output, "Output", "" )
DefNode(TextureNode, TEX_NODE_CHECKER, 0, "CHECKER", Checker, "Checker", "" )
@ -237,11 +241,13 @@ DefNode(TextureNode, TEX_NODE_VIEWER, 0, "VIEWER
DefNode(TextureNode, TEX_NODE_TRANSLATE, 0, "TRANSLATE", Translate, "Translate", "" )
DefNode(TextureNode, TEX_NODE_COORD, 0, "COORD", Coordinates, "Coordinates", "" )
DefNode(TextureNode, TEX_NODE_DISTANCE, 0, "DISTANCE", Distance, "Distance", "" )
DefNode(TextureNode, TEX_NODE_COMPOSE, 0, "COMPOSE", Compose, "Combine RGBA", "" )
DefNode(TextureNode, TEX_NODE_DECOMPOSE, 0, "DECOMPOSE", Decompose, "Separate RGBA", "" )
DefNode(TextureNode, TEX_NODE_COMPOSE_LEGACY, 0, "COMPOSE", Compose, "Combine RGBA", "" )
DefNode(TextureNode, TEX_NODE_DECOMPOSE_LEGACY,0, "DECOMPOSE", Decompose, "Separate RGBA", "" )
DefNode(TextureNode, TEX_NODE_VALTONOR, 0, "VALTONOR", ValToNor, "Value to Normal", "" )
DefNode(TextureNode, TEX_NODE_SCALE, 0, "SCALE", Scale, "Scale", "" )
DefNode(TextureNode, TEX_NODE_AT, 0, "AT", At, "At", "" )
DefNode(TextureNode, TEX_NODE_COMBINE_COLOR, def_tex_combsep_color, "COMBINE_COLOR", CombineColor, "Combine Color", "" )
DefNode(TextureNode, TEX_NODE_SEPARATE_COLOR, def_tex_combsep_color, "SEPARATE_COLOR", SeparateColor, "Separate Color", "" )
/* procedural textures */
DefNode(TextureNode, TEX_NODE_PROC+TEX_VORONOI, 0, "TEX_VORONOI", TexVoronoi, "Voronoi", "" )
DefNode(TextureNode, TEX_NODE_PROC+TEX_BLEND, 0, "TEX_BLEND", TexBlend, "Blend", "" )
@ -256,6 +262,7 @@ DefNode(TextureNode, TEX_NODE_PROC+TEX_DISTNOISE, 0, "TEX_DI
DefNode(FunctionNode, FN_NODE_ALIGN_EULER_TO_VECTOR, def_fn_align_euler_to_vector, "ALIGN_EULER_TO_VECTOR", AlignEulerToVector, "Align Euler To Vector", "")
DefNode(FunctionNode, FN_NODE_BOOLEAN_MATH, def_boolean_math, "BOOLEAN_MATH", BooleanMath, "Boolean Math", "")
DefNode(FunctionNode, FN_NODE_COMBINE_COLOR, def_fn_combsep_color, "COMBINE_COLOR", CombineColor, "Combine Color", "")
DefNode(FunctionNode, FN_NODE_COMPARE, def_compare, "COMPARE", Compare, "Compare", "")
DefNode(FunctionNode, FN_NODE_FLOAT_TO_INT, def_float_to_int, "FLOAT_TO_INT", FloatToInt, "Float to Integer", "")
DefNode(FunctionNode, FN_NODE_INPUT_BOOL, def_fn_input_bool, "INPUT_BOOL", InputBool, "Boolean", "")
@ -267,6 +274,7 @@ DefNode(FunctionNode, FN_NODE_INPUT_VECTOR, def_fn_input_vector, "INPUT_VECTOR",
DefNode(FunctionNode, FN_NODE_RANDOM_VALUE, def_fn_random_value, "RANDOM_VALUE", RandomValue, "Random Value", "")
DefNode(FunctionNode, FN_NODE_REPLACE_STRING, 0, "REPLACE_STRING", ReplaceString, "Replace String", "")
DefNode(FunctionNode, FN_NODE_ROTATE_EULER, def_fn_rotate_euler, "ROTATE_EULER", RotateEuler, "Rotate Euler", "")
DefNode(FunctionNode, FN_NODE_SEPARATE_COLOR, def_fn_combsep_color, "SEPARATE_COLOR", SeparateColor, "Separate Color", "")
DefNode(FunctionNode, FN_NODE_SLICE_STRING, 0, "SLICE_STRING", SliceString, "Slice String", "")
DefNode(FunctionNode, FN_NODE_STRING_LENGTH, 0, "STRING_LENGTH", StringLength, "String Length", "")
DefNode(FunctionNode, FN_NODE_VALUE_TO_STRING, 0, "VALUE_TO_STRING", ValueToString, "Value to String", "")

View File

@ -46,6 +46,8 @@ void register_node_type_tex_at(void);
void register_node_type_tex_compose(void);
void register_node_type_tex_decompose(void);
void register_node_type_tex_combine_color(void);
void register_node_type_tex_separate_color(void);
void register_node_type_tex_proc_voronoi(void);
void register_node_type_tex_proc_blend(void);

View File

@ -91,6 +91,7 @@ set(SRC
nodes/node_composite_rotate.cc
nodes/node_composite_scale.cc
nodes/node_composite_scene_time.cc
nodes/node_composite_sepcomb_color.cc
nodes/node_composite_sepcomb_hsva.cc
nodes/node_composite_sepcomb_rgba.cc
nodes/node_composite_sepcomb_xyz.cc

View File

@ -0,0 +1,139 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#include "node_composite_util.hh"
static void node_cmp_combsep_color_init(bNodeTree *UNUSED(ntree), bNode *node)
{
NodeCMPCombSepColor *data = MEM_cnew<NodeCMPCombSepColor>(__func__);
data->mode = CMP_NODE_COMBSEP_COLOR_RGB;
data->ycc_mode = BLI_YCC_ITU_BT709;
node->storage = data;
}
static void node_cmp_combsep_color_label(const ListBase *sockets, CMPNodeCombSepColorMode mode)
{
bNodeSocket *sock1 = (bNodeSocket *)sockets->first;
bNodeSocket *sock2 = sock1->next;
bNodeSocket *sock3 = sock2->next;
node_sock_label_clear(sock1);
node_sock_label_clear(sock2);
node_sock_label_clear(sock3);
switch (mode) {
case CMP_NODE_COMBSEP_COLOR_RGB:
node_sock_label(sock1, "Red");
node_sock_label(sock2, "Green");
node_sock_label(sock3, "Blue");
break;
case CMP_NODE_COMBSEP_COLOR_HSV:
node_sock_label(sock1, "Hue");
node_sock_label(sock2, "Saturation");
node_sock_label(sock3, "Value");
break;
case CMP_NODE_COMBSEP_COLOR_HSL:
node_sock_label(sock1, "Hue");
node_sock_label(sock2, "Saturation");
node_sock_label(sock3, "Lightness");
break;
case CMP_NODE_COMBSEP_COLOR_YCC:
node_sock_label(sock1, "Y");
node_sock_label(sock2, "Cb");
node_sock_label(sock3, "Cr");
break;
case CMP_NODE_COMBSEP_COLOR_YUV:
node_sock_label(sock1, "Y");
node_sock_label(sock2, "U");
node_sock_label(sock3, "V");
break;
default:
BLI_assert_unreachable();
break;
}
}
/* **************** SEPARATE COLOR ******************** */
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_output<decl::Float>(N_("Red"));
b.add_output<decl::Float>(N_("Green"));
b.add_output<decl::Float>(N_("Blue"));
b.add_output<decl::Float>(N_("Alpha"));
}
static void cmp_node_separate_color_update(bNodeTree *ntree, bNode *node)
{
const NodeCMPCombSepColor *storage = (NodeCMPCombSepColor *)node->storage;
node_cmp_combsep_color_label(&node->outputs, (CMPNodeCombSepColorMode)storage->mode);
}
} // namespace blender::nodes::node_composite_separate_color_cc
void register_node_type_cmp_separate_color()
{
namespace file_ns = blender::nodes::node_composite_separate_color_cc;
static bNodeType ntype;
cmp_node_type_base(&ntype, CMP_NODE_SEPARATE_COLOR, "Separate Color", NODE_CLASS_CONVERTER);
ntype.declare = file_ns::cmp_node_separate_color_declare;
node_type_init(&ntype, node_cmp_combsep_color_init);
node_type_storage(
&ntype, "NodeCMPCombSepColor", node_free_standard_storage, node_copy_standard_storage);
node_type_update(&ntype, file_ns::cmp_node_separate_color_update);
nodeRegisterType(&ntype);
}
/* **************** COMBINE COLOR ******************** */
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_("Green"))
.default_value(0.0f)
.min(0.0f)
.max(1.0f)
.subtype(PROP_FACTOR);
b.add_input<decl::Float>(N_("Blue"))
.default_value(0.0f)
.min(0.0f)
.max(1.0f)
.subtype(PROP_FACTOR);
b.add_input<decl::Float>(N_("Alpha"))
.default_value(1.0f)
.min(0.0f)
.max(1.0f)
.subtype(PROP_FACTOR);
b.add_output<decl::Color>(N_("Image"));
}
static void cmp_node_combine_color_update(bNodeTree *ntree, bNode *node)
{
const NodeCMPCombSepColor *storage = (NodeCMPCombSepColor *)node->storage;
node_cmp_combsep_color_label(&node->inputs, (CMPNodeCombSepColorMode)storage->mode);
}
} // namespace blender::nodes::node_composite_combine_color_cc
void register_node_type_cmp_combine_color()
{
namespace file_ns = blender::nodes::node_composite_combine_color_cc;
static bNodeType ntype;
cmp_node_type_base(&ntype, CMP_NODE_COMBINE_COLOR, "Combine Color", NODE_CLASS_CONVERTER);
ntype.declare = file_ns::cmp_node_combine_color_declare;
node_type_init(&ntype, node_cmp_combsep_color_init);
node_type_storage(
&ntype, "NodeCMPCombSepColor", node_free_standard_storage, node_copy_standard_storage);
node_type_update(&ntype, file_ns::cmp_node_combine_color_update);
nodeRegisterType(&ntype);
}

View File

@ -28,7 +28,7 @@ void register_node_type_cmp_sephsva()
static bNodeType ntype;
cmp_node_type_base(&ntype, CMP_NODE_SEPHSVA, "Separate HSVA", NODE_CLASS_CONVERTER);
cmp_node_type_base(&ntype, CMP_NODE_SEPHSVA_LEGACY, "Separate HSVA", NODE_CLASS_CONVERTER);
ntype.declare = file_ns::cmp_node_sephsva_declare;
nodeRegisterType(&ntype);
}
@ -54,7 +54,7 @@ void register_node_type_cmp_combhsva()
static bNodeType ntype;
cmp_node_type_base(&ntype, CMP_NODE_COMBHSVA, "Combine HSVA", NODE_CLASS_CONVERTER);
cmp_node_type_base(&ntype, CMP_NODE_COMBHSVA_LEGACY, "Combine HSVA", NODE_CLASS_CONVERTER);
ntype.declare = file_ns::cmp_node_combhsva_declare;
nodeRegisterType(&ntype);

View File

@ -27,7 +27,7 @@ void register_node_type_cmp_seprgba()
static bNodeType ntype;
cmp_node_type_base(&ntype, CMP_NODE_SEPRGBA, "Separate RGBA", NODE_CLASS_CONVERTER);
cmp_node_type_base(&ntype, CMP_NODE_SEPRGBA_LEGACY, "Separate RGBA", NODE_CLASS_CONVERTER);
ntype.declare = file_ns::cmp_node_seprgba_declare;
nodeRegisterType(&ntype);
@ -54,7 +54,7 @@ void register_node_type_cmp_combrgba()
static bNodeType ntype;
cmp_node_type_base(&ntype, CMP_NODE_COMBRGBA, "Combine RGBA", NODE_CLASS_CONVERTER);
cmp_node_type_base(&ntype, CMP_NODE_COMBRGBA_LEGACY, "Combine RGBA", NODE_CLASS_CONVERTER);
ntype.declare = file_ns::cmp_node_combrgba_declare;
nodeRegisterType(&ntype);

View File

@ -33,7 +33,7 @@ void register_node_type_cmp_sepycca()
static bNodeType ntype;
cmp_node_type_base(&ntype, CMP_NODE_SEPYCCA, "Separate YCbCrA", NODE_CLASS_CONVERTER);
cmp_node_type_base(&ntype, CMP_NODE_SEPYCCA_LEGACY, "Separate YCbCrA", NODE_CLASS_CONVERTER);
ntype.declare = file_ns::cmp_node_sepycca_declare;
node_type_init(&ntype, file_ns::node_composit_init_mode_sepycca);
@ -66,7 +66,7 @@ void register_node_type_cmp_combycca()
static bNodeType ntype;
cmp_node_type_base(&ntype, CMP_NODE_COMBYCCA, "Combine YCbCrA", NODE_CLASS_CONVERTER);
cmp_node_type_base(&ntype, CMP_NODE_COMBYCCA_LEGACY, "Combine YCbCrA", NODE_CLASS_CONVERTER);
ntype.declare = file_ns::cmp_node_combycca_declare;
node_type_init(&ntype, file_ns::node_composit_init_mode_combycca);

View File

@ -28,7 +28,7 @@ void register_node_type_cmp_sepyuva()
static bNodeType ntype;
cmp_node_type_base(&ntype, CMP_NODE_SEPYUVA, "Separate YUVA", NODE_CLASS_CONVERTER);
cmp_node_type_base(&ntype, CMP_NODE_SEPYUVA_LEGACY, "Separate YUVA", NODE_CLASS_CONVERTER);
ntype.declare = file_ns::cmp_node_sepyuva_declare;
nodeRegisterType(&ntype);
@ -55,7 +55,7 @@ void register_node_type_cmp_combyuva()
static bNodeType ntype;
cmp_node_type_base(&ntype, CMP_NODE_COMBYUVA, "Combine YUVA", NODE_CLASS_CONVERTER);
cmp_node_type_base(&ntype, CMP_NODE_COMBYUVA_LEGACY, "Combine YUVA", NODE_CLASS_CONVERTER);
ntype.declare = file_ns::cmp_node_combyuva_declare;
nodeRegisterType(&ntype);

View File

@ -20,6 +20,7 @@ set(INC
set(SRC
nodes/node_fn_align_euler_to_vector.cc
nodes/node_fn_boolean_math.cc
nodes/node_fn_combine_color.cc
nodes/node_fn_compare.cc
nodes/node_fn_float_to_int.cc
nodes/node_fn_input_bool.cc
@ -31,6 +32,7 @@ set(SRC
nodes/node_fn_random_value.cc
nodes/node_fn_replace_string.cc
nodes/node_fn_rotate_euler.cc
nodes/node_fn_separate_color.cc
nodes/node_fn_slice_string.cc
nodes/node_fn_string_length.cc
nodes/node_fn_value_to_string.cc

View File

@ -0,0 +1,108 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#include "node_function_util.hh"
#include "UI_interface.h"
#include "UI_resources.h"
namespace blender::nodes {
NODE_STORAGE_FUNCS(NodeCombSepColor)
static void fn_node_combine_color_declare(NodeDeclarationBuilder &b)
{
b.is_function_node();
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_("Green"))
.default_value(0.0f)
.min(0.0f)
.max(1.0f)
.subtype(PROP_FACTOR);
b.add_input<decl::Float>(N_("Blue"))
.default_value(0.0f)
.min(0.0f)
.max(1.0f)
.subtype(PROP_FACTOR);
b.add_input<decl::Float>(N_("Alpha"))
.default_value(1.0f)
.min(0.0f)
.max(1.0f)
.subtype(PROP_FACTOR);
b.add_output<decl::Color>(N_("Color"));
};
static void fn_node_combine_color_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiItemR(layout, ptr, "mode", 0, "", ICON_NONE);
}
static void fn_node_combine_color_update(bNodeTree *ntree, bNode *node)
{
const NodeCombSepColor &storage = node_storage(*node);
node_combsep_color_label(&node->inputs, (NodeCombSepColorMode)storage.mode);
}
static void fn_node_combine_color_init(bNodeTree *UNUSED(tree), bNode *node)
{
NodeCombSepColor *data = MEM_cnew<NodeCombSepColor>(__func__);
data->mode = NODE_COMBSEP_COLOR_RGB;
node->storage = data;
}
static const fn::MultiFunction *get_multi_function(bNode &bnode)
{
const NodeCombSepColor &storage = node_storage(bnode);
static fn::CustomMF_SI_SI_SI_SI_SO<float, float, float, float, ColorGeometry4f> rgba_fn{
"RGB", [](float r, float g, float b, float a) { return ColorGeometry4f(r, g, b, a); }};
static fn::CustomMF_SI_SI_SI_SI_SO<float, float, float, float, ColorGeometry4f> hsva_fn{
"HSV", [](float h, float s, float v, float a) {
ColorGeometry4f r_color;
hsv_to_rgb(h, s, v, &r_color.r, &r_color.g, &r_color.b);
r_color.a = a;
return r_color;
}};
static fn::CustomMF_SI_SI_SI_SI_SO<float, float, float, float, ColorGeometry4f> hsla_fn{
"HSL", [](float h, float s, float l, float a) {
ColorGeometry4f color;
hsl_to_rgb(h, s, l, &color.r, &color.g, &color.b);
color.a = a;
return color;
}};
switch (storage.mode) {
case NODE_COMBSEP_COLOR_RGB:
return &rgba_fn;
case NODE_COMBSEP_COLOR_HSV:
return &hsva_fn;
case NODE_COMBSEP_COLOR_HSL:
return &hsla_fn;
}
BLI_assert_unreachable();
return nullptr;
}
static void fn_node_combine_color_build_multi_function(NodeMultiFunctionBuilder &builder)
{
const fn::MultiFunction *fn = get_multi_function(builder.node());
builder.set_matching_fn(fn);
}
} // namespace blender::nodes
void register_node_type_fn_combine_color(void)
{
static bNodeType ntype;
fn_node_type_base(&ntype, FN_NODE_COMBINE_COLOR, "Combine Color", NODE_CLASS_CONVERTER);
ntype.declare = blender::nodes::fn_node_combine_color_declare;
node_type_update(&ntype, blender::nodes::fn_node_combine_color_update);
node_type_init(&ntype, blender::nodes::fn_node_combine_color_init);
node_type_storage(
&ntype, "NodeCombSepColor", node_free_standard_storage, node_copy_standard_storage);
ntype.build_multi_function = blender::nodes::fn_node_combine_color_build_multi_function;
ntype.draw_buttons = blender::nodes::fn_node_combine_color_layout;
nodeRegisterType(&ntype);
}

View File

@ -0,0 +1,205 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#include "node_function_util.hh"
#include "UI_interface.h"
#include "UI_resources.h"
namespace blender::nodes {
NODE_STORAGE_FUNCS(NodeCombSepColor)
static void fn_node_separate_color_declare(NodeDeclarationBuilder &b)
{
b.is_function_node();
b.add_input<decl::Color>(N_("Color")).default_value({1.0f, 1.0f, 1.0f, 1.0f});
b.add_output<decl::Float>(N_("Red"));
b.add_output<decl::Float>(N_("Green"));
b.add_output<decl::Float>(N_("Blue"));
b.add_output<decl::Float>(N_("Alpha"));
};
static void fn_node_separate_color_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
uiItemR(layout, ptr, "mode", 0, "", ICON_NONE);
}
static void fn_node_separate_color_update(bNodeTree *ntree, bNode *node)
{
const NodeCombSepColor &storage = node_storage(*node);
node_combsep_color_label(&node->outputs, (NodeCombSepColorMode)storage.mode);
}
static void fn_node_separate_color_init(bNodeTree *UNUSED(tree), bNode *node)
{
NodeCombSepColor *data = MEM_cnew<NodeCombSepColor>(__func__);
data->mode = NODE_COMBSEP_COLOR_RGB;
node->storage = data;
}
class SeparateRGBAFunction : public fn::MultiFunction {
public:
SeparateRGBAFunction()
{
static fn::MFSignature signature = create_signature();
this->set_signature(&signature);
}
static fn::MFSignature create_signature()
{
fn::MFSignatureBuilder signature{"Separate Color"};
signature.single_input<ColorGeometry4f>("Color");
signature.single_output<float>("Red");
signature.single_output<float>("Green");
signature.single_output<float>("Blue");
signature.single_output<float>("Alpha");
return signature.build();
}
void call(IndexMask mask, fn::MFParams params, fn::MFContext UNUSED(context)) const override
{
const VArray<ColorGeometry4f> &colors = params.readonly_single_input<ColorGeometry4f>(0,
"Color");
MutableSpan<float> red = params.uninitialized_single_output<float>(1, "Red");
MutableSpan<float> green = params.uninitialized_single_output<float>(2, "Green");
MutableSpan<float> blue = params.uninitialized_single_output<float>(3, "Blue");
MutableSpan<float> alpha = params.uninitialized_single_output_if_required<float>(4, "Alpha");
for (int64_t i : mask) {
red[i] = colors[i].r;
green[i] = colors[i].g;
blue[i] = colors[i].b;
}
if (!alpha.is_empty()) {
for (int64_t i : mask) {
alpha[i] = colors[i].a;
}
}
}
};
class SeparateHSVAFunction : public fn::MultiFunction {
public:
SeparateHSVAFunction()
{
static fn::MFSignature signature = create_signature();
this->set_signature(&signature);
}
static fn::MFSignature create_signature()
{
fn::MFSignatureBuilder signature{"Separate Color"};
signature.single_input<ColorGeometry4f>("Color");
signature.single_output<float>("Hue");
signature.single_output<float>("Saturation");
signature.single_output<float>("Value");
signature.single_output<float>("Alpha");
return signature.build();
}
void call(IndexMask mask, fn::MFParams params, fn::MFContext UNUSED(context)) const override
{
const VArray<ColorGeometry4f> &colors = params.readonly_single_input<ColorGeometry4f>(0,
"Color");
MutableSpan<float> hue = params.uninitialized_single_output<float>(1, "Hue");
MutableSpan<float> saturation = params.uninitialized_single_output<float>(2, "Saturation");
MutableSpan<float> value = params.uninitialized_single_output<float>(3, "Value");
MutableSpan<float> alpha = params.uninitialized_single_output_if_required<float>(4, "Alpha");
for (int64_t i : mask) {
rgb_to_hsv(colors[i].r, colors[i].g, colors[i].b, &hue[i], &saturation[i], &value[i]);
}
if (!alpha.is_empty()) {
for (int64_t i : mask) {
alpha[i] = colors[i].a;
}
}
}
};
class SeparateHSLAFunction : public fn::MultiFunction {
public:
SeparateHSLAFunction()
{
static fn::MFSignature signature = create_signature();
this->set_signature(&signature);
}
static fn::MFSignature create_signature()
{
fn::MFSignatureBuilder signature{"Separate Color"};
signature.single_input<ColorGeometry4f>("Color");
signature.single_output<float>("Hue");
signature.single_output<float>("Saturation");
signature.single_output<float>("Lightness");
signature.single_output<float>("Alpha");
return signature.build();
}
void call(IndexMask mask, fn::MFParams params, fn::MFContext UNUSED(context)) const override
{
const VArray<ColorGeometry4f> &colors = params.readonly_single_input<ColorGeometry4f>(0,
"Color");
MutableSpan<float> hue = params.uninitialized_single_output<float>(1, "Hue");
MutableSpan<float> saturation = params.uninitialized_single_output<float>(2, "Saturation");
MutableSpan<float> lightness = params.uninitialized_single_output<float>(3, "Lightness");
MutableSpan<float> alpha = params.uninitialized_single_output_if_required<float>(4, "Alpha");
for (int64_t i : mask) {
rgb_to_hsl(colors[i].r, colors[i].g, colors[i].b, &hue[i], &saturation[i], &lightness[i]);
}
if (!alpha.is_empty()) {
for (int64_t i : mask) {
alpha[i] = colors[i].a;
}
}
}
};
static void fn_node_separate_color_build_multi_function(NodeMultiFunctionBuilder &builder)
{
const NodeCombSepColor &storage = node_storage(builder.node());
switch (storage.mode) {
case NODE_COMBSEP_COLOR_RGB: {
static SeparateRGBAFunction fn;
builder.set_matching_fn(fn);
break;
}
case NODE_COMBSEP_COLOR_HSV: {
static SeparateHSVAFunction fn;
builder.set_matching_fn(fn);
break;
}
case NODE_COMBSEP_COLOR_HSL: {
static SeparateHSLAFunction fn;
builder.set_matching_fn(fn);
break;
}
default: {
BLI_assert_unreachable();
break;
}
}
}
} // namespace blender::nodes
void register_node_type_fn_separate_color(void)
{
static bNodeType ntype;
fn_node_type_base(&ntype, FN_NODE_SEPARATE_COLOR, "Separate Color", NODE_CLASS_CONVERTER);
ntype.declare = blender::nodes::fn_node_separate_color_declare;
node_type_update(&ntype, blender::nodes::fn_node_separate_color_update);
node_type_init(&ntype, blender::nodes::fn_node_separate_color_init);
node_type_storage(
&ntype, "NodeCombSepColor", node_free_standard_storage, node_copy_standard_storage);
ntype.build_multi_function = blender::nodes::fn_node_separate_color_build_multi_function;
ntype.draw_buttons = blender::nodes::fn_node_separate_color_layout;
nodeRegisterType(&ntype);
}

View File

@ -226,6 +226,39 @@ void node_filter_label(const bNodeTree *UNUSED(ntree), const bNode *node, char *
BLI_strncpy(label, IFACE_(name), maxlen);
}
void node_combsep_color_label(const ListBase *sockets, NodeCombSepColorMode mode)
{
bNodeSocket *sock1 = (bNodeSocket *)sockets->first;
bNodeSocket *sock2 = sock1->next;
bNodeSocket *sock3 = sock2->next;
node_sock_label_clear(sock1);
node_sock_label_clear(sock2);
node_sock_label_clear(sock3);
switch (mode) {
case NODE_COMBSEP_COLOR_RGB:
node_sock_label(sock1, "Red");
node_sock_label(sock2, "Green");
node_sock_label(sock3, "Blue");
break;
case NODE_COMBSEP_COLOR_HSL:
node_sock_label(sock1, "Hue");
node_sock_label(sock2, "Saturation");
node_sock_label(sock3, "Lightness");
break;
case NODE_COMBSEP_COLOR_HSV:
node_sock_label(sock1, "Hue");
node_sock_label(sock2, "Saturation");
node_sock_label(sock3, "Value");
break;
default: {
BLI_assert_unreachable();
break;
}
}
}
/** \} */
/* -------------------------------------------------------------------- */

View File

@ -65,6 +65,7 @@ void node_filter_label(const struct bNodeTree *ntree,
const struct bNode *node,
char *label,
int maxlen);
void node_combsep_color_label(const ListBase *sockets, NodeCombSepColorMode mode);
/*** Link Handling */

View File

@ -82,6 +82,7 @@ set(SRC
nodes/node_shader_rgb.cc
nodes/node_shader_rgb_to_bw.cc
nodes/node_shader_script.cc
nodes/node_shader_sepcomb_color.cc
nodes/node_shader_sepcomb_hsv.cc
nodes/node_shader_sepcomb_rgb.cc
nodes/node_shader_sepcomb_xyz.cc

View File

@ -0,0 +1,162 @@
/* SPDX-License-Identifier: GPL-2.0-or-later
* Copyright 2022 Blender Foundation. All rights reserved. */
/** \file
* \ingroup shdnodes
*/
#include "node_shader_util.hh"
#include "UI_interface.h"
#include "UI_resources.h"
static void node_combsep_color_init(bNodeTree *UNUSED(tree), bNode *node)
{
NodeCombSepColor *data = MEM_cnew<NodeCombSepColor>(__func__);
data->mode = NODE_COMBSEP_COLOR_RGB;
node->storage = data;
}
/* **************** SEPARATE COLOR ******************** */
namespace blender::nodes::node_shader_separate_color_cc {
NODE_STORAGE_FUNCS(NodeCombSepColor)
static void sh_node_sepcolor_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Color>(N_("Color")).default_value({0.8f, 0.8f, 0.8f, 1.0f});
b.add_output<decl::Float>(N_("Red"));
b.add_output<decl::Float>(N_("Green"));
b.add_output<decl::Float>(N_("Blue"));
}
static void node_sepcolor_update(bNodeTree *ntree, bNode *node)
{
const NodeCombSepColor &storage = node_storage(*node);
node_combsep_color_label(&node->outputs, (NodeCombSepColorMode)storage.mode);
}
static const char *gpu_shader_get_name(int mode)
{
switch (mode) {
case NODE_COMBSEP_COLOR_RGB:
return "separate_color_rgb";
case NODE_COMBSEP_COLOR_HSV:
return "separate_color_hsv";
case NODE_COMBSEP_COLOR_HSL:
return "separate_color_hsl";
}
return nullptr;
}
static int gpu_shader_sepcolor(GPUMaterial *mat,
bNode *node,
bNodeExecData *UNUSED(execdata),
GPUNodeStack *in,
GPUNodeStack *out)
{
const NodeCombSepColor &storage = node_storage(*node);
const char *name = gpu_shader_get_name(storage.mode);
if (name != nullptr) {
return GPU_stack_link(mat, node, name, in, out);
}
return 0;
}
} // namespace blender::nodes::node_shader_separate_color_cc
void register_node_type_sh_sepcolor()
{
namespace file_ns = blender::nodes::node_shader_separate_color_cc;
static bNodeType ntype;
sh_node_type_base(&ntype, SH_NODE_SEPARATE_COLOR, "Separate Color", NODE_CLASS_CONVERTER);
ntype.declare = file_ns::sh_node_sepcolor_declare;
node_type_update(&ntype, file_ns::node_sepcolor_update);
node_type_init(&ntype, node_combsep_color_init);
node_type_storage(
&ntype, "NodeCombSepColor", node_free_standard_storage, node_copy_standard_storage);
node_type_gpu(&ntype, file_ns::gpu_shader_sepcolor);
nodeRegisterType(&ntype);
}
/* **************** COMBINE COLOR ******************** */
namespace blender::nodes::node_shader_combine_color_cc {
NODE_STORAGE_FUNCS(NodeCombSepColor)
static void sh_node_combcolor_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_("Green"))
.default_value(0.0f)
.min(0.0f)
.max(1.0f)
.subtype(PROP_FACTOR);
b.add_input<decl::Float>(N_("Blue"))
.default_value(0.0f)
.min(0.0f)
.max(1.0f)
.subtype(PROP_FACTOR);
b.add_output<decl::Color>(N_("Color"));
}
static void node_combcolor_update(bNodeTree *ntree, bNode *node)
{
const NodeCombSepColor &storage = node_storage(*node);
node_combsep_color_label(&node->inputs, (NodeCombSepColorMode)storage.mode);
}
static const char *gpu_shader_get_name(int mode)
{
switch (mode) {
case NODE_COMBSEP_COLOR_RGB:
return "combine_color_rgb";
case NODE_COMBSEP_COLOR_HSV:
return "combine_color_hsv";
case NODE_COMBSEP_COLOR_HSL:
return "combine_color_hsl";
}
return nullptr;
}
static int gpu_shader_combcolor(GPUMaterial *mat,
bNode *node,
bNodeExecData *UNUSED(execdata),
GPUNodeStack *in,
GPUNodeStack *out)
{
const NodeCombSepColor &storage = node_storage(*node);
const char *name = gpu_shader_get_name(storage.mode);
if (name != nullptr) {
return GPU_stack_link(mat, node, name, in, out);
}
return 0;
}
} // namespace blender::nodes::node_shader_combine_color_cc
void register_node_type_sh_combcolor()
{
namespace file_ns = blender::nodes::node_shader_combine_color_cc;
static bNodeType ntype;
sh_node_type_base(&ntype, SH_NODE_COMBINE_COLOR, "Combine Color", NODE_CLASS_CONVERTER);
ntype.declare = file_ns::sh_node_combcolor_declare;
node_type_update(&ntype, file_ns::node_combcolor_update);
node_type_init(&ntype, node_combsep_color_init);
node_type_storage(
&ntype, "NodeCombSepColor", node_free_standard_storage, node_copy_standard_storage);
node_type_gpu(&ntype, file_ns::gpu_shader_combcolor);
nodeRegisterType(&ntype);
}

View File

@ -36,7 +36,7 @@ void register_node_type_sh_sephsv()
static bNodeType ntype;
sh_node_type_base(&ntype, SH_NODE_SEPHSV, "Separate HSV", NODE_CLASS_CONVERTER);
sh_node_type_base(&ntype, SH_NODE_SEPHSV_LEGACY, "Separate HSV", NODE_CLASS_CONVERTER);
ntype.declare = file_ns::node_declare_sephsv;
node_type_gpu(&ntype, file_ns::gpu_shader_sephsv);
@ -72,7 +72,7 @@ void register_node_type_sh_combhsv()
static bNodeType ntype;
sh_node_type_base(&ntype, SH_NODE_COMBHSV, "Combine HSV", NODE_CLASS_CONVERTER);
sh_node_type_base(&ntype, SH_NODE_COMBHSV_LEGACY, "Combine HSV", NODE_CLASS_CONVERTER);
ntype.declare = file_ns::node_declare_combhsv;
node_type_gpu(&ntype, file_ns::gpu_shader_combhsv);

View File

@ -76,7 +76,7 @@ void register_node_type_sh_seprgb()
static bNodeType ntype;
sh_fn_node_type_base(&ntype, SH_NODE_SEPRGB, "Separate RGB", NODE_CLASS_CONVERTER);
sh_fn_node_type_base(&ntype, SH_NODE_SEPRGB_LEGACY, "Separate RGB", NODE_CLASS_CONVERTER);
ntype.declare = file_ns::sh_node_seprgb_declare;
node_type_gpu(&ntype, file_ns::gpu_shader_seprgb);
ntype.build_multi_function = file_ns::sh_node_seprgb_build_multi_function;
@ -119,7 +119,7 @@ void register_node_type_sh_combrgb()
static bNodeType ntype;
sh_fn_node_type_base(&ntype, SH_NODE_COMBRGB, "Combine RGB", NODE_CLASS_CONVERTER);
sh_fn_node_type_base(&ntype, SH_NODE_COMBRGB_LEGACY, "Combine RGB", NODE_CLASS_CONVERTER);
ntype.declare = file_ns::sh_node_combrgb_declare;
node_type_gpu(&ntype, file_ns::gpu_shader_combrgb);
ntype.build_multi_function = file_ns::sh_node_combrgb_build_multi_function;

View File

@ -25,6 +25,7 @@ set(SRC
nodes/node_texture_bricks.c
nodes/node_texture_checker.c
nodes/node_texture_common.c
nodes/node_texture_combine_color.c
nodes/node_texture_compose.c
nodes/node_texture_coord.c
nodes/node_texture_curves.c
@ -38,6 +39,7 @@ set(SRC
nodes/node_texture_output.c
nodes/node_texture_proc.c
nodes/node_texture_rotate.c
nodes/node_texture_separate_color.c
nodes/node_texture_scale.c
nodes/node_texture_texture.c
nodes/node_texture_translate.c

View File

@ -0,0 +1,76 @@
/* SPDX-License-Identifier: GPL-2.0-or-later
* Copyright 2022 Blender Foundation. All rights reserved. */
/** \file
* \ingroup texnodes
*/
#include "BLI_listbase.h"
#include "NOD_texture.h"
#include "node_texture_util.h"
static bNodeSocketTemplate inputs[] = {
{SOCK_FLOAT, N_("Red"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
{SOCK_FLOAT, N_("Green"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
{SOCK_FLOAT, N_("Blue"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
{SOCK_FLOAT, N_("Alpha"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
{-1, ""},
};
static bNodeSocketTemplate outputs[] = {
{SOCK_RGBA, N_("Color")},
{-1, ""},
};
static void colorfn(float *out, TexParams *p, bNode *node, bNodeStack **in, short thread)
{
int i;
for (i = 0; i < 4; i++) {
out[i] = tex_input_value(in[i], p, thread);
}
/* Apply color space if required. */
switch (node->custom1) {
case NODE_COMBSEP_COLOR_RGB: {
/* Pass */
break;
}
case NODE_COMBSEP_COLOR_HSV: {
hsv_to_rgb_v(out, out);
break;
}
case NODE_COMBSEP_COLOR_HSL: {
hsl_to_rgb_v(out, out);
break;
}
default: {
BLI_assert_unreachable();
break;
}
}
}
static void update(bNodeTree *ntree, bNode *node)
{
node_combsep_color_label(&node->inputs, (NodeCombSepColorMode)node->custom1);
}
static void exec(void *data,
int UNUSED(thread),
bNode *node,
bNodeExecData *execdata,
bNodeStack **in,
bNodeStack **out)
{
tex_output(node, execdata, in, out[0], &colorfn, data);
}
void register_node_type_tex_combine_color(void)
{
static bNodeType ntype;
tex_node_type_base(&ntype, TEX_NODE_COMBINE_COLOR, "Combine Color", NODE_CLASS_OP_COLOR);
node_type_socket_templates(&ntype, inputs, outputs);
node_type_exec(&ntype, NULL, NULL, exec);
node_type_update(&ntype, update);
nodeRegisterType(&ntype);
}

View File

@ -42,7 +42,7 @@ void register_node_type_tex_compose(void)
{
static bNodeType ntype;
tex_node_type_base(&ntype, TEX_NODE_COMPOSE, "Combine RGBA", NODE_CLASS_OP_COLOR);
tex_node_type_base(&ntype, TEX_NODE_COMPOSE_LEGACY, "Combine RGBA", NODE_CLASS_OP_COLOR);
node_type_socket_templates(&ntype, inputs, outputs);
node_type_exec(&ntype, NULL, NULL, exec);

View File

@ -62,7 +62,7 @@ void register_node_type_tex_decompose(void)
{
static bNodeType ntype;
tex_node_type_base(&ntype, TEX_NODE_DECOMPOSE, "Separate RGBA", NODE_CLASS_OP_COLOR);
tex_node_type_base(&ntype, TEX_NODE_DECOMPOSE_LEGACY, "Separate RGBA", NODE_CLASS_OP_COLOR);
node_type_socket_templates(&ntype, inputs, outputs);
node_type_exec(&ntype, NULL, NULL, exec);

View File

@ -0,0 +1,102 @@
/* SPDX-License-Identifier: GPL-2.0-or-later
* Copyright 2022 Blender Foundation. All rights reserved. */
/** \file
* \ingroup texnodes
*/
#include "BLI_listbase.h"
#include "NOD_texture.h"
#include "node_texture_util.h"
#include <math.h>
static bNodeSocketTemplate inputs[] = {
{SOCK_RGBA, N_("Color"), 0.0f, 0.0f, 0.0f, 1.0f},
{-1, ""},
};
static bNodeSocketTemplate outputs[] = {
{SOCK_FLOAT, N_("Red")},
{SOCK_FLOAT, N_("Green")},
{SOCK_FLOAT, N_("Blue")},
{SOCK_FLOAT, N_("Alpha")},
{-1, ""},
};
static void apply_color_space(float *out, NodeCombSepColorMode type)
{
switch (type) {
case NODE_COMBSEP_COLOR_RGB: {
/* Pass */
break;
}
case NODE_COMBSEP_COLOR_HSV: {
rgb_to_hsv_v(out, out);
break;
}
case NODE_COMBSEP_COLOR_HSL: {
rgb_to_hsl_v(out, out);
break;
}
default: {
BLI_assert_unreachable();
break;
}
}
}
static void valuefn_r(float *out, TexParams *p, bNode *node, bNodeStack **in, short thread)
{
tex_input_rgba(out, in[0], p, thread);
apply_color_space(out, (NodeCombSepColorMode)node->custom1);
*out = out[0];
}
static void valuefn_g(float *out, TexParams *p, bNode *node, bNodeStack **in, short thread)
{
tex_input_rgba(out, in[0], p, thread);
apply_color_space(out, (NodeCombSepColorMode)node->custom1);
*out = out[1];
}
static void valuefn_b(float *out, TexParams *p, bNode *node, bNodeStack **in, short thread)
{
tex_input_rgba(out, in[0], p, thread);
apply_color_space(out, (NodeCombSepColorMode)node->custom1);
*out = out[2];
}
static void valuefn_a(float *out, TexParams *p, bNode *UNUSED(node), bNodeStack **in, short thread)
{
tex_input_rgba(out, in[0], p, thread);
*out = out[3];
}
static void update(bNodeTree *ntree, bNode *node)
{
node_combsep_color_label(&node->outputs, (NodeCombSepColorMode)node->custom1);
}
static void exec(void *data,
int UNUSED(thread),
bNode *node,
bNodeExecData *execdata,
bNodeStack **in,
bNodeStack **out)
{
tex_output(node, execdata, in, out[0], &valuefn_r, data);
tex_output(node, execdata, in, out[1], &valuefn_g, data);
tex_output(node, execdata, in, out[2], &valuefn_b, data);
tex_output(node, execdata, in, out[3], &valuefn_a, data);
}
void register_node_type_tex_separate_color(void)
{
static bNodeType ntype;
tex_node_type_base(&ntype, TEX_NODE_SEPARATE_COLOR, "Separate Color", NODE_CLASS_OP_COLOR);
node_type_socket_templates(&ntype, inputs, outputs);
node_type_exec(&ntype, NULL, NULL, exec);
node_type_update(&ntype, update);
nodeRegisterType(&ntype);
}