Responsive Plants
The Responsive Plants Template uses physically reactive collision rigs to create plants that can deform based on physical forces. It features four plants that are ready to implement in your own Lenses. Additionally, the template includes Scripts that you can use to make your own 3D-rigged plants responsive.
The Responsive Plants Template was created and provided by Bare Tree Media
Video Walkthrough
In this Lens Studio tutorial, Naomi will walk you through how the Responsive Plants Template works with the latest version of Lens Studio's Physics system.
Template Walkthrough
The core structure underlying each of the plant rigs in this template is a chain of dynamic and tangible Physics Bodies that form semi-rigid plant parts like stems and fronds. These Physics Bodies each drive the position and rotation of a joint in a 3D-rigged plant, causing the plant’s mesh visual to deform based on the bone movement. In addition to physics bodies, some of the examples have additional constraints and weights that lift and counterbalance certain parts of the plant. Let’s explore the examples!
It is recommended to learn more about the Lens Studio Physics System before diving into the Responsive Plants.
Example 1: Seaweed
Seaweed features a basic sample of the chained colliders that form a flexible plant frond.Think of this as an upside-down version of Chain Physics. The seaweed fronds are “hanging” up from the ground, using a Physics World resource with upward gravity.
Each seaweed frond uses a simple chain of collision bodies, each of which is constrained to the one directly below it. Since the seaweed fronds are long and flat, they use rectangular bodies and hinge constraints to limit their flexibility to one axis.
Each group of seaweed uses a Plant Settings Script. Learn how this script works in the Support Scripts section below. Note: The Seaweed Example does not use any “Extra Rigging” - it is made up entirely of physics bodies and constraints that form the actual frond.
Example 2: Daffodils
Watch out - the daffodil example adds some tension into the mix! Let’s get back to standard gravity, and explore how these flowers manage to stand upright.
Each Daffodil stem uses a similar basic setup to the seaweed, with some key differences. The collision bodies used for the daffodil stem are cylindrical, which gives them some more freedom to “twist” slightly. Additionally, the “stem-chain” constraints are fixed, making the stem joints less likely to bend. However, this is not enough tension on its own.
The daffodil stem requires a tension rod to maintain most of its rigidity. This is a long, intangible cylinder collider which spans from the base of the stem to the flowerhead. The top collision body of the stem is constrained to the tension rod, which is in turn constrained to the ground. This forms a “loop” of constraints which allows the tangible stem to flex slightly, but forces it to maintain its length.
The tension rod is constrained to the ground with a vertical hinge, which keeps it upright, but allows the stem to sway from side to side. Note: You can use the visualizer script attached to each Daffodil SceneObject to view the tension rod by selecting “Show Extra Rigging”, and to view its Hinge Constraint by selecting “Show Extra Rigging Constraints”.
Example 3: Potted Fern
The Potted Fern is primarily made up of many copies of a single responsive plant element: the Suspension Frond. Each Suspension Frond is similar to a frond of seaweed. Like the seaweed, the suspension frond uses rectangular collision bodies to limit twisting along each frond.
Since each frond expands horizontally, a tension rod is not enough to keep it upright. Instead, a crane system is used to hold each frond in its primary position. Imagine a vertical spire that sticks up in the center of the plant. From that vertical spire, a horizontal bar sticks out directly above each plant frond. Each of the collision bodies that make up the frond itself are essentially held up by strings attached to the horizontal bar. While each frond has its own horizontal “Crane Boom”, there is one vertical spire, called the “Center Tether”, which is shared by all of the suspension fronds.
Additionally, since the potted fern is made up of many suspension fronds that spread weight in many directions, balance becomes an issue that cannot be ignored. The pot includes stabilizing elements to help it stay upright, and improve the strength of the center tether. There are 8 counterweights positioned in a ring far outside the bounds of the plant. These are intangible, but still carry weight, which is spread wide to keep the Pot+Plant systems’ overall center of mass low.
The Center Tether, Crane Booms, and Counterweights are all considered “Extra Rigging”. You can use the visualizer script attached to the Potted Fern SceneObject to view the weights that make up these components by selecting “Show Extra Rigging”, and to view the constraints that hold it together by selecting “Show Extra Rigging Constraints”.
Example 4: Palm Tree
The Palm Tree explores a rigidity-focused design with a trunk made of many disc-shaped segments layered on top of each other. Each segment is heavily constrained to the one below it to keep them sandwiched together like a stack of magnets. The overall height of the trunk is determined by the starting Y-position of the “Top Group”.
The trunk itself is generated On Start by a script that makes several copies of a cylindrical collision body, and constraints each of these segments to each other to form the stack. Each segment has the same height, calculated automatically as a portion of the overall trunk (Total Height / Segment Count). The radius and density of each segment are interpolated linearly based on the segment’s position in the stack, between specified radius and density values for the top and bottom segments.
The Top Group consists of one extra trunk segment that automatically gets constrained to the last script-generated segment. This segment allows the rest of the treetop to be built in the Scene Panel. The palm fronds in this example are composed of intangible, static colliders. The mass of the fronds is approximated by the mass of the top trunk segment. The four coconuts attached to the Top Group Base Body each have their own weighted bodies, and Behavior Scripts that deactivate their respective constraints, allowing them to drop in sequence.
The Stack Trunk Builder
script highlights options that can be modified to alter various aspects of the trunk that is generated. These factors work together to affect the properties of the resulting trunk.
- Reference Segment [SceneObject]: A unit cylinder that is copied to create each segment of the trunk. The script destroys the Reference Segment as soon as the trunk is generated.
- Top Group [SceneObject]: This object’s Y-position is used to calculate the height of the trunk.
- Tree Top Base Body [Physics.BodyComponent]: The physics body that will be constrained to the final trunk segment
- Base Anchor [Physics.ColliderComponent]: the “ground” to which the base segment will be constrained
- Segment Count [integer]: The number of script-generated segments
- Base Radius [float]: the radius of the base segment
- Top Radius [float]: the radius of the top segment (not counting the Top Group)
- Base Density [float]: the density of the base segment
- Top Density [float]: the density of the top segment (not counting the Top Group)
- Constraint Count: the number of constraints per segment
- Constraint Width: the distance from the center of the stack where the constraints will be positioned, expressed as a percentage of the width of each given segment. A value of 1.0 will place each layer of constraints right along the edge of each segment that is being constrained.
- Show Constraints: check ON to enable visibility of the constraints
The Stack Trunk Builder
script is provided as an inspirational and educational example. It is designed for a greater range of experimentation with physics bodies. Unlike the generator scripts detailed below, Stack Trunk Builder does not contain automatic 3D rig tracking functionality.
Support Scripts
ResponsivePlantSettings.js
The Responsive Plant Visualizer
is built to help troubleshoot plant rigs quickly. It allows you to quickly apply settings to all objects in a plant rig. By default, this script applies to its own SceneObject plus all of its descendants in the scene hierarchy. You can attach this script to a group and quickly edit the physical properties of all plant bodies contained in that group.
You can add specific descendant objects to the “Extra Rigging” list. This list is meant to include abstract rig components such as counterweights, cranes, tension rods, etc. Settings within the “Physics Setup” dropdown will not apply to objects in the Extra Rigging list, or their sub-hierarchies. Essentially, the Extra Rigging would be anything that is not supposed to be a tangible part of the plant.
- Show Mesh Visuals: enable/disable all Render Mesh Visual components (except in Extra Rigging groups)
- Show Physics Bodies: enable/disable the “Show Collider” setting on all Physics Body components (except in Extra Rigging groups)
- Show Primary Constraints: enable/disable the “Show Constraint” setting on all Physics Constraint components (except in Extra Rigging groups)
- Show Extra Rigging: enable/disable all Render Mesh Visual components and the “Show Collider” setting on all Physics Body components in Extra Rigging groups
- Show Extra Rigging Constraints - enable/disable the “Show Constraint” setting on all Physics Constraint components in Extra Rigging groups
- Extra Rigging: specify a list of physics object groups that are not part of the tangible plant
- Physics Setup: apply settings to all plant physics bodies (not applied to Extra Rigging)
- Density: set the density property for all plant segment colliders
- Damping: set the dampingproperty for all plant segment colliders
- Angular Damping: set the angular damping property for all plant segment colliders
- Plant Matter: Specify a Physics Matter resource to be used by all plant segment colliders
- World Resource: Specify a Physics World resource to be used by all plants in the group
- Override Matter: enable modification of the Plant Matter resource via this script
- Override World: enable modification of the Physics World resource via this script
- WARNING: changing the “Override” settings will affect their respective resources directly. If other objects in the scene use the same Physics Matter or World resources, these settings overrides may cause the other objects to behave unexpectedly.
BonesTargetColliders.js
This script links a 3D rig to a Collider Rig. Specify physics objects to use as tracking points for the bones / joints in a 3D rig. On an Update Event, the script copies the simulated position and rotation of the trackers, and transforms the bones in a 3D rig to match.
Rigged bones drive the deformation of a plant mesh based on how they are skinned in an external 3D design software. See Rigging Best Practices below.
BonesTarget Colliders standalone script does not build a collision rig - to use this script, you must build a collision rig in the scene panel. This means that Bones Target Colliders can be used with custom plant rigs that you develop!
Make sure that the number of input bones matches the number of input colliders. For this script, it is not necessary to include the end joint of a bone chain. Usually, when constructing a collision rig manually, you will not need to create a collider that points past the end joint.
TensionStemGenerator.js
Plug in a 3D Rig, and let the script build the colliders for you! For each rig bone you specify, this script will generate a collision segment that corresponds to the bone. The bones will automatically be targeted to the collision segments, so you do not need to add a Bones Target Colliders script.
The Tension Stem is optimized for flowers with vertical stems that have a very slight bend. You must specify a Base Anchor Collider, which is essentially the ground that the stem grows out of. You can specify a collider that acts as a weight for the flowerhead. The script will not build this collider, but will attach it to the end of the topmost stem segment!
-
Base Anchor: Specify a Physics Collider to constrain the base of the plant to
-
Stem Joints: Specify the bones/joints used to generate the stem
- It is important to include the end joint in this list because the script will need to use the end joint’s position to build the final segment of the Collision Rig.
-
Flowerhead Collider: Specify a collider to constrain to the top segment of the stem
- You can create a head collider object manually, and feed it to the script, which will attach it to the tip of the generated stem.
- If you are using a flowerhead, keep the head mesh separate from the skinned stem rig while you design it in a 3D program. Once you import everything into Lens Studio, you can simply parent the head mesh to the head collider, and it will be attached to the collision rig!
- Make sure to input the end
-
Stem Matter: Specify a Physics Matter resource for the stem segments
-
Base Radius: the radius of the base stem segment
-
Tip Radius: the radius of the tip stem segment
-
Base Density: the density of the base stem segment
-
Tip Density: the density of the tip stem segment
-
Show Colliders: show / hide all colliders (including the flowerhead collider, if specified)
-
Show Constraints: show / hide all constraints
-
Advanced Setup
-
Damping: set damping property for all generated physics bodies
-
Angular Damping: set angular damping property for all generated physics bodies
-
Intangible Base Segments: Specify a certain number of segments at the base of the stem to be intangible. This can help prevent strange behavior if plants are rooted very close to each other.
-
Segment Length: set the length of each collider segment, expressed as a percentage of the length of the bone that each collider segment is based on. Lower values add space between the bones, increasing flexibility, but values too low can lead to floppy results.
-
Constraint Count: how many constraints are applied from segment to segment. Increasing this value can increase overall firmness of the segments’ connection points.
-
Tension Constraint All
-
If true, every segment gets a constraint targeted to the tension rod. This can help maintain a firm structure for rigs that have many small bones.
-
If false, only the last segment gets such a constraint.
-
SuspensionFrondGenerator.js
Plug in a 3D Rig, and let the script build the colliders for you! For each rig bone you specify, the script will generate a collision segment that corresponds to the bone. The bones will automatically be targeted to the collision segments, so you do not need to add a Bones Target Colliders script.
The Potted Fern example is composed of many individual Suspension Fronds. Each suspension frond relies on a Center Tether to hold it up. Multiple fronds can share a single Center Tether. For best results, fronds should be oriented so they spread directly out from a center point.
-
Frond Joints: Specify the bones/joints used to generate the frond
- It is important to include the end joint in this list because the script will need to use the end joint’s position to build the final segment of the Collision Rig.
-
Base Anchor: Specify the Physics Collider to constrain the base of the plant
-
Center Tether: Specify the Collider to use as a tether for the crane
-
Frond Matter
-
Base Density: the density of the base stem segment
-
Tip Density: the density of the tip stem segment
-
Base Collider Lateral Scale: the radius of the base stem segment
-
Tip Collider Lateral Scale: the radius of the tip stem segment
-
Show Colliders
-
Show Constraints
-
Advanced Setup
-
Crane Density: set the density of the crane (default is 1.0)
-
Crane Rise Adjust: adjust the height of the crane, between the Center Tether and the apex joint of the frond
-
1.0 is level with the center tether
-
0.0 (default) is directly in the middle
-
-1.0 is level with the apex joint
-
Intangible Base Segments: Specify a certain number of segments at the base of the stem to be intangible. This can help prevent strange behavior if plants are rooted very close to each other.
-
Unconstrained Tip Segments: set the number of segments at the tip of the frond which will not be constrained to the crane, and will hang freely from the tip of the segment before it.
-
Entering a negative value for this field will cause the script to automatically use the segment at the apex of the frond curve as the threshold for unconstrained segments. This means that the “rising” portion of the frond will be fully constrained, and any segments after the highest point will hang freely.
-
Segment Length: set the length of each collider segment, expressed as a percentage of the length of the bone that each collider segment is based on. Lower values add space between the bones, increasing flexibility, but values too low can lead to floppy results.
-
Support Prefab: Flowerpot
Any plant needs firm ground to support itself! The Flowerpot provides a portable option that is weighted to give plants the proper grounding. The Pot Collider can be used as a Base Anchor for any of the other plants in the template. The pot includes a stabilizing system of widely-spread counterweights, and a Center Tether to help support suspension fronds.
Modeling / Rigging Tips
The generator scripts are abstracted so they can use any rig, so you can use them on your own plants! Below are some tips on modeling and rigging stems and fronds that will be optimized to work well with the generator scripts.
General Advice
Rig the plant in its “resting” position - no need for a “t-pose” for your bones. (One of the modeling techniques detailed below does involve modeling a flat frond, but it should be curved for the rigging and skinning phase.) The auto-rig scripts use the initial position of the bones in the 3D Rig to determine the “base” position and rotation of the collider rigs. If force is applied to the collider rigs, they will try to morph back to their base positions and orientations, resulting in the “natural” shape of the plant.
How detailed should the model be?
This depends on several factors! The general rule is: more bones and more vertices will lead to a smoother result. Keep in mind how much of a “featured” element you want your plant to be. If there will be just a few plants that will be a significant part of your lens, it is probably best to include plenty of detail. If you have many plants in the scene, or if the plants are a minor scene element, it may be better to keep a low detail level.
Model + Rig Workflow
These workflows are developed and presented using Blender, but many of the techniques are applicable to other 3D design programs. Some familiarity with 3D modeling and rigging is recommended.
Cylindrical Stem
The “Skin” modifier can let you quickly build a rough stem shape that will end up being very rig-friendly. This modifier takes each edge of a mesh, and generates a tube for that edge. Essentially, you will create a line of connected vertices that determines the stem or frond’s path, and the modifier will add thickness to the line. (To be clear - the Skin modifier is not used for “skinning” the model to the rig.)
Base Model
-
First, create the initial vertex. Create a mesh cube, enter Edit Mode (Vertex), select all the vertices and use the “Merge At Center” command to collapse them all into one point.
-
Next, build a curve by extruding many small segments. Select the first vertex, and extrude slightly in the direction you’d like the stem to travel, and then extrude that next one, and so on, until you have a path with a nice curve.
-
Return to Object Mode and apply a Skin modifier to the object. It should now show as a rectangular tube that follows along the path.
Refine the Stem Mesh
-
Let’s smooth it out! Add a “Subdivision Surface” Modifier. You will probably want to turn the Subdivision Levels up to at least 2.
-
To add some tapering to the model, go back into Edit Mode (Vertex). Here, you can select a vertex and use the Mesh > Transform > Skin Resize command to alter the thickness of that point.
-
If there are any segments that have visible bends, you can increase the detail of that part of the curve by adding an edge “loop”. Use the Loop Cut and Slide command, and click on an edge where you want a smoother curve. (Don’t forget to move the new vertex!)
-
Use X-Ray and Wireframe Shading views to easily select your actual vertices while being able to see the resulting mesh shape.
If you are using a flowerhead, model the head mesh separately from the skinned stem rig, and do not skin the head mesh. Once you import everything into Lens Studio, you can simply parent the head mesh to a head collider, and constrain the head collider to the topmost stem segment!
Flat Frond
Since the frond has a flat cross-section, the Skin method won’t be as effective. Instead, we can use a Curve.
Base Model - Fully Extended
-
Model the Frond pointing straight up. Start with a cube and scale it to the size of a frond as though it is fully extended.
-
Add edge loops as needed for detail. Make sure to create enough loops along the cross section so the frond can bend smoothly.
-
Scale various edge loops to create tapering. Consider using Proportional Editing to smoothly scale nearby edge loops together. If you do, make sure you restrict scaling to the horizontal plane so as to avoid adjusting the height of nearby edge loops.
Apply a Curve
Once you have a shape that you like for the fully extended frond, create a curved object, and position it in a way you would like the frond to be curved. This example shows a NURBS curve with 5 control points.
Select the frond mesh object, add a Curve modifier to it, and add the new Curve Object to the modifier. If the frond orients in an unexpected way, you can rotate the frond around the vertical axis to adjust its orientation about the curve.
Unwrap UVs
Don’t forget to do this before skinning! You don’t have to make finalized textures yet, but UV data must be generated before the mesh is rigged or you might risk warped textures or other glitches.
Build Armature with Position Snapping
-
Stem Model Prep: Using the Skin modifier means the mesh is actually a string of vertices right in the center of the mesh, perfectly prepared for joint positioning.
-
Frond Model Prep: If you have a center edge loop along the long, flat side of the frond, this will provide a nice line of vertices to easily snap joints into place.
-
Activate Position Snapping in the viewport, and set the snap target to “Vertex”
-
Create an Armature Object, and position it at the base vertex.
-
Enter Edit Mode. Extrude the first bone. Move that bone so it snaps to the next vertex. Repeat until all bones are built!
Skinning the Mesh
- Make a copy of your mesh that will maintain the modifiers. Hide one copy.
- Apply all modifiers to the second copy of the mesh.
- Armature Deform the mesh to the rig (Select the mesh, then the rig, then press “P” and select your preferred )
Importing 3D Content
Once you have your 3D model rigged and exported, import it into Lens Studio by selecting File
-> Import from the menu bar. Then, add your model into the scene by dragging it from the Asset Browser
panel into the Scene Hierarchy
panel.
If your plant uses either a Tension Stem or a Suspension Frond, simply add a Script Component, and apply the appropriate generator script. Specify the model’s bones / joints in the script component, as well as any necessary colliders, and your collision rig should be generated once the Lens starts. Read more about how the Generator scripts create collision rigs above.
Building a Custom Collision Rig
Perhaps you are envisioning a type of plant that doesn’t behave exactly like the examples here! The examples all have different support and counterweight structures, but the key similarity between all the examples provided here is the chain of Physics Bodies that make up the plant. Your custom plants will most likely have some form of tendrils, vines, other types of stems and fronds, etc. Here are some tips on building the chain that represents the physical portion of the plant:
-
Start with a rigged model! A collider rig is significantly easier to build if there are bone positions you can reference.
- If you are manually constructing a collision rig, it helps to have your 3D rig align with one of the horizontal axes. This will make it easier to rotate collision bodies into place.
-
Consider adding a Flowerpot Prefab to your scene for grounding. In order to be flexible, your plant will need some sort of “ground” collider to anchor to at its base. Depending on how your plant behaves, it might benefit from the built-in extra support of a weighted tether.
-
To build a collision segment:
-
Create a Scene Object with a
Physics Body component
. Place, orient, and scale it so that it lines up with the first bone in the plant rig. -
Think about how your plant is shaped, and how you want your plant to deform. Explore the examples in the template - some use boxes, some use cylinders. perhaps yours will use a different shape!
-
Set the
Physics Body
todynamic
and add a constraint by clicking the+ Add Constraint Object
button on thePhysics Body Component
.- The Constraint Object will appear as a child of the
Physics Body Object
. On the constraint object’sTarget
setting, enter thePhysics Body
orCollider
that the constraint should anchor to.
- The Constraint Object will appear as a child of the
-
The first constraint target will be the ground, and each subsequent constraint should target the bone before it in the chain.
-
Set the constraint to
Fixed
for constraints that form the chain itself. The spaces in between the colliders are meant to give some flexibility, but
-
-
Pay attention to scene hierarchy. Whereas classic 3D rig bones use a nested hierarchy, constrained physics bodies and colliders must not be hierarchically linked.
-
Above: Classic nested-hierarchy rig
-
Above: Collision rig. The Physics Body objects that make up a collision rig can be grouped together, as long as the Physics objects are not parents of one another. Even though the Stem Collider objects form a linked chain via constraints, they all exist on the same hierarchy level. Constraints have to be direct children of the object that they constrain.
-
Above: Stem Collider 1 is anchored via its Base Constraint to the Ground Object. The Ground is able to be in a totally separate group from the Stem Collider because the Base Constraint will tie them together once the Lens starts. Importantly though - Stem Collider 1 is not within the scene hierarchy of the Ground. Because of this, the Ground can have transformations determined elsewhere in your scene, such as scripted animations. It will affect Stem Collider 1 via the constraint, but not via relative transform space.
-
-
Continue placing and constraining collision segments until they cover the whole plant.
- Consider leaving some extra space between each collision segment. If they are sandwiched against each other, there will be very little room for them to flex. However, if there is too much space, they may have trouble retaining tension. To learn more, experiment with the “Segment Length” property in the Advanced Setup section of the Suspension Frond Generator script.
-
Finally, you are ready to experiment with different suspension systems! Look to the examples for ideas on how to build extra rigging.
- Extra rigging is primarily made up of dynamic, intangible physics bodies. These react to gravity, but won’t collide with other objects, so they can essentially create “hidden weights”. They will still allow the main collision segments to move somewhat freely, but they can alter the overall distribution of weight.
- Try different kinds of constraints! Point and Hinge Constraints can provide some extra freedom of movement, which may translate to additional flexibility and fluid motion.
- If a fixed constraint isn’t strong enough, add more! Multiple constraints can help collision bodies stay in their constrained orientation when they are pushed by stronger forces. It often helps to have multiple fixed constraints in different positions.
Previewing Your Lens
You’re now ready to preview your Lens! To preview your Lens in Snapchat, follow the Pairing to Snapchat guide.