Hello, it’s me again…
Im trying to implement a custom node in blender-cycles…
My problem is that the node seems to be ignored when rendering, it appears in the nodegraph and looks just normal, but if I connect it to let’s say an emission shader (color) the color won’t be overwritten. The node does nothing and the color stays the same. It seems like it’s ignored.
I debugged the SVMCompiler::generate_node function and realized that my Nodeclass was never given to this function but the other nodes are.
It feels realy stupid to ask this question since I surely forgot something relatively simple, but what is going on here?
Diff file:
diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp
index 03ed88e..cf0f9e6 100644
--- a/intern/cycles/blender/blender_shader.cpp
+++ b/intern/cycles/blender/blender_shader.cpp
@@ -921,6 +921,14 @@ static ShaderNode *add_node(Scene *scene,
aov->name = b_aov_node.name();
node = aov;
}
+ else if (b_node.is_a(&RNA_ShaderNodeInsideTest))
+ {
+ BL::ShaderNodeInsideTest b_inside_test_node(b_node);
+ InsideTestNode *itest = graph->create_node<InsideTestNode>();
+ node = itest;
+ }
+
+
if (node) {
node->name = b_node.name();
diff --git a/intern/cycles/kernel/shaders/CMakeLists.txt b/intern/cycles/kernel/shaders/CMakeLists.txt
index 02be781..a84d3d0 100644
--- a/intern/cycles/kernel/shaders/CMakeLists.txt
+++ b/intern/cycles/kernel/shaders/CMakeLists.txt
@@ -107,6 +107,7 @@ set(SRC_OSL
node_uv_map.osl
node_principled_bsdf.osl
node_rgb_to_bw.osl
+ node_inside_test.osl
)
# The headers that OSL ships differs per release so we can not
diff --git a/intern/cycles/kernel/shaders/node_inside_test.osl b/intern/cycles/kernel/shaders/node_inside_test.osl
new file mode 100644
index 0000000..0bed383
--- /dev/null
+++ b/intern/cycles/kernel/shaders/node_inside_test.osl
@@ -0,0 +1,56 @@
+#include "stdosl.h"
+
+shader node_inside_test(int object=-1,
+ point position=P,
+ int samples = 1,
+ output float result=0){
+
+ int i = 0;
+ vector rand;
+
+ int hit_name;
+ vector hit_normal;
+
+ int hits = 0;
+
+ while(i < samples){
+ rand = noise("cell", P*(2000+i));
+ rand -= 0.5;
+
+ if(trace(position, rand)){
+ getmessage("trace", "object:index", hit_name);
+ if(object==hit_name){
+ point triVerts[3];
+ getmessage("trace","geom:trianglevertices",triVerts);
+ vector triNormal = cross(triVerts[1]-triVerts[0],triVerts[2]-triVerts[0]);
+ if(dot(triNormal, rand) >= 0){
+ hits += 1;
+ }
+ }
+ else{
+ break;
+
+ }
+ }
+ else{
+
+ break;
+
+ }
+ i += 1;
+
+ }
+ if(hits == samples){
+ result = 1;
+
+ }
+
+ else{
+
+ result = 0;
+
+ }
+
+ result = 0;
+
+}
\ No newline at end of file
diff --git a/intern/cycles/kernel/svm/svm.h b/intern/cycles/kernel/svm/svm.h
index abeb8fa..af3d813 100644
--- a/intern/cycles/kernel/svm/svm.h
+++ b/intern/cycles/kernel/svm/svm.h
@@ -208,6 +208,7 @@ CCL_NAMESPACE_END
#include "kernel/svm/svm_wavelength.h"
#include "kernel/svm/svm_white_noise.h"
#include "kernel/svm/svm_wireframe.h"
+#include "kernel/svm/svm_inside_test.h"
#ifdef __SHADER_RAYTRACE__
# include "kernel/svm/svm_ao.h"
@@ -461,6 +462,10 @@ ccl_device_noinline void svm_eval_nodes(KernelGlobals *kg,
case NODE_IES:
svm_node_ies(kg, sd, stack, node, &offset);
break;
+ case NODE_INSIDE_TEST:
+ svm_node_inside_test(kg, sd, stack, node);
+ break;
+
#endif /* NODES_GROUP(NODE_GROUP_LEVEL_2) */
#if NODES_GROUP(NODE_GROUP_LEVEL_3)
diff --git a/intern/cycles/kernel/svm/svm_inside_test.h b/intern/cycles/kernel/svm/svm_inside_test.h
new file mode 100644
index 0000000..8c806d5
--- /dev/null
+++ b/intern/cycles/kernel/svm/svm_inside_test.h
@@ -0,0 +1,83 @@
+
+CCL_NAMESPACE_BEGIN
+
+ccl_device_noinline float svm_inside_test(KernelGlobals *kg,
+ ShaderData *sd,
+ float3 pos,
+ int obj,
+ int samples)
+ {
+ /* Early out if no sampling needed. */
+ if (samples < 1 || sd->object == OBJECT_NONE) {
+ return 1.0f;
+ }
+
+ /* Can't raytrace from shaders like displacement, before BVH exists. */
+ if (kernel_data.bvh.bvh_layout == BVH_LAYOUT_NONE) {
+ return 1.0f;
+ }
+
+
+ int hits = 0;
+for (int i = 0; i < samples; i++) {
+
+ /* Create ray. */
+ Ray ray;
+ ray.P = pos;
+ ray.D = make_float3(1.0f, 0.0f, 0.0f); // limits the shader to closed surfaces, otherwise this is invalide!
+ ray.t = std::numeric_limits<float>::max();
+ ray.time = sd->time;
+ ray.dP = sd->dP;
+ ray.dD = differential3_zero();
+
+ Intersection isect;
+ if (scene_intersect(kg, &ray, PATH_RAY_DIFFUSE, &isect)) {
+ hits += (isect.object == obj) && (isect.Ng.x < 0); //optimize dotproduct since d is (1, 0, 0) -> just check if hit_n.x < 0
+ }
+ }
+
+ if (hits==samples) {
+ return 1;
+ }
+ else {
+ return 0;
+ }
+}
+
+ccl_device void svm_node_inside_test(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node){
+
+ /*
+ svm_unpack_node_uchar4(node.y, &co_offset, &color1_offset, &color2_offset, &scale_offset);
+ svm_unpack_node_uchar2(node.z, &color_offset, &fac_offset);
+
+ float3 co = stack_load_float3(stack, co_offset);
+ float3 color1 = stack_load_float3(stack, color1_offset);
+ float3 color2 = stack_load_float3(stack, color2_offset);
+ float scale = stack_load_float_default(stack, scale_offset);
+ */
+ //SOCKET_IN_INT(object, "ObjectID", ustring());
+ //SOCKET_IN_INT(samples, "Samples", 1);
+ //SOCKET_IN_VECTOR(position, "Position", make_float3(0.0f, 0.0f, 0.0f));
+ //
+ //SOCKET_OUT_FLOAT(result_osl, "result", 0);
+
+ uint obj_offset, samples_offset, pos_offset, result_offset;
+
+ svm_unpack_node_uchar4(node.x, &obj_offset, &samples_offset, &pos_offset, &result_offset);
+
+ int obj = stack_load_int(stack, obj_offset);
+ int samples = stack_load_int(stack, samples_offset);
+ float3 pos = stack_load_float3(stack, pos_offset);
+
+ float result = svm_inside_test(kg,
+ sd,
+ pos,
+ obj,
+ samples);
+ result = 0;
+ stack_store_float(stack, result_offset, result);
+}
+
+
+
+CCL_NAMESPACE_END
\ No newline at end of file
diff --git a/intern/cycles/kernel/svm/svm_types.h b/intern/cycles/kernel/svm/svm_types.h
index f1ebb37..750824f 100644
--- a/intern/cycles/kernel/svm/svm_types.h
+++ b/intern/cycles/kernel/svm/svm_types.h
@@ -153,6 +153,7 @@ typedef enum ShaderNodeType {
NODE_AOV_START,
NODE_AOV_COLOR,
NODE_AOV_VALUE,
+ NODE_INSIDE_TEST,
/* NOTE: for best OpenCL performance, item definition in the enum must
* match the switch case order in svm.h. */
} ShaderNodeType;
diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp
index fc525e0..13c4be3 100644
--- a/intern/cycles/render/nodes.cpp
+++ b/intern/cycles/render/nodes.cpp
@@ -4933,6 +4933,51 @@ void MixNode::constant_fold(const ConstantFolder &folder)
}
}
+/*Inside Test*/
+
+NODE_DEFINE(InsideTestNode)
+{
+ NodeType *type = NodeType::add("inside_test", create, NodeType::SHADER);
+ SOCKET_IN_INT(object, "ObjectID", -1);
+ SOCKET_IN_INT(samples, "Samples", 1);
+ SOCKET_IN_VECTOR(position, "Position", make_float3(0.0f, 0.0f, 0.0f));
+
+ SOCKET_OUT_FLOAT(result, "result");
+ return type;
+}
+
+InsideTestNode::InsideTestNode() : ShaderNode(node_type)
+{
+ result = 0.0f;
+}
+
+void InsideTestNode::compile(OSLCompiler &compiler)
+{
+ std::cout << "\n\n\n\n\n\ncompiling OSL\n\n\n\n\n\n";
+ compiler.add(this, "node_inside_test");
+}
+
+void InsideTestNode::compile(SVMCompiler &compiler) {
+ std::cout << "\n\n\n\n\n\ncompiling SVM\n\n\n\n\n\n";
+ ShaderInput *object_in = input("Object");
+ ShaderInput *samples_in = input("Samples");
+ ShaderInput *position_in = input("Position");
+ ShaderOutput *result_out = output("Result");
+
+ int object_in_offset = compiler.stack_assign(object_in);
+ int samples_in_offset = compiler.stack_assign(samples_in);
+ int position_in_offset = compiler.stack_assign(position_in);
+ int result_out_offset = compiler.stack_assign(result_out);
+
+ compiler.add_node(
+ +NODE_INSIDE_TEST,
+ compiler.encode_uchar4(
+ object_in_offset, samples_in_offset, position_in_offset, result_out_offset));
+ compiler.add_node(__float_as_int(object), +__float_as_int(samples));
+ compiler.add_node(NODE_INSIDE_TEST, position);
+}
+
+
/* Combine RGB */
NODE_DEFINE(CombineRGBNode)
diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h
index 62dd9d8..278451e 100644
--- a/intern/cycles/render/nodes.h
+++ b/intern/cycles/render/nodes.h
@@ -1637,6 +1637,28 @@ class VectorDisplacementNode : public ShaderNode {
float scale;
};
+
+
+
+
+class InsideTestNode : public ShaderNode{
+ public:
+ SHADER_NODE_CLASS(InsideTestNode);
+ int object;
+ int samples;
+ float3 position;
+ float result;
+
+ bool has_spatial_varying()
+ {
+ return true;
+ }
+
+};
+
+
+
+
CCL_NAMESPACE_END
#endif /* __NODES_H__ */
diff --git a/release/scripts/startup/nodeitems_builtins.py b/release/scripts/startup/nodeitems_builtins.py
index 027f406..0ca874d 100644
--- a/release/scripts/startup/nodeitems_builtins.py
+++ b/release/scripts/startup/nodeitems_builtins.py
@@ -237,7 +237,8 @@ shader_node_categories = [
NodeItem("ShaderNodeVolumeScatter", poll=eevee_cycles_shader_nodes_poll),
NodeItem("ShaderNodeVolumePrincipled"),
NodeItem("ShaderNodeEeveeSpecular", poll=object_eevee_shader_nodes_poll),
- NodeItem("ShaderNodeBsdfHairPrincipled", poll=object_cycles_shader_nodes_poll)
+ NodeItem("ShaderNodeBsdfHairPrincipled", poll=object_cycles_shader_nodes_poll),
+ NodeItem("ShaderNodeInsideTest")
]),
ShaderNodeCategory("SH_NEW_TEXTURE", "Texture", items=[
NodeItem("ShaderNodeTexImage"),
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index 5200a1b..0f9eb6d 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -1039,7 +1039,7 @@ void BKE_nodetree_remove_layer_n(struct bNodeTree *ntree,
#define SH_NODE_VERTEX_COLOR 706
#define SH_NODE_OUTPUT_AOV 707
#define SH_NODE_VECTOR_ROTATE 708
-
+#define SH_NODE_INSIDE_TEST 2048
/* custom defines options for Material node */
// #define SH_NODE_MAT_DIFF 1
// #define SH_NODE_MAT_SPEC 2
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c
index cf31b53..41193b7 100644
--- a/source/blender/blenkernel/intern/node.c
+++ b/source/blender/blenkernel/intern/node.c
@@ -4699,6 +4699,7 @@ static void registerTextureNodes(void)
register_node_type_tex_proc_noise();
register_node_type_tex_proc_stucci();
register_node_type_tex_proc_distnoise();
+ register_node_type_sh_inside_test();
}
static void registerSimulationNodes(void)
diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c
index 10aa53a..840870a 100644
--- a/source/blender/editors/space_node/drawnode.c
+++ b/source/blender/editors/space_node/drawnode.c
@@ -1189,6 +1189,11 @@ static void node_shader_buts_output_aov(uiLayout *layout, bContext *UNUSED(C), P
uiItemR(layout, ptr, "name", DEFAULT_FLAGS, NULL, ICON_NONE);
}
+static void node_shader_buts_inside_test(uiLayout * layout, bContext *C, PointerRNA * ptr) {
+ ;
+}
+
+
/* only once called */
static void node_shader_set_butfunc(bNodeType *ntype)
{
@@ -1351,6 +1356,9 @@ static void node_shader_set_butfunc(bNodeType *ntype)
case SH_NODE_OUTPUT_AOV:
ntype->draw_buttons = node_shader_buts_output_aov;
break;
+ case SH_NODE_INSIDE_TEST:
+ ntype->draw_buttons = node_shader_buts_inside_test;
+ break;
}
}
diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt
index 4172dc06..9a62222 100644
--- a/source/blender/nodes/CMakeLists.txt
+++ b/source/blender/nodes/CMakeLists.txt
@@ -229,6 +229,7 @@ set(SRC
shader/nodes/node_shader_wireframe.c
shader/node_shader_tree.c
shader/node_shader_util.c
+ shader/nodes/node_shader_inside_test.c
simulation/nodes/node_sim_age_reached_event.cc
simulation/nodes/node_sim_common.cc
diff --git a/source/blender/nodes/NOD_shader.h b/source/blender/nodes/NOD_shader.h
index 2911e0f..77187ef 100644
--- a/source/blender/nodes/NOD_shader.h
+++ b/source/blender/nodes/NOD_shader.h
@@ -139,6 +139,8 @@ void register_node_type_sh_tex_checker(void);
void register_node_type_sh_bump(void);
void register_node_type_sh_tex_ies(void);
void register_node_type_sh_tex_white_noise(void);
+void register_node_type_sh_inside_test(void);
+
void register_node_type_sh_custom_group(bNodeType *ntype);
diff --git a/source/blender/nodes/NOD_static_types.h b/source/blender/nodes/NOD_static_types.h
index 7922a73..0ce94be 100644
--- a/source/blender/nodes/NOD_static_types.h
+++ b/source/blender/nodes/NOD_static_types.h
@@ -132,6 +132,7 @@ DefNode(ShaderNode, SH_NODE_VECTOR_DISPLACEMENT,def_sh_vector_displacement,"
DefNode(ShaderNode, SH_NODE_TEX_IES, def_sh_tex_ies, "TEX_IES", TexIES, "IES Texture", "" )
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_INSIDE_TEST, 0, "INSIDE_TEST", InsideTest, "Inside Test", "" );
DefNode(CompositorNode, CMP_NODE_VIEWER, def_cmp_viewer, "VIEWER", Viewer, "Viewer", "" )
DefNode(CompositorNode, CMP_NODE_RGB, 0, "RGB", RGB, "RGB", "" )
diff --git a/source/blender/nodes/shader/nodes/node_shader_inside_test.c b/source/blender/nodes/shader/nodes/node_shader_inside_test.c
new file mode 100644
index 0000000..046363a
--- /dev/null
+++ b/source/blender/nodes/shader/nodes/node_shader_inside_test.c
@@ -0,0 +1,22 @@
+ #include "../node_shader_util.h"
+static bNodeSocketTemplate sh_node_inside_test_in[] = {
+ {SOCK_INT, N_("Object"), 0, 0, 0, 0, 0, 1000},
+ {SOCK_INT, N_("Samples"), 1, 0, 0, 0, 1, 10},
+ {SOCK_VECTOR, N_("Position"), 0.5f, 0.5f, 1.0f, 1.0f, 0.0f, 1.0f},
+ {-1, ""},
+ };
+static bNodeSocketTemplate sh_node_inside_test_out[] = {
+ {SOCK_FLOAT, 0, N_("Result"), 0, 0, 0, 0, 0, 0}, {-1, ""}, };
+
+void node_shader_init_inside_test(bNodeTree *UNUSED(ntree), bNode *node)
+{
+ ;
+}
+ void register_node_type_sh_inside_test(void)
+{
+ static bNodeType ntype;
+ sh_node_type_base(&ntype, SH_NODE_INSIDE_TEST, "Inside Test", NODE_CLASS_TEXTURE, 0);
+ node_type_socket_templates(&ntype, sh_node_inside_test_in, sh_node_inside_test_out);
+ node_type_init(&ntype, node_shader_init_inside_test);
+ nodeRegisterType(&ntype);
+}