LuxCoreRender / BlendLuxCore

Blender Integration for LuxCore
GNU General Public License v3.0
727 stars 91 forks source link

Inserted keyframes in material node graph don't show up in graph editor or anywhere else #167

Open novacrazy opened 6 years ago

novacrazy commented 6 years ago

Description

I've been trying to animate some material properties from the node graph, and while I can add keyframes to node fields (like animating opacity), they simply don't show up in the graph editor or dope sheet like they would for Cycles and so forth.

Unfortunately, this also forces the default (non-linear) interpolation between those keyframes.

System Information

Windows 10 Pro with GTX 970 GPU

Software Version

Related:

--- Want to back this issue? **[Post a bounty on it!](https://www.bountysource.com/issues/58903562-inserted-keyframes-in-material-node-graph-don-t-show-up-in-graph-editor-or-anywhere-else?utm_campaign=plugin&utm_content=tracker%2F80143047&utm_medium=issues&utm_source=github)** We accept bounties via [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F80143047&utm_medium=issues&utm_source=github).
Theverat commented 6 years ago

Unfortunately, this is a Blender limitation. All addons with custom nodes are affected (e.g. Sverchok, Animation Nodes).

novacrazy commented 6 years ago

Dang, that's a bummer. Has there been any activity in Blender 2.8 that would allow for third-party node animations?

Theverat commented 6 years ago

I haven't seen any, but I don't follow the development too closely. You could try to ask in their developer IRC or so.

I added some related bug reports/questions to your first post.

novacrazy commented 6 years ago

Would it be feasible to add support for getting basic transform properties of objects from the material graph as scalar or vector/color values? For example the object scale as a color or 3D vector, or the X position as a scalar.

That would give us a few animatable controls for materials until Blender figures their stuff out on this.

Theverat commented 6 years ago

What you can do if you know a little Python is something like the following:

scrn_2018-06-02_11-06-06

import bpy
from bpy.app.handlers import persistent

@persistent
def handler(scene):
    node_tree = bpy.data.node_groups["Material.004"]
    matte = node_tree.nodes["Matte Material"]

    frame = scene.frame_current
    matte.inputs["Opacity"].default_value = frame / 100

def register():
    bpy.app.handlers.frame_change_post.append(handler)

def unregister():
    bpy.app.handlers.frame_change_post.remove(handler)

if __name__ == "__main__":
    register()

Another idea is: I could create a node that outputs the current frame, and you can then work with this with the math nodes (however they are a bit limited at the moment). This node could also be more general: allowing access to any property of any datablock.

novacrazy commented 6 years ago

That’s way too hardcoded for my taste. I’d prefer to be able to control values via the graph editor ideally.

A node which could select an object (like how the smoke data node allows you to select the domain), and extract transform values would be a functional workaround to animate arbitrary properties by animating those transforms.

Edit: I might just fork this and experiment this weekend with workarounds.

Theverat commented 6 years ago

A node which could select an object (like how the smoke data node allows you to select the domain), and extract transform values would be a functional workaround to animate arbitrary properties by animating those transforms.

Yes, this is possible with the "more general" version of the node I mentioned:

This node could also be more general: allowing access to any property of any datablock.

The datablock could be an object, a scene, image etc.

Theverat commented 6 years ago

I have an initial draft working, however it still needs some refinement. For example, it seems like PointerProperty only allows to store one kind of subclass of ID: https://docs.blender.org/api/2.79/bpy.types.ID.html#bpy.types.ID Not any subclass. So currently you can only select objects. I'll see if I can find a solution that allows any ID type.

Another thing I'd like to support is accessing attributes through multiply calls, e.g. object.location.x.

(And if we want to get really fancy, the output socket would change depending if the property is a vector or scalar...)

I opened a new branch for this node: https://github.com/LuxCoreRender/BlendLuxCore/tree/feature/propertyaccess_node So if you want to help, feel free to work with it :)

scrn_2018-06-02_12-26-03 scrn_2018-06-02_12-26-28

Theverat commented 6 years ago

You can do funny stuff with this node. Like drive the color of a material with the color of the node itself.

scrn_2018-06-02_18-18-57

Todo:

Theverat commented 6 years ago

Another idea: show a dropdown with the possible attributes. Maybe even filter for actually usable ones, like scalars, vectors, colors etc.

scrn_2018-06-02_19-52-39

Theverat commented 6 years ago

Another idea: show a dropdown with the possible attributes.

This turned out to be much more complicated than I thought, so I dropped this idea. However I'm still considering to add a popup that shows all available attributes of a datablock (but only the first level).

Stuff I added:

scrn_2018-06-04_19-51-36

novacrazy commented 6 years ago

On your checklist, for the function call example, it would probably be better and more flexible for artists to add those as other nodes like I listed in LuxCoreRender/LuxCore#118.

A node for vector normalization and another for splitting vectors/colors into their scalar components would reduce the complexity of the property access node, and add extra flexibility for other stuff like what I talked about in the other issue.

Also, even though this technically started as a workaround, I’m very excited for this now. Dynamic effects based on other object arbitrary properties is exactly what every offline renderer needs, in my opinion, and by wrapping it in even the most barebones of nodes gives a lot of power to artists.

Even now, I just had an idea to use this to compute distance from an object inside of a heterogenous volume to add procedural clouds or fog around that object.

Theverat commented 6 years ago

Yes, I think I will not add function call support for now because it adds another bunch of complexity. For example, how to handle functions that expect arguments? Maybe this can be added at a later time.

The only thing I want to try is to add a popup that shows the available attributes (basically a filtered dir()), so you don't have to check in the Python console every time. After this, I'll merge it into master.

novacrazy commented 6 years ago

One idea I had for easier deeply nested property access, at the cost of another new node and a connection data type, was to separate out the object selection node and a property access node, then have all the property access nodes work recursively (sort of). Additionally, an array index/slice menu on the property node.

So for your material_slots[0].material.diffuse_color[0:2] example if would become:

Cube:                   Object Select Node -> 
material_slots[0]:      Property Node (with Array Index) -> 
material:               Property Node -> 
diffuse_color[0:2]:     Property Node (with Array Slice) -> Color Output

On each Property Node it would auto-populate a dropdown with dir(). If the selected property is a scalar/vector/color, it could output it there. If the selected property is another nested object, it would output that and sub-properties could be selected with another Property Node.

If the selected property is an array, it would offer the index/slice options and do the same as the previous two outcomes with the result of that index/slice operation.

Furthermore, this would allow for branching selections, like if they want to select the diffuse_color and specular_color properties from the same object material slot, they could branch off of the same parent Property Node. Or if they want to select multiple transforms from the same object, it would reduce repetition by only selecting the object once in the Object Select Node.

What do you think of that?

Theverat commented 6 years ago

This sounds good, it solves several issues in an elegant way. It also adheres to the "UI principle of discoverability" in a better way than my node, because the dir() dropdown, output socket and array/slice option show the user all he needs to be able to explore. With this proposal there is probably no need to keep the Python console open at the side.

Do you want to have a go at it? My time is currently rather short, unfortunately.

novacrazy commented 6 years ago

Well, it's a start: selectobject And some minimal sorting of the data types sorted data types

So I decided I would like to give this a try. I've never worked with Blender's API before, and it's been a year or two since I've touched Python, so it took a few hours to figure out things like the custom socket types and nodes in general. I suppose next up is tracing back through the tree to get the correct properties and dynamically generate the selection options.

Theverat commented 6 years ago

Looking good. If you have questions, feel free to ask me. And if you want me to review code, post a link and I'll have a look.

novacrazy commented 6 years ago

I now more or less have the recursion done, and I was able to get reroute nodes working.

selectobject2

Next up is list slicing and correct output types, and then finally getting it to export these to LuxCore texture constants.

canonex commented 5 years ago

Alternative coded solution is to directly apply values from driver function: https://forums.luxcorerender.org/viewtopic.php?f=4&t=626#p6229

Not a perfect solution but it works.

LaurieAnnis commented 4 years ago

Apparently you have to have the object AND the node selected, for the keyframes to appear. I found this old thread because I was having the same issue, and stumbled across this solution on another site, and it worked for me.

Theverat commented 4 years ago

Apparently you have to have the object AND the node selected, for the keyframes to appear.

This is the case for Cycles nodes, but it does not work on LuxCore node trees - the keyframes never appear in the graph editor.

NazzarenoGiannelli commented 4 years ago

I am having the same issue with Sverchok. I am trying to simply keyframe a Vector Lerp, but keyframes do not show up and values I modify get not registered. Anyone knows how to solve this?

Viper1-1 commented 1 year ago

Alright, I have found a solution!

Screen Shot 2022-09-30 at 10 07 48 PM Screen Shot 2022-09-30 at 10 07 55 PM
Viper1-1 commented 1 year ago

First select the node with the keyframes, go into the Dope Sheet, and voila, there is the keyframe! and you can edit it and everything!