How do I simulate a flock of birds?

Resources

This tutorial was originally printed in 3DWorld Magazine back in January of 2009 – over 10 years ago as I write this now in October of 2019.  It was originally called “Is there a simple flocking procedure in Maya?” (version 8 at the time) a question sent to the Magazine by someone called DuneBug73.  The answer at the time was “not really.”  You could make a passable pipe of particles at the relative press of a button, but the process of animating birds with enough randomness to lose the 3D-ness took a little longer.  Now we have both fluid particles and MASH in Maya making this sort of process a lot simpler to produce and control.  Still, as tutorials go, it’s a nice introduction to using the original particle system and expressions.

Image converted using ifftoany

Image converted using ifftoany

Download archive 112 here

If there are two words that I would never, ever put together in a sentence referring to Computer Graphics, unless I was prone to creating oxymorons, they would be ‘simple’ and ‘flocking’. There is nothing simple about flocking. Nothing at all.

Quite honestly, if I had to make a system of flocking objects, I would fly like the wind to http://www.highend3d.com and download the brainbugz1.3.3 plug-in created by Carsten Kolve (www.kolve.com) rapidly applying it to my scene and then sitting back to watch it make pretty particle patterns on my lovely big widescreen monitor. Hmm, shiny… However, the point of the question was how to create a simple system, and so a simple one is what we will create. So, how about a flock of starlings, my darlings?

 

Now hold on, I hear you all cry, that’s a hell of a lot of starlings. Don’t fret it, we are only going to make a few hundred of them, but the flocking patterns of a starling are really great as they show a high level of conformity, and this is really quite important if you want to create a simple system. To do this, we are going to use Maya’s goal weights to drive the motion of a group of particles which in turn will drive a series of cyclically animating objects simulating actual bird flight. Don’t worry, it is a lot simpler than it sounds. Well, simple is the name of the game in this instance – excuse the pun – but impressive is what we hope to achieve.

We’ll begin by creating a simple ball of particles and then a sphere which we will turn into a goal object. Think of a goal object as a magnet, the power of its attraction set by the attractors rather than the magnet itself. To add some discontinuity, we will then push some forces at our particles.

Once the initial motion is about right, the next step is to take our basic bird shape and using some bones, animate a simple flapping motion. Creating duplicate shapes for each pose in our animation cycle, we will then be able to add all of these as an instance group and cycle through them making it look as though our birds as really flying around. It’s a lot easier than it sounds, honestly. And it really can look very impressive. Let’s get to it, shall we?

Walkthrough

It’s balls!

112-FLOCK.001

1.

Open a new Maya scene.

Yup, I like to start from nothing.

Now change to the Dynamics menuset and from the Particle menu select Particle tool > Option Box.

Under Conserve, set the number to 300 and the radius to 10.

Now Click as close the Origin as you can then press Enter.

In the Channel Box set the particle1Shape’s Particle Render Type to Spheres.

Hey, it’s a ball of balls!

112-FLOCK.002

2.

Create a polygon sphere, holding down X to snap to the grip in the front orthographic view.

Now in the polygon sphere’s inputs, set the radius to 10.

Change the subdivision axis to 20 and the subdivision height to 15, giving a multiple vertex count to 300 to match our particles.

112-FLOCK.003

3.
Create a CV curve in the top view that curves over itself, I made one like an ampersand.
Now in the other views, using Maya’s soft selection radius adjust the CV positions until you end up with a swooping curve that we will use as a motion path to animate the ball.

Adjusting the Animation and influences

112-FLOCK.004

4.

Reset your timeline to around 200 frames.

Select the sphere and the curve then in the animation menuset, select Animate > Motion Paths > Attach To Motion Path.

Playback your animation and the ball will be attached to your curve.

But it’s motion is very linear and not at all swoopy.

Open up the graph editor and select the sphere.

112-FLOCK.005

5.

In your graph editor, select the motionPath’s curve.

Now select the add keys tool and MMB click on the motionPath’s animation curve where the ball reaches peaks in its motion.

Adjust the bezier handles so you have slower motions into and out of these points.

 This should give your ball a more weighted animation.

112-FLOCK.006

6.

Change to the Dynamics Menuset.

Select the particles and then the sphere followed by Particles > Goal > Option box.

Making sure the goal weight is set to 0.5, click Apply then close down the option window.

Playback your animation and you’ll notice your particles looking like a bouncy ball following the ball, trying to stick to its vertices.

112-FLOCK.007

7.

Change your channel box to an Attribute Editor, by clicking the Attribute Button at the top right of Maya’s interface.

Select the particles.

In the attribute Editor, you can see a setting called conserve.

Setting this a little lower will reduce the amount of bounciness in your particles.

Set it to around 0.9.

112-FLOCK.008

8.

To add some variety to the individual particle goal weights, move down the Attribute Editor until you see five oblong buttons in the Goal Weights and Objects rolldown menu.

Click the button marked Create Goal Weight 0 PP.

This creates an Array Attribute further down the editor.

112-FLOCK.009

9.

RMB click over the new Goal Weight 0PP attribute and in the pop-up select Creation Expression.

This will open the Expression editor for the particle.

Type in: particleShape1.goalWeight0PP = rand(0.3,0.8);

Playback your animation and some of your particles are now trailing behind the others.

Creating More Realistic Results

112-FLOCK.010

10.

Go back up to the Goal Weights and Objects rolldown.

If you put the Goal smoothness to 0, all the particles lose their lag and lock to the sphere.

For a laugh set it to 10 and playback the results.

Stretchy!

