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
diff options
context:
space:
mode:
authorSergey Sharybin <sergey.vfx@gmail.com>2016-06-14 12:31:00 +0300
committerSergey Sharybin <sergey.vfx@gmail.com>2016-06-14 12:31:00 +0300
commit6d111a233cd65433564ffb106bb9e0c6f34939e8 (patch)
tree3577abccda4555a1330689f8e249737a8bba1885
parent51cb4ea2cf09dee6938653c537701b04a864a278 (diff)
Fix T48613: Bump mapping in cycles is not shown on the viewport when the material use node groups
-rw-r--r--source/blender/blenkernel/BKE_node.h1
-rw-r--r--source/blender/blenkernel/intern/node.c19
-rw-r--r--source/blender/nodes/shader/node_shader_tree.c144
3 files changed, 143 insertions, 21 deletions
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index 76e49566d19..4b92c1f7a3a 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -348,6 +348,7 @@ void ntreeUserDecrefID(struct bNodeTree *ntree);
struct bNodeTree *ntreeFromID(struct ID *id);
void ntreeMakeLocal(struct bNodeTree *ntree, bool id_in_mainlist);
+struct bNode *ntreeFindType(const struct bNodeTree *ntree, int type);
bool ntreeHasType(const struct bNodeTree *ntree, int type);
bool ntreeHasTree(const struct bNodeTree *ntree, const struct bNodeTree *lookup);
void ntreeUpdateTree(struct Main *main, struct bNodeTree *ntree);
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c
index 75f899dd597..fa0367d1656 100644
--- a/source/blender/blenkernel/intern/node.c
+++ b/source/blender/blenkernel/intern/node.c
@@ -2418,15 +2418,20 @@ void ntreeInterfaceTypeUpdate(bNodeTree *ntree)
/* ************ find stuff *************** */
+bNode *ntreeFindType(const bNodeTree *ntree, int type) {
+ if (ntree) {
+ for (bNode * node = ntree->nodes.first; node; node = node->next) {
+ if (node->type == type) {
+ return node;
+ }
+ }
+ }
+ return NULL;
+}
+
bool ntreeHasType(const bNodeTree *ntree, int type)
{
- bNode *node;
-
- if (ntree)
- for (node = ntree->nodes.first; node; node = node->next)
- if (node->type == type)
- return true;
- return false;
+ return ntreeFindType(ntree, type) != NULL;
}
bool ntreeHasTree(const bNodeTree *ntree, const bNodeTree *lookup)
diff --git a/source/blender/nodes/shader/node_shader_tree.c b/source/blender/nodes/shader/node_shader_tree.c
index 29b1e5bc5c7..afccef46174 100644
--- a/source/blender/nodes/shader/node_shader_tree.c
+++ b/source/blender/nodes/shader/node_shader_tree.c
@@ -199,6 +199,12 @@ void register_node_tree_type_sh(void)
/* GPU material from shader nodes */
+static void ntree_shader_link_builtin_normal(bNodeTree *ntree,
+ bNode *node_from,
+ bNodeSocket *socket_from,
+ bNode *displacement_node,
+ bNodeSocket *displacement_socket);
+
/* Find an output node of the shader tree.
*
* NOTE: it will only return output which is NOT in the group, which isn't how
@@ -277,32 +283,138 @@ static bool ntree_shader_has_displacement(bNodeTree *ntree,
return displacement->link != NULL;
}
+static bool ntree_shader_relink_node_normal(bNodeTree *ntree,
+ bNode *node,
+ bNode *node_from,
+ bNodeSocket *socket_from)
+{
+ bNodeSocket *sock = ntree_shader_node_find_input(node, "Normal");
+ /* TODO(sergey): Can we do something smarter here than just a name-based
+ * matching?
+ */
+ if (sock == NULL) {
+ /* There's no Normal input, nothing to link. */
+ return false;
+ }
+ if (sock->link != NULL) {
+ /* Something is linked to the normal input already. can't
+ * use other input for that.
+ */
+ return false;
+ }
+ /* Create connection between specified node and the normal input. */
+ nodeAddLink(ntree, node_from, socket_from, node, sock);
+ return true;
+}
+
+static void ntree_shader_link_builtin_group_normal(
+ bNodeTree *ntree,
+ bNode *group_node,
+ bNode *node_from,
+ bNodeSocket *socket_from,
+ bNode *displacement_node,
+ bNodeSocket *displacement_socket)
+{
+ bNodeTree *group_ntree = (bNodeTree *)group_node->id;
+ /* Create input socket to plug displacement connection to. */
+ bNodeSocket *group_normal_socket =
+ ntreeAddSocketInterface(group_ntree,
+ SOCK_IN,
+ "NodeSocketVector",
+ "Normal");
+ /* Need to update tree so all node instances nodes gets proper sockets. */
+ ntreeUpdateTree(G.main, group_ntree);
+ /* Assumes sockets are always added at the end. */
+ bNodeSocket *group_node_normal_socket = (bNodeSocket*)group_node->inputs.last;
+ if (displacement_node == group_node) {
+ /* If displacement is coming from this node group we need to perform
+ * some internal re-linking in order to avoid cycles.
+ */
+ bNode *group_output_node = ntreeFindType(group_ntree, NODE_GROUP_OUTPUT);
+ BLI_assert(group_output_node != NULL);
+ bNodeSocket *group_output_node_displacement_socket =
+ nodeFindSocket(group_output_node,
+ SOCK_IN,
+ displacement_socket->identifier);
+ bNodeLink *group_displacement_link = group_output_node_displacement_socket->link;
+ if (group_displacement_link == NULL) {
+ /* Displacement output is not connected to anything, can just stop
+ * right away.
+ */
+ return;
+ }
+ /* This code is similar to ntree_shader_relink_displacement() */
+ bNode *group_displacement_node = group_displacement_link->fromnode;
+ bNodeSocket *group_displacement_socket = group_displacement_link->fromsock;
+ nodeRemLink(group_ntree, group_displacement_link);
+ /* Create and link bump node.
+ * Can't re-use bump node from parent tree because it'll cause cycle.
+ */
+ bNode *bump_node = nodeAddStaticNode(NULL, group_ntree, SH_NODE_BUMP);
+ bNodeSocket *bump_input_socket = ntree_shader_node_find_input(bump_node, "Height");
+ bNodeSocket *bump_output_socket = ntree_shader_node_find_output(bump_node, "Normal");
+ BLI_assert(bump_input_socket != NULL);
+ BLI_assert(bump_output_socket != NULL);
+ nodeAddLink(group_ntree,
+ group_displacement_node, group_displacement_socket,
+ bump_node, bump_input_socket);
+ /* Relink normals inside of the instanced tree. */
+ ntree_shader_link_builtin_normal(group_ntree,
+ bump_node,
+ bump_output_socket,
+ group_displacement_node,
+ group_displacement_socket);
+ ntreeUpdateTree(G.main, group_ntree);
+ }
+ else {
+ /* Connect group node normal input. */
+ nodeAddLink(ntree,
+ node_from, socket_from,
+ group_node, group_node_normal_socket);
+ bNode *group_input_node = ntreeFindType(group_ntree, NODE_GROUP_INPUT);
+ BLI_assert(group_input_node != NULL);
+ bNodeSocket *group_input_node_normal_socket =
+ nodeFindSocket(group_input_node,
+ SOCK_OUT,
+ group_normal_socket->identifier);
+ BLI_assert(group_input_node_normal_socket != NULL);
+ /* Relink normals inside of the instanced tree. */
+ ntree_shader_link_builtin_normal(group_ntree,
+ group_input_node,
+ group_input_node_normal_socket,
+ displacement_node,
+ displacement_socket);
+ ntreeUpdateTree(G.main, group_ntree);
+ }
+}
+
/* Use specified node and socket as an input for unconnected normal sockets. */
static void ntree_shader_link_builtin_normal(bNodeTree *ntree,
bNode *node_from,
- bNodeSocket *socket_from)
+ bNodeSocket *socket_from,
+ bNode *displacement_node,
+ bNodeSocket *displacement_socket)
{
for (bNode *node = ntree->nodes.first; node != NULL; node = node->next) {
if (node == node_from) {
/* Don't connect node itself! */
continue;
}
- bNodeSocket *sock = ntree_shader_node_find_input(node, "Normal");
- /* TODO(sergey): Can we do something smarter here than just a name-based
- * matching?
- */
- if (sock == NULL) {
- /* There's no Normal input, nothing to link. */
+ if (node->type == NODE_GROUP && node->id) {
+ /* Special re-linking for group nodes. */
+ ntree_shader_link_builtin_group_normal(ntree,
+ node,
+ node_from,
+ socket_from,
+ displacement_node,
+ displacement_socket);
continue;
}
- if (sock->link != NULL) {
- /* Something is linked to the normal input already. can't
- * use other input for that.
- */
+ if (ELEM(node->type, NODE_GROUP_INPUT, NODE_GROUP_OUTPUT)) {
+ /* Group inputs and outputs needs nothing special. */
continue;
}
- /* Create connection between specified node and the normal input. */
- nodeAddLink(ntree, node_from, socket_from, node, sock);
+ ntree_shader_relink_node_normal(ntree, node, node_from, socket_from);
}
}
@@ -346,7 +458,11 @@ static void ntree_shader_relink_displacement(bNodeTree *ntree,
displacement_node, displacement_socket,
bump_node, bump_input_socket);
/* Connect all free-standing Normal inputs. */
- ntree_shader_link_builtin_normal(ntree, bump_node, bump_output_socket);
+ ntree_shader_link_builtin_normal(ntree,
+ bump_node,
+ bump_output_socket,
+ displacement_node,
+ displacement_socket);
/* TODO(sergey): Reconnect Geometry Info->Normal sockets to the new
* bump node.
*/