[Bf-committers] Proposal for unifying nodes

Nathan Vegdahl cessen at cessen.com
Tue Jun 16 11:32:52 CEST 2009

> back.  Similar things could be done for any node type in any tree: as
> long as you can decompose it into scalars, conversion is possible.  We

   Ack, I meant: "as long as you can decompose data into scalars...".
Data, not the node itself.

   (I shouldn't write emails at odd hours of the morning...)

--Nathan V

On Tue, Jun 16, 2009 at 2:26 AM, Nathan Vegdahl<cessen at cessen.com> wrote:
>> Tree types is something you can't avoid in my opinion. To me the purpose
>> of unification would be to share nodes between tree types, not to allow
>> all nodes in all tree types.
>   Maybe.  What the tree types really do, IMO, is simply tell Blender
> how to use the tree.
>   Fundamentally all data can be decomposed into scalars of some sort
> or another.  Which means that, for example, if we had a "constraint
> nodes tree" we could still use compositing nodes in them as long as we
> could, for example, convert a vector into a 1x3 gray-scale bitmap and
> back.  Similar things could be done for any node type in any tree: as
> long as you can decompose it into scalars, conversion is possible.  We
> just need sufficient data-conversion nodes, and then all nodes can be
> used everywhere.
>   So ultimately the "type" of the tree just tells Blender what
> context to use it in.  The context does place some restrictions, but
> they're restrictions on the contextual data available (texture
> coordinates, for example), and the data types of the outputs of the
> tree.  None of the restrictions have to do with the "normal"
> functional nodes that just take input and produce output.
>   So unification of the node trees in that sense makes a lot of sense
> to me, and I could see it being really powerful.  Potentially it also
> means that (as in the proposal, but with some restrictions) entire
> trees could be used as nodes in other trees (even of differing types),
> because they simply take input and produce output, just like nodes.
>   What I *don't* see is how passing functions through the node
> networks--instead of passing data--generalizes or helps anything.
>   If anything I see the shift towards "functions as data" as forcing
> even more separation between tree types, rather than unifying them.
> If everything is data, then everything can be much more easily unified
> and shared between trees.
>   Passing functions instead of data also makes a lot of things
> implicit in the trees instead of explicit, which IMO is an extremely
> bad thing.  For example, in the current texture nodes, texture
> coordinates are both implicit as inputs to the whole tree and
> implicitly passed downstream to later nodes.  And that's ultimately
> because those coordinates are treated as inputs of the function object
> being passed along.  The user never sees the coordinates, even though
> they are a core part of how textures work, and would be powerful to be
> able to manipulate directly as data (for example, passing them through
> a compositing node for kicks).
>   Lastly, it's confusing as hell to have nodes--which are very much
> functions themselves--processing and passing other functions.  I can
> imagine myself tearing a lot of hair out trying trouble-shoot issues
> resulting from that.
>   All I see in the "functions-as-data" paradigm is limitations,
> increased categorization, and user confusing.  Not freedom and
> unification, and user clarity.
>   IMO nodes should remain data-based.
> --Nathan V
> On Mon, Jun 15, 2009 at 12:40 PM, Brecht Van Lommel<brecht at blender.org> wrote:
>> Hi Robin,
>> I think this is a matter of preference for a large part, but just want
>> to point out a few more subtle consequences of passing texture
>> functions.
>> First is the case where the node tree is not an actual tree but a graph.
>> If a node output is used by two or more nodes, it would be good to not
>> execute that node twice. As I understand it, the texture nodes
>> implementation currently executes it twice, but I may be wrong here. It
>> is of course fixable (though with functions the result of that first
>> node are not necessarily the same each time, so need to do it only when
>> possible).
>> On Mon, 2009-06-15 at 17:35 +0100, Robin Allen wrote:
>>> 2009/6/15 Brecht Van Lommel <brecht at blender.org>:
>>> > This is also possible, if you apply these operations to texture
>>> > coordinates and input them into image or procedural textures.
>>> > A texture node tree could have a special node that gives you the default
>>> > texture coordinate. Furthermore, the inputs of image or procedural
>>> > textures coordinate input would use the default texture coordinate if it
>>> > is not linked to anything.
>>> You see, now you're splitting up the tree types again. A texture node
>>> tree would have this special node, it would have a 'default
>>> coordinate', whereas other tree types wouldn't. I'm not saying that
>>> wouldn't work, I'm saying it doesn't get us anywhere, we still end up
>>> with split trees which are demonstrably underpowered.
>> Tree types is something you can't avoid in my opinion. To me the purpose
>> of unification would be to share nodes between tree types, not to allow
>> all nodes in all tree types.
>> A shader Geometry or Lighting node makes no sense without a shading
>> context, nor can you place a modifier node in a shader or particle node
>> tree. This kind of restriction you have to deal with in any design.
>>> > For compositing nodes, I can see the advantage of passing along
>>> > functions, then they naturally fit in a single node tree. For shader
>>> > nodes I don't see a problem.
>>> >
>>> > But, even though it unifies one thing, the effect is also that it is
>>> > inconsistent in another way. Now you need two nodes for e.g. rotation,
>>> > one working on texture functions, and another on vectors (modifier
>>> > nodes). And further, these nodes need to placed in the tree in a
>>> > different order, one after, and another before the thing you want to
>>> > rotate.
>>> Hmm, I think there may be a misunderstanding here. Nothing would have
>>> to be placed before the thing it modifies. The rotate texture node
>>> would take in a Texture, an Axis and an Angle, and output a Texture.
>>> The fact that the texture it outputs would be a function calling its
>>> input texture with modified coordinates wouldn't even be apparent to
>>> the user.
>> Being placed before the thing it modifies I guess is a matter of
>> terminology, but let me be more clear on what I mean by differences in
>> ordering. As I understand the texture nodes code, currently the texture
>> manipulation runs in reverse order compared to shading nodes (while
>> color manipulation runs in the same order). Example that at first sight
>> seems to give the same result, but is actually different:
>> shading nodes: geom orco -> rotate X -> rotate Y -> texture voronoi
>> evalualted as: voronoi(rY(rX(orco)))
>> texture nodes: voronoi -> rotate X -> rotate Y (mapped to orco)
>> evaluated as: voronoi(rX(rY(orco)))
>> The shading nodes example may not be a great one because you want to add
>> ShaderCallData there too, but consider for example two rotate nodes
>> manipulating a vector which is then input in a modifier node.
>> The order of texture nodes can however be reversed, if you go over the
>> nodes in two passes.
>>> Likewise, vector rotate would take in a vector, axis and angle and
>>> output a vector.
>>> In fact, thinking about it now, the fact that rotating textures and
>>> vectors would still be different nodes in the new system is solvable.
>>> In the same way that anything applicable to a color is applicable to a
>>> texture: anything applicable to a vector is applicable to a texture
>>> simply by modifying its coordinates. So using the same implicit
>>> conversion I proposed which converts operations on colors to
>>> operations on textures, one could trivially implement a similar
>>> conversion allowing any operation on a vector to be used on a texture.
>>> So, instead of modifying the texture function's output (a color) we
>>> modify its input (a vector).
>>> More generally, we extend my proposed implicit conversion rule
>>> (A -> B) -> ((Q -> A) -> (Q -> B))
>>> to also perform the conversion
>>> (A -> B) -> ((A -> Q) -> (B -> Q))
>>> The specific case in question being
>>> (vector -> vector) -> ((vector -> color) -> (vector -> color))
>>> As you can see, since (vector -> color) is the type of a texture, this
>>> means any operation taking and returning vectors can also work on
>>> textures.
>> OK, implicit conversions go a long way to unifying such nodes, I agree.
>> How would you drive for example specularity with a texture in the
>> shading nodes (or velocity in particle nodes)? Can you link up those two
>> directly, using perhaps orco texture coordinates by default? Or do you
>> add a node inbetween which takes that texture function + coordinate to
>> do the conversion?
>> Another thing that is not clear to me is ShaderCallData. With texture
>> nodes you're passing a function which takes a coordinate as input, what
>> does the shader function take as input? It doesn't make much sense to
>> rotate a shader result I guess, what does that rotate, the point,
>> normal, tangent? So you don't pass along shader functions, and it stays
>> basically the same?
>>> Now, even if this wasn't true and the implicit conversion couldn't be
>>> implemented (which it could), the new system would still unify all the
>>> different versions of the common nodes like Math and Invert, each of
>>> which there currently has three different implementations, one for
>>> each tree. Good luck modifying the Math node once we have five tree
>>> types.
>> I'm not proposing to keep the nodes separated per tree type, only a
>> subset of nodes would be tied to tree types, Math nodes would not be one
>> of those.
>> Anyways, I can see that it would be cool to mix texture nodes with
>> modifier nodes for displacement for example, and that this is only
>> possible when passing functions. I'm just not sure I like all the
>> consequences.
>> Brecht.
>> _______________________________________________
>> Bf-committers mailing list
>> Bf-committers at blender.org
>> http://lists.blender.org/mailman/listinfo/bf-committers

More information about the Bf-committers mailing list