A common technique for laying out random objects on a scene in Blender is to use the Particle System. (That is, before Geometry Nodes in Blender 2.92)
In this tutorial, we are going to explore how to lay out objects in a scene randomly and export that scene for use with OGRE.
This tutorial is based on the ideas shown in this "CG Geek" video: Create Realistic Grass in Blender 2.8 in 15 minutes
Terminology:
- Base Object: an object with a mesh that represents a terrain or some other form on which we want to place random objects on.
- Dupli Objects: an object with a mesh that represents random objects (like grass, trees, rocks, etc.) that we want to place on the Base object.
The scene in the images is available here, it was made with the A.N.T Landscape Plugin that comes bundled with Blender (River preset) and very simple "Earth" and "Water" materials.
Select the mesh where you want to place your foliage or debris (the Base Object).
Go to the Particles
tab and click on new to add a new particle system.
Select type: Hair
and click on Advanced
to show the advanced options.
By default Hair Length
is set to 4 which makes the debris show 4 x larger so set the value to 1.
With Number
it is possible to control the number of objects that will appear randomly on the mesh surface.
Click on Rotation
and select Initial Orientation: Normal
.
You can change the Phase
and Random
values to have the debris show random rotations around the Z axis (tangent space), this way if you have trees they will be showing in different orientations.
In the Render
setting change the type to Object
and in Dupli Object
select the object you want to duplicate randomly over the mesh.
Check the Rotation
and Scale
options so the Particle System will take the Dupli Objects rotation and scale into account.
Set Size
to 1 and choose a Random Size
value to control the amount of randomness in the size distribution of the Dupli Objects.
At this point, you should see the object appearing randomly in the places where there were hair strands.
But, the objects appear rotated -90 degrees over the Y axis.
To solve this it is necessary to rotate the Dupli Object 90 degrees over the Y-axis to counter this rotation.
Don't apply this rotation to the Dupli Object, otherwise the blender2ogre
add-on will export the mesh with this rotation applied.
The add-on will automatically apply this rotation to the nodes in the exported scene.
Another thing to take into account is that the Dupli Object origin should be at its base, otherwise it will appear to be buried halfway.
It is also possible to paint certain parts of the Base Objects mesh to modify the Dupli Objects density by using weight painting. Select the Base Object, go into weight paint mode and start painting the areas where you want to increase the Dupli Objects density.
Remember that the Base Object should have some tesselation for this to work well, otherwise there might be few vertices to paint. One way to tesselate is to go into Edit mode and subdivide or activate Dynotopo in Sculpt mode.
After painting the areas go back to the Particles
tab and in the Vertex Groups
section choose the vertex group in Density
and Length
(the default vertex group is Default
).
Some tips for troubleshooting:
- Don't apply the 90-degree rotation on the Y axis to the Dupli Object, that rotation is just to see the object well placed in Blender
- Make sure that the origin of the Dupli Object is centered in the base
- Apply any scale used on the Dupli and Base Objects
- Check the logs for any errors or warnings (in Windows: Window > Toggle System Console)
After adding the second particle system you will probably be asking for a way to automate the process of adding more foliage/debris layers to the scene.
That is possible with a very simple Blender script, switch to the Scripting
layout and copy the following script:
import bpy
def add_debris_layer( object_name, seed=1, number=100, phase=1, random=1, size=1, size_rnd=1 ):
bpy.ops.object.particle_system_add()
index = len(bpy.context.object.particle_systems) - 1
particle_system = bpy.context.object.particle_systems[index]
particle_system_settings = particle_system.settings
particle_system.name = object_name
particle_system_settings.name = object_name
particle_system_settings.use_advanced_hair = True
particle_system_settings.type = "HAIR"
particle_system_settings.hair_length = 1
particle_system_settings.count = number
particle_system.seed = seed
particle_system_settings.use_rotations = True
particle_system_settings.rotation_mode = "NOR"
particle_system_settings.phase_factor = phase
particle_system_settings.phase_factor_random = random
particle_system_settings.render_type = "OBJECT"
particle_system_settings.use_rotation_dupli = True
particle_system_settings.dupli_object = bpy.data.objects[object_name]
particle_system_settings.particle_size = size
particle_system_settings.size_random = size_rnd
bpy.ops.object.vertex_group_add()
index = len(bpy.context.object.vertex_groups) - 1
vertex_group = bpy.context.object.vertex_groups[index]
vertex_group.name = object_name
particle_system.vertex_group_density = object_name
particle_system.vertex_group_length = object_name
# Example usage:
add_debris_layer("Bush", 1)
add_debris_layer("Grass 1", 2)
add_debris_layer("Stone 1", 5)
add_debris_layer("Tree 1", 10)