To get some lag, set the value to around 4 and playback these results.

112-FLOCK.011

11.

Now some more variation.

Select the particles and pick Fields > Turbulence.

Set its magnitude to 500 – that’s not a typo – and it’s attenuation to 0.

Set the timeline to end at around 300.

Playback your animation and you’ll see that there is a far greater variety of motion.

After frame 201 you’ll see the particles trying to lock onto the sphere, but the turbulence keeps pushing them about, making it look more like a swarm of bees.

112-FLOCK.012

12.

Select the sphere and set its visibility to 0.

Playback your scene.

Some of the particles are locked too closely to the shape of the ball.

In the Attribute Editor of particleShape1, RMB click on the Creation Rule we previously created.

Change the high value 0.8 to around 0.4, and the 0.3 to 0.25

Click on the Edit button and playback the results.

Save your scene.

Getting into a flap over animation

112-FLOCK.013

13.

Open up starling.mb.

Yep, it’s a very simple bird shape.  For a flock, this is probably about the amount of detail you would want for a distant blurry object.  (The trick here is as long as you get the animation right, you can get away with a lot, or more to the point a little.)

Pressing F2 to toggle to the Animation menuset.

Select Skeleton > Joint Tool and, from the Top View, Pressing X to snap to the grid, create a joint in the middle of the bird.

Continue on the create a shoulder and then follow the second row of vertices from the front of the wing and create an elbow, wrist and finger end effector.

112-FLOCK.014

14.

Raise joint1 up to about shoulder height of the bird.

Select the shoulder and press insert on your keyboard.

(This has been superceded by pressing D to accomodate both MAC and PC systems)

You can now move the joint up and down without altering its transform value.

Continue in this way until all the joints are in the wing.

Press Insert again exit the transform offset mode and lock their transforms.

112-FLOCK.015

15.

Select the shoulder joint and select Skeleton > Mirror Joint > Option Box.

Set the Mirror across to YZ leaving Mirror Function to behaviour.

This done, select the bird, then the joints and select Skin > Bind Skin > Rigid Bind.

Save the scene.

We are now going to animate the bird to make shapes that will be applied as cycling instances of our particle later.

112-FLOCK.016

16.

Use the Edit Membership Tool in the Edit Deformers menu to adjust those vertices that are being moved by the wrong joints.

Now pose your wings so that at frame 1 they are high up in the air as above.

Select the root joint and click Edit > Select Hierarchy and press S to save a keyframe on every joint. Go to frame 9 and save another duplicate keyframe for all the selected joints.

112-FLOCK.017

17.

At frame 5, set the wings at their lowest position.

Select the joint hierarchy again and save a new keyframe.

Continue to adjust and save keyframes on the other frames until you are satisfied that you have a birdlike animation sequence.

Now save your scene as starlingAnim.mb.

112-FLOCK.018

18.

Now let’s create individual models of the bird for each frame of its animation cycle.

Select the bird geometry at frame 1 and press Ctrl + D to duplicate it.

Select all the locked transforms in the channel box of the duplicate and select Channels > Unlock Selected.

Now move it left of the original bird.

Go to frame 2 and repeat the process of duplicating and unlocking up to frame 8.

Frame 9 is the same as frame 1 therefore we do not need it in the cycle.

Changing Particles Into Birds

112-FLOCK.019

19.

Save the StralingAnim.mb again.

Now select all of the duplicates and click File > Export selection.

In the pop up window write out the file with the name birdExports.mb.

Close down the current scene and open up your original particle animation scene.

Now import your birds.

Wow, they look far too big.

Select all the birds, reset their tranformations to 0,0,0 and then scale them down, until their bodies are around the same size as the balls.

112-FLOCK.020

20.

Press F5 to toggle to the Dynamics menuset.

Select your birds in order from 1 to 8 followed by particle1 and select Particles > Instancer (Replacement).

Presto instanto, you should now see lots of birds with their wings up in the viewpane.

Open the Outliner and double click on the teardrops by the new object instance1.

N.B. You cannot select an instance in the window.

112-FLOCK.021

21.

In the Attribute Editor that pops up, you can see the names of your starlings in the Instanced Objects list.

If any are in the wrong order, move them up or down to make the order correct.

Where it says Cycle above, set that to Sequential.

Playback your animation now and the birds are all flapping together.

Now let’s make them point in the direction they are flying.

Refining Your Particle Instance

112-FLOCK.022

22.

In the Attribute Editor select the Tab at the top that says ParticleShape1 and go down to the Instancer(Geometry Replacement) rolldown.

Pop it open and click the box beside Allow All Data Types.

In the Rotation Options, set the AimDirection to WorldVelocity.

Play back the animation and the birds are flying more directionally, but they seem to be suffering from a bad case of crabs.

112-FLOCK.023

23.

In the top view, select the original birds that make our instances.

Press F8 to toggle to component mode and then select all of the birds vertices.

Carefully rotate them until the birds are looking down the positive X axis.

If you press J before rotating, it will go rotate in the set increment values of your tool, so the as the default value is 10, it should take 9 rotates to set the birds facing in the right direction.

If you look at your animation now, you’ll find that the birds are all flying the same way as the particles.

112-FLOCK.024

24.

Finally to add some variation to each bird, we need to make sure that the wings are not all synchronising.

Select particle1 and in the Attribute Editor roll down to the instance section again.

You should see a section called Cycle Options.

At the top, where it says CycleStartObject change this to particleId.

This means that the first object in the cycle refers to each individual particle’s number.

If you now playback the animation, the results should be far more randomised and, guess what, you’ve got your very first flock of starlings.

