I have 3500 cubes and I want to randomly place about 119 different images on the sides of the cubes. I loaded the images into an image sequence node and changing the offset changes the picture. How can I connect the object info random node to the offset so that each cube gets a random texture?

I have tried using a driver to pass the value from a math node field, but it does not update with the object info random data...



1 Answer 1


here is a quick and dirty script, its really inefficient though, creates a distinct material for each cube. I Suggest maybe investigating the animation nodes plugin? you can do fancier programming logic with that.

import bpy
import random
import glob

scene = bpy.context.scene

image_names = glob.glob("/Users/myuser/Blender/images/*")

for name in image_names:

cube_count = 1000

for c in range(cube_count):
      location=(3*random.random(), 3*random.random(), 3*random.random()))

for ind,ob in enumerate(scene.objects):
    if ob.type == 'MESH' and ob.name.startswith("Cube"):
        ob.select = True

        #make a new material
        rand = "--"+ str(random.randint(0,100))
        mat = bpy.data.materials.new(name="Mat"+str(ind)) #set new material to variable
        #add the material to the object
        ob.active_material_index = len(ob.material_slots) - 1

        #make a new node texture node
        mat.use_nodes = True
        node_tree = mat.node_tree
        node = node_tree.nodes.new("ShaderNodeTexImage")
        tex_coord_node = node_tree.nodes.new("ShaderNodeTexCoord")
        mapping_node = node_tree.nodes.new("ShaderNodeMapping")
        diff_node = node_tree.nodes['Diffuse BSDF']

        node_tree.links.new(tex_coord_node.outputs['Generated'],       mapping_node.inputs['Vector'])
        node_tree.links.new(mapping_node.outputs['Vector'], node.inputs['Vector'])
        node_tree.links.new(node.outputs['Color'], diff_node.inputs['Color'])

        node.projection = 'BOX'
        node.select = True
        node_tree.nodes.active = node

        rand_image_index = random.randint(0, len(bpy.data.images))
        node.image = bpy.data.images[rand_image_index]

        ob.select = False
  • $\begingroup$ That is very cool thanks! I was able to use animation nodes to change the value of the math node that is driving the offset value in the image sequence node, however this only gives me the same random texture on each cube. $\endgroup$
    – Talmore
    Commented Nov 23, 2017 at 3:10
  • $\begingroup$ @Talmore try using a 'Object Info' node and hook up the random output into a math node 'add' then each object should have a random value in the image sequence. $\endgroup$
    – csch0
    Commented Nov 25, 2017 at 21:29
  • 1
    $\begingroup$ I have the object info node. The problem is the offset value on the image sequence does not have an input. I set a driver to read from a math node that is attached to the object info, but the driver does not read the current data. $\endgroup$
    – Talmore
    Commented Nov 28, 2017 at 2:48
  • 1
    $\begingroup$ Ah, okay, heres another solution, stitch all 119 images together in 1 long jpg/png, then use the mapping node to change the x/y location based on the object info #. That way you don't depend on image seq #, but just on a X/Y displacement on a huge image map $\endgroup$
    – csch0
    Commented Nov 29, 2017 at 22:39
  • $\begingroup$ saw the pile images into one file in my research. too hands on for the number of images down the road. I am currently working with animation nodes. I loaded the images onto planes. Then I create instances of them. The instance is placed on the face of the cubes. It is working so far. I need to rotate all of the images to keep the top edge the z-up $\endgroup$
    – Talmore
    Commented Dec 1, 2017 at 3:43

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .