Wednesday, November 29, 2017

Create an array of planes that fits inside of Camera View using Drivers


This tutorial is based on a question from Blender Stack Exchange user 3pointedit

The main goal is to create a variable count of Plane objects in array (row) that fit in Camera view with additional option for offset space between the objects and the Camera view bounds as well as different coloration of the tiles. Here is a preview of what we are going to create:



This tutorial includes using Custom Properties, Drivers and Compositing and not very complicated mathematical expressions. It is oriented more to the advanced Blender user but I will gladly answer any relevant question left in the comments below.

Warning: Read it slowly to avoid headache :)


If you feel lost - after each main stage you can download a blend file with the current progress.


Let' s Begin!


Start with an empty scene (delete everything). Create a default Plane and rotate it 90 degrees around X axis. Apply Rotation & Scale (Fig. 1).



Figure 1. Create empty scene and add default Plane object aligned to Front view.

Add an Array Modifier with default values.


How Array Modifier's Relative Offset Works and some Math


Let's examine the X value of the Relative Offset parameter (Fig. 2).



Figure 2. Add Array modifier to the Plane.

Value of 1 means no offset from the previous copy.
Value of 2 means the next copy is offset by the width of the original object.
Which means that the offset distance is relative to the object's width and is equal to:

width * (x_off - 1)          (1)

where width is the X dimension of the object,
x_off is the relative offset

width + width * (x_off - 1)          (2)

represents the common width of the object plus the offset distance.

To find the actual width of the object after Array modifier (including the last offset distance) we have to multiply the above equation by the number of copies:

n * (width + width * (x_off - 1))          (3)

where n is number of copies (Count property in Array modifier)

For our task we need to scale back the width of the array object to the initial width size (including the empty space from the last offset distance).

Finding the X scale factor that will bring back the array object to the initial width


We have to find the scale factor that will do the trick. It is simply dividing the original width by the width of the array object:

x_ scale = width / (n * (width + width * (x_off - 1)))          (4)

where x_scale is the scale factor for the X axis

Let's clean up the above equation:

x_ scale = width/(n * width * (1 + (x_off - 1)))          (5)
x_ scale = width/(n * width * (1 + x_off - 1))          (6)
x_ scale = width/(n * width * x_off)          (7)

x_ scale = 1/(n * x_off)          (8)

So, finding the scale factor does not require the width of the object itself

Finding the X location of the center of the array object


Initially the Plane's center (not origin) is located at 0 on the X axis
with each copy the center of the object will move to the right. The relative center of the array object is the width of the Plane multiplied by the number of copies and divided by two

n*width/2          (9)

with the offsets added:

n * (width + width * (x_off - 1))/2          (10)

So we have to move the whole array object back to the left:

width/2 - n * (width + width * (x_off - 1))/2          (10)

Don't forget that we have an offset empty space at the end of the array object so we have to move to the right the half offset distance in order the visible parts to be centered:

width/2 - n * (width + width * (x_off - 1))/2 + width * (x_off - 1)/2          (11)

And because we apply a scale factor to the width of the array object we have to apply the same scale factor (x_scale) to the transformation for the array object:

x_location = (width/2 - n * (width + width * (x_off - 1))/2 + width * (x_off - 1)/2) * x_scale     (12)

where x_location is the new position of the Plane's origin

If we simplify this equation we get

x_location = (1-n)*width*x_off*x_scale/2          (13)

we can further simplify by replacing x_scale with the equation (8)