Turn off the visibility of the particles, curve and the polySphere and render out the results in your favourite render engine, composite your results and enjoy.

I hope you liked this tutorial, even though it might seem a little dated.  The fact of the matter is most of the things in here all still are in Maya and so everything is still relevant and useful.  If you like this, please leave a comment below.  You can also find my other tutorials by clocking on the Resources button on the menu bar.

Bye for now!

 

Here is a final version rendered out of Maya about . gazillion years ago

Final M-Class Planet Image

How Can I create an M-Class Planet in Maya?

Resources

This tutorial was originally printed in 3DWorld Magazine back in March 2008 – 11 years ago as I write this now in 2019.  It was originally titles, “How do I create, texture and render a photorealistic planet?” but to be frank, I don’t feel it really stands up to that sort of scrutiny today.  However, it does still show the principles to creating a good base for a planet with the effective usage of fractal gradients to generate height, so here you go.  Enjoy… well, I hope you enjoy it.

Download archive 101 here

There are quite a few nice maps of the planet Earth on the web. At JHT’s Planetary Pixel Emporium you can find surface maps for all the planets in our solar system. But this is all fine and dandy until you want to come up with your own. See, no matter how hard you try, you end up painting something that, well, lacks definition. It all looks a bit flat, doesn’t it? Not enough of those, as Slartibartfast of “Hitch-hikers Guide to the Galaxy” fame would put it, “lovely crinkly edges.” Planets are, after all, fractal by nature thus providing more crinkly edges than you can shake an Arcturan Mega-Donkey at.

When it comes to making a terrain or planet you have the choice of using a DEM map – a digital elevation model to the uninitiated – which replicates reality or the nightmare of coming up with something in Photoshop both of which are prohibitive by the very nature of being pixelated. In other words, you can’t get in really close without seeing squares. In 3D we are inundated with people telling us that 2D maps are the only way forward, that for reality you need to use the realistic. But if the nature of the world is fractal, then surely using a 3D texture which is, by its nature, fractal means we are using realism? Well… No, not really. But if you are trying to create a planet from nothing, fractals are the way to go.

Let’s take a look at the Earth. It is made up of flat and mountainous land masses, shallow and deep water, equatorial regions, arid deserts and polar icecaps. Not to mention, we have an atmosphere which reflects light, clouds that swirl over the surface and, thanks to certain ape descended lifeforms, electricity lighting up the planet’s dark side. Though the lighting is man-made and the clouds follow distinct weather patterns the rest is fractal. So it is arguably possible to make a planet using fractals.

@page { size: 21cm 29.7cm; margin: 2cm }
p { margin-bottom: 0.25cm; line-height: 115%; background: transparent }

 Here’s how we turn ourselves into potential Magratheans. To put it simply we use the colour amplitude values of a 3Dtexture map to control the UV coordinates of colour ramps to form land, sea and so on. Yes, told you it sounded simple. And what this does is give us a prime opportunity to work intensely within the hypershade, rendering our results

1.

Time to start, well, make yourself a sphere (nurbsSphere’s are fine for this, but if you want to use a polygon Sphere, that’s fine too) Oh, and a light, too! Okay, select the sphere and create and add a new blinn shader to it. For viewing in the viewport, we’re going to keep this as vanilla as possible, so don’t do anything you can’t see in the viewport.  We are going to begin by creating one of many colour ramps, the first one here will be to provide the divide between land and sea.

2.

 Attach a new ramp to the blinn’s colour. Delete the middle colour and change the top and bottom colours to white and black respectively.

Open the hypershade and select the blinn then in the menu Graph > Input Connections.

Now you have the blinn shader in the bottom box, create a 3D texture crater. This will control much of our shader.

3.

In the Hypershade, select the crater and in the Attribute Editor, turn the colours to black, grey and white.

Now MMB drag the crater onto the ramp selecting other from the popdown menu to open up the Connection Editor.

Scroll down the left hand side until you find outColor, click it open and then connect the outcolorR to the U Coord and V Coord under the ramp’s Uv Coor

4.

Now open the ramp in the Attribute Editor. At the moment, you can see in the hypershade that the ramp’s two colour values are looking a little like a negative of the crater.

In the ramp, bring the two colours closer together, around .51 and .49.

Looking in the hypershade now, you should see a monochrome planet in the making.

5.

Render out a view from the perspective window and take a look at the placement of your texture.

Well, you’ve got nice edging, but really it all looks a little on the small side.

Either in the Outliner or the hypershade, select the place3dTexture1 node and then in the Attribute Editor or Channel box change all the scale values to around 5.

6.

Better, although let’s add a little more information into our planet.

Select crater1.

In the Attribute Editor at the top is a slider caller Shaker set to 1.5.

Move it up to 2 but no higher. Higher and the white value goes above 1 and causes the texture to wrap black.

Try it, it looks weird.

Okay, now turn it back to 2.

Edit the scale again to your taste.

7.

In the hypershade, select the connecting line between the ramp.outColor and the Blinn then delete it.

Now create a blendColors node and connect it’s output into the blinn’s colour.

Now MMB drag the ramp onto the blendColor to open the Connection Editor and connect the outAlpha of the ramp onto to blender of the blendColors node.

Wow, you’ve got a red and blue planet.

Weird.

8.

In the blendColors click the checkerbox of the colour that you want to be your land.

I chose the blue From the menu that appears create a new ramp.

Now, following the method set out in step 3, connect the outColorR of the crater to the Uand V coordinates of this ramp.

Render out an ipr image. Set the green to sandy brown and the blue to a deepish green.

