Building on this answer, the Rotation details can be captured to an image - with each frame on a subsequent line of the image - and interfaced into the Cycles material using an Image Texture node.
The following script will run through each frame of the scene and create an image (width = number of objects, height = number of frames) containing the Rotation details encoded stored in each pixel.
import bpy
import os
width = len(bpy.data.objects)
height = bpy.context.scene.frame_end
# Create the image
image = bpy.data.images.new("object_rotations_"+str(width)+"x"+str(height), width=width, height=height,float_buffer=True)
# Create an empty array of pixel data (each will hold R, G, B, A values as floats)
pixels = [None] * width * height
# For each frame
for frame in range(0,height):
bpy.context.scene.frame_set(frame)
# For each object
for x in range(0,width):
y = frame
object = bpy.data.objects[x]
pixels[(y*width)+x] = [object.rotation_euler[0], object.rotation_euler[1], object.rotation_euler[2],1.0]
object.pass_index = x
# 'flatten' the array
pixels = [chan for px in pixels for chan in px]
# Store the pixels in the image
image.pixels = pixels
image.update()
# Save image to temporary file and pack it (from answer by @sambler)
scn = bpy.data.scenes.new('img_settings')
scn.render.image_settings.file_format = 'OPEN_EXR'
scn.render.image_settings.color_mode = 'RGBA'
scn.render.image_settings.color_depth = '32'
img_path = bpy.path.abspath('//')
img_file = image.name+'.exr'
image.save_render(img_path+img_file, scene=scn)
try:
# Remove the scene (pre-2.78)
bpy.data.scenes.remove(scn)
except:
# Remove the scene, (Blender 2.78+)
bpy.data.scenes.remove(scn, do_unlink=True)
bpy.data.images.remove(image)
bpy.ops.image.open(filepath=img_path+img_file)
image = bpy.data.images[img_file]
image.pack()
os.remove(img_path+img_file)
# Add a fake user to ensure the image is retained
image.use_fake_user = True
This will capture the rotation details of each object into a row of pixels in a generated image with one row for each frame in the timeline. Each pixel's RGB values represent the XYZ Euler rotation values for the corresponding object on that particular frame.
The material can extract the rotation of each object using some relatively simple maths - set the Image Texture to point to the generated image (and set to Non-color Data).
Set keyframes on the highlighted Frame value node - to vary the frame in step with the actual timeline frame (and set Interpolation to Linear) - this is the easiest method of getting the frame number into the Cycles material. Also, ensure the highlighted Width and Height Maths Divide nodes match the Width and Height of the generated image.
This can produce the following effect, varying the color based on the object rotation.
Note that if the rotation of the objects (or the number of objects) is changed then the script will need to be re-run to re-capture the object rotations to the image.