# Unityshader uses plane to turn over books

Time：2021-8-17

This example shares the specific code of unityshader using plane to realize the book flipping effect for your reference. The specific contents are as follows

I saw a shadr on the Internet that can realize the rotation effect, so I used it to realize a Book flipping effect. The solution is to display and hide different models. Like sequence frames, in order to achieve the effect, it feels cumbersome and takes up resources. In the later optimization, object pool can be considered. Today, try to use vertex shader to realize it. Exchange and learn from each other. Don’t spray.

It takes about three steps to achieve a simple book turning effect:

1. Distortion of plane

2. Rotation of plane

3. Front and back sampling

Plane twist:

The effect of turning a book is that the middle protrudes outward, and the positive direction of the x-axis will offset backward.

The negative edge of the x-axis remains stationary, and the degree of distortion increases and decreases with the rotation angle, and 90 degrees is the maximum. Rotation of plane:

According to the range of vertex x of plane (- 5, 5) Map sampling for plane:

Two pass channels are used to realize, one is the back elimination and the other is the front elimination. Sample two pictures respectively.

``````
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'

Properties
{
_Color ("Color", Color) = (1,1,1,1)
_MainTex("MainTex",2D)="White"{}
_SecTex("SecTex",2D)="White"{}
_Angle("Angle",Range(0,180))=0
_Warp("Warp",Range(0,10))=0
_WarpPos("WarpPos",Range(0,1))=0
_Downward("Downward",Range(0,1))=0
}
{
pass
{
Cull Back

CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"

struct v2f
{
float4 pos : POSITION;
float2 uv : TEXCOORD0;
};
fixed4 _Color;
float _Angle;
float _Warp;
float _Downward;
float _WarpPos;
sampler2D _MainTex;
float4 _MainTex_ST;

v2f vert(appdata_base v)
{
v2f o;
v.vertex += float4(5,0,0,0);
float s;
float c;
float4x4 rotate={
c,s,0,0,
-s,c,0,0,
0,0,1,0,
0,0,0,1};
float rangeF=saturate(1 - abs(90-_Angle)/90);
v.vertex.y += -_Warp*sin(v.vertex.x*0.4-_WarpPos* v.vertex.x)*rangeF;
v.vertex.x -= rangeF * v.vertex.x*_Downward;
v.vertex = mul(rotate,v.vertex);

v.vertex += float4(-5,0,0,0);
o.pos = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.texcoord,_MainTex);
return o;
}

fixed4 frag(v2f i):COLOR
{
fixed4 color = tex2D(_MainTex,-i.uv);
return _Color * color;
}

ENDCG
}

pass
{
Cull Front

CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"

struct v2f
{
float4 pos : POSITION;
float2 uv : TEXCOORD0;
};
fixed4 _Color;
float _Angle;
float _Warp;
float _Downward;
float _WarpPos;
sampler2D _SecTex;
float4 _MainTex_ST;

v2f vert(appdata_base v)
{
v2f o;
v.vertex += float4(5,0,0,0);
float s;
float c;
float4x4 rotate={
c,s,0,0,
-s,c,0,0,
0,0,1,0,
0,0,0,1};
float rangeF=saturate(1 - abs(90-_Angle)/90);
v.vertex.y += -_Warp*sin(v.vertex.x*0.4-_WarpPos* v.vertex.x)*rangeF;
v.vertex.x -= rangeF * v.vertex.x*_Downward;
v.vertex = mul(rotate,v.vertex);

v.vertex += float4(-5,0,0,0);
o.pos = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.texcoord,_MainTex);
return o;
}

fixed4 frag(v2f i):COLOR
{
float2 uv = i.uv;
uv.x = -uv.x;
fixed4 color = tex2D(_SecTex,-uv);
return _Color * color;
}
ENDCG
}
}
}``````

By dynamically modifying this value, the plan can be flipped Let’s turn the book

We’re going to use dotween next. I don’t understand dotween, but Baidu comes down to understand and use it. I won’t explain it in detail here;

Create a Resources folder and create sub folders fronttextur (front) and versotextur (back) to store the front and back pictures of a book. Import the pictures prepared by myself. For dynamic loading, I use numbers instead of the page Next, we create a plan to zero the position Then copy another one, renamed pageturning3

Then drag the plan as a preset into resources.

Next, turn the book with the following code

``````using UnityEngine;
using DG.Tweening;

public class PageTurning : MonoBehaviour
{
private Material m_Material;
private int nowPage = 1; // Bottom page
private int lastPage;   // Already turned
private int allPage = 10;   // All pages
private float Thickness = 0; // Book thickness

void Start ()
{
m_Material = GetComponent<MeshRenderer>().material;
Texture ShowFront =  Resources.Load("AllTextur/FrontTextur/" + nowPage.ToString(), typeof(Texture)) as Texture;
Texture ShowVerso = Resources.Load("AllTextur/VersoTextur/" + nowPage.ToString(), typeof(Texture)) as Texture;
m_Material.SetTexture("_MainTex", ShowFront);
m_Material.SetTexture("_SecTex", ShowVerso);
}

public void Turning()
{
nowPage += 1;
If (nowpage > 10) // set the threshold
{
nowPage = 1;
}
lastPage = nowPage - 1;
if (lastPage < 1)
{
lastPage = allPage;
}
#Region flipped page

Material m_Material2 = (Instantiate(Resources.Load("Plane"),new Vector3(0, Thickness+=0.001f, 0), Quaternion.identity) as GameObject).GetComponent<MeshRenderer>().material;

m_ Material2.SetFloat("_ Angle", 0);      // Dotween does rotation animation
m_Material2.DOFloat(180, "_Angle", 2);

//m_ Material2.name = "current material" + lastpage;
Texture ShowFrontLast = Resources.Load("AllTextur/FrontTextur/" + lastPage.ToString(), typeof(Texture)) as Texture;  // Resources load front image
Texture ShowVersoLast = Resources.Load("AllTextur/VersoTextur/" + lastPage.ToString(), typeof(Texture)) as Texture;  // Resources load reverse image
m_ Material2.SetTexture("_ MainTex", ShowFrontLast);   // Change the front face of the material
m_ Material2.SetTexture("_ SecTex", ShowVersoLast);    // Change the reverse side of the shader

#endregion

Texture ShowFront = Resources.Load("AllTextur/FrontTextur/" + nowPage.ToString(), typeof(Texture)) as Texture;    // Resources load front image
Texture ShowVerso = Resources.Load("AllTextur/VersoTextur/" + nowPage.ToString(), typeof(Texture)) as Texture;   // Resources load reverse image
m_ Material.SetTexture("_ MainTex", ShowFront);       // Change the front face of the material
m_ Material.SetTexture("_ SecTex", ShowVerso);       // Change the reverse side of the shader
//m_ Material. Name = "current material" + nowpage. Tostring();

}
}``````

Mount this code on the newly created plan

Create a button binding script of the UI and the turning method on pageturning. In this way, the effect of turning the book is realized.

Now we only have the effect of turning back the book. If you want to turn forward, you can load the plans created each time into the collection, and then modify their shaders from the collection

``````
m_Material.SetFloat("_Angle", value)``````

The above is the whole content of this article. I hope it will be helpful to your study, and I hope you can support developpaer.