9.

In the hypershade, select the new ramp then RMB to open Edit > Duplicate > With Connections to Network.

This new ramp, drag it onto the blendColor1 node and connect it to the remaining colour.

This will be our sea, so adjust this new ramp to look something like the colours to the left.

10.

Let’s make the planet more regional.

In the land ramp, select the green colour and click it’s checkerbox connecting a new ramp into it.

Change that ramp to a U Ramp and change the top and bottom colours to white.

Change the middle colour to a desert like shade and then slowly add quite a few various green shades to the areas in between.

Something like in the image to the left.

11.

Now would be a good time to save.

We still need more variety in the land.

Open the region land ramp – here ramp4 – in the Attribute Editor.

Pop open the menu marked HSV Color Noise and add raise the Hue, Sat and Val Noise up a little, then set their frequencies to something like 5.

This should chase the colour around a little bit

12.

Make a new ramp, this time selecting the divider ramp we first created, then from the hypershade menu select Edit > Duplicate > With Connections to network.

Set both values to black and put them at the top and middle of your new ramp.

Connect the outAlpha of this to the U Wave and V wave of ramp4.

Make the top black a little bit grey and this will swirl the land.

3.

Save your work.

Well, it’s a flat planet with no highlights, isn’t it?

Create a new blendColors and attach ramp1’s outAlpha to its blender.

Connect the outColor of the blender into the Specular Color of the Blinn.

Now change the colours in this blendColor to white and very dark blue.

Rename this new blendColor to specularHighlight and the one connected to the colour to landSeaColor.

14. 

Select the Blinn. click the diffuse’s checkerbox . 

When the Create Render Node window opens create a blendColors. 

The Connection Editor will pop open and in here connect the outColorR of the blendColor into the Blinn’s diffuse. 

Set the colours to white and light grey then click on the blender checkerbox and create a solidFractal node. 

Set its values as in the image to the left adding some global diffuse lowlights.

15.

Click on the Blinn’s bump checkerbox, creating a new Crater.

Make its colours range from white to black. Create a Reverse node in the hypershade and plug ramps1’s colour into its input.

This will add a depth value of 1 to just the land.

For control over this value create a MultiplyDivide node, connect the reverse1.output into its input then it’s outputX into the bump3D’s bump depth.

16.

Create another bump3D and in the Connection Editor, making sure both displays’ Show Hidden are flagged, connect its outNormal into the normalCamera of the first bump3D.

Create a Brownian, set its weight 3D to 2,2,2 and attach it to the bump3D’s value.

Duplicate the multiplyDivide node without connections.

Connect the outColour of ramp1 into this.

Connect the multiplyDivide to the bump3d2’s height as you did in step 15.

17.

You might notice a lack of cities.

We are going to paint these, but we need a canvas.

Select your planet and then in the hypershade shift select the landSeaColor node you created.

In the hypershade menu select Edit > Convert To File Texture.

In the box that opens, set the resolution to 2048 by 2048, file type to tiff and click Apply.

18.

In your project’s sourceimages folder, you should now find a big tiff called landSeaColor-planet.tif.

Load it into your paint package, in this case Photoshop, rotate the canvas by 90 degrees clockwise and the change the image size to 4096 x 2048.

19.

Create a new layer and on it paint white blobs where you fancy you want cities.

When you are happy, add the maximum monochromatic noise to it.

Then, using the wave filter set to a square type experiment until you get a kind if city grid feel as above.

Duplicate this layer and repeat the wave on this, putting them against black.

Save this out as cities.tga or png – whatever, your choice.

20.

Back in Maya click the checkerbox next to Incandescence and connect up a new ramp.

We want this to be black on the sun side and our cities map on the dark side.

Create a Blinn shader.

To use its light info as a UV control for the connect its outColour into the UVCoordinates of the ramp.

Adjust the blinn’s lighting until you get something like the image here.

21.

Now change the ramp’s colours, removing the red and turning the green black.

Move the blue up a touch and then click its checkerbox and create a new file node.

Navigate to the cities image file we created in the sourceimages folder.

Adjust its colour gain to an orange tone.

22.

But our cities are in the water too.

Create a new blendColors and attach the initial ramp we built into the blender.

Attach the blend to the colour offset gain of the city texture.

Change the colors to the city orange for the land and black for the water.

Hey presto, no floating cities, which is a bit of a bonus.

23.

Import the shader cloudShader.ma provided.

I recommend real clouds maps which you can find online, but as we are working with fractals, this is a good example shader.

In the hypershade, create a Layered shader.

Open the Attribute Editor.

Drag into the Layer Shader Attributes the cloud shader then the planet shader.

Delete the green placement shader.

Next we will create the atmosphere.

Final M-Class Planet Image

24.

Create a lambert.

Select the layered Shader, open the Attribute Editor then drag the new Lambert into the Layer Shader Attributes moving it to the far left.

Click the Lambert’s transparency’s checkerbox and create a new ramp, setting it top down white to black.

Now create a samplerInfo node and in the Connection Editor connect its facingRatio output into the Vcoord of the ramp.

Change the lambert’s colour to a pale blue and, bingo, you’ve got some atmosphere.

If you want to change the look of the planet, just move the 3dTexturePlacement node of that first crater and almost everything moves to suit.

Work up your final render in something like Photoshop or GIMP, Krita or Affinity Photo.

For the lead image, I duplicated the rendered image, blurred it and dropped it behind the original to create the atmospheric penumbra, as well other effects to improve the final output.

QnA 106 how to make a pin matrix - sip-sop.com

