# How to get a Material property driver to update properly (2.78)?

After watching this excellent tutorial (https://vimeo.com/40389198) I thought "what ho, this is just what I was looking for, I can make random variations in mass-produced objects!" So I started trying to reproduce the technique in a simple blendfile. I got past Step One (expose the python rand functions to the driver code); I can verify that, say, the randf function exists in driver space and does work:

>>> bpy.app.driver_namespace['randf']
<function randf at 0x11ce3f158>

>>> bpy.app.driver_namespace['randf'](1.0,1.5)
1.4099068216884594


so far so good. Step Two: try to make random variations in the Intensity of a Material (BI!). I assign a Material to the good ol' Default Cube, set the Diffuse Colour, then apply a Driver to the Intensity. Everything seems to work as described; the Intensity field turns purple, and in the Graph Editor I can see that the Material now has a Driver attached for Diffuse Intensity. I set the Driver Type to be Scripted Expression, enter my randf function, turn on Show Debug...

I am all ready to see variations appear when I press Update Dependencies button. Imagine my chagrin when nothing at all happens... the Driver Value is always zero...

... so I experiment some more. I find I can drive Z Scale with my randf function; so why doesn't Intensity work? Headbanging eventually reveals that I omitted one essential step, and I am not sure why it is necessary in some cases but not in others. Diffuse Intensity requires a Driver Variable whereas Z Scale does not.

My question is therefore now Why do certain object attributes require a driver variable whereas others do not, and is there a list?

UPDATE: in light of comments below I tried again from scratch. Brand new blendfile, just a cube and a camera. Screenshot:

I think it shows all the relevant details: the property field is purpled, and I accessed it through the datablocks. If I hover over the purple prop field I get a popup confirming that its value should be randf(.1,.9). The randf function is valid and produces appropriate output. There is no red highlighting indicating a driver error. Everything looks good, to the best of my knowledge.

But when I hit Update Dependencies, nothing happens. I can create a var or not, it makes no difference. Something else... what? ... is determining whether the driver is evaluated when the Update button is pressed, and that something is either broken, or misunderstood by me. I no longer believe the initial premise of this Question, which is that creating the variable made it work. Something else I did made it work... but what?

Blendfile with non-working driver:

Finally some progress:

As a sanity check, I threw a randf driver at X Scale of the cube in the above blendfile. Scale randomising works perfectly, without any var, instantly. So I believe that I've done all the setup for a driver correctly, but there is something tricky about certain properties, including (but possibly not limited to) Material properties. My question is slowly getting more focused.

I also tried getting at the Material property 2 ways through the datablock tree: via the object (Cube) and via the Materials hierarchy. The property field was correctly highlighted either way. Neither way causes Update to work.

I also tried stepping a few frames forward and back to trigger animation events (there aren't any, but I thought it might goose the Update code somehow). No dice.

I deleted the Diffuse Intensity driver, leaving the X Scale driver in place. I then re-created the DI driver. It didn't work. I then added a var for it. And guess what: now it works. So my current version of the needed incantation is this: (1) create a geometry driver. (2) create the DI driver. (3) add the var. Then it should work, even if "path to property" in the Var pane is left blank.

And here it gets interesting: If I get rid of the X Scale driver, the DI driver stops working! If I restore the X Scale driver, the DI driver starts working again. If I keep the X Scale driver, but delete the variable for the working DI driver, it stops working. If I mute the X Scale driver, the DI driver continues to work.

I therefore conclude that (at least in my version of Blender, 2.78 Steam version for OSX) to make a driver work for Material properties such as Diffuse Intensity or RGB values, one must first create a driver for some other, more "ordinary" property such as object scale. This other driver can then be muted, but not deleted, if you want the Material driver to keep working. One must also create a var for the non-geometry driver.

It is as if there is some initialisation or event handler registration or similar, which is done correctly by a geometry (or perhaps some other "good" property) driver, but not by drivers attached to some (no idea how many) other "bad" properties. It's as if the updater code is simply not aware that there are any drivers in the list to be evaluated at scene update or on button press, unless at least one "good" driver is added. But once it is aware, the list is fully populated and gets evaluated correctly. It would be truly an Herculean labour to test every possible property for goodness or badness of this kind -- so I hope someone who knows the guts of Blender will have an Aha! moment at this point, and it will get fixed in a forthcoming release.

• Indeed, an excellent tutorial. However, I could not reproduce your problem: when I add the diffuse intensity driver via the datablocks, it does work without a variable, and when I do it the normal way, it does not work anyway. I guess this part of Blender has bugs (it should not be necessary to go to the datablocks to set up a material driver) , and hopefully with the new dependency system in 2.8 it will be better. – lbalazscs Jan 8 '17 at 16:55
• thanks lbalazscs, I will give it another go from scratch and try to confirm your result. there are breadcrumbs here and there in various fora suggesting that driver implementation is a bit inconsistent -- was more so in the past, still is a little -- so perhaps we should not be surprised at having to take different access routes to drive some properties. – Tazling Jan 8 '17 at 21:12

"the property field is purpled, and I accessed it through the datablocks"

Crazy, but I think that it is a problem if the the property field is purpled. If the field is purpled, delete the driver and try again. There are lots of minefields when applying this workaround, and you have to be very careful. Watch the video again between minutes 20 and 25, especially noticing that the property does not change color at 24:30

I didn't download your file (I wouldn't know what to look for), but my experience is that when the field is not purple, then it works...

And of course, this whole crazy workaround is necessary only for material properties.

The current Dependency graph was written during Elephants Dream (haha! the circle is complete). This is way before the modern animation system of “everything can be animated” we have now. That design really worked for the rigid old system, in which only specific properties could be animated. Starting from 2.5 and until now, only dependencies that worked in 2.4x could reliably be expected to work, even though the interface allows you to create them. Think of driving a bone”s transform with another bone”s transform in the same rig, or parenting an empty to the body of a character, then IK”ing the arm to that empty, or trying to get a flower to open up based on the brightness of the sun lamp…. Even worse, the interface fully allows you to set up these drivers, but after you do, you get some strange lags and stutters, with very limited feedback as to why this happens. Previous patches enabled some very specific new setups, while not really changing the system under the hood. With the update, we can expect these setups and more to work, in a predictable and speedy way. This also lays the groundwork for future changes in blender, such as creating a new node system for modifiers constraints transforms particles, basically enabling more procedural-ism and flexible rigging. For now, in addition to “Animate all the things” we will be able to “Drive all the things” – very cool.

• Interesting... I have no idea how I would get the field not to purple! will check video again as you suggest. It works fine with purple property fields but ONLY if one or more geometry drivers pre-exist (see above, my painfully detailed notes on recent headbanging). – Tazling Jan 8 '17 at 22:58
• I don't agree with your theory, because I tried it from scratch, without any geometry drivers, and the first time I did it wrong (I don't know what), because it was purple, so I deleted and repeated adding the driver, and this time it is not purple but it works :) – lbalazscs Jan 8 '17 at 23:01
• Let's compare versions: I am running 2.78 Steam release, OSX 10.11.6 ... and you? – Tazling Jan 8 '17 at 23:09
• 2.78a on Win 8.1, but I don't think that it depends on the OS. Maybe adding a non-working purple driver has the same initializing effect as adding a geometry node, even if it is deleted. – lbalazscs Jan 8 '17 at 23:20
• You could create a bug report, it would be interesting to see what the developers think. But the dependency graph is going to be rewritten anyway: code.blender.org/2016/12/dependency-graph-proposal – lbalazscs Jan 8 '17 at 23:24

Workaround:

1) create a geometry driver (say, x scale, that's simple).

2) set the Expression to a constant that you like, say 1.0

you now have a placebo geometry driver.

3) now create your Material property driver

4) create a var for it

it should work. don't delete that geometry driver -- it seems to be what tells some event loop or other that there are any drivers to be evaluated! just leave it as an "anchor" for any non-geometry drivers you want to add.

it's even a little weirder than this: in my version of Blender, if I create a second Material properties driver, both MP drivers stop working if I delete the Geom driver; the first MP driver I create has to have a var or it won't work; but once I have two MP drivers, I can delete the variable from either one of them without ill effect. if I delete both vars, then both drivers stop working. if I restore one var, both drivers start working. this makes my brain hurt.

recipe for success: pre-existing geom driver, and first MP driver must have a var. after that life gets easy. I think :-)

https://www.flickr.com/photos/rootlessagrarian/32196171315

this is not a pretty movie by any means -- but it demonstrates success: the cube is rotating randomly with each frame, its diffuse intensity is changing randomly with each frame, and its reflectivity is changing ditto. just to show that when I follow the formula above, I can drive Material properties.

• Yes, success, but I had the same success without geometry drivers :) – lbalazscs Jan 8 '17 at 23:33