Tutorial: Turning pages in a book

Tutorial: Turning pages in a book

Demo engine version: 2.3.1

Demo address


Have you ever wanted to have your level select screen or make your story look like it’s coming out of a book? We’ve seen this type of effect in many smaller games or games that use books to tell their story.

It looks very impressive, but you might think it’s way too hard to build. Thankfully the team at Yuefu Interactive Entertainment sent out a fantastic tutorial this summer to our forums, and we had to share it with you.

Introduction

This article mainly discusses how to use Cocos Creator to simulate the page-turning effect of a book, respectively introducing the use of Bezier curve and the Verlet Integration Algorithm to simulate the bending deformation of the bottom edge of the book page during the turning process, and finally pass in custom assembler vertices to render the original book page texture into a curved look to achieve the effect of simulating page-turning.

The final result

First, let’s show the final effect:

42e9aec0bef43b20ec08f1a399e1a4b448bba462

But how do we get there?

Problem analysis

The book’s pages will have a certain bending deformation during the turning process, which means that in each frame, the book pages we see have different shapes. If you use sequential frame animation to achieve this, you must separate each frame and draw a picture that will generate many resources. If it can be simulated by code, resource problems can be avoided.

The problem we want to solve becomes how to render the original book page picture into a curved state during the page-turning process?

Let’s first observe what the page looks like after being deformed:

image

Through the above picture, we found that the deformation of the page can be simplified as follows:

  1. Imagine the book page’s bottom edge as a rope, the left piece remains unchanged, and then pull from the right to the upper left to form a curve.

  2. Move the entire page upward along this curve.

Through the above two steps, we can simulate the appearance of the page at any moment. The difference in page form at different times is actually the difference in the curve. As long as the curve at the bottom of the page at any time can be obtained, the effect of page-turning can be simulated.

Solution

So how to get that curve? Here are two solutions.

Bezier curve

Background introduction

A Bezier curve is a mathematical curve applied to two-dimensional graphics applications. At least three control points can describe a curve. The N-order Bezier curve has N+1 control points. Taking the third-order Bezier curve as an example, its specific formula is as follows:

image

f7d85538b174db409a9df7bcf7179abf0e28083d

As long as the starting point P0, control point P1, control point P2, and endpoint P3 are determined, such a curve can be drawn, which will be tangent to P0P1 and P2P3, respectively.

Does that make sense?

In other words, as long as we find the positions of the four control points at any time, we can simulate the curve at the bottom of the page. Of course, the starting point’s location is actually fixed (unless you tear the page from the book).

If the angle between the endpoint and the starting point and the horizontal plane is used to describe a specific position in the page-turning process, then we can observe the curve shape of the page at each angle and then derive the position of the control point to restore the whole process of turning the book, but this is obviously impossible to achieve.

We can only determine the control points of some unique angles first and then interpolate between these control points.

Step 1: Select several unique angles to obtain the position of the control points, and ensure that the shape of the curve at these unique angles is more realistic.

For example, at and 180°, we must obtain a straight line, while at 90°, the curve is roughly like this:

image

Step 2: Interpolate between unique angles.

It is conceivable that uniform interpolation is not realistic enough. Taking to 90° as an example, the end point’s trajectory should be similar to the following figure. The transformation of the x coordinate is from slow to fast, while the transformation of y coordinate is from fast to slow.

image

Choose a suitable interpolation function and you can simulate a pretty good page-turning effect:

2

The biggest problem with using the Bezier curve to simulate is that this method has nothing to do with real physical motion. Its shape at a certain moment is actually obtained by an interpolation formula that is inferred from observation. This leads to the fact that the length of the curve we finally get is not equal to the width of the page, so after obtaining the curve, we need to modify the length of the curve to be consistent with the width of the page. The specific implementation will be mentioned later.

Verlet Integration Algorithm

Considering the Bezier curve’s shortcomings, we need a method that is closer to the real physical motion law, which is the second implementation scheme - The verlet integral algorithm.

Background knowledge

The mass point spring system