How do I create a pin matrix effect in Maya

Resources

How Do I Create a Pin Matrix Effect in Maya?

First published in 3DWorld Magazine 106 in 2008 – come on, I’m not that old, surely!? – This tutorial was set in motion by, apparently, someone called Dennis, in an email.  Thanks, Dennis, you made me learn a truckload!  Now you can all do it too.

Now, keep in mind that this was before Python Scripting was a big thing in Maya and that Komodo Edit is far better than some of the other free text editors out there.  For more info on both of those click on the links above.

Right, it’s time to make a pin matrix, from nothing.

You can also get to the archive for this project here:

QnA_106_Page_01_Image_0001

Sometimes, in the course of doing these Q&As, a question comes up that makes us have to use more than our current knowledge allows. This particular question is a case in point. Starting it, it soon became apparent that the original plan was not going to work out. It took a lot of searching and, in all honesty, a call to a colleague to get me on the right track. I mean, how was I going to get
individual UV sample information from an animation and apply it to an object? Answer: colorAtPoint.
Apparently, it’s been in the kit for quite some time but I have never needed to use it and, therefore, never knew it was there. I can now see a hundred uses for it. The colorAtPoint command is a simple way of extracting pixel information from a file based upon its UV coordinates. By sampling values from specific points across the surface of a texture, you can then pipe this info into an object to move it, scale it, whatever it. And if we use a script we can loop this to do it for every frame. Before we start building our pin matrix, however, there a few things that need to be understood.

We need to make sure that the aspect ration of our pins matches our image sequence. For this reason, I have decided to stick to a 640 by 480 image sequence. It is a standard resolution and is easily divisible. This way we can make a matrix that has 48 pins longitudinally and 64 pins latitudinally, and keep the aspect ratios the same so that our texture looks correct on our matrix. That makes us 3072 pins in all (ouch!) so is also important that you make sure to use NURBS for the pins as well as instances. (actually, you can do this with polygons these days [May 2017], but nurbs were still quite the thing at the time :)
Finally, and then we’ll get down to modelling, scripting and animating, a few words about UV coordinates. Think of them as X and Y in a front view pane. Your U values are like X and run horizontally and the V values are vertical.

Step 1.

QNA106 How to make a Pin Matrix in Maya

QNA106_image2

Open a new scene in Maya. Now create a polygon plane with a width/height ratio of 64 to 48. Make the subdivisions the same. Now scale up the tile by 10 in all dimensions, rotate it 90 degrees in the X and move is 240 units in the Y. you should have something like the image above.

Step 2.

QnA_106_Page_03

QnA_106_Page_03

RMB click on the object to bring up its attribute marking menu and select Assign New Material > Lambert. In the Attribute Editor that pops up click on the Color checkerbox and navigate to your image sequence, or use the one supplied. Press six in the view pane. You should see your texture.

Step 3.

QnA_106_Page_04

With the Attribute Editor still open, click the tickbox marked Use Image. Set your timeline to the length of your image sequence. In your animation Preferences, set the timeline animation playback speed to Play Every Frame. Now when you playback your animation you should see your animation playing on the tile.

Step 4.

QnA_106_Page_05_Image_0001

In any view, create a nurbSphere with a radius of 5 at the origin. Rotate it -90 in the Y axis and then select the middle isoparm in the side view. From the Edit Nurbs menu select Detach Surfaces then delete the new back hemisphere. Select the remaining hemisphere and in component mode drag three new isoparms on the surface near the back. Now select Edit Nurbs > Insert Isoparms

Step 5.

QnA_106_Page_06

In component mode still, switch your selection to Hulls and select the back three, scaling them down to about half their diameter. Now translate the last one back about 50 units until you have something that looks like a pin

Step 6.

QnA_106_Page_07

In the front view move this new pin -315 in the X and to 5 in the Y until it fits in the bottom left hand square of your map grid. Rename it pin0 – that’s zero – and select Modify > Freeze Transformations followed by Edit > Delete By Type > History. Save your scene.

Step 7.

QnA_106_Page_08

Selecting pin0, press CTRL+G to group it. Rename the group pins. Opening the group in the Outliner, select your pin and then select Edit > Duplicate Special > Option Box. In this option box be sure to set it to Instance and Parent. Change the translate Y to 10 and the Number of Copies to 47. Press Apply. Whoop-de-doo, you’ve got a vertical column of pins.

Step 8.

QnA_106_Page_09

Select all 48 of these pins from the bottom up and in the duplicate window change the Y translate back to 0 and set the X to 10. Change the number from 47 to 63 and click Apply again. Eventually, you should have a grid of pins covering your grid. Save your scene. Select your pin group and under Display set Object Display > Bounding Box. Phew, that’s a bit faster to manipulate.

Step 9.

QnA_106_Page_10

For the rest of the pin matrix, build a round edged front plate and set it about 50 unit in front of the pins. Duplicate it and make it twice as deep then move this behind the pins to make a back. Create four bolts with stems and put these in the corners. When you’re happy, group everything and sit it on the z-x plane for neatness. Or load in pinEdge.mb

Step 10.

QnA_106_Page_011

colorAtPoint needs to specify an output (-o) of either RGB, RGBA or A where A is alpha, a U and V coordinate or samples(-u,-v and -su, -sv) and a source file. So, colorAtPoint -o RGB -u 0.5 -v 0.5 file1 returns the colour in the middle of file1 or colorAtPoint -o A -su 10 -sv 10 image1 returns 100 alpha samples uniformly spaced in 10 rows of 10.

Step 11.

QnA_106_Page_12

