Using Actions with Materials

Consider a row of several planes. All planes have the same material assigned, two colors with a factor that can be keyframed to switch from one to the other.
image
I can create an action to move an object from its base position to another and back again. I can assign that action to each of the planes. I can adjust the timing of each plane’s action so they don’t happen at the same time.

However, I cannot create an action to control the value used as the factor of the fade.

Back in the action editor, I create a new action and go through the normal process of adding keyframes and changing values of the custom value in the material but no keyframes appear so the action cannot be pushed down to an NLA track. Then I animate the custom property as one normally would, and as expected it works fine and everything with the material applied changes at the same time. The timeline for the custom property animation shows up in the NLA timeline for each of the planes. It shows up as a “material action” for each material row and includes a pushdown button. Pushing that button adds a strip to the NLA track for the material action. At this point moving any of the material actions moves all of the material actions in each NLA track.

How can I fix this so the material action can be timed separately for each instance of the material? I’m trying to avoid having to create a separate material for each object which would have to be animated individually. Maybe use some property that isn’t assigned as part of the object properties or material properties? Does such a thing exist?

Thanks
shader action test.blend (829.0 KB)

While I haven’t messed with this particular thing, animating material values are a pain, and NLA is really focused on armature deformation (not anything else, not even object transformations.)

So given that, I’d go with the path of least resistance, and create a driver for the value from a bone transform, at which point NLA animation of that bone should be totally trivial.

As for timing for each material, while there are ways to do this with shared materials, the fact is, you want different behavior for each instance, and that sounds like a different material. That does not mean that you have to animate each material individually. They could, for example, use a value inside a linked node group, after which each individual material did some math on it.

If you really, really need to share materials, then you need some property outside the material that indicates when the material mixes. For example, you could create a new UV map for each mesh, and then read UV.x and add #frame to it. But no matter what, if you want each object to behave differently, you’re going to have to define how each one is different, and doing that with different materials doesn’t seem any harder (or easier) than doing that with different UV.

1 Like

Using a common node group in a separate material for each object will work but is a little ungainly since I’m ultimately going to have 50 objects flashing at different arbitrary times, but building the material node group to accept a frame number as an input will still allow me to adjust any timing changes in that shared node group. Now to figure out how I can get the material to accept multiple frame numbers…

No matter what, if you want 50 objects behaving differently, and not just randomly (in which case you could use object info/random in the material), you’re going to have to define 50 different things. Whether you want to define those with keyframes, or with different math in the nodes of different materials, or with different attributes read by a single material.

1 Like

Maybe this addon will help?