Procedural awesomeness... in Blender. |
Procedurality is a terminology and concept that I have interested in when I touch Computer Graphics, whether it is procedural animation, modeling, texturing or thinking.
Maybe that is because my big interest in interaction and game design when it comes to computer. Each level of game design is similar, but different.
Input --> Process / Algorithm --> Output
I also happened to grow up next to a biscuit factory, and so it is always interesting to see Marie Biscuits got made from dough into machine until it gets looking like Biscuits that is edible.
Not all biscuits looking exactly the same. Below are some examples of Biscuits and Snacks from Indonesia that explains the idea of proceduralism: (if you want to know where to buy this snacks, contact me personally or leave a comments)
If Australian foods and snacks:
- Chips
- Cereals
- Jelly Worms
It is not so much about "automating" the whole process, but more of idea of creating TOOLS that generates variations that might be random, but still within boundary of controls or matching a certain template.
Maybe there is a sense of "laziness" in Procedural Design, perhaps this is just part of nature. We don't like sameness, we like customization and variations, even just slightly.
Think of anything that is similar, yet different:
- Jelly Beans
- Bricks
- Trees
- Leaves
- Clouds
- Pop Corns
- Cereals
- etc
At the moment, Blender seems to be pushing the Procedural Material generation via Cycles.
http://cgcookie.com/blender/cgc-series/creating-an-uber-shader-in-cycles/
http://blenderartists.org/forum/showthread.php?283248-Ubershader-v4-0-New-Release-5-24-2013-Come-and-Get-It!
Wait! Did I say Cycles is procedural? Maybe Cycles OSL (Open Shading Language) is more true procedural:
http://www.openshading.com/blog/
http://blenderthings.blogspot.com.au/
Pardon me, I often get node-based system and procedural concept mixed up.
Node-Based and Procedural are kind of related to each other.
- Node-Based is where one can simply connect a bunch of nodes to process input values and getting output values as desired.
- While Proceduralism, in my understanding is a series of interconnected step by step instructions or algorithm which can give one the ability to modify and generate variations of different outputs by modifying a set of parameters and values, without having to recreate things from scratch each time or deleting history or other destructive process. Once a process baked, continue to the next.
Blender Modeling should be fine as it is, with Dynamic Sculpting and the traditional workflow.
However, the truth is that Blender has some capabilities for procedural modeling via Modifier and Python and maybe Particles.
INSPIRING ARTIST IN PROCEDURALITY
- Dolf Entoform
http://www.entoforms.com/scripts/ - Shigeto Maeda: GMP - the Generative Modeling Project
http://www.youtube.com/watch?v=s0x5WnykR5Y
HOUDINI PROCEDURALITY VS BLENDER SEMI-PROCEDURALITY
Houdini is really one 3D package that is truly node based of everything. Maya is a little like that too. But if you want to understand node-based 3D workflow, learn Houdini. Their Apprentice version is free to download and use. Houdini is very powerful. Keep in mind that NOT everything is always better as node based. For simple things, node based can be overkill. Blender seems to be the perfect balance.
Recently, with my little knowledge of Python that I actually learned via Blender, I decided to refresh my knowledge in Houdini (as I would like to get serious into VFX). I want to take it to the next level.
Of course I like to incorporate some Blender to work together with Houdini. I still find many Blender features are much more practical, such as Blender Cycles and Compositing.
I was watching this old video by Ari Danesh for SideFX Houdini that explains about Procedural Modeling in Houdini:
http://www.sidefx.com/index.php?option=com_content&task=view&id=2166&Itemid=361
In that Houdini tutorial, Ari is showing a basic procedural modeling workflow in Houdini to generate random little stones (pebbles).
While watching that video, I figure that we could actually adapt the same procedural workflow of Houdini in Blender, up to certain extent.
BLENDER PROCEDURAL MODELING: Pebbles Generator
I will take you through few example cases and we will be looking at some potential techniques that you can later improve on your own. If you have been reading all Blender Sushi articles, you may find old techniques, but I like to push it further.1. STEP ONE: Prepare Base Model or Template Model
Start with some kind of BASE MODEL and think HOW we can add VARIATIONS.
With pebbles, we could simple start with a Subdivided Cube which will give us some kind of round looking objects. We can flatten it a bit.
Box + Subsurface Modifier |
2. STEP ONE: Add Variations
I applied the Subsurf Modifier and Smoothen the Shading of Pebble template. Next, we can use Displace Modifier to create variation. I use the default Cloud texture to displace the mesh.
The direction of displacement is using the Normal, but you could try other option. Including RGB as XYZ that could potentially give more variations. I assign an Empty as Texture Coordinate so that if the Empty being moved, the model will change slightly in shape (because of the procedural Cloud Texture itself).
TIPS: Smooth Modifier can be added on top of Displace Modifier to smoothen the Pebbles.
3. STEP THREE: Bake and Output the Variations
Once we are able to create variations that can be keyframed/animated (different variation on every frame), we can BAKE the variations.
We could actually try to keep all the connections and never actually do the baking, but often in production it is a much more efficient to bake or delete history of the procedural model, and then further process the baked model.
In Houdini, they have bgeo file format, kind of like an efficient way of Houdini storing objects outside of Houdini (can be Particles, Mesh).
With Blender, we just use the good old OBJ with Animated sequences. Yes, Blender can easily output Animated OBJ sequence via File - Export - OBJ (Animation ON).
I have animated the Empty for 100 frames (animated in Translation and Rotation, with Linear Interpolation) and then Export out as OBJ with Animation option checked. I saved the OBJ sequence inside a folder for easy organization.
4. STEP FOUR: Import the Baked Objects
We have 100 procedurally generated pebbles to be used in any Blender scenes. What do you like to do with it is totally up to you. You can use Blender Bullet Physics with the Pebbles. Or maybe use Blender Particles system to randomly place them in a certain shape.
But first, we need to import multiple OBJs, can we do that? We need Python script for this. Because by default, Blender will only import 1 OBJ at a time.
Importing Multiple OBJs using Python
I borrow the script from here:
Copy paste the script: (credited to McBuff, Blender Artist Member) - just in case if Blender Artist Forum is down.
##################
##################
import bpy
import glob
import os
importDir = "C:/Users/Yourname/Desktop/pebbles_out"
print(importDir)
os.chdir(importDir)
for files in glob.glob("*.obj"):
print( files )
bpy.ops.import_scene.obj(filepath=files, filter_glob="*.obj;*.mtl", use_ngons=True, use_edges=True, use_smooth_groups=True, use_split_objects=True, use_split_groups=True, use_groups_as_vgroups=False, use_image_search=True, split_mode='ON', global_clamp_size=0, axis_forward='-Z', axis_up='Y')
for files in glob.glob("*.3ds"):
print( files )
bpy.ops.import_scene.autodesk_3ds(filepath=files, filter_glob="*.3ds", constrain_size=10, use_image_search=True,use_apply_transform=True,axis_forward='Y', axis_up='Z')
##################
NOTE: I will try to improve the Python script above so it handles PATH better to handle forward slash and backward slash.
import glob
import os
importDir = "C:/Users/Yourname/Desktop/pebbles_out"
print(importDir)
os.chdir(importDir)
for files in glob.glob("*.obj"):
print( files )
bpy.ops.import_scene.obj(filepath=files, filter_glob="*.obj;*.mtl", use_ngons=True, use_edges=True, use_smooth_groups=True, use_split_objects=True, use_split_groups=True, use_groups_as_vgroups=False, use_image_search=True, split_mode='ON', global_clamp_size=0, axis_forward='-Z', axis_up='Y')
for files in glob.glob("*.3ds"):
print( files )
bpy.ops.import_scene.autodesk_3ds(filepath=files, filter_glob="*.3ds", constrain_size=10, use_image_search=True,use_apply_transform=True,axis_forward='Y', axis_up='Z')
##################
NOTE: I will try to improve the Python script above so it handles PATH better to handle forward slash and backward slash.
Ok, in a new Blender scene file, we simply need to point the path to the folder with OBJs and run the script above to import all the OBJs in the folder, and this is what we get:
All the pebbles mesh are bunched up on top of each other. This is fine.
If you like to arrange them in a grid, you can use quick rough Python script like below:
import bpy
'''
Arrange selected objects in specified grid space
'''
def arrangeIn2DGrid(width=10, height=10, spread=2):
# Get List of Selected Objects
myObjects = bpy.context.selected_objects
if(myObjects):
print('Please select some objects')
totalGrid = width * height
if(len(myObjects) > totalGrid):
print('You need to specify bigger grid for your objects')
coords = []
for x in range(0,width):
for z in range(0,height):
coords.append([x,z])
# For every object in list, place each one in order into provided coordinates
for number, object in enumerate(myObjects):
object.location = coords[number][0] * spread, coords[number][1] * spread , 0.0
arrangeIn2DGrid(spread = 2)
NOTE: Make sure the Total of Width X Height is MORE than the Total number of Objects to be arranged in 2D grid. I wrote this quickly. Script can be improved.
With 100 variations, it is enough to tell our brain: they are bunch of random shape of stone Pebbles.
Further on:
All the pebbles mesh are bunched up on top of each other. This is fine.
If you like to arrange them in a grid, you can use quick rough Python script like below:
##########
'''
Arrange selected objects in specified grid space
'''
def arrangeIn2DGrid(width=10, height=10, spread=2):
# Get List of Selected Objects
myObjects = bpy.context.selected_objects
if(myObjects):
print('Please select some objects')
totalGrid = width * height
if(len(myObjects) > totalGrid):
print('You need to specify bigger grid for your objects')
coords = []
for x in range(0,width):
for z in range(0,height):
coords.append([x,z])
# For every object in list, place each one in order into provided coordinates
for number, object in enumerate(myObjects):
object.location = coords[number][0] * spread, coords[number][1] * spread , 0.0
arrangeIn2DGrid(spread = 2)
##########
NOTE: Make sure the Total of Width X Height is MORE than the Total number of Objects to be arranged in 2D grid. I wrote this quickly. Script can be improved.
With 100 variations, it is enough to tell our brain: they are bunch of random shape of stone Pebbles.
Further on:
- Randomize the Color and Texture of each stone (choose Blender Render or Blender Cycles first, then try add Material variations)
- Randomize the Size using Particles
We can group the Pebbles and use as Particle Instances. Do whatever you like with it. Maybe arrange the pebbles in a shape that makes you or the other half happy. Well, or use it in 3D production.
Snail made with Pebbles. |
Alrightly, we can generate random variation of pebbles.
Now what? Use the same concept and workflow and do more procedural creation of your own!
Need more examples? Ok, continue on.
BLENDER PROCEDURAL MODELING: Starfish Generator
I will go through each step but slightly faster this time.
1. Create Starfish Base Template.
- Couple of connected Edges
- Skin Modifier
- Smooth Modifier
2. Create Variation of Starfish
I will use multiple Hooks for the leg of starfish. You have learned this technique before. Hook is a way to modify Component level (Vertices) of mesh in Object level. You can animate and keyframe the Hook, so it is perfect for our purpose to model random Starfish.
Manually Hook the vertices if you like. Select a vertex, CTRL+H and hook to new object (Empty).
NOTE: I have to ask some Blender developers, I am curious on how we can actually "hook" the weight of each vertex to translate it into the Skin Modifier. There must be a way to do this.
The cool thing with this setup is that Skin Modifier will adjust and even modify the mesh slightly to generate random yet still maintain the form.
3. Bake and output the Startfish Variation
We can now export the OBJ sequence variations, but not forgetting to ANIMATE the Empty that control the shape of Starfish beforehand. That is the KEY to give variations.
Here we just manually animate the Empty. But in the future, we can use some other techniques to make it more procedural and with variations that is more random.
Let's arrange our Starfishes:
Many Star Fishes! |
BLENDER MESH CACHE MODIFIER & MESHFOOT
You could also make each one of them ANIMATED if you use MDD export-import into the mesh. Blender has nice Mesh Cache Modifier that does the job.
In effect, it gives some kind of random Procedural Animation look. Well, maybe not 100% because we were manually animating them. But we can actually use Python to create procedural animation.
I have not yet explored the potential. Although I have been using Mesh Cache to export-import MDD animation from Maya and Houdini to Blender to use with Cycles Renderer.
https://vimeo.com/64965747
See how ATOM's Meshfoot can import OBJ, turn it into MDD data which can be read as cache. This is GREAT for procedural animation.
I have not yet explored the potential. Although I have been using Mesh Cache to export-import MDD animation from Maya and Houdini to Blender to use with Cycles Renderer.
https://vimeo.com/64965747
See how ATOM's Meshfoot can import OBJ, turn it into MDD data which can be read as cache. This is GREAT for procedural animation.
DAVID MILLER PROCEDURAL TECHNIQUE (Key: PyDrivers)
I have actually mentioned David Miller's procedural technique few times in the past, involving Blender Drivers and Python. It is quite advance, but easily applicable once understood. Not too complicated, this is really worth your time:
David is cleverly use Python binding of drivers and use the number inside for drivers.
What does this mean? Whole heaps of possibility! Because Blender Drivers, although does not always update itself (dirty data), is quite powerful for procedurality. It is another key to add procedurality.
I borrowed (copy, paste) David Miller's script that bind Python function into Blender's Driver: (David, I hope you don't mind):
##########
# FULL CREDIT TO DAVID MILLER
import bpy
import random
# Random floating point number between lo and hi
def randf(lo, hi):
return random.uniform(lo,hi)
# Random integer from lo (inclusive) to hi (inclusive)
def randi(lo, hi):
return random.randint(lo, hi)
# Random values given mean and standard deviation
def gauss(mean, stdev):
return random.gauss(mean, stdev)
bpy.app.driver_namespace["randf"] = randf
bpy.app.driver_namespace["randi"] = randi
bpy.app.driver_namespace["gauss"] = gauss
##########
##########
I always keep the above example code handy, whenever I need to give randomization to Drivers.
I actually wanted to write a post especially on PyDrivers, but I guess for now it is sufficient if you do your own research:
PyDriver + Auto-Update
http://blenderartists.org/forum/showthread.php?224923-Real-Time-pyDrivers
PyDriver Videos
https://www.youtube.com/watch?v=6v5gtbaDfHk
https://www.youtube.com/watch?v=HOeoVJYupQk
I actually wanted to write a post especially on PyDrivers, but I guess for now it is sufficient if you do your own research:
PyDriver + Auto-Update
http://blenderartists.org/forum/showthread.php?224923-Real-Time-pyDrivers
PyDriver Videos
https://www.youtube.com/watch?v=6v5gtbaDfHk
https://www.youtube.com/watch?v=HOeoVJYupQk
SHAPE KEYS + DRIVERS FOR PROCEDURAL MODELING
Limitation: Mesh needs to have same number of vertices and topologyImagine you create some blend shapes or shape keys mesh. Each with Minimum and Maximum range of variations of shapes. You can then use Python to randomize the Shape Keys using Drivers (just like David Miller does). You will end up with unlimited procedural generative workflow.
Example below is a Cube with 3 Shape Keys that Scale in X, Y, and Z. I then assign Drivers with Python Binding ala David Miller above.
The Box will change procedurally for every frame changes. |
It is a little bit more complicated than before, but also more robust! You need a little familiarity with:
- Blender Drivers
- Python
- Blender Shape Keys
So, this is KEY on how you could do modeling procedurally in Blender. Always think of TEMPLATE and VARIATIONS.
MSMESHER FOR PROCEDURAL RANDOM DOODLE
How about try MSMesher Add-On to create random mesh?
Well, basically, Blender does not have Mesher that generate mesh using Particles, yet, but there are some Add-On out there that cleverly does this function. Above is one recent Add-On.
I give it a go:
Something that looks like random Corgi Poo. |
A real Particle Mesher is definitely something to look forward to in the future. When Blender got one, we can create a more interesting shapes. But you can do it today with this Add-On actually.
In the way, Skin Modifier is kind of doing Meshing for Polygon Edges, but using Particles we can get more interesting shapes. With Skin Modifier, you can create Procedural Maggots. Try it yourself.
BLENDER METABALLS BLOBS
To create random blobs, you can use Blender Metaballs Object that is instanced by Blender Particles and changing the Seed value or maybe scatter Particles that live only for 1 frame so that you get freshly generated Particles on each frame that will form a new blob shape for each frame.PS: Notice the extra stray Blob on the generated mesh? That is the original Metaball object that got exported when I tried exporting the OBJ sequence of Metaball. Maybe there is an option to get rid of it, but that can be cleaned up.
Once cleaned up, we have some nice interesting randomly generated blobs. What do we do with these blobs? Anything. I wish I have some connections with 3D printer or manufacturing because even such blobs when made into product will look quite interesting.
I assign basic Emission material to each blobs:
The glowing blobs reminds me of Light Blobs Chairs that is on display at Sydney Vivid Festival 2013 (still going on now).
Glowing Blob Chair at Sydney Vivid Festival 2013. |
LATTICE & SOFT BODY
Have you every tried using Lattice and Soft Body to randomly deform an object? Add Force to it as well and see what you could come up with.
Matrix of Generatively Modified Suzanne (using Lattice):
If the Lattice is more dense and the object is Remeshed with certain details, you can get more variations. You can always add Remesh Modifier, Reduce with Decimate Modifier, and also use Smooth Modifier to make sure the mesh toplogy is clean and no overlapping happening.
ADDON: Ivy Generator
You probably know this Ivy Generator Add-On that is inside Blender since a while back.
What would be interesting is if maybe we use Python to randomly place seed and tell Blender to also export out the Ivy.
I was also reading this SIGGRAPH Paper PDF about proceduralism titled "METROPOLIS":
Check out the part where they use Voxelation to build something that is like Procedural Building. Blender has the Remesh Modifier which could be perfect for this. Especially when accompanied with the OSL Shading Language to maybe procedurally make city texture.
See also:
SUICIDATOR PROCEDURAL CITY GENERATOR
http://cgchan.com/suicidator/
FUTURE: Random Creature Generator
This is my proposal on how one could create Random Generative Creature in Blender.
I am thinking to create something like this in near future, but maybe you want to make one before me. Go for it. Use Skin Modifier, use Mirror Modifier, or try all kind of Blender Modifiers and Python to create random shapes that can be further used in Design or other production.
Lastly, I am wondering a Python script that can change Geometry and update it every frame ... maybe I need to ask some Blender Developers. ---- the response I get: maybe too slow at the moment.
http://blenderartists.org/forum/showthread.php?245450-Real-Time-Python
http://www.blender.org/documentation/blender_python_api_2_60_6/bpy.app.handlers.html
http://learningblender3dsoftware.blogspot.com.au/2012/10/messing-around-with-prepost-handlers.html
http://blenderscripting.blogspot.com.au/2012/09/python-driven-animaion.html
So... I guess until PyNode happening, keep creative to discover and to invent Blender proceduralism.
http://www.noeol.de/attractors/
I might check PyDrivers and PyHandler stuff though...
Generative Stick Figures quick test. I am sure you can do better. |
Lastly, I am wondering a Python script that can change Geometry and update it every frame ... maybe I need to ask some Blender Developers. ---- the response I get: maybe too slow at the moment.
http://blenderartists.org/forum/showthread.php?245450-Real-Time-Python
http://www.blender.org/documentation/blender_python_api_2_60_6/bpy.app.handlers.html
http://learningblender3dsoftware.blogspot.com.au/2012/10/messing-around-with-prepost-handlers.html
http://blenderscripting.blogspot.com.au/2012/09/python-driven-animaion.html
So... I guess until PyNode happening, keep creative to discover and to invent Blender proceduralism.
http://www.noeol.de/attractors/
I might check PyDrivers and PyHandler stuff though...
BLENDER CURVE + ARRAY MODIFIER
Have I mentioned before that Blender Curve object has hidden ability? Yes, I did, many times in previous post.
You can actually create FEATHER, PIPE, GRASS, HOSE, TRUMPET or CHINESE FAN like below just by using a Curve, adjusting its Extrude, Feather Scale, in combination with Array Modifier to model a Chinese Fan.
I have tried similar concept both in Blender and Houdini:
Houdini proceduralism is of course more robust, it was made like that. But I say, doing it in Blender with its Semi Proceduralism, just by following similar logic is equivalently interesting.
JUST FOR FUN:
You can also create umbrella just by using Blender Curves + Array Modifier. Very easy. remember just use Curve and Array Modifier. The cool thing with this method is that you can easily change the bracket/cage or the shape and adjust the number of rotation.
JUST FOR FUN:
You can also create umbrella just by using Blender Curves + Array Modifier. Very easy. remember just use Curve and Array Modifier. The cool thing with this method is that you can easily change the bracket/cage or the shape and adjust the number of rotation.
5 minutes Umbrella. |
MAKE HUMAN + BLENDER SHAPEKEYS
Maybe try using Make Human for the Base Mesh and Shapes:
Take it further so that you could produce 3D printed generative models this way.
WISHLIST: custom 3D Printed Food and Chocolate, all in random variations, made in Blender.
Post a Comment