forked from bartvdbraak/blender
Nodes: Add Multiply Add to Vector Math nodes
Cycles, Eevee, OSL, Geo, Attribute This operator provides consistency with the standard math node. Allows users to use a single node instead of two nodes for this common operation. Reviewed By: HooglyBoogly, brecht Differential Revision: https://developer.blender.org/D10808
This commit is contained in:
parent
eb030204f1
commit
00073651d4
@ -52,6 +52,9 @@ shader node_vector_math(string math_type = "add",
|
||||
else if (math_type == "faceforward") {
|
||||
Vector = compatible_faceforward(Vector1, Vector2, Vector3);
|
||||
}
|
||||
else if (math_type == "multiply_add") {
|
||||
Vector = Vector1 * Vector2 + Vector3;
|
||||
}
|
||||
else if (math_type == "dot_product") {
|
||||
Value = dot(Vector1, Vector2);
|
||||
}
|
||||
|
@ -58,7 +58,8 @@ ccl_device void svm_node_vector_math(KernelGlobals *kg,
|
||||
float3 vector;
|
||||
|
||||
/* 3 Vector Operators */
|
||||
if (type == NODE_VECTOR_MATH_WRAP || type == NODE_VECTOR_MATH_FACEFORWARD) {
|
||||
if (type == NODE_VECTOR_MATH_WRAP || type == NODE_VECTOR_MATH_FACEFORWARD ||
|
||||
type == NODE_VECTOR_MATH_MULTIPLY_ADD) {
|
||||
uint4 extra_node = read_node(kg, offset);
|
||||
c = stack_load_float3(stack, extra_node.x);
|
||||
}
|
||||
|
@ -52,6 +52,9 @@ ccl_device void svm_vector_math(float *value,
|
||||
case NODE_VECTOR_MATH_FACEFORWARD:
|
||||
*vector = faceforward(a, b, c);
|
||||
break;
|
||||
case NODE_VECTOR_MATH_MULTIPLY_ADD:
|
||||
*vector = a * b + c;
|
||||
break;
|
||||
case NODE_VECTOR_MATH_DOT_PRODUCT:
|
||||
*value = dot(a, b);
|
||||
break;
|
||||
|
@ -341,6 +341,7 @@ typedef enum NodeVectorMathType {
|
||||
NODE_VECTOR_MATH_TANGENT,
|
||||
NODE_VECTOR_MATH_REFRACT,
|
||||
NODE_VECTOR_MATH_FACEFORWARD,
|
||||
NODE_VECTOR_MATH_MULTIPLY_ADD,
|
||||
} NodeVectorMathType;
|
||||
|
||||
typedef enum NodeClampType {
|
||||
|
@ -6093,6 +6093,7 @@ NODE_DEFINE(VectorMathNode)
|
||||
type_enum.insert("reflect", NODE_VECTOR_MATH_REFLECT);
|
||||
type_enum.insert("refract", NODE_VECTOR_MATH_REFRACT);
|
||||
type_enum.insert("faceforward", NODE_VECTOR_MATH_FACEFORWARD);
|
||||
type_enum.insert("multiply_add", NODE_VECTOR_MATH_MULTIPLY_ADD);
|
||||
|
||||
type_enum.insert("dot_product", NODE_VECTOR_MATH_DOT_PRODUCT);
|
||||
|
||||
@ -6165,7 +6166,8 @@ void VectorMathNode::compile(SVMCompiler &compiler)
|
||||
int vector_stack_offset = compiler.stack_assign_if_linked(vector_out);
|
||||
|
||||
/* 3 Vector Operators */
|
||||
if (math_type == NODE_VECTOR_MATH_WRAP || math_type == NODE_VECTOR_MATH_FACEFORWARD) {
|
||||
if (math_type == NODE_VECTOR_MATH_WRAP || math_type == NODE_VECTOR_MATH_FACEFORWARD ||
|
||||
math_type == NODE_VECTOR_MATH_MULTIPLY_ADD) {
|
||||
ShaderInput *vector3_in = input("Vector3");
|
||||
int vector3_stack_offset = compiler.stack_assign(vector3_in);
|
||||
compiler.add_node(
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 5ab29b1331d2103dae634b987f121c4599459d7f
|
||||
Subproject commit 2cef4877edc40875978c4e95322bb5193f5815bf
|
@ -150,3 +150,9 @@ void vector_math_faceforward(
|
||||
{
|
||||
outVector = faceforward(a, b, c);
|
||||
}
|
||||
|
||||
void vector_math_multiply_add(
|
||||
vec3 a, vec3 b, vec3 c, float scale, out vec3 outVector, out float outValue)
|
||||
{
|
||||
outVector = a * b + c;
|
||||
}
|
||||
|
@ -1633,6 +1633,7 @@ typedef enum NodeVectorMathOperation {
|
||||
NODE_VECTOR_MATH_TANGENT = 23,
|
||||
NODE_VECTOR_MATH_REFRACT = 24,
|
||||
NODE_VECTOR_MATH_FACEFORWARD = 25,
|
||||
NODE_VECTOR_MATH_MULTIPLY_ADD = 26,
|
||||
} NodeVectorMathOperation;
|
||||
|
||||
/* Boolean math node operations. */
|
||||
|
@ -248,6 +248,7 @@ const EnumPropertyItem rna_enum_node_vec_math_items[] = {
|
||||
{NODE_VECTOR_MATH_SUBTRACT, "SUBTRACT", 0, "Subtract", "A - B"},
|
||||
{NODE_VECTOR_MATH_MULTIPLY, "MULTIPLY", 0, "Multiply", "Entry-wise multiply"},
|
||||
{NODE_VECTOR_MATH_DIVIDE, "DIVIDE", 0, "Divide", "Entry-wise divide"},
|
||||
{NODE_VECTOR_MATH_MULTIPLY_ADD, "MULTIPLY_ADD", 0, "Multiply Add", "A * B + C"},
|
||||
{0, "", ICON_NONE, NULL, NULL},
|
||||
{NODE_VECTOR_MATH_CROSS_PRODUCT, "CROSS_PRODUCT", 0, "Cross Product", "A cross B"},
|
||||
{NODE_VECTOR_MATH_PROJECT, "PROJECT", 0, "Project", "Project A onto B"},
|
||||
|
@ -347,6 +347,8 @@ inline bool try_dispatch_float_math_fl3_fl3_fl3_to_fl3(const NodeVectorMathOpera
|
||||
};
|
||||
|
||||
switch (operation) {
|
||||
case NODE_VECTOR_MATH_MULTIPLY_ADD:
|
||||
return dispatch([](float3 a, float3 b, float3 c) { return a * b + c; });
|
||||
case NODE_VECTOR_MATH_WRAP:
|
||||
return dispatch([](float3 a, float3 b, float3 c) {
|
||||
return float3(wrapf(a.x, b.x, c.x), wrapf(a.y, b.y, c.y), wrapf(a.z, b.z, c.z));
|
||||
|
@ -59,8 +59,11 @@ static bool operation_use_input_b(const NodeVectorMathOperation operation)
|
||||
|
||||
static bool operation_use_input_c(const NodeVectorMathOperation operation)
|
||||
{
|
||||
return ELEM(
|
||||
operation, NODE_VECTOR_MATH_WRAP, NODE_VECTOR_MATH_REFRACT, NODE_VECTOR_MATH_FACEFORWARD);
|
||||
return ELEM(operation,
|
||||
NODE_VECTOR_MATH_WRAP,
|
||||
NODE_VECTOR_MATH_REFRACT,
|
||||
NODE_VECTOR_MATH_FACEFORWARD,
|
||||
NODE_VECTOR_MATH_MULTIPLY_ADD);
|
||||
}
|
||||
|
||||
static void geo_node_attribute_vector_math_layout(uiLayout *layout,
|
||||
@ -137,6 +140,7 @@ static CustomDataType operation_get_result_type(const NodeVectorMathOperation op
|
||||
case NODE_VECTOR_MATH_TANGENT:
|
||||
case NODE_VECTOR_MATH_REFRACT:
|
||||
case NODE_VECTOR_MATH_FACEFORWARD:
|
||||
case NODE_VECTOR_MATH_MULTIPLY_ADD:
|
||||
return CD_PROP_FLOAT3;
|
||||
case NODE_VECTOR_MATH_DOT_PRODUCT:
|
||||
case NODE_VECTOR_MATH_DISTANCE:
|
||||
@ -495,6 +499,7 @@ static void attribute_vector_math_calc(GeometryComponent &component,
|
||||
break;
|
||||
case NODE_VECTOR_MATH_WRAP:
|
||||
case NODE_VECTOR_MATH_FACEFORWARD:
|
||||
case NODE_VECTOR_MATH_MULTIPLY_ADD:
|
||||
do_math_operation_fl3_fl3_fl3_to_fl3(attribute_a->typed<float3>(),
|
||||
attribute_b->typed<float3>(),
|
||||
attribute_c->typed<float3>(),
|
||||
|
@ -209,6 +209,8 @@ const FloatMathOperationInfo *get_float3_math_operation_info(const int operation
|
||||
RETURN_OPERATION_INFO("Refract", "vector_math_refract");
|
||||
case NODE_VECTOR_MATH_FACEFORWARD:
|
||||
RETURN_OPERATION_INFO("Faceforward", "vector_math_faceforward");
|
||||
case NODE_VECTOR_MATH_MULTIPLY_ADD:
|
||||
RETURN_OPERATION_INFO("Multiply Add", "vector_math_multiply_add");
|
||||
}
|
||||
|
||||
#undef RETURN_OPERATION_INFO
|
||||
|
@ -94,6 +94,8 @@ static const char *gpu_shader_get_name(int mode)
|
||||
return "vector_math_refract";
|
||||
case NODE_VECTOR_MATH_FACEFORWARD:
|
||||
return "vector_math_faceforward";
|
||||
case NODE_VECTOR_MATH_MULTIPLY_ADD:
|
||||
return "vector_math_multiply_add";
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
@ -134,8 +136,11 @@ static void node_shader_update_vector_math(bNodeTree *UNUSED(ntree), bNode *node
|
||||
NODE_VECTOR_MATH_ABSOLUTE,
|
||||
NODE_VECTOR_MATH_FRACTION,
|
||||
NODE_VECTOR_MATH_NORMALIZE));
|
||||
nodeSetSocketAvailability(
|
||||
sockC, ELEM(node->custom1, NODE_VECTOR_MATH_WRAP, NODE_VECTOR_MATH_FACEFORWARD));
|
||||
nodeSetSocketAvailability(sockC,
|
||||
ELEM(node->custom1,
|
||||
NODE_VECTOR_MATH_WRAP,
|
||||
NODE_VECTOR_MATH_FACEFORWARD,
|
||||
NODE_VECTOR_MATH_MULTIPLY_ADD));
|
||||
nodeSetSocketAvailability(sockScale,
|
||||
ELEM(node->custom1, NODE_VECTOR_MATH_SCALE, NODE_VECTOR_MATH_REFRACT));
|
||||
nodeSetSocketAvailability(sockVector,
|
||||
@ -154,6 +159,10 @@ static void node_shader_update_vector_math(bNodeTree *UNUSED(ntree), bNode *node
|
||||
node_sock_label_clear(sockC);
|
||||
node_sock_label_clear(sockScale);
|
||||
switch (node->custom1) {
|
||||
case NODE_VECTOR_MATH_MULTIPLY_ADD:
|
||||
node_sock_label(sockB, "Multiplier");
|
||||
node_sock_label(sockC, "Addend");
|
||||
break;
|
||||
case NODE_VECTOR_MATH_FACEFORWARD:
|
||||
node_sock_label(sockB, "Incident");
|
||||
node_sock_label(sockC, "Reference");
|
||||
|
Loading…
Reference in New Issue
Block a user