The simplest way to simulate the deformation of an object is to use a spring-mass point system. In the mass point spring system, we need to define a series of mass points, that is, points with mass, and assume that there is a spring with a certain length and a mass of 0 between the mass points. When the mass point moves, it will be affected by internal and external forces. The internal force includes the spring’s elastic force and damping force, and the external force includes gravity and air resistance.

Simulating the movement of an object is calculating the position of the object at any moment. In the mass point spring system, we can get each mass point’s force and its mass. According to Newton’s second law, we can calculate the acceleration of the mass point. With acceleration, through a certain algorithm, the position of the particle can be calculated.

Explicit Euler method algorithm

The Explicit Euler method is a relatively simple algorithm. In the Explicit Euler method, the state at the next moment is determined by the state at the current moment. The problem with Explicit Euler integration is that the error is large and unstable, so we don’t use it.

image

Verlet Integration Algorithm

The Verlet Integration Algorithm is a position-based integration that calculates a new position through the mass point position at the current time and the previous time. The Verlet Integration Algorithm is better than the explicit Euler Method Algorithm in terms of accuracy and stability, and the computational complexity is not much different.

image

Constraints

Assuming that the spring force coefficient between the mass points is infinite, the distance between the two mass points will always remain at the original length when the spring is stretched or compressed. Using this idea, we can simplify the elasticity calculation by increasing the distance constraint between the particles.

Implementation

Now, we regard the bottom edge of the page as a connection of some horizontally placed mass points. When we move the tail mass point position, other mass points will follow the movement due to the constraint of the spring between the mass points. In this way, we can use a more realistic method to obtain a curve.

The method of using verlet integral to calculate the curve is as follows:

  1. First, define a series of horizontal mass points according to the width of the page.

    image

  2. Update the position of each particle according to the verlet integral formula in each frame.

    The difference between the current position and the previous position can be regarded as the speed of the mass point. The energy loss caused by air resistance, etc., needs to be multiplied by an additional attenuation coefficient.

    The effect of acceleration can be simplified here as vertical downward gravity.

    image

  3. The position of the mass point is corrected by the spring constraint. The more the number of corrections, the better the effect, but at the same time, the greater the performance overhead.

    image

  4. Add a method to move the tail’s mass point.

    Here we use the same trajectory as the Bezier curve for comparison, and we can see that the result obtained by using the verlet integration algorithm is more realistic.

The influence of parameters on the effect

Using different parameter values will show different material effects. The main parameters that affect the verlet integral algorithm’s effect are velocity attenuation coefficient, gravity, and correction times. When using it, you need to adjust the parameters to get a more satisfactory effect.

  • Speed attenuation coefficient

    The speed difference between the current position and the previous position is calculated, which can be regarded as an approximate inertia performance. When the movement stops, each mass point will continue to move due to inertia. The greater the speed attenuation coefficient, the greater the inertia, and the simulated book pages will shake more severely.

  • Gravity

    Gravity will pull the mass point downward for a certain distance in each frame. If the page moves at a slower speed in the horizontal direction, it will show a feeling that it is difficult to pull the page up.

  • Correction times

    The more corrections are made, the closer the distance between each two mass points is to the initial fixed value so that the corrections will affect the pages’ softness. It should be noted that the more corrections, the more calculations, which should be considered in a balanced manner.

Supplementary

How to render the texture of the book page as it moves upward along the curve?

When it comes to rendering issues, we first have to look at how the rendering pipeline works.

image

First, the vertex shader will process each vertex we pass in, and the processed vertices will be combined into triangles, and these triangles will form fragments after rasterization. Finally, the color value of each fragment is calculated by the fragment shader.

To put it simply, the Sprite component obtains a rectangle surrounded by four vertices according to the width, height, coordinates, anchor point, and other information of the node where it is located. When this rectangle is finally displayed on the screen, it will become many small pixels. OpenGL samples the color of each pixel according to the texture coordinates of the fragment and the texture used by Sprite.

