How useful could be a Material Input node?

Following the lines of how nodegroups work, what if a whole “material” shading nodetree was a ‘‘meta’’ nodegroup?

Like this:

image

As if it was an input group, this node would provide Shader, Volume Shader and Displacement data from an existing material, to be used at will into any material.
This would be sooo handy when you want to mix two or more already done/estabilished materials (ie from a mat-library), into a new one. Think of a rusted metal: you already have the two shaders; no need to encapsulate them into nodegroups, or to copy-paste nodes from tree to tree, you just call the shaders into the new one and mix them at will.

Or you can use this to build up on a material, for example changing only the displacement. Or adding shaders (ie a coatlayer), volume or whatever. Again, no need to rearrange previous materials in nodegroups. No duplicated nodetrees. Just import all your material outputs into another one!

Of course the material Input node shouldn’t allow cross-reference between materials. Only actual linkable materials in the drop-down menu should be shown.

The idea could be extended with the ability to plug any wire into the Output Material node, just as it happens in nodegroups.

image

So any data could be tranferred in any other material. Directly pointing at them in the source nodetree. There could be even a dedicated panel in the sidebar to rearrange and rename this AOVs, very similar to what we have for nodegroups.

14 Likes

This is the idea of the century. No more bundling entire materials into node groups for re-use. But how to avoid dependency cycles ? -> what if material A references material B, but material B contains itself a reference to material A ?

This should be managed automatically, and if I am not wrong Blender already does it with nodegroups: you are not allowed to do “cyclic relationships”

1 Like

Ah, right. I don’t know how this works.

Thousand times yes.
I even made a semi-popular right-click-select post about it here: https://blender.community/c/rightclickselect/TTdbbc/

1 Like

Yep I voted that.
I actually built one of mine on the shoulders of your idea (after digesting it) :wink:

Current design allows to create several outputs per material.
We have an AOV output and a material output node that can be only used by EEVEE or Cycles or can be used by both.

IMO, Node Properties panel would not be needed if we could simply precise output node from indicated material.
That way, we could exploit that for materials containing one nodetree for EEVEE and one nodetree for Cycles without confusion.
Otherwise, that situation would be problematic.
Sockets would be duplicated or one output would be ignored and the other one used, without any indication of which one is really used.

1 Like

Yes it could be a solution for some caveats. How do you think this could work? A drop down menu? A text-field as in Attribute node?

Yes. I would use a text-field as in Attribute node to identify Output node.

Mmm… But then how would you precisely point to a specific output?
Say you have two principled Bsdf pointing to two outputs, one cycles and one Eevee. What name should you write in the text field?

I think this is not difficult to implement… Would this node access only the materials present in the blend file, or do you want to have some kind of external library?
Also, having this as nodegroups would give you the possibility to add inputs to your material nodetree, since you then can design the material’s interface through the GroupIO nodes.

I think it should work also with linked datablocks

The idea is to add ‘‘outputs’’ that you can later find listed in the Material Input node (or @RonanDucluzeau’s Material Attribute node).

I don’t think that is a good idea to let the user link wires to the Material Input node,as you can do with nodegroups. First you won’t be able to do that for external libraries. Second I like the idea that a material is “set in stone” and can be explicitly changed only when it is directly edited in the nodetree.

Just a preliminary test…

This required a bit of python, since NodeGroupOutput isn’t available in the AddNode menu (for materials), and the ShaderNodeGroup don’t look up to materials’ node_trees.
But still, it works without any problem.

All I did was to add a GroupOutput to the material_A, and setup as in a normal nodegroup.

bpy.data.materials['Material_A'].node_tree.nodes.new("NodeGroupOutput")

In the Material_B, add a ShaderNodeGroup, and set its node_tree to point to Material_A.node_tree.

gnode = bpy.data.materials['Material_B'].node_tree.nodes.new("ShaderNodeGroup")
gnode.node_tree = bpy.data.materials['Material_A'].node_tree
1 Like

I made a custom node group that did same thing.

1 Like

Nice test but:
the whole point is to not need to set anything in material A. The “surface” output you had to link to the group output is a thing that shouldn’t be needed. The ShaderNodeGroup should have access to the same green-dot output, without any pre-work. That’s how the user could link libraries without worries

This only shows that it’s possible.
Now, for a good implementation, all we need to do is to treat ‘MaterialOutput’ nodes as ‘NodeGroupOutput’, and add some method to look for node_trees in materials instead of just using blenddata.node_groups.

It’s also possible to do a copy on_the_fly of the materials’ node_tree, and just add NodeGroupOutput just for the instanced material nodes. (that can be done just with python, and I suspect that was what @AFWS did)

That’s also a nice start.
I start to wonder if this “instanced material node” could be useful enough as a feature, leaving the whole AOV stuff as an additional side feature. In other words, maybe it’s just the matter of adding “AOV Input” to the shader add menu, complementar of the AOV Output, which already exists.

1 Like

Currently, in material output node, we have a list saying (All, EEVEE, Cycles).
You just add an item “Meta Material” to this list and a text field to name your material output node.
Or you create a new type of output nodes : a metamaterial output node. (what Secrop did in his test.)

Then, in a Material Input node of a Meta Material, you just need to precise name of material and name of output node.
Like in compositing nodes, a Renderlayer node is requesting a Scene name and a View Layer name.

Why should an implementation be made so clumsy? Why not having an “Input Material” node that just can retrieve all nodes from another material? The coer of the point here is: not having the need of making changes in the original material, neither adjustments to use it as “meta”.
It should just work whenever, and wherever, summoned.

The idea is just to be able to create different nodetrees for EEVEE and Cycles.

If you have a complex nodetree that will only work in Cycles and unfornately provide something ugly in EEVEE. You may care about producing a simple but good looking nodetree for EEVEE.
In that case, your material contains 2 outputs.

Then, if you want to use that material as an input in another one, you have to provide a way to define what output to use as an input.

We could have a text field to precise output with ability to keep it blank when there is only one material output node in material.
The same way, that an UVmap node works when text field indicating UV channel to use stays blank. It works when there is only one UVmap. Or it uses active one until user indicates another one to use.