diff options
-rw-r--r-- | intern/cycles/kernel/shaders/node_math.h | 7 | ||||
-rw-r--r-- | intern/cycles/kernel/shaders/node_vector_math.osl | 6 | ||||
-rw-r--r-- | intern/cycles/kernel/svm/svm_math.h | 10 | ||||
-rw-r--r-- | intern/cycles/kernel/svm/svm_math_util.h | 22 | ||||
-rw-r--r-- | intern/cycles/kernel/svm/svm_types.h | 2 | ||||
-rw-r--r-- | intern/cycles/render/nodes.cpp | 13 | ||||
-rw-r--r-- | intern/cycles/util/util_math_float3.h | 16 | ||||
-rw-r--r-- | source/blender/blenlib/BLI_float3.hh | 18 | ||||
-rw-r--r-- | source/blender/gpu/shaders/material/gpu_shader_material_vector_math.glsl | 12 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_node_types.h | 2 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_nodetree.c | 49 | ||||
-rw-r--r-- | source/blender/nodes/NOD_math_functions.hh | 29 | ||||
-rw-r--r-- | source/blender/nodes/geometry/nodes/node_geo_attribute_vector_math.cc | 52 | ||||
-rw-r--r-- | source/blender/nodes/intern/math_functions.cc | 4 | ||||
-rw-r--r-- | source/blender/nodes/intern/node_util.c | 19 | ||||
-rw-r--r-- | source/blender/nodes/intern/node_util.h | 1 | ||||
-rw-r--r-- | source/blender/nodes/shader/nodes/node_shader_vector_math.cc | 44 |
17 files changed, 264 insertions, 42 deletions
diff --git a/intern/cycles/kernel/shaders/node_math.h b/intern/cycles/kernel/shaders/node_math.h index 3a008721d5e..2da73b94212 100644 --- a/intern/cycles/kernel/shaders/node_math.h +++ b/intern/cycles/kernel/shaders/node_math.h @@ -88,6 +88,13 @@ point wrap(point value, point max, point min) wrap(value[2], max[2], min[2])); } +/* Built in OSL faceforward is `(dot(I, Nref) > 0) ? -N : N;` which is different to + * GLSL `dot(Nref, I) < 0 ? N : -N` for zero values. */ +point compatible_faceforward(point vec, point incident, point reference) +{ + return dot(reference, incident) < 0.0 ? vec : -vec; +} + matrix euler_to_mat(point euler) { float cx = cos(euler[0]); diff --git a/intern/cycles/kernel/shaders/node_vector_math.osl b/intern/cycles/kernel/shaders/node_vector_math.osl index 30f0b1daf4c..3963c23ea9c 100644 --- a/intern/cycles/kernel/shaders/node_vector_math.osl +++ b/intern/cycles/kernel/shaders/node_vector_math.osl @@ -46,6 +46,12 @@ shader node_vector_math(string math_type = "add", else if (math_type == "reflect") { Vector = reflect(Vector1, normalize(Vector2)); } + else if (math_type == "refract") { + Vector = refract(Vector1, normalize(Vector2), Scale); + } + else if (math_type == "faceforward") { + Vector = compatible_faceforward(Vector1, Vector2, Vector3); + } else if (math_type == "dot_product") { Value = dot(Vector1, Vector2); } diff --git a/intern/cycles/kernel/svm/svm_math.h b/intern/cycles/kernel/svm/svm_math.h index 12a2bbdeb9b..dda2e50f916 100644 --- a/intern/cycles/kernel/svm/svm_math.h +++ b/intern/cycles/kernel/svm/svm_math.h @@ -44,26 +44,26 @@ ccl_device void svm_node_vector_math(KernelGlobals *kg, int *offset) { uint value_stack_offset, vector_stack_offset; - uint a_stack_offset, b_stack_offset, scale_stack_offset; + uint a_stack_offset, b_stack_offset, param1_stack_offset; svm_unpack_node_uchar3( - inputs_stack_offsets, &a_stack_offset, &b_stack_offset, &scale_stack_offset); + inputs_stack_offsets, &a_stack_offset, &b_stack_offset, ¶m1_stack_offset); svm_unpack_node_uchar2(outputs_stack_offsets, &value_stack_offset, &vector_stack_offset); float3 a = stack_load_float3(stack, a_stack_offset); float3 b = stack_load_float3(stack, b_stack_offset); float3 c = make_float3(0.0f, 0.0f, 0.0f); - float scale = stack_load_float(stack, scale_stack_offset); + float param1 = stack_load_float(stack, param1_stack_offset); float value; float3 vector; /* 3 Vector Operators */ - if (type == NODE_VECTOR_MATH_WRAP) { + if (type == NODE_VECTOR_MATH_WRAP || type == NODE_VECTOR_MATH_FACEFORWARD) { uint4 extra_node = read_node(kg, offset); c = stack_load_float3(stack, extra_node.x); } - svm_vector_math(&value, &vector, (NodeVectorMathType)type, a, b, c, scale); + svm_vector_math(&value, &vector, (NodeVectorMathType)type, a, b, c, param1); if (stack_valid(value_stack_offset)) stack_store_float(stack, value_stack_offset, value); diff --git a/intern/cycles/kernel/svm/svm_math_util.h b/intern/cycles/kernel/svm/svm_math_util.h index d1e1fa87e53..389c44ab1da 100644 --- a/intern/cycles/kernel/svm/svm_math_util.h +++ b/intern/cycles/kernel/svm/svm_math_util.h @@ -22,7 +22,7 @@ ccl_device void svm_vector_math(float *value, float3 a, float3 b, float3 c, - float scale) + float param1) { switch (type) { case NODE_VECTOR_MATH_ADD: @@ -46,6 +46,12 @@ ccl_device void svm_vector_math(float *value, case NODE_VECTOR_MATH_REFLECT: *vector = reflect(a, b); break; + case NODE_VECTOR_MATH_REFRACT: + *vector = refract(a, normalize(b), param1); + break; + case NODE_VECTOR_MATH_FACEFORWARD: + *vector = faceforward(a, b, c); + break; case NODE_VECTOR_MATH_DOT_PRODUCT: *value = dot(a, b); break; @@ -56,7 +62,7 @@ ccl_device void svm_vector_math(float *value, *value = len(a); break; case NODE_VECTOR_MATH_SCALE: - *vector = a * scale; + *vector = a * param1; break; case NODE_VECTOR_MATH_NORMALIZE: *vector = safe_normalize(a); @@ -98,7 +104,7 @@ ccl_device void svm_vector_math(float *value, *vector = make_float3(tanf(a.x), tanf(a.y), tanf(a.z)); break; default: - *vector = make_float3(0.0f, 0.0f, 0.0f); + *vector = zero_float3(); *value = 0.0f; } } @@ -236,10 +242,12 @@ ccl_device float3 svm_math_blackbody_color(float t) return make_float3(4.70366907f, 0.0f, 0.0f); } - int i = (t >= 6365.0f) ? - 5 : - (t >= 3315.0f) ? 4 : - (t >= 1902.0f) ? 3 : (t >= 1449.0f) ? 2 : (t >= 1167.0f) ? 1 : 0; + int i = (t >= 6365.0f) ? 5 : + (t >= 3315.0f) ? 4 : + (t >= 1902.0f) ? 3 : + (t >= 1449.0f) ? 2 : + (t >= 1167.0f) ? 1 : + 0; ccl_constant float *r = blackbody_table_r[i]; ccl_constant float *g = blackbody_table_g[i]; diff --git a/intern/cycles/kernel/svm/svm_types.h b/intern/cycles/kernel/svm/svm_types.h index 4a00afc1d7f..64a8f82a094 100644 --- a/intern/cycles/kernel/svm/svm_types.h +++ b/intern/cycles/kernel/svm/svm_types.h @@ -339,6 +339,8 @@ typedef enum NodeVectorMathType { NODE_VECTOR_MATH_SINE, NODE_VECTOR_MATH_COSINE, NODE_VECTOR_MATH_TANGENT, + NODE_VECTOR_MATH_REFRACT, + NODE_VECTOR_MATH_FACEFORWARD, } NodeVectorMathType; typedef enum NodeClampType { diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp index 7d485fa3f03..f3d420c6fcb 100644 --- a/intern/cycles/render/nodes.cpp +++ b/intern/cycles/render/nodes.cpp @@ -6091,6 +6091,9 @@ NODE_DEFINE(VectorMathNode) type_enum.insert("cross_product", NODE_VECTOR_MATH_CROSS_PRODUCT); type_enum.insert("project", NODE_VECTOR_MATH_PROJECT); 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("dot_product", NODE_VECTOR_MATH_DOT_PRODUCT); type_enum.insert("distance", NODE_VECTOR_MATH_DISTANCE); @@ -6151,24 +6154,24 @@ void VectorMathNode::compile(SVMCompiler &compiler) { ShaderInput *vector1_in = input("Vector1"); ShaderInput *vector2_in = input("Vector2"); - ShaderInput *scale_in = input("Scale"); + ShaderInput *param1_in = input("Scale"); ShaderOutput *value_out = output("Value"); ShaderOutput *vector_out = output("Vector"); int vector1_stack_offset = compiler.stack_assign(vector1_in); int vector2_stack_offset = compiler.stack_assign(vector2_in); - int scale_stack_offset = compiler.stack_assign(scale_in); + int param1_stack_offset = compiler.stack_assign(param1_in); int value_stack_offset = compiler.stack_assign_if_linked(value_out); int vector_stack_offset = compiler.stack_assign_if_linked(vector_out); /* 3 Vector Operators */ - if (math_type == NODE_VECTOR_MATH_WRAP) { + if (math_type == NODE_VECTOR_MATH_WRAP || math_type == NODE_VECTOR_MATH_FACEFORWARD) { ShaderInput *vector3_in = input("Vector3"); int vector3_stack_offset = compiler.stack_assign(vector3_in); compiler.add_node( NODE_VECTOR_MATH, math_type, - compiler.encode_uchar4(vector1_stack_offset, vector2_stack_offset, scale_stack_offset), + compiler.encode_uchar4(vector1_stack_offset, vector2_stack_offset, param1_stack_offset), compiler.encode_uchar4(value_stack_offset, vector_stack_offset)); compiler.add_node(vector3_stack_offset); } @@ -6176,7 +6179,7 @@ void VectorMathNode::compile(SVMCompiler &compiler) compiler.add_node( NODE_VECTOR_MATH, math_type, - compiler.encode_uchar4(vector1_stack_offset, vector2_stack_offset, scale_stack_offset), + compiler.encode_uchar4(vector1_stack_offset, vector2_stack_offset, param1_stack_offset), compiler.encode_uchar4(value_stack_offset, vector_stack_offset)); } } diff --git a/intern/cycles/util/util_math_float3.h b/intern/cycles/util/util_math_float3.h index 67c5c61e4c0..9673c043189 100644 --- a/intern/cycles/util/util_math_float3.h +++ b/intern/cycles/util/util_math_float3.h @@ -388,6 +388,22 @@ ccl_device_inline float3 reflect(const float3 incident, const float3 normal) return incident - 2.0f * unit_normal * dot(incident, unit_normal); } +ccl_device_inline float3 refract(const float3 incident, const float3 normal, const float eta) +{ + float k = 1.0f - eta * eta * (1.0f - dot(normal, incident) * dot(normal, incident)); + if (k < 0.0f) + return zero_float3(); + else + return eta * incident - (eta * dot(normal, incident) + sqrt(k)) * normal; +} + +ccl_device_inline float3 faceforward(const float3 vector, + const float3 incident, + const float3 reference) +{ + return (dot(reference, incident) < 0.0f) ? vector : -vector; +} + ccl_device_inline float3 project(const float3 v, const float3 v_proj) { float len_squared = dot(v_proj, v_proj); diff --git a/source/blender/blenlib/BLI_float3.hh b/source/blender/blenlib/BLI_float3.hh index 7e49cc89b52..cbc4d4ed366 100644 --- a/source/blender/blenlib/BLI_float3.hh +++ b/source/blender/blenlib/BLI_float3.hh @@ -191,6 +191,24 @@ struct float3 { return result; } + static float3 refract(const float3 &incident, const float3 &normal, const float eta) + { + float3 result; + float k = 1.0f - eta * eta * (1.0f - dot(normal, incident) * dot(normal, incident)); + if (k < 0.0f) { + result = float3(0.0f); + } + else { + result = eta * incident - (eta * dot(normal, incident) + sqrt(k)) * normal; + } + return result; + } + + static float3 faceforward(const float3 &vector, const float3 &incident, const float3 &reference) + { + return dot(reference, incident) < 0.0f ? vector : -vector; + } + static float3 safe_divide(const float3 &a, const float3 &b) { float3 result; diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_vector_math.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_vector_math.glsl index 0b65fdb229a..60ed098beb3 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_vector_math.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_vector_math.glsl @@ -138,3 +138,15 @@ void vector_math_tangent( { outVector = tan(a); } + +void vector_math_refract( + vec3 a, vec3 b, vec3 c, float scale, out vec3 outVector, out float outValue) +{ + outVector = refract(a, normalize(b), scale); +} + +void vector_math_faceforward( + vec3 a, vec3 b, vec3 c, float scale, out vec3 outVector, out float outValue) +{ + outVector = faceforward(a, b, c); +} diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index f959f680895..f24d0e40d19 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -1550,6 +1550,8 @@ typedef enum NodeVectorMathOperation { NODE_VECTOR_MATH_SINE = 21, NODE_VECTOR_MATH_COSINE = 22, NODE_VECTOR_MATH_TANGENT = 23, + NODE_VECTOR_MATH_REFRACT = 24, + NODE_VECTOR_MATH_FACEFORWARD = 25, } NodeVectorMathOperation; /* Boolean math node operations. */ diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 7fa67ad351f..3aba3e51217 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -224,6 +224,18 @@ const EnumPropertyItem rna_enum_node_vec_math_items[] = { 0, "Reflect", "Reflect A around the normal B. B doesn't need to be normalized"}, + {NODE_VECTOR_MATH_REFRACT, + "REFRACT", + 0, + "Refract", + "For a given incident vector A, surface normal B and ratio of indices of refraction, Ior, " + "refract returns the refraction vector, R"}, + {NODE_VECTOR_MATH_FACEFORWARD, + "FACEFORWARD", + 0, + "Faceforward", + "Orients a vector A to point away from a surface B as defined by its normal C. " + "Returns (dot(B, C) < 0) ? A : -A"}, {NODE_VECTOR_MATH_DOT_PRODUCT, "DOT_PRODUCT", 0, "Dot Product", "A dot B"}, {0, "", ICON_NONE, NULL, NULL}, {NODE_VECTOR_MATH_DISTANCE, "DISTANCE", 0, "Distance", "Distance between A and B"}, @@ -1961,7 +1973,7 @@ static const EnumPropertyItem *rna_GeometryNodeAttributeFill_type_itemf(bContext /** * This bit of ugly code makes sure the float / attribute option shows up instead of - * vector / attribute if the node uses an operation that uses a float for input B. + * vector / attribute if the node uses an operation that uses a float for input B or C. */ static const EnumPropertyItem *rna_GeometryNodeAttributeVectorMath_input_type_b_itemf( bContext *UNUSED(C), PointerRNA *ptr, PropertyRNA *UNUSED(prop), bool *r_free) @@ -1994,6 +2006,37 @@ static const EnumPropertyItem *rna_GeometryNodeAttributeVectorMath_input_type_b_ return item_array; } +static const EnumPropertyItem *rna_GeometryNodeAttributeVectorMath_input_type_c_itemf( + bContext *UNUSED(C), PointerRNA *ptr, PropertyRNA *UNUSED(prop), bool *r_free) +{ + bNode *node = ptr->data; + NodeAttributeVectorMath *node_storage = (NodeAttributeVectorMath *)node->storage; + + EnumPropertyItem *item_array = NULL; + int items_len = 0; + for (const EnumPropertyItem *item = rna_node_geometry_attribute_input_type_items_any; + item->identifier != NULL; + item++) { + if (item->value == GEO_NODE_ATTRIBUTE_INPUT_ATTRIBUTE) { + RNA_enum_item_add(&item_array, &items_len, item); + } + else if (item->value == GEO_NODE_ATTRIBUTE_INPUT_FLOAT) { + if (node_storage->operation == NODE_VECTOR_MATH_REFRACT) { + RNA_enum_item_add(&item_array, &items_len, item); + } + } + else if (item->value == GEO_NODE_ATTRIBUTE_INPUT_VECTOR) { + if (node_storage->operation != NODE_VECTOR_MATH_REFRACT) { + RNA_enum_item_add(&item_array, &items_len, item); + } + } + } + RNA_enum_item_end(&item_array, &items_len); + + *r_free = true; + return item_array; +} + static void rna_GeometryNodeAttributeVectorMath_operation_update(Main *bmain, Scene *scene, PointerRNA *ptr) @@ -8901,7 +8944,9 @@ static void def_geo_attribute_vector_math(StructRNA *srna) prop = RNA_def_property(srna, "input_type_c", PROP_ENUM, PROP_NONE); RNA_def_property_enum_bitflag_sdna(prop, NULL, "input_type_c"); - RNA_def_property_enum_items(prop, rna_node_geometry_attribute_input_type_items_vector); + RNA_def_property_enum_items(prop, rna_node_geometry_attribute_input_type_items_any); + RNA_def_property_enum_funcs( + prop, NULL, NULL, "rna_GeometryNodeAttributeVectorMath_input_type_c_itemf"); RNA_def_property_ui_text(prop, "Input Type C", ""); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_socket_update"); } diff --git a/source/blender/nodes/NOD_math_functions.hh b/source/blender/nodes/NOD_math_functions.hh index c662220fea7..08496e044c5 100644 --- a/source/blender/nodes/NOD_math_functions.hh +++ b/source/blender/nodes/NOD_math_functions.hh @@ -351,6 +351,35 @@ inline bool try_dispatch_float_math_fl3_fl3_fl3_to_fl3(const NodeVectorMathOpera 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)); }); + case NODE_VECTOR_MATH_FACEFORWARD: + return dispatch([](float3 a, float3 b, float3 c) { return float3::faceforward(a, b, c); }); + default: + return false; + } + return false; +} + +/** + * This is similar to try_dispatch_float_math_fl_to_fl, just with a different callback signature. + */ +template<typename Callback> +inline bool try_dispatch_float_math_fl3_fl3_fl_to_fl3(const NodeVectorMathOperation operation, + Callback &&callback) +{ + const FloatMathOperationInfo *info = get_float3_math_operation_info(operation); + if (info == nullptr) { + return false; + } + + /* This is just a utility function to keep the individual cases smaller. */ + auto dispatch = [&](auto math_function) -> bool { + callback(math_function, *info); + return true; + }; + + switch (operation) { + case NODE_VECTOR_MATH_REFRACT: + return dispatch([](float3 a, float3 b, float c) { return float3::refract(a, b.normalized(), c); }); default: return false; } diff --git a/source/blender/nodes/geometry/nodes/node_geo_attribute_vector_math.cc b/source/blender/nodes/geometry/nodes/node_geo_attribute_vector_math.cc index aa207860f32..8b6960a05a6 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_attribute_vector_math.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_vector_math.cc @@ -40,6 +40,7 @@ static bNodeSocketTemplate geo_node_attribute_vector_math_in[] = { {SOCK_FLOAT, N_("B"), 0.0f, 0.0f, 0.0f, 0.0f, -FLT_MAX, FLT_MAX}, {SOCK_STRING, N_("C")}, {SOCK_VECTOR, N_("C"), 0.0f, 0.0f, 0.0f, 0.0f, -FLT_MAX, FLT_MAX}, + {SOCK_FLOAT, N_("C"), 0.0f, 0.0f, 0.0f, 0.0f, -FLT_MAX, FLT_MAX}, {SOCK_STRING, N_("Result")}, {-1, ""}, }; @@ -65,7 +66,8 @@ static bool operation_use_input_b(const NodeVectorMathOperation operation) static bool operation_use_input_c(const NodeVectorMathOperation operation) { - return operation == NODE_VECTOR_MATH_WRAP; + return ELEM( + operation, NODE_VECTOR_MATH_WRAP, NODE_VECTOR_MATH_REFRACT, NODE_VECTOR_MATH_FACEFORWARD); } static void geo_node_attribute_vector_math_layout(uiLayout *layout, @@ -97,6 +99,14 @@ static CustomDataType operation_get_read_type_b(const NodeVectorMathOperation op return CD_PROP_FLOAT3; } +static CustomDataType operation_get_read_type_c(const NodeVectorMathOperation operation) +{ + if (operation == NODE_VECTOR_MATH_REFRACT) { + return CD_PROP_FLOAT; + } + return CD_PROP_FLOAT3; +} + static void geo_node_attribute_vector_math_init(bNodeTree *UNUSED(tree), bNode *node) { NodeAttributeVectorMath *data = (NodeAttributeVectorMath *)MEM_callocN( @@ -132,6 +142,8 @@ static CustomDataType operation_get_result_type(const NodeVectorMathOperation op case NODE_VECTOR_MATH_SINE: case NODE_VECTOR_MATH_COSINE: case NODE_VECTOR_MATH_TANGENT: + case NODE_VECTOR_MATH_REFRACT: + case NODE_VECTOR_MATH_FACEFORWARD: return CD_PROP_FLOAT3; case NODE_VECTOR_MATH_DOT_PRODUCT: case NODE_VECTOR_MATH_DISTANCE: @@ -223,6 +235,37 @@ static void do_math_operation_fl3_fl3_fl3_to_fl3(const Float3ReadAttribute &inpu UNUSED_VARS_NDEBUG(success); } +static void do_math_operation_fl3_fl3_fl_to_fl3(const Float3ReadAttribute &input_a, + const Float3ReadAttribute &input_b, + const FloatReadAttribute &input_c, + Float3WriteAttribute result, + const NodeVectorMathOperation operation) +{ + const int size = input_a.size(); + + Span<float3> span_a = input_a.get_span(); + Span<float3> span_b = input_b.get_span(); + Span<float> span_c = input_c.get_span(); + MutableSpan<float3> span_result = result.get_span_for_write_only(); + + bool success = try_dispatch_float_math_fl3_fl3_fl_to_fl3( + operation, [&](auto math_function, const FloatMathOperationInfo &UNUSED(info)) { + for (const int i : IndexRange(size)) { + const float3 a = span_a[i]; + const float3 b = span_b[i]; + const float c = span_c[i]; + const float3 out = math_function(a, b, c); + span_result[i] = out; + } + }); + + result.apply_span(); + + /* The operation is not supported by this node currently. */ + BLI_assert(success); + UNUSED_VARS_NDEBUG(success); +} + static void do_math_operation_fl3_fl3_to_fl(const Float3ReadAttribute &input_a, const Float3ReadAttribute &input_b, FloatWriteAttribute result, @@ -364,7 +407,7 @@ static void attribute_vector_math_calc(GeometryComponent &component, const bool use_input_b = operation_use_input_b(operation); const CustomDataType read_type_b = operation_get_read_type_b(operation); const bool use_input_c = operation_use_input_c(operation); - const CustomDataType read_type_c = CD_PROP_FLOAT3; + const CustomDataType read_type_c = operation_get_read_type_c(operation); /* The result domain is always point for now. */ const CustomDataType result_type = operation_get_result_type(operation); @@ -433,9 +476,14 @@ static void attribute_vector_math_calc(GeometryComponent &component, do_math_operation_fl3_to_fl3(*attribute_a, *attribute_result, operation); break; case NODE_VECTOR_MATH_WRAP: + case NODE_VECTOR_MATH_FACEFORWARD: do_math_operation_fl3_fl3_fl3_to_fl3( *attribute_a, *attribute_b, *attribute_c, *attribute_result, operation); break; + case NODE_VECTOR_MATH_REFRACT: + do_math_operation_fl3_fl3_fl_to_fl3( + *attribute_a, *attribute_b, *attribute_c, *attribute_result, operation); + break; } attribute_result.save(); } diff --git a/source/blender/nodes/intern/math_functions.cc b/source/blender/nodes/intern/math_functions.cc index 14de2fce9b3..fb34144abf6 100644 --- a/source/blender/nodes/intern/math_functions.cc +++ b/source/blender/nodes/intern/math_functions.cc @@ -205,6 +205,10 @@ const FloatMathOperationInfo *get_float3_math_operation_info(const int operation RETURN_OPERATION_INFO("Cosine", "vector_math_cosine"); case NODE_VECTOR_MATH_TANGENT: RETURN_OPERATION_INFO("Tangent", "vector_math_tangent"); + case NODE_VECTOR_MATH_REFRACT: + RETURN_OPERATION_INFO("Refract", "vector_math_refract"); + case NODE_VECTOR_MATH_FACEFORWARD: + RETURN_OPERATION_INFO("Faceforward", "vector_math_faceforward"); } #undef RETURN_OPERATION_INFO diff --git a/source/blender/nodes/intern/node_util.c b/source/blender/nodes/intern/node_util.c index c7c3ced4e56..00db819721c 100644 --- a/source/blender/nodes/intern/node_util.c +++ b/source/blender/nodes/intern/node_util.c @@ -90,6 +90,13 @@ void node_sock_label(bNodeSocket *sock, const char *name) BLI_strncpy(sock->label, name, MAX_NAME); } +void node_sock_label_clear(bNodeSocket *sock) +{ + if (sock->label[0] != '\0') { + sock->label[0] = '\0'; + } +} + void node_math_update(bNodeTree *UNUSED(ntree), bNode *node) { bNodeSocket *sock1 = BLI_findlink(&node->inputs, 0); @@ -127,15 +134,9 @@ void node_math_update(bNodeTree *UNUSED(ntree), bNode *node) NODE_MATH_SMOOTH_MIN, NODE_MATH_SMOOTH_MAX)); - if (sock1->label[0] != '\0') { - sock1->label[0] = '\0'; - } - if (sock2->label[0] != '\0') { - sock2->label[0] = '\0'; - } - if (sock3->label[0] != '\0') { - sock3->label[0] = '\0'; - } + node_sock_label_clear(sock1); + node_sock_label_clear(sock2); + node_sock_label_clear(sock3); switch (node->custom1) { case NODE_MATH_WRAP: diff --git a/source/blender/nodes/intern/node_util.h b/source/blender/nodes/intern/node_util.h index 1b542a9420a..9cbb21e02f7 100644 --- a/source/blender/nodes/intern/node_util.h +++ b/source/blender/nodes/intern/node_util.h @@ -71,6 +71,7 @@ extern void *node_initexec_curves(struct bNodeExecContext *context, /**** Updates ****/ void node_sock_label(struct bNodeSocket *sock, const char *name); +void node_sock_label_clear(struct bNodeSocket *sock); void node_math_update(struct bNodeTree *ntree, struct bNode *node); /**** Labels ****/ diff --git a/source/blender/nodes/shader/nodes/node_shader_vector_math.cc b/source/blender/nodes/shader/nodes/node_shader_vector_math.cc index e8396c7cfc1..becc83dd694 100644 --- a/source/blender/nodes/shader/nodes/node_shader_vector_math.cc +++ b/source/blender/nodes/shader/nodes/node_shader_vector_math.cc @@ -88,6 +88,10 @@ static const char *gpu_shader_get_name(int mode) return "vector_math_cosine"; case NODE_VECTOR_MATH_TANGENT: return "vector_math_tangent"; + case NODE_VECTOR_MATH_REFRACT: + return "vector_math_refract"; + case NODE_VECTOR_MATH_FACEFORWARD: + return "vector_math_faceforward"; } return nullptr; @@ -128,8 +132,10 @@ 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)); - nodeSetSocketAvailability(sockScale, node->custom1 == NODE_VECTOR_MATH_SCALE); + nodeSetSocketAvailability( + sockC, ELEM(node->custom1, NODE_VECTOR_MATH_WRAP, NODE_VECTOR_MATH_FACEFORWARD)); + nodeSetSocketAvailability(sockScale, + ELEM(node->custom1, NODE_VECTOR_MATH_SCALE, NODE_VECTOR_MATH_REFRACT)); nodeSetSocketAvailability(sockVector, !ELEM(node->custom1, NODE_VECTOR_MATH_LENGTH, @@ -142,13 +148,14 @@ static void node_shader_update_vector_math(bNodeTree *UNUSED(ntree), bNode *node NODE_VECTOR_MATH_DOT_PRODUCT)); /* Labels */ - if (sockB->label[0] != '\0') { - sockB->label[0] = '\0'; - } - if (sockC->label[0] != '\0') { - sockC->label[0] = '\0'; - } + node_sock_label_clear(sockB); + node_sock_label_clear(sockC); + node_sock_label_clear(sockScale); switch (node->custom1) { + case NODE_VECTOR_MATH_FACEFORWARD: + node_sock_label(sockB, "Incident"); + node_sock_label(sockC, "Reference"); + break; case NODE_VECTOR_MATH_WRAP: node_sock_label(sockB, "Max"); node_sock_label(sockC, "Min"); @@ -156,6 +163,12 @@ static void node_shader_update_vector_math(bNodeTree *UNUSED(ntree), bNode *node case NODE_VECTOR_MATH_SNAP: node_sock_label(sockB, "Increment"); break; + case NODE_VECTOR_MATH_REFRACT: + node_sock_label(sockScale, "Ior"); + break; + case NODE_VECTOR_MATH_SCALE: + node_sock_label(sockScale, "Scale"); + break; } } @@ -186,7 +199,6 @@ static const blender::fn::MultiFunction &get_multi_function( "Divide", [](float3 a, float3 b) { return float3::safe_divide(a, b); }}; return fn; } - case NODE_VECTOR_MATH_CROSS_PRODUCT: { static blender::fn::CustomMF_SI_SI_SO<float3, float3, float3> fn{ "Cross Product", float3::cross_high_precision}; @@ -205,7 +217,6 @@ static const blender::fn::MultiFunction &get_multi_function( static blender::fn::CustomMF_SI_SI_SO<float3, float3, float> fn{"Dot Product", float3::dot}; return fn; } - case NODE_VECTOR_MATH_DISTANCE: { static blender::fn::CustomMF_SI_SI_SO<float3, float3, float> fn{"Distance", float3::distance}; @@ -226,7 +237,17 @@ static const blender::fn::MultiFunction &get_multi_function( "Normalize", [](float3 a) { return a.normalized(); }}; return fn; } - + case NODE_VECTOR_MATH_REFRACT: { + static blender::fn::CustomMF_SI_SI_SI_SO<float3, float3, float, float3> fn{ + "Refract", + [](float3 a, float3 b, float c) { return float3::refract(a, b.normalized(), c); }}; + return fn; + } + case NODE_VECTOR_MATH_FACEFORWARD: { + static blender::fn::CustomMF_SI_SI_SI_SO<float3, float3, float3, float3> fn{ + "Faceforward", float3::faceforward}; + return fn; + } case NODE_VECTOR_MATH_SNAP: { return builder.get_not_implemented_fn(); } @@ -263,7 +284,6 @@ static const blender::fn::MultiFunction &get_multi_function( case NODE_VECTOR_MATH_TANGENT: { return builder.get_not_implemented_fn(); } - default: BLI_assert(false); return builder.get_not_implemented_fn(); |