If you want to render a picture of a book page surrounded by a curve, four vertices are obviously not enough. Therefore, we need to customize a rendering component to pass in more vertices to complete the requirements:

  1. Divide the upper and lower sides of the page into several line segments to fit the curve, that is, create more vertices between the two endpoints of the upper and lower sides of the original rectangle.

  2. Connect the top and bottom vertices to form several triangles.

image

The final figure can be seen as splicing several small rectangles. Obviously, the more the number of vertices, the smoother the curve. After the previous analysis, we can easily obtain the coordinates of each vertex at any time. It can be obtained by directly applying the Bezier formula using the Bezier curve method, while the mass points in the verlet integration method exactly correspond to the vertices here.

If you lower the number of vertices, you can clearly see the range of each small rectangle:

image

If you want to pass in more vertices, you have to customize the rendering component and Assembler. The assembler refers to a series of methods for processing vertex data of rendering components. Each rendering component has an Assembler member. Assembler must define the updateRenderData and fillBuffers methods. The former needs to update and prepare the vertex data, and the latter is to fill the prepared vertex data into VetexBuffer and IndiceBuffer.

Correct the length of the Bezier curve

If the Bezier curve is not corrected, the pages will be widened or shortened during the turning process:

image

Since the Bezier curve is inferred, the curve’s length finally obtained is not equal to the width of the actual book page. The correction method is also straightforward. The distance between each two vertices currently obtained (that is, the small rectangle Width), if it is greater than the real width, attenuation is performed, and the last vertex is reduced and compensated for making the width of all small rectangles equal to the actual width.

Another point to note is the calculation of texture coordinates. After calculation by the Bezier curve formula, the vertices will no longer be uniformly distributed, so the texture coordinates must be obtained according to each small rectangle’s proportion to the total length. If you use equal division to obtain texture coordinates, the effect will be as shown in the following figure:

image

Realization of back texture

As you can see in the previous renderings, the textures on the front and back of the page are different. How is this achieved? Two ideas are provided here.

Reject the back

By setting the back culling, OpenGL will identify the front and back according to the winding order of the nodes and remove all the vertices on the end without participating in the final rendering.

As long as two nodes are used to represent the front and back of the page, and one to remove the end and the other to remove the front, the final image can be assembled. However, it is also necessary to consider the level of the front and back. In the realization of the Bezier curve, the back is always above the front level, but the verlet integration algorithm’s effect is obviously not the case, and sometimes even a surface appears. Interspersed on the other side:

image

Therefore, the method of back culling has certain limitations.

Custom Shader

Another method is to create a custom shader, pass in two textures, and add a new vertex attribute to tell the fragment shader which texture should be sampled.

It is actually very simple to judge whether a small rectangle should use the front texture or the back texture. Just use the x-coordinates of the two vertices before and after it. If the x-coordinate of the latter vertex is larger, it is positive. And since the vertices drawn later will cover the previous vertices, there is no need to consider the level of hierarchy in this method.


About Yuefu Interactive Entertainment

Founded in 2019, Yuefu Interactive Entertainment is a star start-up company focusing on boutique mobile games’ development and operation.

The company’s core team is the original team of the “Juvenile Three Kingdoms” and “Youth Journey to the West” series. The core members of producers, planning, technology, art, UI, publishing, and other modules have worked together for many years and have a mature R & D product and management system.

The team has been deeply involved in card mobile games and other categories for a long time. It has a keen sense of smell and efficient research and transportation capabilities. It is known for its long-term game development and operation. It has created several products with monthly sales of over 100 million, including “Juvenile Three Kingdoms,” “Journey to the West,” etc. , The game has a cumulative turnover of nearly 10 billion yuan.

The company was highly recognized by the capital market at the beginning of its establishment and has now completed the angel round and the A round of financing. In the short term, Yuefu will combine its own advantages and continue to devote itself to the profound cultivation of medium and light card mobile games, and maintain its leading position in this field.

In the long term, Yuefu Club will focus on the road to “game industrialization” and continue to build classic game IP under the premise of self-research and self-development.

7 Likes