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!
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…
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/
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.
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
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.
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
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.
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.
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.
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.
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
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.
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.
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.
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.
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.
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.
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.
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.
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
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.
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.
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.