Shaders: add target setting to material output node.
This makes it possible to have a single shading nodetree that contains separate Cycles and Eevee shaders. By default the target is set to All so shaders are shared.
This commit is contained in:
@@ -17,7 +17,7 @@
|
|||||||
# <pep8 compliant>
|
# <pep8 compliant>
|
||||||
|
|
||||||
import bpy
|
import bpy
|
||||||
from bpy_extras.node_utils import find_node_input, find_output_node
|
from bpy_extras.node_utils import find_node_input
|
||||||
from bl_operators.presets import PresetMenu
|
from bl_operators.presets import PresetMenu
|
||||||
|
|
||||||
from bpy.types import (
|
from bpy.types import (
|
||||||
@@ -1069,14 +1069,14 @@ class CYCLES_OT_use_shading_nodes(Operator):
|
|||||||
return {'FINISHED'}
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
|
||||||
def panel_node_draw(layout, id_data, output_types, input_name):
|
def panel_node_draw(layout, id_data, output_type, input_name):
|
||||||
if not id_data.use_nodes:
|
if not id_data.use_nodes:
|
||||||
layout.operator("cycles.use_shading_nodes", icon='NODETREE')
|
layout.operator("cycles.use_shading_nodes", icon='NODETREE')
|
||||||
return False
|
return False
|
||||||
|
|
||||||
ntree = id_data.node_tree
|
ntree = id_data.node_tree
|
||||||
|
|
||||||
node = find_output_node(ntree, output_types)
|
node = ntree.get_output_node('CYCLES')
|
||||||
if node:
|
if node:
|
||||||
input = find_node_input(node, input_name)
|
input = find_node_input(node, input_name)
|
||||||
if input:
|
if input:
|
||||||
@@ -1176,7 +1176,7 @@ class CYCLES_LAMP_PT_nodes(CyclesButtonsPanel, Panel):
|
|||||||
layout = self.layout
|
layout = self.layout
|
||||||
|
|
||||||
lamp = context.lamp
|
lamp = context.lamp
|
||||||
if not panel_node_draw(layout, lamp, ('OUTPUT_LAMP',), 'Surface'):
|
if not panel_node_draw(layout, lamp, 'OUTPUT_LAMP', 'Surface'):
|
||||||
layout.prop(lamp, "color")
|
layout.prop(lamp, "color")
|
||||||
|
|
||||||
|
|
||||||
@@ -1226,7 +1226,7 @@ class CYCLES_WORLD_PT_surface(CyclesButtonsPanel, Panel):
|
|||||||
|
|
||||||
world = context.world
|
world = context.world
|
||||||
|
|
||||||
if not panel_node_draw(layout, world, ('OUTPUT_WORLD',), 'Surface'):
|
if not panel_node_draw(layout, world, 'OUTPUT_WORLD', 'Surface'):
|
||||||
layout.prop(world, "horizon_color", text="Color")
|
layout.prop(world, "horizon_color", text="Color")
|
||||||
|
|
||||||
|
|
||||||
@@ -1244,7 +1244,7 @@ class CYCLES_WORLD_PT_volume(CyclesButtonsPanel, Panel):
|
|||||||
layout = self.layout
|
layout = self.layout
|
||||||
|
|
||||||
world = context.world
|
world = context.world
|
||||||
panel_node_draw(layout, world, ('OUTPUT_WORLD',), 'Volume')
|
panel_node_draw(layout, world, 'OUTPUT_WORLD', 'Volume')
|
||||||
|
|
||||||
|
|
||||||
class CYCLES_WORLD_PT_ambient_occlusion(CyclesButtonsPanel, Panel):
|
class CYCLES_WORLD_PT_ambient_occlusion(CyclesButtonsPanel, Panel):
|
||||||
@@ -1425,7 +1425,7 @@ class CYCLES_MATERIAL_PT_surface(CyclesButtonsPanel, Panel):
|
|||||||
layout = self.layout
|
layout = self.layout
|
||||||
|
|
||||||
mat = context.material
|
mat = context.material
|
||||||
if not panel_node_draw(layout, mat, ('OUTPUT_MATERIAL', 'OUTPUT_EEVEE_MATERIAL'), 'Surface'):
|
if not panel_node_draw(layout, mat, 'OUTPUT_MATERIAL', 'Surface'):
|
||||||
layout.prop(mat, "diffuse_color")
|
layout.prop(mat, "diffuse_color")
|
||||||
|
|
||||||
|
|
||||||
@@ -1445,7 +1445,7 @@ class CYCLES_MATERIAL_PT_volume(CyclesButtonsPanel, Panel):
|
|||||||
mat = context.material
|
mat = context.material
|
||||||
# cmat = mat.cycles
|
# cmat = mat.cycles
|
||||||
|
|
||||||
panel_node_draw(layout, mat, ('OUTPUT_MATERIAL', 'OUTPUT_EEVEE_MATERIAL'), 'Volume')
|
panel_node_draw(layout, mat, 'OUTPUT_MATERIAL', 'Volume')
|
||||||
|
|
||||||
|
|
||||||
class CYCLES_MATERIAL_PT_displacement(CyclesButtonsPanel, Panel):
|
class CYCLES_MATERIAL_PT_displacement(CyclesButtonsPanel, Panel):
|
||||||
@@ -1461,7 +1461,7 @@ class CYCLES_MATERIAL_PT_displacement(CyclesButtonsPanel, Panel):
|
|||||||
layout = self.layout
|
layout = self.layout
|
||||||
|
|
||||||
mat = context.material
|
mat = context.material
|
||||||
panel_node_draw(layout, mat, ('OUTPUT_MATERIAL', 'OUTPUT_EEVEE_MATERIAL'), 'Displacement')
|
panel_node_draw(layout, mat, 'OUTPUT_MATERIAL', 'Displacement')
|
||||||
|
|
||||||
|
|
||||||
class CYCLES_MATERIAL_PT_settings(CyclesButtonsPanel, Panel):
|
class CYCLES_MATERIAL_PT_settings(CyclesButtonsPanel, Panel):
|
||||||
|
|||||||
@@ -1001,31 +1001,6 @@ static ShaderOutput *node_find_output_by_name(ShaderNode *node,
|
|||||||
return node->output(name.c_str());
|
return node->output(name.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
static BL::ShaderNode find_output_node(BL::ShaderNodeTree& b_ntree)
|
|
||||||
{
|
|
||||||
BL::ShaderNodeTree::nodes_iterator b_node;
|
|
||||||
BL::ShaderNode output_node(PointerRNA_NULL);
|
|
||||||
|
|
||||||
for(b_ntree.nodes.begin(b_node); b_node != b_ntree.nodes.end(); ++b_node) {
|
|
||||||
BL::ShaderNodeOutputMaterial b_output_node(*b_node);
|
|
||||||
|
|
||||||
if (b_output_node.is_a(&RNA_ShaderNodeOutputMaterial) ||
|
|
||||||
b_output_node.is_a(&RNA_ShaderNodeOutputWorld) ||
|
|
||||||
b_output_node.is_a(&RNA_ShaderNodeOutputLamp)) {
|
|
||||||
/* regular Cycles output node */
|
|
||||||
if(b_output_node.is_active_output()) {
|
|
||||||
output_node = b_output_node;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else if(!output_node.ptr.data) {
|
|
||||||
output_node = b_output_node;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return output_node;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void add_nodes(Scene *scene,
|
static void add_nodes(Scene *scene,
|
||||||
BL::RenderEngine& b_engine,
|
BL::RenderEngine& b_engine,
|
||||||
BL::BlendData& b_data,
|
BL::BlendData& b_data,
|
||||||
@@ -1045,7 +1020,7 @@ static void add_nodes(Scene *scene,
|
|||||||
BL::Node::outputs_iterator b_output;
|
BL::Node::outputs_iterator b_output;
|
||||||
|
|
||||||
/* find the node to use for output if there are multiple */
|
/* find the node to use for output if there are multiple */
|
||||||
BL::ShaderNode output_node = find_output_node(b_ntree);
|
BL::ShaderNode output_node = b_ntree.get_output_node(BL::ShaderNodeOutputMaterial::target_CYCLES);
|
||||||
|
|
||||||
/* add nodes */
|
/* add nodes */
|
||||||
for(b_ntree.nodes.begin(b_node); b_node != b_ntree.nodes.end(); ++b_node) {
|
for(b_ntree.nodes.begin(b_node); b_node != b_ntree.nodes.end(); ++b_node) {
|
||||||
|
|||||||
@@ -20,7 +20,6 @@
|
|||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
"find_node_input",
|
"find_node_input",
|
||||||
"find_output_node",
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -31,22 +30,3 @@ def find_node_input(node, name):
|
|||||||
return input
|
return input
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
# Return the output node to display in the UI. In case multiple node types are
|
|
||||||
# specified, node types earlier in the list get priority.
|
|
||||||
|
|
||||||
|
|
||||||
def find_output_node(ntree, nodetypes):
|
|
||||||
if ntree:
|
|
||||||
output_node = None
|
|
||||||
for nodetype in nodetypes:
|
|
||||||
for node in ntree.nodes:
|
|
||||||
if getattr(node, "type", None) == nodetype:
|
|
||||||
if getattr(node, "is_active_output", True):
|
|
||||||
return node
|
|
||||||
if not output_node:
|
|
||||||
output_node = node
|
|
||||||
if output_node:
|
|
||||||
return output_node
|
|
||||||
|
|
||||||
return None
|
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ import bpy
|
|||||||
from bpy.types import Menu, Panel, UIList
|
from bpy.types import Menu, Panel, UIList
|
||||||
from rna_prop_ui import PropertyPanel
|
from rna_prop_ui import PropertyPanel
|
||||||
from bpy.app.translations import pgettext_iface as iface_
|
from bpy.app.translations import pgettext_iface as iface_
|
||||||
from bpy_extras.node_utils import find_node_input, find_output_node
|
from bpy_extras.node_utils import find_node_input
|
||||||
|
|
||||||
|
|
||||||
class MATERIAL_MT_specials(Menu):
|
class MATERIAL_MT_specials(Menu):
|
||||||
@@ -140,7 +140,7 @@ class EEVEE_MATERIAL_PT_context_material(MaterialButtonsPanel, Panel):
|
|||||||
|
|
||||||
|
|
||||||
def panel_node_draw(layout, ntree, output_type):
|
def panel_node_draw(layout, ntree, output_type):
|
||||||
node = find_output_node(ntree, output_type)
|
node = ntree.get_output_node('EEVEE')
|
||||||
|
|
||||||
if node:
|
if node:
|
||||||
input = find_node_input(node, 'Surface')
|
input = find_node_input(node, 'Surface')
|
||||||
@@ -171,7 +171,7 @@ class EEVEE_MATERIAL_PT_surface(MaterialButtonsPanel, Panel):
|
|||||||
layout.separator()
|
layout.separator()
|
||||||
|
|
||||||
if mat.use_nodes:
|
if mat.use_nodes:
|
||||||
panel_node_draw(layout, mat.node_tree, ('OUTPUT_EEVEE_MATERIAL', 'OUTPUT_MATERIAL'))
|
panel_node_draw(layout, mat.node_tree, 'OUTPUT_MATERIAL')
|
||||||
else:
|
else:
|
||||||
layout.use_property_split = True
|
layout.use_property_split = True
|
||||||
layout.prop(mat, "diffuse_color", text="Base Color")
|
layout.prop(mat, "diffuse_color", text="Base Color")
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
import bpy
|
import bpy
|
||||||
from bpy.types import Panel
|
from bpy.types import Panel
|
||||||
from rna_prop_ui import PropertyPanel
|
from rna_prop_ui import PropertyPanel
|
||||||
from bpy_extras.node_utils import find_node_input, find_output_node
|
from bpy_extras.node_utils import find_node_input
|
||||||
|
|
||||||
|
|
||||||
class WorldButtonsPanel:
|
class WorldButtonsPanel:
|
||||||
@@ -109,7 +109,7 @@ class EEVEE_WORLD_PT_surface(WorldButtonsPanel, Panel):
|
|||||||
|
|
||||||
if world.use_nodes:
|
if world.use_nodes:
|
||||||
ntree = world.node_tree
|
ntree = world.node_tree
|
||||||
node = find_output_node(ntree, ('OUTPUT_WORLD',))
|
node = ntree.get_output_node('EEVEE')
|
||||||
|
|
||||||
if node:
|
if node:
|
||||||
input = find_node_input(node, 'Surface')
|
input = find_node_input(node, 'Surface')
|
||||||
|
|||||||
@@ -812,6 +812,7 @@ void BKE_nodetree_remove_layer_n(struct bNodeTree *ntree, struct Scene *scene, c
|
|||||||
struct bNodeTreeExec *ntreeShaderBeginExecTree(struct bNodeTree *ntree);
|
struct bNodeTreeExec *ntreeShaderBeginExecTree(struct bNodeTree *ntree);
|
||||||
void ntreeShaderEndExecTree(struct bNodeTreeExec *exec);
|
void ntreeShaderEndExecTree(struct bNodeTreeExec *exec);
|
||||||
bool ntreeShaderExecTree(struct bNodeTree *ntree, int thread);
|
bool ntreeShaderExecTree(struct bNodeTree *ntree, int thread);
|
||||||
|
struct bNode *ntreeShaderOutputNode(struct bNodeTree *ntree, int target);
|
||||||
|
|
||||||
void ntreeGPUMaterialNodes(struct bNodeTree *ntree, struct GPUMaterial *mat,
|
void ntreeGPUMaterialNodes(struct bNodeTree *ntree, struct GPUMaterial *mat,
|
||||||
bool *has_surface_output, bool *has_volume_output);
|
bool *has_surface_output, bool *has_volume_output);
|
||||||
|
|||||||
@@ -1066,6 +1066,11 @@ static void node_shader_buts_script_ex(uiLayout *layout, bContext *C, PointerRNA
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void node_buts_output_shader(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
|
||||||
|
{
|
||||||
|
uiItemR(layout, ptr, "target", 0, "", ICON_NONE);
|
||||||
|
}
|
||||||
|
|
||||||
static void node_buts_output_linestyle(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
|
static void node_buts_output_linestyle(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
|
||||||
{
|
{
|
||||||
uiLayout *row, *col;
|
uiLayout *row, *col;
|
||||||
@@ -1209,6 +1214,11 @@ static void node_shader_set_butfunc(bNodeType *ntype)
|
|||||||
case SH_NODE_UVALONGSTROKE:
|
case SH_NODE_UVALONGSTROKE:
|
||||||
ntype->draw_buttons = node_shader_buts_uvalongstroke;
|
ntype->draw_buttons = node_shader_buts_uvalongstroke;
|
||||||
break;
|
break;
|
||||||
|
case SH_NODE_OUTPUT_MATERIAL:
|
||||||
|
case SH_NODE_OUTPUT_LAMP:
|
||||||
|
case SH_NODE_OUTPUT_WORLD:
|
||||||
|
ntype->draw_buttons = node_buts_output_shader;
|
||||||
|
break;
|
||||||
case SH_NODE_OUTPUT_LINESTYLE:
|
case SH_NODE_OUTPUT_LINESTYLE:
|
||||||
ntype->draw_buttons = node_buts_output_linestyle;
|
ntype->draw_buttons = node_buts_output_linestyle;
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -1101,39 +1101,6 @@ enum {
|
|||||||
|
|
||||||
#define CMP_NODE_MASK_MBLUR_SAMPLES_MAX 64
|
#define CMP_NODE_MASK_MBLUR_SAMPLES_MAX 64
|
||||||
|
|
||||||
/* geometry output socket defines */
|
|
||||||
#define GEOM_OUT_GLOB 0
|
|
||||||
#define GEOM_OUT_LOCAL 1
|
|
||||||
#define GEOM_OUT_VIEW 2
|
|
||||||
#define GEOM_OUT_ORCO 3
|
|
||||||
#define GEOM_OUT_UV 4
|
|
||||||
#define GEOM_OUT_NORMAL 5
|
|
||||||
#define GEOM_OUT_VCOL 6
|
|
||||||
#define GEOM_OUT_VCOL_ALPHA 7
|
|
||||||
#define GEOM_OUT_FRONTBACK 8
|
|
||||||
|
|
||||||
/* material input socket defines */
|
|
||||||
#define MAT_IN_COLOR 0
|
|
||||||
#define MAT_IN_SPEC 1
|
|
||||||
#define MAT_IN_REFL 2
|
|
||||||
#define MAT_IN_NORMAL 3
|
|
||||||
#define MAT_IN_MIR 4
|
|
||||||
#define MAT_IN_AMB 5
|
|
||||||
#define MAT_IN_EMIT 6
|
|
||||||
#define MAT_IN_SPECTRA 7
|
|
||||||
#define MAT_IN_RAY_MIRROR 8
|
|
||||||
#define MAT_IN_ALPHA 9
|
|
||||||
#define MAT_IN_TRANSLUCENCY 10
|
|
||||||
#define NUM_MAT_IN 11 /* for array size */
|
|
||||||
|
|
||||||
/* material output socket defines */
|
|
||||||
#define MAT_OUT_COLOR 0
|
|
||||||
#define MAT_OUT_ALPHA 1
|
|
||||||
#define MAT_OUT_NORMAL 2
|
|
||||||
#define MAT_OUT_DIFFUSE 3
|
|
||||||
#define MAT_OUT_SPEC 4
|
|
||||||
#define MAT_OUT_AO 5
|
|
||||||
|
|
||||||
/* image */
|
/* image */
|
||||||
#define CMP_NODE_IMAGE_USE_STRAIGHT_OUTPUT 1
|
#define CMP_NODE_IMAGE_USE_STRAIGHT_OUTPUT 1
|
||||||
|
|
||||||
@@ -1176,4 +1143,12 @@ enum {
|
|||||||
SHD_POINTDENSITY_COLOR_VERTNOR = 2,
|
SHD_POINTDENSITY_COLOR_VERTNOR = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Output shader node */
|
||||||
|
|
||||||
|
typedef enum NodeShaderOutputTarget {
|
||||||
|
SHD_OUTPUT_ALL = 0,
|
||||||
|
SHD_OUTPUT_EEVEE = 1,
|
||||||
|
SHD_OUTPUT_CYCLES = 2,
|
||||||
|
} NodeShaderOutputTarget;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -175,6 +175,14 @@ static const EnumPropertyItem node_sampler_type_items[] = {
|
|||||||
{2, "BICUBIC", 0, "Bicubic", ""},
|
{2, "BICUBIC", 0, "Bicubic", ""},
|
||||||
{0, NULL, 0, NULL, NULL}
|
{0, NULL, 0, NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static const EnumPropertyItem prop_shader_output_target_items[] = {
|
||||||
|
{SHD_OUTPUT_ALL, "ALL", 0, "All", "Use shaders for all renderers and viewports, unless there exists a more specific output"},
|
||||||
|
{SHD_OUTPUT_EEVEE, "EEVEE", 0, "Eevee", "Use shaders for Eevee renderer"},
|
||||||
|
{SHD_OUTPUT_CYCLES, "CYCLES", 0, "Cycles", "Use shaders for Cycles renderer"},
|
||||||
|
{0, NULL, 0, NULL, NULL}
|
||||||
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef RNA_RUNTIME
|
#ifdef RNA_RUNTIME
|
||||||
@@ -3536,6 +3544,12 @@ static void def_sh_output(StructRNA *srna)
|
|||||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", NODE_DO_OUTPUT);
|
RNA_def_property_boolean_sdna(prop, NULL, "flag", NODE_DO_OUTPUT);
|
||||||
RNA_def_property_ui_text(prop, "Active Output", "True if this node is used as the active output");
|
RNA_def_property_ui_text(prop, "Active Output", "True if this node is used as the active output");
|
||||||
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
|
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
|
||||||
|
|
||||||
|
prop = RNA_def_property(srna, "target", PROP_ENUM, PROP_NONE);
|
||||||
|
RNA_def_property_enum_sdna(prop, NULL, "custom1");
|
||||||
|
RNA_def_property_enum_items(prop, prop_shader_output_target_items);
|
||||||
|
RNA_def_property_ui_text(prop, "Target", "Which renderer and viewport shading types to use the shaders for");
|
||||||
|
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void def_sh_output_linestyle(StructRNA *srna)
|
static void def_sh_output_linestyle(StructRNA *srna)
|
||||||
@@ -8377,12 +8391,21 @@ static void rna_def_composite_nodetree(BlenderRNA *brna)
|
|||||||
static void rna_def_shader_nodetree(BlenderRNA *brna)
|
static void rna_def_shader_nodetree(BlenderRNA *brna)
|
||||||
{
|
{
|
||||||
StructRNA *srna;
|
StructRNA *srna;
|
||||||
|
FunctionRNA *func;
|
||||||
|
PropertyRNA *parm;
|
||||||
|
|
||||||
srna = RNA_def_struct(brna, "ShaderNodeTree", "NodeTree");
|
srna = RNA_def_struct(brna, "ShaderNodeTree", "NodeTree");
|
||||||
RNA_def_struct_ui_text(srna, "Shader Node Tree",
|
RNA_def_struct_ui_text(srna, "Shader Node Tree",
|
||||||
"Node tree consisting of linked nodes used for materials (and other shading data-blocks)");
|
"Node tree consisting of linked nodes used for materials (and other shading data-blocks)");
|
||||||
RNA_def_struct_sdna(srna, "bNodeTree");
|
RNA_def_struct_sdna(srna, "bNodeTree");
|
||||||
RNA_def_struct_ui_icon(srna, ICON_MATERIAL);
|
RNA_def_struct_ui_icon(srna, ICON_MATERIAL);
|
||||||
|
|
||||||
|
func = RNA_def_function(srna, "get_output_node", "ntreeShaderOutputNode");
|
||||||
|
RNA_def_function_ui_description(func, "Return active shader output node for the specified target");
|
||||||
|
parm = RNA_def_enum(func, "target", prop_shader_output_target_items, SHD_OUTPUT_ALL, "Target", "");
|
||||||
|
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
|
||||||
|
parm = RNA_def_pointer(func, "node", "ShaderNode", "Node", "");
|
||||||
|
RNA_def_function_return(func, parm);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rna_def_texture_nodetree(BlenderRNA *brna)
|
static void rna_def_texture_nodetree(BlenderRNA *brna)
|
||||||
|
|||||||
@@ -209,20 +209,52 @@ static void ntree_shader_link_builtin_normal(bNodeTree *ntree,
|
|||||||
* render engines works but it's how the GPU shader compilation works. This we
|
* render engines works but it's how the GPU shader compilation works. This we
|
||||||
* can change in the future and make it a generic function, but for now it stays
|
* can change in the future and make it a generic function, but for now it stays
|
||||||
* private here.
|
* private here.
|
||||||
*
|
|
||||||
* It also does not yet take into account render engine specific output nodes,
|
|
||||||
* it should give priority to e.g. the Eevee material output node for Eevee.
|
|
||||||
*/
|
*/
|
||||||
static bNode *ntree_shader_output_node(bNodeTree *ntree)
|
bNode *ntreeShaderOutputNode(bNodeTree *ntree, int target)
|
||||||
{
|
{
|
||||||
/* Make sure we only have single node tagged as output. */
|
/* Make sure we only have single node tagged as output. */
|
||||||
ntreeSetOutput(ntree);
|
ntreeSetOutput(ntree);
|
||||||
for (bNode *node = ntree->nodes.first; node != NULL; node = node->next) {
|
|
||||||
if (node->flag & NODE_DO_OUTPUT) {
|
/* Find output node that matches type and target. If there are
|
||||||
return node;
|
* multiple, we prefer exact target match and active nodes. */
|
||||||
|
bNode *output_node = NULL;
|
||||||
|
|
||||||
|
for (bNode *node = ntree->nodes.first; node; node = node->next) {
|
||||||
|
if (!ELEM(node->type, SH_NODE_OUTPUT_MATERIAL,
|
||||||
|
SH_NODE_OUTPUT_WORLD,
|
||||||
|
SH_NODE_OUTPUT_LAMP))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node->custom1 == SHD_OUTPUT_ALL) {
|
||||||
|
if (output_node == NULL) {
|
||||||
|
output_node = node;
|
||||||
|
}
|
||||||
|
else if (output_node->custom1 == SHD_OUTPUT_ALL) {
|
||||||
|
if ((node->flag & NODE_DO_OUTPUT) &&
|
||||||
|
!(output_node->flag & NODE_DO_OUTPUT))
|
||||||
|
{
|
||||||
|
output_node = node;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NULL;
|
}
|
||||||
|
else if (node->custom1 == target) {
|
||||||
|
if (output_node == NULL) {
|
||||||
|
output_node = node;
|
||||||
|
}
|
||||||
|
else if(output_node->custom1 == SHD_OUTPUT_ALL) {
|
||||||
|
output_node = node;
|
||||||
|
}
|
||||||
|
else if ((node->flag & NODE_DO_OUTPUT) &&
|
||||||
|
!(output_node->flag & NODE_DO_OUTPUT))
|
||||||
|
{
|
||||||
|
output_node = node;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return output_node;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Find socket with a specified identifier. */
|
/* Find socket with a specified identifier. */
|
||||||
@@ -555,7 +587,7 @@ void ntreeGPUMaterialNodes(bNodeTree *ntree, GPUMaterial *mat, bool *has_surface
|
|||||||
{
|
{
|
||||||
/* localize tree to create links for reroute and mute */
|
/* localize tree to create links for reroute and mute */
|
||||||
bNodeTree *localtree = ntreeLocalize(ntree);
|
bNodeTree *localtree = ntreeLocalize(ntree);
|
||||||
bNode *output = ntree_shader_output_node(localtree);
|
bNode *output = ntreeShaderOutputNode(localtree, SHD_OUTPUT_EEVEE);
|
||||||
bNodeTreeExec *exec;
|
bNodeTreeExec *exec;
|
||||||
|
|
||||||
/* Perform all needed modifications on the tree in order to support
|
/* Perform all needed modifications on the tree in order to support
|
||||||
|
|||||||
Reference in New Issue
Block a user