6
$\begingroup$

I am trying to script a basic grid of cubes with different colors for each cube. Does each cube need its own “material” or can the diffuse color for a single material be changed for each cube?

In any event, I’m not sure how to assign the materials or the colors.

The basic grid of cubes looks like this:

import bpy

for x in range(10):
    for y in range(10):
        location = (x*4, y*4, 0)
        bpy.ops.mesh.primitive_cube_add(size=2, enter_editmode=False, align='WORLD', location = location, scale = (1, 1, 1))
$\endgroup$

2 Answers 2

7
$\begingroup$

if you want to use python, you can use this script:

Explanation:

newMat = bpy.data.materials.new(name = 'Material')

This just creates a new material with name "Material". Is is not used by an object right now.

object.data.materials.append(newMat)

This appends the materials to the object's data.

newMat.use_nodes = True

This tells the material to use nodes (instead of being a "pure" color).

nodes = newMat.node_tree.nodes

With this the variable nodes gets access to the nodeTree/nodes (this is basically what you see in the shader editor).

material_output = nodes.get("Material Output")

Here i get the material output node.

enter image description here

node_emission = nodes.new(type='ShaderNodeBsdfDiffuse')

Creates a new Diffuse node

enter image description here

node_emission.inputs[0].default_value = (random.uniform(0, 1),random.uniform(0, 1),random.uniform(0, 1),1) 

Sets the color to the diffuse node. The inputs array represents all incoming values. Default value is the value/color in this case.

links = newMat.node_tree.links

Gets access to the links

newLink = links.new(node_emission.outputs[0], material_output.inputs[0])

Creates the link between your diffuse and material output

import bpy 
import random
 
def createRandomMat(object):
    
    newMat = bpy.data.materials.new(name = 'Material')
    object.data.materials.append(newMat)

    newMat.use_nodes = True

    nodes = newMat.node_tree.nodes

    material_output = nodes.get("Material Output")

    node_emission = nodes.new(type='ShaderNodeBsdfDiffuse')

    node_emission.inputs[0].default_value = (random.uniform(0, 1),random.uniform(0, 1),random.uniform(0, 1),1) 

    links = newMat.node_tree.links

    newLink = links.new(node_emission.outputs[0], material_output.inputs[0])
    
   

for x in range(10):
    for y in range(10):
        location = (x*4, y*4, 0)
        bpy.ops.mesh.primitive_cube_add(size=2, enter_editmode=False, align='WORLD', location = location, scale = (1, 1, 1))
        
        object = bpy.context.active_object
        
        createRandomMat(object)

result:

enter image description here

material created:

enter image description here

$\endgroup$
6
$\begingroup$

You could use the object info node and connect the random output to a color ramp, as shown on this page

enter image description here

enter image description here

$\endgroup$
2
  • $\begingroup$ is this is in "cycles"? is there a way to do it as text? $\endgroup$
    – vpo
    Commented Aug 9, 2021 at 2:18
  • $\begingroup$ @vpo text might need Geometry -> random per island $\endgroup$ Commented Aug 9, 2021 at 17:25

You must log in to answer this question.

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