UnityShader_用Plane实现翻书效果

之前在网上看到一个Shadr可以实现旋转效果,就拿来实现一个翻书效果。解决办法是用不同模型的显示与隐藏,像序列帧一样,为了实现效果感觉实现起来很繁琐且占用资源,后期优化可考虑用对象池解决。今天就试着用vertex shader来实现一下,互相交流学习,大神勿喷。

实现简单的翻书效果大概需要三步:
1.Plane的扭曲
2.Plane的旋转

3.正反面的采样

Plane的扭曲:
翻书的效果大概是,中间向外突出,X轴方向的正方向会向后偏移。

X轴负方向边沿是保持不动的,且扭曲程度跟随旋转角度增加又减小,90度为最大值。


Plane的旋转:

根据Plane的顶点X的范围(-5,5)

Plane的贴图采样:

用了两个Pass通道来实现,一个是后面剔除,一个是前面剔除。分别对两个图片采样。

下面是Shader

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

Shader "Personal/PageTurning" {
	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
	}
	SubShader
	{
		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;
				sincos(radians(-_Angle),s,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;
				sincos(radians(-_Angle),s,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
		}
	}
}

动态修改这个值就可以达到Plan的翻转

下面我们实现翻书效果

我们接下来要用DOTween,不明白DOTween可百度下来了解使用这里就不详解;

创建Resources文件夹 在内创建子文件夹FrontTextur(正面)和VersoTextur(反面)用来存放一本书的正反面图片 把自己准备的图片导入 为了方面动态加载我都用数字代替第几页

 

接下来我们创建一个Plan位置归零

创建材质球PageTurning2

然后再复制一个改名PageTurning3

把刚才创建的Plan添加材质球PageTurning3

然后将Plan作为预设拖入Resources。

删除Plan,然后重新创建一个Plan添加材质球PageTurning2。

接下来用下面代码实现翻书

using UnityEngine;
using DG.Tweening;

public class PageTurning : MonoBehaviour
{
    private Material m_Material;
    private int nowPage = 1; //最下面页码
    private int lastPage;   //已经翻过的
    private int allPage = 10;   //所有的页数
    private float Thickness = 0; //书的厚度

    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)   //设置阈值
        {
            nowPage = 1;
        }
        lastPage = nowPage - 1;
        if (lastPage < 1)
        {
            lastPage = allPage;
        }
        #region  翻动的页面

        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做旋转动画
        m_Material2.DOFloat(180, "_Angle", 2);
        
        //m_Material2.name = "当前Material"+ lastPage;
        Texture ShowFrontLast = Resources.Load("AllTextur/FrontTextur/" + lastPage.ToString(), typeof(Texture)) as Texture;  //Resources加载正面图片
        Texture ShowVersoLast = Resources.Load("AllTextur/VersoTextur/" + lastPage.ToString(), typeof(Texture)) as Texture;  //Resources加载反面图片
        m_Material2.SetTexture("_MainTex", ShowFrontLast);   //更改材质的正面 
        m_Material2.SetTexture("_SecTex", ShowVersoLast);    //更改材质球的反面

        #endregion

        Texture ShowFront = Resources.Load("AllTextur/FrontTextur/" + nowPage.ToString(), typeof(Texture)) as Texture;    //Resources加载正面图片
        Texture ShowVerso = Resources.Load("AllTextur/VersoTextur/" + nowPage.ToString(), typeof(Texture)) as Texture;   //Resources加载反面图片
        m_Material.SetTexture("_MainTex", ShowFront);       //更改材质求的正面
        m_Material.SetTexture("_SecTex", ShowVerso);       //更改材质球的反面
        //m_Material.name = "当前Material"+nowPage.ToString();

       
    }
}

把这个代码挂载到刚创建的Plan上

创建一个 UI的Button绑定脚本PageTurning上的 Turning方法。这样就实现了翻书的效果。

现在只做了往后翻书效果,如果想做往前翻的效果可把每次创建的Plan加载到集合中然后从集合中修改他们的材质球

 m_Material.SetFloat("_Angle", value)
  • 1
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
The "Unity3D Book Page Curl" is a unity package that is used to create a book with page flip effect using unity3D native UI tools. Getting Started Create your first book:  Import the unity package  Create a canvas and EventSystem objects if you don't have one (the easiest way to create them is by adding any UI object -like a button- then you can delete it).  Drag a book prefab under the Canvas element  Resize the book on your scene and reposition the anchors as required.  Select the book from hierarchy to show it in inspector.  Assign the canvas to the canvas slot in inspector  Assign the background sprite with the sprite that you want to show on the right or left side when all pages flipped to the other side.  To edit the book pages, expand the Book Pages list in inspector, change the Size to your pages count, then start drag your pages in the Element boxes in order  Set the current page to the page that you want to be shown initially in the right side of the book.  If you want to call any function when any page flipped add it to the OnFlip Event List.  If you want to resize the area that the user can drag the page from it, open the Book node in inspector to show its children, you will find two objects "RightHotSpot" and "LeftHotSpot" resize them and set their anchors as required.  RUN and enjoy the page curl effect! Create Automatic Flipping Book:  After creating your book as mentioned above add an "Auto Flip" component on it.  Choose flipping direction( if you choose left to right make sure that the current page of the book component is equal to your page count "last page index + 1").  Uncheck the interactable check in the book component.  Specify the page flipping time parameters (Page Flip Time, Time Between Pages, Delay before Start flipping, Number of Animation frames for each page flip).  Check "Auto Start Flip" if you want the book to start flipping automatically, or uncheck it and call the StartFlipping() function in your code. Control Flipping Manually: This section will explore how to create a scene like the “Example_2_Controled Flipping” scene  To be able to let the user control page flipping using some buttons, create your book, add an "Auto Flip" component on it and configured them as mentioned above.  Uncheck the “interactable” of the book and "Auto Start Flip" of the “Auto Flip” components.  Add previous and next buttons to your scene (check Example_2_Controled Flipping scene if you have any issues setting them correctly).  Add a new slot on each button OnClick list by clicking the (+) sign, assign the Book as the game object then select the “AutoFlip->FlipRightPage” for the next button and “Auto Flip->Flip Left Page” to the previous button.  If you need to flip the page from code (based on custom action) you can call the FlipLeftPage() or FlipRightPage().
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Cool-浩

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值