x_location = (1-n)*width*x_off*(1/(n * x_off)/2           (14)

Finally we get:

x_location = ((1-n)*width)/(2*n)           (15)

effectively solving x_location with two variables

Solving the task

Prerequisites


We need three custom properties that will control our Array object:

count - that will control the number of copies
x_offset - that will control the horizontal offset between the copies
z_offset - that will control the vertical offset between the copies

We also need a reference object that will hold an information for the initial dimensions of the Plane and specifically its width. To do that create a linked duplicate of the Plane (Alt+D) move it above and rename it to Reference. Also delete the Array modifier for the Reference object (Fig. 3)



Figure 3. Create linked duplicate of the Plane and name it Reference. Move it up out of the way.


Let's create the custom properties for the Plane.

In Object tab of the Properties editor - go to Custom properties and Add and Edit three properties with the following settings (Fig. 4):

1. count
Property Name: count
Property Value: 1 (note that the value is integer not float)
Min: 1.000
Max: 100.000

2. x_offset
Property Name: x_offset
Property Value: 1.0
Min: 1.000
Max: 2.000

3. z_offset
Property Name: z_offset
Property Value: 0.0
Min: 0.000
Max: 1.000




Figure 4. Add 3 custom properties for the Plane with the given settings.

In Properties Shelf locate and expand  Properties panel for easy access (Fig. 5).



Figure 5. Make sure the Properties shelf is open and the custom properties visible.

You can download the progress so far here:

Prerequisites.blend

Drivers


We will use two methods for adding drivers (Fig. 6):

1. Right click  ( or Ctrl+D) over property - Add Driver - Single from Target - Click with the Picker over Target property
2. Right click  ( or Ctrl+D) over property - Add Driver - Manually Create Later (Single)



Figure 6. This is the usual menu for adding drivers to property.

So let's create the first driver!

Right click over Count property of the Array modifier of the Plane and select Add Driver - Single from Target. Move the Picker over the count custom property of the Plane and click.

Add Graph Editor view to access the drivers channels (Fig. 7)



Figure 7. Create Graph Editor view and open Drivers context view.

Click on the Count channel and go into Drivers tab.
Change the variable name of var to n.
Enter in Expr: field - n
Increase the count value to observe adding new copies to the array (Fig. 8)



Figure 8. Our first driver controls the number of Plane copies.

Similarly, let's add driver for the X value of the Relative Offset of the Array modifier.
Again use Single from Target but this time the Target property is x_offset custom property of the Plane.
Change the variable name var to x_off and type in Expr: x_off. Modify the x_offset value to observe different spacing between the copies (Fig. 9)

.

Figure 9. The second driver controls the Relative Offset X value.

Go to Object tab, Transform panel and add driver for the X Scale this time use Manually Create Later (Single).
Click on the X scale channel in Graph Editor to view the driver variables.
Rename the variable var to n and change its type to Single Property.
Select Plane object in Prop field and type: ["count"] in Path field
Add another Single Property variable.
Name it x_off.
Select Plane as object and type: ["x_offset"] in Path field.

In Expr field we'll enter the right side of the equation 8:

1/(n * x_off)

Play with the count and x_offset properties and observe how the array keeps the initial width but slightly moves to the right (Fig. 10).



Figure 10. The third driver scales the copies to fit the initial width of the Plane.

To fix that shift let's add driver to X Location of the Plane.

Right click over X value of Location parameter and add Single from Target driver. The target property is count.
Change variable name var to n.
Add second Single Property variable and name it width.
This time as object select Reference and in Path type: dimensions[0].
In Expr: field enter the right side of the equation 15:

((1-n)*width)/(2*n)

If everything is correctly done changing count and x_offset properties will not affect the position and width of the array object while changing the number of copies and the offset between them  (Fig. 11).



Figure 11. The fourth driver moves the Plane object so the whole array stays in place when the user changes the custom properties.

Finally, lets add driver for the vertical offset.
Add single driver from target to the Z Scale value of the Plane object. As target pick z_offset
Rename var to z_off.
Type the expression:

1 - z_off

Changing z_offset custom property will scale the array object vertically (Fig. 12).



Figure 12. The fifth driver controls the vertical scale of the Plane.

Because the drivers update from the custom properties we can change the dimensions of the Plane to our liking.
If we want to fit a Plane to Camera view we need to make the aspect ratio of the Plane dimensions and Camera frame equal.
Lets Add Orthographic Camera to the scene and move it along -Y axis (Fig. 13).



Figure 13. Create Orthographic Camera and place it in front of the Plane.

You'll notice the Resolution is 1920x1080 with aspect ratio of the image 16:9.
You can use any resolution as long as you know how to derive the image aspect ratio from it.
In this case our Plane object must have width to height ratio - 16 : 9.
As we already have Reference object as linked duplicate any vertex editing of the Reference will reflect to the Plane object.

In front view select Reference object, enter Edit mode and scale all vertices along X axis by 1.6, then scale again along Z axis by 0.9. Exit edit mode and the Plane object will update with new dimensions that will correspond to 16 : 9 ratio.

Select Plane object and set all custom properties to default values (just drag the values with the mouse to the left) .Right click Reset to Default Value would not work for the count property and will reset the value to 0 instead of 1, that will cause division by zero error in the drivers. It's a bug - not a feature!

After properties reset go in Camera view and with Plane selected press Space bar and type in search field Camera Fit Frame to Selected (Fig. 14)



Figure 14. Camera Fit Frame to Selected command will do the magic that will fit the Plane into the frame.

This will change the Camera's Orthographic Scale and the Plane will fit completely inside the frame.
Test again the custom properties. The result should be similar to Fig. 15



Figure 15. The final look of the Plane with custom Array modifier which will always fit inside the frame.

With that the drivers set up for the Plane is complete.

You can download the progress so far in the blend file below:

Drivers.blend

Adding unique colors to the tiles.


As final touch we will add unique color to each tile. This could be useful for selective masking of specific tile by its color.
A quick and easy approach is to take advantage of the color posterization effect.
We will create shadeless material and apply single blend texture to the plane object.
Then we will create a Shader node and with the help of a few Math nodes and custom Color Ramp we will add unique color to each tile.

First with Plane selected create new material and name it Mat_Tiles. Make the material Shadeless.
In Texture tab Create new Texture of Type: Blend
In Colors enable Ramp and change the Alpha of the Black color to 1.
In Mapping set Coordinates to Window (Fig. 16).



Figure 16. The initial settings of the Mat_Tiles material.

Download:

Material.blend

In Node Editor switch to Shader type, select Mat_Tiles material and enable Use Nodes. Select Mat_Tiles in Material node (Fig. 17)



Figure 17. The initial look of the Material nodes of Mat_Tiles.


Add the following nodes as shown in Fig. 18



Figure 18. Using some Math nodes and custom Color Ramp we can posterize the gradient of the Blend texture.

Finally we'll add a driver to the Value node to reflect the current number of the tiles defined by the count custom property.
Open Properties Shelf to reveal the custom properties of the Plane add single driver from target and pick the count property.

That's it!

Now whenever you change the number of tiles it will automatically change the number of colors too (Fig. 19).



Figure 19. The last driver will control the number of color posterization steps.

Download the final blend:

Final.blend

Note: Due to the nature of the Window coordinate space - Rendered viewport shading will work correctly only if the camera frame touches the edges of the window (as shown above). The best way to see the result of is to render.

Tuesday, November 28, 2017

Domino line-up using Curves as guide

You haven't used Blender Physics Engine if you didn't toppled a few dominoes.
It's fun and introduce you to the awesome world of physics in Blender.
One problem is that you probably arranged the dominoes painstakingly one by one and you don't have the whole time in the world for that.
There are few good resources of how to set up a domino toppling, but it's rare to find a good one that uses the aid of the Curve object in order to arrange a great looking line of dominoes.
Added some links at the bottom of the page.
So let's get into it.


This tutorial requires some basic knowledge of Blenders Interface and navigation through the program.
For anyone who is new to Blender don't feel discouraged. Please, ask your relevant question in the comments below and I will try to answer shortly and clearly as possible.


Preparing the domino tile


Start with the default blender scene.

This is not a modeling tutorial so we'll just create a basic shape of a domino, that could be easily replaced later on with more complex model.
Using the basic Cube object enter the following values for its dimensions (Fig. 1):

X - 1.0
Y - 0.3
Z - 2.0

I read somewhere that those are one of the classic proportions of a domino tile, so I believe its true.

Name the object Domino.



Figure 1. Creating the Domino model from the default Cube (here shown for comparison). You are forbidden to move on without completing this step!

You will notice that the Scale values above Dimensions also change. We have to bring each of them back to 1 to make sure the simulation will be correct. To do this lets apply the scale and rotation of the object. Pres Ctrl+A and select Scale in the Apply menu (Fig. 2).



Figure 2. Reset any transformations made to the object.

Creating the Curve object


There are many ways of creating curves and different types of them to pick. You are free to experiment and to find the best way for your artistic needs. Me, I will stick with creating a simple Path curve.
Go to Top view and press Shift+A to Add a Path curve. In edit mode, shape the curve, extrude the points, until you get the desired look (Fig. 3). Just make sure the first point is near our domino object. Notice the little arrows of the curve hinting where is the beginning and where is the end! Also our curve should be flat on XY plane!



Figure 3. Building the curve that will shape our domino line-up.

With that we have all we need to begin. But here we'll split the creation process into two variants:

Variant A - Duplication based on Frames
Variant B - Text on Curve

So save this file as starting point by creating a copy.
Feel free to explore each of them by returning to the starting file.

Variant A - Duplication based on Frames


From the starting file (Fig. 3) in Top view. Make sure you're in Object Mode. Select the Domino and then the Path. Press Ctrl+P and select Follow Path command (Fig. 4).



Figure 4. Parent the domino to the path using Follow Path option.

This will parent the Domino to the Path and if you play the animation you will notice that the domino travels alongside of it. To fix the offset position of the Domino, go to first frame, select the Domino and move it so its center is very close to the beginning of the curve. Also rotate the domino along Z axis to face the direction of the curve (Fig. 5).



Figure 5. Position the domino on the first frame of the animation over the beginning of the path and rotate it appropriately.

While playing the animation you may notice that the Domino is animated until frame 100, where it reaches the end of the path. Now depending on the length of the created path the Domino may travel in too big steps each frame and that could be a problem when duplicating the object (the spacing between the duplicates may be too big to collide with each other).

Figure 6. Set the Path Animation do desired number of frames (resp. number of duplicate objects)

To ensure good distance between each domino tile lets stretch the animation to be a little longer. Select the Path object and in Object Data panel find Path Animation and enter 250 for Frames parameter (Fig. 6).

Also make sure your animation also have 250 frames.

Now we are ready to duplicate the object based on its position during the animation.

In order for this to work we have to bake the object positions as keyframes for each frame. Select the domino object and press the Spacebar to search for the Bake Action command (Fig. 7). Check the options:
Only Selected
Visual Keying
Clear Constraints
Clear Parents




Figure 7. Bake Action command will set keyframe for each frame of the animation. Check the options shown.

After pressing OK the timeline will be filled with keyframes up to the last frame.
With the object still selected go to Object Properties panel and Check Duplication - Frames (Fig. 8)
Enter 2  for End value. You should see a duplicate of the Domino on each frame.



Figure 8. Duplication based on frames is where the fun begins.

That is too dense for our goal. To lower the count of the duplicates we'll take advantage of the Off property (Fig. 8) on the right side of the End property. It controls how many frames to skip for duplication. Entering a value of 8 seems to work for my case (Fig. 9).



Figure 9. A value of 8 for the Off property gives a decent spacing between the tiles.

You may notice that the objects have darker outline compared to the original Domino and are not accessible as separate objects. To convert them to real objects go to the end frame select the Domino object and press Ctrl+Shift+A or search for Make Duplicates Real command. This will make every object available for simulation.
Finally the original Domino is still animated so we have to erase its animation data. To locate the animated domino make sure you're on the last frame (250), our object should be the last on the line. Select it and search for Remove Animation. This command will effectively dispose of all keyframes and will make the object still.
Delete the path object or move it on another layer.


Setting up the physics simulation


This is a quick way to test your domino construction.

1. Create a Plane and scale it to encompass all of the dominoes. Move the Plane -1 units along Z. To avoid sudden jumps at the beginning of the simulation you could move it down a little further for example -1.03 units

2. In the Tools Shelf go to the Physics Tab and with the plane still selected press the Add Passive button.

3. Select only the domino tiles and press the Add Active button.

4. Select the first domino tile and rotate it slightly forward to make it unstable (Fig. 10). You can also rotate and reposition some of the tiles in Top view in order to make better collisions.



Figure 10. Final touches. Tilt the first tile slightly forward and rearrange some tiles for better collision.

5. Press Play (Alt+A)and enjoy your simulation of domino toppling.

6. Additionally in Scene panel - Rigid Body World you can play with the Speed property to make the simulation executing faster and looking more realistic. I changed the speed from 1 to 2.

Here is the final simulation:


Variant B - Text on Curve


Start with the file that we saved earlier (Fig. 3)
The procedure here is more simple. First rename the Domino object to "Domino-a".
In Top view create a text object and add the Path object as Text on Curve deforming object. Also in Object Font text field write "Domino-" (Fig. 11). This instructs the text object whenever the character "a" is typed to display the custom font character - in this case it is our domino tile.



Figure 11. Text on Curve option places the characters of the text along the selected curve without distorting their shapes. Enabling Object Font will add custom mesh whenever you type specific letter in this example typing "a" will add our Domino mesh where the character is located.

Now delete the default text and type the sequence: "a  a  a  a  a  a  a  a  a..." (note, I added two spaces between the 'a's). In Object Properties of the Text object enable Verts Duplication. You should get similar result (Fig. 12)



Figure 12. To see the duplicated objects the Verts option in Duplication panel must be enabled for the Text object.

As you can see the objects are not oriented correctly. And the original mesh must be rotated (-90) degrees along Z axis. To do that select the Domino object, rotate it around Z axis (-90) degrees, then Ctrl+A to apply Rotation.
Keep adding duplicates by typing "a"s and adding some spaces between the characters.
To make the duplicates real objects, select the Text object in Object Mode and Ctrl+Shift+A to make duplicates real (Fig. 13).



Figure 13. Converting the duplicate dominoes to real objects is easy as Ctrl+Shift+A. The original Domino and Text and path object can be moved to another layer or deleted.

Move the original object, path and text to different layer or delete them if not needed.
Then proceed to simulation setup process as described above (go there).

With that this tutorial ends!

For anyone who is new to Blender don't feel discouraged. Please, ask your relevant question in the comments below and I will try to answer shortly and clearly as possible.

Some useful links:


Very close to my solution video tutorial on YouTube by the user refa42


Object Duplication from Blender's manual

Rigid Body Physics from Blender's manual