# A way to get Rate of Change in translation or rotation into a shader node

I am doing a space scene with a space ship, and i'm trying to be physically realistic when it comes to how ships move in space. As such, I only want my thruster effects to fire when the Rate of Change of rotation or translation is changing. I could animate it all by hand, but I don't want to if I don't have to.

Is there an input node I can get this information with? Everything i've seen is just plain location data. Oris there an addon or script I haven't been able to find? Can this information even be retrieved with a script and i'm up a creek?

• Its possible to control nodes values with drivers, did you try that? – Denis Apr 27 '15 at 4:24
• @Denis Thanks for that, I hadn't thought of using those in that way. I was stuck trying to do it only in the nodes. I can drive a shader value off my rotation and translation info, but not the rate of change of that info. At least, not that I can see. – Shaun Yoder Apr 27 '15 at 4:59
• You can achieve this by considering the F-Curve values in the graph editor. If the change in curve evaluation values between two neighboring time steps is greater than that between the previous time step neighbors, you have acceleration. I'm on mobile now so I can't test how to make this work with the node editor, but I'm sure there is a way. Will post an answer if I can make it work once I reach my computer. – Ulf Aslak Apr 27 '15 at 7:46
• @UlfAslak There is no way to evaluate an F-Curve at specific frame in driver, because that requires non-build-in function on that curve. This can be done with pydrivers. They don't update right on nodes though (dependencies issue) so when scripting its better to script this with frame change handlers. – Jaroslav Jerryno Novotny Apr 30 '15 at 15:32
• Sorry, didn't know I needed to check a checkmark. Thanks for pinging me on this. – Shaun Yoder May 9 '15 at 15:33

Blender doesn't give value changes off the sleeve. What you need is to evaluate an animation (F-Curve) in current and previous frames and compute the difference. This solution uses a script that adds a custom frame change handler. Other way could be with PyDrivers or using Animation Nodes plugin.

Run this, it will add new properties to objects and it will update them every frame. You can access them in driver:

import bpy
from mathutils import Vector, Euler

curr_frame = None

def frame_handler(scn):
global curr_frame
if curr_frame != scn.frame_current:
curr_frame = scn.frame_current
for obj in scn.objects:
obj.speed = (obj.matrix_world.translation - Vector(obj.last_loc)).length
last_quat = Euler(obj.last_rot).to_quaternion()
quat = obj.rotation_euler.to_quaternion()
obj.angular_speed = quat.rotation_difference(last_quat).angle
obj.last_loc = obj.matrix_world.translation
obj.last_rot = obj.rotation_euler

bpy.types.Object.last_loc = bpy.props.FloatVectorProperty()
bpy.types.Object.last_rot = bpy.props.FloatVectorProperty()

bpy.types.Object.speed = bpy.props.FloatProperty()
bpy.types.Object.angular_speed = bpy.props.FloatProperty()

if frame_handler not in bpy.app.handlers.frame_change_pre:
bpy.app.handlers.frame_change_pre.append(frame_handler)


• speed (in blender units per frame)
• angular_speed (in rads per frame)

Use them in driver like this:

Here I am driving Y-scale and view-port material color with speed:

Note: this will only work when playing the frames sequentially. If you jump around you will get crazy values. This is a very simple handler using values from last and current frame, but it could be adjusted to read from the Fcurves of objects if you need.

Also it expects rotations in euler, but it transforms it to quaternions anyway. So if you want quaternions no problem.

• This a pretty awesome solution! Addressing your comment to my comment, you can get the F-Curve value at every frame, so my clever idea was to write a script that evaluates the acceleration at each frame using this property and then somehow implement it as a node that would output a value between 0 and 1, to be routed into e.g. a mix shader in the node editor. Didn't get that far in the process, and your solution seems to be working pretty great, so cheers! – Ulf Aslak Apr 30 '15 at 19:35
• @UlfAslak Oh I meant you cannot get the Fcurve value with driver native functions. With scripting (PyDrivers, OSL script nodes, etc.) the possibilities are indeed endless. – Jaroslav Jerryno Novotny Apr 30 '15 at 20:15
• @Jerryno too bad it can't be done directly with the drivers, but this solution is neat! – Denis May 6 '15 at 0:56

You could also play with Animation Nodes Addon by using Location Velocity and Rotation Velocity values of the Object Info Node. Following example uses translation velocity values to drive the strength value of an emission shader:

Test rendering of a simple sphere animation

• Create an Object Info Node,
• Split the velocity values (x,y,z) into single ones by the help of a Seperate Vector Node,
• Add Math Nodes to calculate the sum of the x,y,z velocity and
• Add a Cycles Material Output Node to plug the result into a shader value:

Scene Setup (click to enlarge)

This example is just an idea, things like combining Location Velocity and Rotation Velocity values or creating a color by these values are also possible with simple math, of course.

Preview Scene (click to enlarge)

• I don't see Object Info node anymore, do you know what node to use instead in latest version? – Neil Jun 9 '16 at 12:49
• @Neil unfortunately Velocity sockets have been removed in latest versions, see: blender.stackexchange.com/questions/44556/… I'll update the answer as soon as possible. – p2or Jun 10 '16 at 7:46

Using Animation Nodes, you can compute the velocity of an object based on the F-Curves of its animation as described in this answer. You can then pass that velocity to Cycles in a form of vertex color map per object using the Set Vertex Color node.