With Blender's script, we will create something ** like that that was talked about at the Expo. Since it is procedurally generated based on random numbers, it is possible to generate innumerable patterns. Blender version is 2.8.
import bpy
import numpy as np
#Set the red material here
bpy.data.materials.new(name = 'red')
mat_red = bpy.data.materials['red']
mat_red.use_nodes = False
mat_red.diffuse_color = (1,0,0,1)
#Sphere generation
bpy.ops.mesh.primitive_uv_sphere_add(radius=1,location=(0,0,0))
bpy.ops.object.material_slot_add()
bpy.context.object.active_material=mat_red
We will create a red sphere by generating primitives and specifying simple materials. You can create a UV sphere with bpy.ops.mesh.primitive_uv_sphere_add
.
I'd like to create innumerable red spheres, but I feel that life is shining if there is some kind of continuity rather than just doing it with a for statement, so I will implement it using a recursive function. I will decide. A recursive function is a program that creates a copy of itself (super-appropriate).
import bpy
import numpy as np
#Set the red material here
bpy.data.materials.new(name = 'red')
mat_red = bpy.data.materials['red']
mat_red.use_nodes = False
mat_red.diffuse_color = (1,0,0,1)
def add_sphere(r,x,y,z,count):
if count > 20: #Infinite loop without this
return
bpy.ops.mesh.primitive_uv_sphere_add(radius=r,location=(x,y,z))
bpy.ops.object.material_slot_add()
bpy.context.object.active_material=mat_red
add_sphere(r,x+1,y,z,count+1) #Call a copy of yourself
return
add_sphere(1,0,0,0,1)
The sphere is generated by the function ʻadd_sphere, but the function ʻadd_sphere
is also called in this. But it's not exactly the same, it produces a copy that is x by 1 off itself. An infinite loop occurs in which the copy is further shifted by one, and a continuous process can be described simply. This is just a horizontal move, but with a command like ʻadd_sphere (1.1 * r, y, x + 1, z, count + 1) `, it looks like this:
You can feel the mystery of life.
However, this is too regular and does not shine. Looking at the original material, it seems that a number of red spheres of different sizes are connected to form a ring. After all, it seems that a feeling of life comes out if there is some variation in size. The positions of occurrence of each other should also be shaped so that they grow while barely touching the child from the parent.
import bpy
import numpy as np #Add numpy import
#Set the red material here
bpy.data.materials.new(name = 'red')
mat_red = bpy.data.materials['red']
mat_red.use_nodes = False
mat_red.diffuse_color = (1,0,0,1)
def add_sphere(r,x,y,z,count):
if count > 20: #Infinite loop without this
return
bpy.ops.mesh.primitive_uv_sphere_add(radius=r,location=(x,y,z))
bpy.ops.object.material_slot_add()
bpy.context.object.active_material=mat_red
#Randomly specify longitude and latitude
theta = np.random.rand()*np.pi*2
phi = (np.random.rand()-0.5)*np.pi
#Specify new coordinates
nr = r*(0.5 + np.random.rand())#The child's ball is the parent's 0.5 times to 1.5 times
nx = x+(r+nr)*np.cos(theta)*np.cos(phi)
ny = y+(r+nr)*np.sin(theta)*np.cos(phi)
nz = z+(r+nr)*np.sin(phi)
add_sphere(nr,nx,ny,nz,count+1)#Call a copy of yourself
return
add_sphere(1,0,0,0,1)
I will add a cute eyeball. It would be nice if I could set the texture, but here I will draw only with primitives.
It's shining a lot. After that, if you arrange the shading a little and render it, you can generate a shining image like the beginning.
The code has a lot of verbose parts, so I've simplified some of them as functions.
import bpy
import numpy as np #Add numpy import
#Writing three material settings is lengthy, so make it a function
def create_material(color_name,r,g,b):
bpy.data.materials.new(name = color_name)
mat = bpy.data.materials[color_name]
mat.use_nodes = False
mat.diffuse_color = (r,g,b,1)
return mat
mat_red = create_material('red',1,0,0)
mat_white = create_material('white',1,1,1)
mat_eye = create_material('eye',0,1.5,1)
#Writing three coordinate specifications is long, so it is partially functionalized
def next_params(x,y,z,theta,phi,dist):
nx = x + dist*np.cos(theta)*np.cos(phi)
ny = y + dist*np.sin(theta)*np.cos(phi)
nz = z + dist*np.sin(phi)
return nx,ny,nz
#It takes a long time to write three UV sphere generations, so it is partially functionalized.
def create_sphere(r,x,y,z,mat):
bpy.ops.mesh.primitive_uv_sphere_add(radius=r,location=(x,y,z))
bpy.ops.object.material_slot_add()
bpy.context.object.active_material=mat
return
#By the way, angle generation is also functionalized
def create_angular():
theta = np.random.rand()*np.pi*2
phi = (np.random.rand()-0.5)*np.pi
return theta,phi
def add_sphere(r,x,y,z,count):
if count > 20: #Infinite loop without this
return
create_sphere(r,x,y,z,mat_red)
theta,phi = create_angular()
nr = r*(0.5 + np.random.rand())
nx,ny,nz = next_params(x,y,z,theta,phi,r+nr)
add_sphere(nr,nx,ny,nz,count+1)#Call a copy of yourself
#Generate white eyes (this is just a function)
theta,phi = create_angular()
nx,ny,nz = next_params(x,y,z,theta,phi,r/3)
create_sphere(0.8*r,nx,ny,nz,mat_white)
#Generate pupil (this is just a function)
nx,ny,nz = next_params(x,y,z,theta,phi,r/2)
create_sphere(0.65*r,nx,ny,nz,mat_eye)
return
add_sphere(1,0,0,0,1)
You can see a different beauty of life by splitting it in the middle or reducing the size of the child's ball.
If you are interested, it may be a good idea to play with different parameters. However, please note that if you change around count> 20
, the amount of objects may increase exponentially and Blender may freeze depending on how the program is constructed.
Recommended Posts