Fix T70614 EEVEE: Bump with texture connected to other branches don't work

Was caused by the bump node not being evaluated because the other branch
was evaluated before.

To fix this, we use fromnode instead of tonode.

Also we fix a potential issue with recursiveness because
ntree_shader_copy_branch() also use nodeChainIterBackwards() which would
reset the iter_flag in the middle of the parent iteration. Use iter_flag
as a bitflag for each iteration to fix this.
This commit is contained in:
Clément Foucault 2019-10-10 00:31:47 +02:00
parent 8163fda9fb
commit f61a8a2abd
Notes: blender-bot 2023-02-14 09:21:21 +01:00
Referenced by issue #70707, Crashing modes round 3: Sculpt to Vertex Paint
Referenced by issue #70699, Select Edge Ring not found in search menu
Referenced by issue #70614, Texture won't display or won't do correctly on eevee when used as bump and other input
3 changed files with 23 additions and 15 deletions

View File

@ -594,7 +594,8 @@ void nodeChainIter(const bNodeTree *ntree,
void nodeChainIterBackwards(const bNodeTree *ntree,
const bNode *node_start,
bool (*callback)(bNode *, bNode *, void *),
void *userdata);
void *userdata,
int recursion_lvl);
void nodeParentsIter(bNode *node, bool (*callback)(bNode *, void *), void *userdata);
struct bNodeLink *nodeFindLink(struct bNodeTree *ntree,

View File

@ -950,7 +950,8 @@ void nodeChainIter(const bNodeTree *ntree,
static void iter_backwards_ex(const bNodeTree *ntree,
const bNode *node_start,
bool (*callback)(bNode *, bNode *, void *),
void *userdata)
void *userdata,
char recursion_mask)
{
LISTBASE_FOREACH (bNodeSocket *, sock, &node_start->inputs) {
bNodeLink *link = sock->link;
@ -961,18 +962,17 @@ static void iter_backwards_ex(const bNodeTree *ntree,
/* Skip links marked as cyclic. */
continue;
}
if (link->fromnode->iter_flag) {
/* Only iter on nodes once. */
if (link->fromnode->iter_flag & recursion_mask) {
continue;
}
else {
link->fromnode->iter_flag = 1;
link->fromnode->iter_flag |= recursion_mask;
}
if (!callback(link->fromnode, link->tonode, userdata)) {
return;
}
iter_backwards_ex(ntree, link->fromnode, callback, userdata);
iter_backwards_ex(ntree, link->fromnode, callback, userdata, recursion_mask);
}
}
@ -981,6 +981,8 @@ static void iter_backwards_ex(const bNodeTree *ntree,
* \a callback for each node (which can return false to end iterator).
*
* Faster than nodeChainIter. Iter only once per node.
* Can be called recursively (using another nodeChainIterBackwards) by
* setting the recursion_lvl accordingly.
*
* \note Needs updated socket links (ntreeUpdateTree).
* \note Recursive
@ -988,18 +990,23 @@ static void iter_backwards_ex(const bNodeTree *ntree,
void nodeChainIterBackwards(const bNodeTree *ntree,
const bNode *node_start,
bool (*callback)(bNode *, bNode *, void *),
void *userdata)
void *userdata,
int recursion_lvl)
{
if (!node_start) {
return;
}
/* Limited by iter_flag type. */
BLI_assert(recursion_lvl < 8);
char recursion_mask = (1 << recursion_lvl);
/* Reset flag. */
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
node->iter_flag = 0;
node->iter_flag &= ~recursion_mask;
}
iter_backwards_ex(ntree, node_start, callback, userdata);
iter_backwards_ex(ntree, node_start, callback, userdata, recursion_mask);
}
/**

View File

@ -629,7 +629,7 @@ static bNode *ntree_shader_copy_branch(bNodeTree *ntree,
/* Count and tag all nodes inside the displacement branch of the tree. */
start_node->tmp_flag = 0;
int node_count = 1;
nodeChainIterBackwards(ntree, start_node, ntree_branch_count_and_tag_nodes, &node_count);
nodeChainIterBackwards(ntree, start_node, ntree_branch_count_and_tag_nodes, &node_count, 1);
/* Make a full copy of the branch */
bNode **nodes_copy = MEM_mallocN(sizeof(bNode *) * node_count, __func__);
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
@ -763,13 +763,13 @@ static void node_tag_branch_as_derivative(bNode *node, int dx)
}
}
static bool ntree_shader_bump_branches(bNode *UNUSED(fromnode), bNode *tonode, void *userdata)
static bool ntree_shader_bump_branches(bNode *fromnode, bNode *UNUSED(tonode), void *userdata)
{
bNodeTree *ntree = (bNodeTree *)userdata;
if (tonode->type == SH_NODE_BUMP) {
if (fromnode->type == SH_NODE_BUMP) {
bNodeSocket *height_dx_sock, *height_dy_sock, *bump_socket, *bump_dx_socket, *bump_dy_socket;
bNode *bump = tonode;
bNode *bump = fromnode;
bump_socket = ntree_shader_node_find_input(bump, "Height");
bump_dx_socket = ntree_shader_node_find_input(bump, "Height_dx");
bump_dy_socket = ntree_shader_node_find_input(bump, "Height_dy");
@ -832,7 +832,7 @@ void ntree_shader_tag_nodes(bNodeTree *ntree, bNode *output_node, nTreeTags *tag
/* Make sure sockets links pointers are correct. */
ntreeUpdateTree(G.main, ntree);
nodeChainIterBackwards(ntree, output_node, ntree_tag_bsdf_cb, tags);
nodeChainIterBackwards(ntree, output_node, ntree_tag_bsdf_cb, tags, 0);
}
/* This one needs to work on a local tree. */
@ -861,7 +861,7 @@ void ntreeGPUMaterialNodes(bNodeTree *localtree,
/* Duplicate bump height branches for manual derivatives.
*/
nodeChainIterBackwards(localtree, output, ntree_shader_bump_branches, localtree);
nodeChainIterBackwards(localtree, output, ntree_shader_bump_branches, localtree, 0);
/* TODO(fclem): consider moving this to the gpu shader tree evaluation. */
nTreeTags tags = {