Let’s try it. Open the script editor and type: colorAtPoint -o A -su 6 -sv 6 file1; Select all the text and press the numeric pad Enter key – This stops the text from being deleted as it runs the command. You should see a resultant string of 36 alpha samples corresponding to your image. They are sampled in the order you can see in the image, starting at the bottom left.

Step 12.

QnA_106_Page_13

Now we need to find a way to use these results. Clear the Script Editor and type in: float $offsets[] = `colorAtPoint -o A -su 6 -sv 6 file1`;print $offsets; Press Enter as before and you get the same values but this time they are in an array called $offsets. Change print $offsets; to print $offsets[20]; and you only get back 1 – the value of sample 20.

Step 13.

QnA_106_Page_14

We have 3072 pins to animate here, so change your mel script to: float $offsets[] =`colorAtPoint -o A -su 64 -sv 48 file1`; print $offsets; Run this as before. To get these results takes longer, so we don’t want to use print statements. Move the print command onto a new line and put // to stop it from calculating.

Step 14.

QnA_106_Page_15

Quick point about scripting. Scripting in the Script Editor is fine, but if you get more involved in scripting, use a text editor. You are able to save progressively without copying and pasting, but it can still be sourced and run in the script editor with ease. Notepad++ and Textpad (or Komodo Edit) are freely available and both handle syntax highlighting making commands easier to see. 

Step 15.

QnA_106_Page_16

We need to get this array into our pin’s Z translation. Add a few lines at the top of our script. Type on the first, string $obj = “pin”; and on the second string $attrib; $obj matches our pin name minus the zero. The $attrib will be used later on in our script, but declaring it at the top of a script is good practice in keeping all your variables together.

Step 16.

QnA_106_Page_17

To use each array offset value in turn, we need to put them into a loop. Add this line: int $i; This sets us up a variable for the loop. Now add this line: for( $i = 0; $i < size($offsets); $i++ ) This loop starts $i at zero and finishes at the last offset array value. On two new lines add an open curly bracket and a close curly bracket.

Step 17.

QnA_106_Page_18

Between these brackets create two new lines of script, the first: $attrib = ($obj + $i + “n”);, the second print $attrib; The first takes our $name pin and adds the number of our offset onto the end of it then performs a carriage return starting a new line. The second line prints it. Select all the text and hit Enter. See all those pin names flashing by.

Step 18.

QnA_106_Page_19

This is all well and good, but what we need $attrib to be is the pin Z transform attribute. Change the last part of the string n to .translateZ so that the line now reads: $attrib = ($obj + $i + “.translateZ”); If you run this now you won’t have the carriage return, but your script editor will bring back the names pin0.translateZ through to pin3071.translateZ. This we can use.

Step 19.

QnA_106_Page_20

Now comment out the print $attrib; Underneath it add this new line: setAttr $attrib $offsets[$i]; What this does is set each offset value to each point in turn through the loop. To make sure, move to around frame 75 in the timeline, select the script and hit Enter. If you look through the side view, you will see the points have moved a little in the Z, but not enough.

Step 20.

QnA_106_Page_21

What we need is to increase the size of the offset. We do this be adding a multiplier to the amount attributed to $attrib. Change the last code line to: setAttr $attrib ($offsets[$i] * 10); Run the script again. The result is still too small. Change the 10 to 50 – after all our pin is 50 units long. Run the script again and check out the results. Dandy.

Step 21.

QnA_106_Page_22

Assigning info at a single frame is fine, but we need to keyframe this if we want our pins to animate like our texture map. Add a new line under the last command: setKeyframe $attrib; If you run the script now, you’ll notice that it takes a little longer. If you move to another frame and repeat the script, you’ll see the keyframing results appear in the script editor.

Step 22.

QnA_106_Page_23

What we have is a good script for a single frame. Now we need to loop this per script so it runs at every frame. Under the line $string $attrib add this: for ($frame = 1; $frame <= 100; $frame ++); On the next line put an open curly bracket. This creates a loop as long as our timeline and our animation sequence.

Step 23.

QnA_106_Page_24

On the line after this curly bracket type in this command: currentTime $frame; The command currentTime is like clicking on a frame on the timeline, but in this loop it acts like a step forwards through the timeline. At the very end of the script put a closed curly bracket. Save your scene. Run your script. Now go have a cup of coffee. Or three.  this could take some time to do.  REally, a cup of tea…a big mug.

Step 24.

QnA 106 how to make a pin matrix - sip-sop.com

At each run of the setKeyframe command, the calculation time for the keyframing takes longer. This seems to be because of the accumulative effect required to add a new keyframe to your scene, so be prepared for a long wait. A useful idea is to break down the script into manageable chunks, say frames 1 – 20, 21 – 30 and so on so as to give you failsafe points to save your animation. Either that or, like a render, leave it running overnight, and wait for the results in the morning. Remember, in this instance alone, you are making 307,200 saved keyes for just four seconds of animation. Just keep reminding yourself, “Good things come to those who wait.”

QUICK TIP

When it comes to lighting the pin matrix, remember Chrome shaders do not really hold shadows well, so render off the shadow as a pass and comp it on later.  Better than that, you might find that if you add a new coloured light to the right of the pin matrix, you’ll probably get more definition, as long as you make sure it does casts shadows.

The finished book for the Tutorial on making ang book and page turn in Maya circa October 2006

How to build an animating book and page turn in Maya

Resources

How to make an animating page turn and a book in Maya

