forked from bartvdbraak/blender
Render: make Cycles and Evee support each other's output material nodes.
This changes the Cycles exporting and Cycles/Eevee UI code to support both output material nodes, giving priority to the renderer native one. Still missing is Eevee code to prefer the Eevee output node.
This commit is contained in:
parent
110d6832a8
commit
c42c129393
@ -899,19 +899,22 @@ class CYCLES_OT_use_shading_nodes(Operator):
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
def panel_node_draw(layout, id_data, output_type, input_name):
|
||||
def panel_node_draw(layout, id_data, output_types, input_name):
|
||||
if not id_data.use_nodes:
|
||||
layout.operator("cycles.use_shading_nodes", icon='NODETREE')
|
||||
return False
|
||||
|
||||
ntree = id_data.node_tree
|
||||
|
||||
node = find_output_node(ntree, output_type)
|
||||
if not node:
|
||||
layout.label(text="No output node")
|
||||
else:
|
||||
node = find_output_node(ntree, output_types)
|
||||
if node:
|
||||
input = find_node_input(node, input_name)
|
||||
layout.template_node_view(ntree, node, input)
|
||||
if input:
|
||||
layout.template_node_view(ntree, node, input)
|
||||
else:
|
||||
layout.label(text="Incompatible output node")
|
||||
else:
|
||||
layout.label(text="No output node")
|
||||
|
||||
return True
|
||||
|
||||
@ -1000,7 +1003,7 @@ class CyclesLamp_PT_nodes(CyclesButtonsPanel, Panel):
|
||||
layout = self.layout
|
||||
|
||||
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")
|
||||
|
||||
|
||||
@ -1055,7 +1058,7 @@ class CyclesWorld_PT_surface(CyclesButtonsPanel, Panel):
|
||||
|
||||
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")
|
||||
|
||||
|
||||
@ -1073,7 +1076,7 @@ class CyclesWorld_PT_volume(CyclesButtonsPanel, Panel):
|
||||
layout = self.layout
|
||||
|
||||
world = context.world
|
||||
panel_node_draw(layout, world, 'OUTPUT_WORLD', 'Volume')
|
||||
panel_node_draw(layout, world, ['OUTPUT_WORLD'], 'Volume')
|
||||
|
||||
|
||||
class CyclesWorld_PT_ambient_occlusion(CyclesButtonsPanel, Panel):
|
||||
@ -1218,7 +1221,7 @@ class CyclesMaterial_PT_surface(CyclesButtonsPanel, Panel):
|
||||
layout = self.layout
|
||||
|
||||
mat = context.material
|
||||
if not panel_node_draw(layout, mat, 'OUTPUT_MATERIAL', 'Surface'):
|
||||
if not panel_node_draw(layout, mat, ['OUTPUT_MATERIAL', 'OUTPUT_EEVEE_MATERIAL'], 'Surface'):
|
||||
layout.prop(mat, "diffuse_color")
|
||||
|
||||
|
||||
@ -1238,7 +1241,7 @@ class CyclesMaterial_PT_volume(CyclesButtonsPanel, Panel):
|
||||
mat = context.material
|
||||
# cmat = mat.cycles
|
||||
|
||||
panel_node_draw(layout, mat, 'OUTPUT_MATERIAL', 'Volume')
|
||||
panel_node_draw(layout, mat, ['OUTPUT_MATERIAL', 'OUTPUT_EEVEE_MATERIAL'], 'Volume')
|
||||
|
||||
|
||||
class CyclesMaterial_PT_displacement(CyclesButtonsPanel, Panel):
|
||||
@ -1254,7 +1257,7 @@ class CyclesMaterial_PT_displacement(CyclesButtonsPanel, Panel):
|
||||
layout = self.layout
|
||||
|
||||
mat = context.material
|
||||
panel_node_draw(layout, mat, 'OUTPUT_MATERIAL', 'Displacement')
|
||||
panel_node_draw(layout, mat, ['OUTPUT_MATERIAL', 'OUTPUT_EEVEE_MATERIAL'], 'Displacement')
|
||||
|
||||
|
||||
class CyclesMaterial_PT_settings(CyclesButtonsPanel, Panel):
|
||||
|
@ -231,14 +231,6 @@ static void get_tex_mapping(TextureMapping *mapping,
|
||||
mapping->max = get_float3(b_mapping.max());
|
||||
}
|
||||
|
||||
static bool is_output_node(BL::Node& b_node)
|
||||
{
|
||||
return (b_node.is_a(&RNA_ShaderNodeOutputMaterial)
|
||||
|| b_node.is_a(&RNA_ShaderNodeOutputWorld)
|
||||
|| b_node.is_a(&RNA_ShaderNodeOutputLamp)
|
||||
|| b_node.is_a(&RNA_ShaderNodeOutputEeveeMaterial));
|
||||
}
|
||||
|
||||
static ShaderNode *add_node(Scene *scene,
|
||||
BL::RenderEngine& b_engine,
|
||||
BL::BlendData& b_data,
|
||||
@ -951,6 +943,42 @@ static ShaderOutput *node_find_output_by_name(ShaderNode *node,
|
||||
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);
|
||||
BL::ShaderNode eevee_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;
|
||||
}
|
||||
}
|
||||
else if (b_output_node.is_a(&RNA_ShaderNodeOutputEeveeMaterial)) {
|
||||
/* Eevee output used if no Cycles node exists */
|
||||
if(b_output_node.is_active_output()) {
|
||||
eevee_output_node = b_output_node;
|
||||
}
|
||||
else if(!eevee_output_node.ptr.data) {
|
||||
eevee_output_node = b_output_node;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return (output_node.ptr.data) ? output_node : eevee_output_node;
|
||||
}
|
||||
|
||||
static void add_nodes(Scene *scene,
|
||||
BL::RenderEngine& b_engine,
|
||||
BL::BlendData& b_data,
|
||||
@ -971,23 +999,7 @@ static void add_nodes(Scene *scene,
|
||||
BL::Node::outputs_iterator b_output;
|
||||
|
||||
/* find the node to use for output if there are multiple */
|
||||
bool found_active_output = false;
|
||||
BL::ShaderNode output_node(PointerRNA_NULL);
|
||||
|
||||
for(b_ntree.nodes.begin(b_node); b_node != b_ntree.nodes.end(); ++b_node) {
|
||||
if(is_output_node(*b_node)) {
|
||||
BL::ShaderNodeOutputMaterial b_output_node(*b_node);
|
||||
|
||||
if(b_output_node.is_active_output()) {
|
||||
output_node = b_output_node;
|
||||
found_active_output = true;
|
||||
break;
|
||||
}
|
||||
else if(!output_node.ptr.data && !found_active_output) {
|
||||
output_node = b_output_node;
|
||||
}
|
||||
}
|
||||
}
|
||||
BL::ShaderNode output_node = find_output_node(b_ntree);
|
||||
|
||||
/* add nodes */
|
||||
for(b_ntree.nodes.begin(b_node); b_node != b_ntree.nodes.end(); ++b_node) {
|
||||
@ -1085,10 +1097,8 @@ static void add_nodes(Scene *scene,
|
||||
else {
|
||||
ShaderNode *node = NULL;
|
||||
|
||||
if(is_output_node(*b_node)) {
|
||||
if(b_node->ptr.data == output_node.ptr.data) {
|
||||
node = graph->output();
|
||||
}
|
||||
if(b_node->ptr.data == output_node.ptr.data) {
|
||||
node = graph->output();
|
||||
}
|
||||
else {
|
||||
BL::ShaderNode b_shader_node(*b_node);
|
||||
|
@ -32,16 +32,19 @@ def find_node_input(node, name):
|
||||
|
||||
return None
|
||||
|
||||
# Return the output node to display in the UI
|
||||
def find_output_node(ntree, nodetype):
|
||||
# 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:
|
||||
active_output_node = None
|
||||
for node in ntree.nodes:
|
||||
if getattr(node, "type", None) == nodetype:
|
||||
if getattr(node, "is_active_output", True):
|
||||
return node
|
||||
if not active_output_node:
|
||||
active_output_node = node
|
||||
return active_output_node
|
||||
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
|
||||
|
@ -1120,10 +1120,12 @@ def panel_node_draw(layout, ntree, output_type):
|
||||
|
||||
if node:
|
||||
input = find_node_input(node, 'Surface')
|
||||
layout.template_node_view(ntree, node, input)
|
||||
return True
|
||||
|
||||
return False
|
||||
if input:
|
||||
layout.template_node_view(ntree, node, input)
|
||||
else:
|
||||
layout.label(text="Incompatible output node")
|
||||
else:
|
||||
layout.label(text="No output node")
|
||||
|
||||
|
||||
class EEVEE_MATERIAL_PT_surface(MaterialButtonsPanel, Panel):
|
||||
@ -1145,8 +1147,7 @@ class EEVEE_MATERIAL_PT_surface(MaterialButtonsPanel, Panel):
|
||||
layout.separator()
|
||||
|
||||
if mat.use_nodes:
|
||||
if not panel_node_draw(layout, mat.node_tree, 'OUTPUT_EEVEE_MATERIAL'):
|
||||
layout.label(text="No output node")
|
||||
panel_node_draw(layout, mat.node_tree, ['OUTPUT_EEVEE_MATERIAL', 'OUTPUT_MATERIAL'])
|
||||
else:
|
||||
raym = mat.raytrace_mirror
|
||||
layout.prop(mat, "diffuse_color", text="Base Color")
|
||||
|
@ -270,13 +270,16 @@ class EEVEE_WORLD_PT_surface(WorldButtonsPanel, Panel):
|
||||
|
||||
if world.use_nodes:
|
||||
ntree = world.node_tree
|
||||
node = find_output_node(ntree, 'OUTPUT_WORLD')
|
||||
node = find_output_node(ntree, ['OUTPUT_WORLD'])
|
||||
|
||||
if not node:
|
||||
layout.label(text="No output node")
|
||||
else:
|
||||
if node:
|
||||
input = find_node_input(node, 'Surface')
|
||||
layout.template_node_view(ntree, node, input)
|
||||
if input:
|
||||
layout.template_node_view(ntree, node, input)
|
||||
else:
|
||||
layout.label(text="Incompatible output node")
|
||||
else:
|
||||
layout.label(text="No output node")
|
||||
else:
|
||||
layout.prop(world, "horizon_color", text="Color")
|
||||
|
||||
|
@ -214,6 +214,9 @@ static void ntree_shader_link_builtin_normal(bNodeTree *ntree,
|
||||
* 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
|
||||
* 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)
|
||||
{
|
||||
|
@ -42,10 +42,6 @@ static int node_shader_gpu_output_material(GPUMaterial *mat, bNode *node, bNodeE
|
||||
{
|
||||
GPUNodeLink *outlink;
|
||||
|
||||
if (BKE_scene_uses_blender_eevee(GPU_material_scene(mat))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
GPU_stack_link(mat, node, "node_output_material", in, out, &outlink);
|
||||
GPU_material_output_link(mat, outlink);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user