Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/intern
diff options
context:
space:
mode:
authorCharlie Jolly <charlie>2021-03-23 12:21:56 +0300
committerCharlie Jolly <mistajolly@gmail.com>2021-03-23 12:59:20 +0300
commitd3758892987d76749fdf1211ed27ff77f39b5b3b (patch)
tree0e0b6b2a614b9829255cae77fb75f93696e7df7b /intern
parent4c19fcacc0b71271ca2fafc87ef5772a819e7075 (diff)
Nodes: Add Refract and Faceforward functions to Vector Maths nodes
Cycles, Eevee, OSL, Geo, Attribute Based on outdated refract patch D6619 by @cubic_sloth `refract` and `faceforward` are standard functions in GLSL, OSL and Godot shader languages. Adding these functions provides Blender shader artists access to these standard functions. Reviewed By: brecht Differential Revision: https://developer.blender.org/D10622
Diffstat (limited to 'intern')
-rw-r--r--intern/cycles/kernel/shaders/node_math.h7
-rw-r--r--intern/cycles/kernel/shaders/node_vector_math.osl6
-rw-r--r--intern/cycles/kernel/svm/svm_math.h10
-rw-r--r--intern/cycles/kernel/svm/svm_math_util.h22
-rw-r--r--intern/cycles/kernel/svm/svm_types.h2
-rw-r--r--intern/cycles/render/nodes.cpp13
-rw-r--r--intern/cycles/util/util_math_float3.h16
7 files changed, 59 insertions, 17 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, &param1_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);