First published in October of 2006 – wow, was it really 11 years ago? – This is a tutorial to recreate something like the book from Shrek.  The question was sent to me by a Paul Greenwood, wanting to know how it should be done.  Well, back in 2006 (heck) this is how I would have done it.  Actually, most of this is still the same, so I’m putting it up here with only tiny edits.

Hope it’s of use!

 

The finished book in the tutorial

Did you know…

..that “Shrek 2” took 10 million computer hours to generate its 1 hour and 45 minutes of CGI? Oh, you did. But did you know that a single frame of the city crowd scene took 35 hours to render? You knew that too. Okay, you got me on the trivia, but do you know, without sneaking a peek at the fact file above, how long it will take to recreate a book and page turns similar to the ones in the introduction to Shrek 2? Ah, you looked! That’s cheating.

Take a sneak peek at step 1, I won’t mind. Do you notice anything peculiar about it? That’s right. In the past I’ve given you something to start with but this time you’ve got nothing. Zilch. A big fat Zero. The reasons for this are twofold. In order to create a convincing page turn, you’ll need to create the book too. Secondly, and more to the point, if I just told you how to create a page turn it wouldn’t be much of a Q&A, would it? Page turns can be simple, a blendShape here, a non-linear deformer there, but opening a book and having the pages seem to fall comfortably into place is another kettle of fish entirely. That is why a page turn really begins with the book.

In this Q&A, the book is going to be a combination of polygons and nurbs. The book cover needs to be bound to a skeleton so we can animate the spine bending. To keep the rigging to a minimum we will use a polygon smooth Proxy. This is useful as we can also create clean UV mapping for texturing. However, because we do want smooth page turns these will be made from nurbs planes. That way we can increase their tesselation at render time. For all of these elements to animate collectively, we will also create a single node to drive everything.

Then we’ll make a double-sided shader so that our pages can accept shading on either side. Supplied for this is a finished scene with a weathered leather book cover. Something that would not look out of place in a land far, far away, actually. Speaking of far, far away, did you know that in the UK version of Shrek 2 the voice of the Ugly sis – oh, what’s the point…

Fact file

Required: Maya 7 or above Difficulty: Intermediate Time took: 2.5 hours

Also required: Krita/Gimp/Photoshop for texturing

Starting from Scratch

Files for textures and reference scenes can be downloaded here: http://www.sip-sop.com/archive82/

Step 1.

Step 2.

Told you it was an empty screen. Create a polygon cube and move it 0.5 in both the X and Y axes. Extrude the top polygon up by four units creating four divisions. Now extrude out the top and bottom right-hand faces by 5 units adding five divisions. You should now have a very boxy C shape.

Step 3.

To round the corners, in the perspective view, select the front top corner vertex and the two vertices either side. Now select edit Polygons > Merge Vertices > Option box. Set the distance to 1 and Apply. Selecting the similar three points on the top and bottom of the mesh and repeat. Now select the eight vertices on the ends of the C-shape and drag them over by about 14 units.

Select the mesh object and scale it in the Z axis by about 28 or until you are happy with the dimensions. In the top view select the mesh and then select edit Polygons > Cut Faces. Holding down shift to snap to 45-degree angle increments, click on a vertical edge about 1 unit on from the top to create a horizontal cut. Repeat this one unit from the bottom.

UV Mapping and refining

Step 4.

Step 5.

Open up the UV Texture Editor. In an orthographic view select all the outer and edge faces of your book. Cylindrically map these polygons using a projection sweep of 180 with the spine central to the mapping. Scale down the Image Scale U and V to around 0.5 and move the projection down in the UV Editor. Repeat the process for the inside polygons, placing these UVs above the others.

Step 6.

In the front view, select the inner poly UVs deselecting the inner UVs afterwards in the UV Texture Editor. Still in the UV Texture Editor, change to a scale manipulator and stretch out the edges so they are visible around the edge. Add a Blinn shader with a checker in the colour to your mesh and pull around the UVs until you’re happier with the results.

Select your mesh and perform a Polygons > Smooth Proxy on it. Edit the proxy mesh until you like how the smooth mesh looks. Having created cleaner UVs in a simpler model, now add more faces by using the Cut Faces tool again, bisecting the book at regular intervals with 90-degree angles. Now add some randomisation to the CVs such as pulling up the corners slightly to simulate ageing.

Driven to animate

Step 7.

Step 8.

Make the smooth Mesh invisible for now. Create a skeleton like the one on the image above. The armature coming off into the book is for our fake page block and pages. Selecting the proxy mesh and then all of the joints except the armature, select Skin > bind skin > rigid bind > option box. Select Selected Joints and then hit apply. Now use Deform > Edit membership to clean up the bind.

 

Step 9.

Set a frame range of 1 to 25. Select joint1, group it to create a top node then rename this group to anim. With anim selected, open up the Attribute Editor and from its menu select Attributes > Add Attributes. In the new window that opens add the attribute name bookOpen, set the minimum to 0, the maximum to 1 and default to 0 and hit OK. This will be our animation driver.

Step 10.

At frame 1, click Animate > Set Driven Key > Set > option box. Select anim and click on the Load Driver button in the Set Driven Key window selecting attribute bookOpen. Select joint1 and shift select the translate and rotation axis, here rotateZ, in Set Driven Key window. Making sure anim.bookOpen and your rotate angle are at 0, click Key. Now set driven keys for the rotations down the joint chain.

Step 11.

At frame 25 set a keyframe on anim.bookOpen of 1. Now translate and rotate joint1, then rotate the other joints until you have a fully open book. Now repeat the Set Driven Key process from step 9 at frame 25. To check your keys, playback the 25 frames. Set Driven Key values appear in the Graph Editor and this is a good place to edit them for better results.

