I have a blender file that contains 6 different individual objects in the scene
I would like to assign them random materials that follow color gradient schemes (see examples in the attachment)
Any idea how to do it in Python?
I guess that it could be something like:
- create Material1 with a random color (example HSV 0.1,1,1) and apply it to the first object
- create Material2, assign the color that Material1 has -0.02 on the H value (which means 0.08,1,1), apply it to the second object
- create Material3, assign the color that Material1 has -0.04 on the H value (which means 0.06,1,1), apply it to the third object
- create Material4, assign the color that Material1 has -0.06 on the H value (which means 0.04,1,1), apply it to the fourth object
- and so on…
Can someone help?
I would be fine also with other ways to reach a similar result
Thank you very much in advance
This snippet should nudge you in the right direction
import numpy as np
from mathutils import Color, Vector
if __name__ == "__main__":
bpy.data.batch_remove(bpy.data.objects) # Uncomment to clear everything before running script
bpy.ops.outliner.orphans_purge(do_local_ids=True, do_linked_ids=True, do_recursive=True)
cubes = 10 # Number of cubes to instantiate
mat = bpy.data.materials.new("My Material")
mat.use_nodes = True
node_tree = mat.node_tree
nodes = node_tree.nodes
principled = next(n for n in nodes if isinstance(n, bpy.types.ShaderNodeBsdfPrincipled))
info = nodes.new(type="ShaderNodeObjectInfo")
info.location = principled.location - Vector((200, 0))
links = node_tree.links
links.new(info.outputs["Color"], principled.inputs["Base Color"])
hsv_base = Color((1, 0, 0))
for i, hue in zip(range(cubes), np.linspace(0, 1, cubes + 1)):
bpy.ops.mesh.primitive_cube_add(location=(0, i * 3, 0)) # This should be replaced by non-ops function if you have performance problems
cube = bpy.context.active_object
cube.material_slots.material = mat
hsv = hsv_base.copy()
hsv.h = hue
cube.color = (hsv.r, hsv.g, hsv.b, 1)
This will create a series of cube with a single material, and use the object info node to color the shader according to the object color. Tweak the upper bound of the
np.linspace function to change the hue change factor
Added perk : You don’t even have to be in preview mode to see the colors, you can use the shaded object color view.
thank you very much for this awesome script and for the information, really awesome!
Unfortunately I need to apply materials to objects that I already have in the scene (not new ones), and the materials need to be Principled BSD with a normal base color (no additional nodes) so that it can be seen also in a glb format)
So I need to find a different solution
This can be adapted to apply to existing objects, just remove the part where it instances cubes and fetch your objects there.
Also I think glb supports vertex colors ? You can try with that too. You can access vertex colors with a node in the shader editor
Thank you for your answer.
I have been struggling to find a solution but no way (I am still a newbie).
Any idea how to apply the colors to all the existing objects in the scene instead of applying them to new cubes?
All the scripts that I can find apply them to new meshes, which is what I cannot afford to do (because my meshes are too complex to be created in python according to my skills)