Tutorial: Turning pages in a book
Demo engine version: 2.3.1
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:
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:
Through the above picture, we found that the deformation of the page can be simplified as follows:
-
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.
-
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:
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 0°
and 180°
, we must obtain a straight line, while at 90°
, the curve is roughly like this:
Step 2: Interpolate between unique angles.
It is conceivable that uniform interpolation is not realistic enough. Taking 0°
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.
Choose a suitable interpolation function and you can simulate a pretty good page-turning effect:
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.
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.
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:
-
First, define a series of horizontal mass points according to the width of the page.
-
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.
-
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.
-
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.
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:
-
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.
-
Connect the top and bottom vertices to form several triangles.
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:
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:
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:
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:
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.