Step 12.

Go to Frame 1. Create a nurbsPlane with 5 U and V patches. Reposition its origin to its left edge and then point snap it to the armature joint. Scale it up to fit within the book. Now Modify > Freeze Transformations renaming it page1. Duplicate it. Move page2 down until it reaches the book back. Constrain > Parent page1 to the armature joint. Constrain > Parent page2 to joint1.

You can see that page 1 is being lifted by the armature. Using the same process above in steps 9 and 10, set driven keys for the armature so it transforms and rotates back towards to a slightly elevated angle. Now in component mode select the bottom isoparms of both pages and Create > Surfaces > Loft. Do the same for the top and side, to create our fake page block.

Deforming the page block

Step 13.

That top page looks a bit flat open don’t you think? Got to frame 1 and duplicate page1 renaming it page1Deformer. Remove any history and constraints and move it up in the y-axis. Select it and shift select page1 and then Deform > Create blend Shape. Go to frame 25, select page1 and in the Channel Box open the blendShape1 node setting its page1Defomer attribute to 1.

Step 14.

Edit the shape of the deformer until you get a nice page curl. This looks fine at frame 25, but at frame one it looks awful. To connect the blendShape.page1Deformer to the anim.openBook, we could use a driven key but as both nodes go from 0 to 1 we can use a quick expression. Open the Expression Editor and type in: blendShape1.page1Deformer = anim.bookOpen; then click Edit.

Step 15.

Now we’ve got a book that opens, but you may notice we haven’t got any pages. As preparation, we need to duplicate page1 at frame 1 and rename it turnPage. Delete any history and constraints and then move it up in the Y axis by a really tiny amount. Duplicate page1Deformer and move that up a similar amount, renaming in animPageDeformer. Now let’s make our first page turn.

Turning the pages.

Step 16.

Select animPageDeformer and shift select turnPage. Now select Deform > Create Blend Shape. Now select the page and Deform > Create nonlinear > Bend. Transform the Bend1Handle to the local origin of turnPage. Now select both turnPage and bend1Handle and group them twice calling the top group pageAnim1. Press Insert and curve snap their origins to the same spot as the bend1Handle. Now Constrain > Parent the top group to the page armature.

Step 17.

Keyframe turnPage’s blendShape to match page1’s. Add 25 frames to your timeline. At frame 20 Set the bend1.curvature to -1.1, it’s low bound to 0 and the high bound to around 3. Move it up to the top of your page so the curve bends upwards and inward but doesn’t change the page shape.

Keyframe the translate and rotate of bend1Handle and the curvature of bend1.

Step 18.

At Frame 30 rotate the bend1Handle clockwise 80 degrees, transform it down the page a little and set a new keyframe. At frame 40 move it to the bottom of the page and set a key on bend1.curvature of 0.8. At frame 50 set the curvature to 0. Now pickwalk up to the above group node and key its rotateZ from frame 24 to 50 to turn the page.

Step 19.

Select the blendShape2 node under turnPage and go to frame 30. Set a keyframe on the blendWeight. Got to frame 50 and now set a keyframe of -.5 to give a little shape to the page. Adjust your keys and their tangents to make everything smoother. Now select pageAnim1 and Edit

Duplicate > option Box checking the Duplicate Input Graph tickbox and Group under World radio button. Apply and repeat.

Step 20.

Now you’ve got three pageAnims, plus all their animation and deformation history. This means we now have two extra skeletons we don’t want. Go to frame 1 and delete all the pageAnim parent constraints and skeletons anim1 and anim2. Adjust them so pageAnim1 is just above pageAnim 2 which is above pageAnim3 as in the image. Now constrain them to the armature again as you did in Step 11.

Step 21.

Now when the pages turn they actually pass through each other because of their height order. Selecting the middle group of pageAnim1 set a transform keyframe as the page begins to turn. When it stops turning, move it left and down to the Y position of pageAnim3. Now pick the equivalent node under pageAnim3 and animate this up to the position of pageAnim1.

Congratulations, you’ve got a working book.

Double sided Shaders

Step 22.

Texture up your book, or open up step22.mb. Pages has two different sides but in 3D shaders work on both sides at the same time. What we need to do is create a shader which applies one material to one side and another material to the other. We can do this in Maya by creating a condition that uses an object’s normal direction as a switch.

Step 23.

Most of the scene is finished, but we need to apply shaders to turnPage1. Open the Hypergraph and selecting the page select Graph > Graph Materials On Selected Objects. You should now see a lambert shader called page1Mat in the Hypergraph. Create a Condition and a samplerInfo node.

Middle Mouse button click and drag the samplerInfo node onto the condition. Select Other as connection to open the Connection Editor.

In the Connection Editor, connect the flipped normal attribute of the samplerInfo node to the second term of the condition. This makes the condition register the facing normals as one value and the flipped normal as another. Now in a similar manner, connect condition1.outColor to the page1Mat.incandescence. Now double-click on conditon1 to open the Attribute Editor. Set its operation to Not Equal to distinguish our two normals from each other. Render a frame and you should see the page has a white and a black side. Create two Blinn shaders colouring one red and another green. Connect the red Blinn’s outColor to condition1.colorIfTrue and the green’s outColor to its colorIfFalse. Rename the green Blinn to page1Front and the red one to page1Back. You can now treat these as two normal, excuse the pun, shaders on one object.

QUICK TIP

For close proximity objects that appear to interpenetrate when rendered, increase the camera’s near clip and decrease the far clip making for more accurate rendering.