UnityShader使用Plane实现翻书效果

作者:Cool-浩 时间:2022-05-19 14:46:14 

本文实例为大家分享了UnityShader使用Plane实现翻书效果的具体代码,供大家参考,具体内容如下

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

实现简单的翻书效果大概需要三步:

1.Plane的扭曲

2.Plane的旋转

3.正反面的采样

Plane的扭曲:

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

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

UnityShader使用Plane实现翻书效果

Plane的旋转:

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

UnityShader使用Plane实现翻书效果

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的翻转

UnityShader使用Plane实现翻书效果

下面我们实现翻书效果

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

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

UnityShader使用Plane实现翻书效果

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

创建材质球PageTurning2

UnityShader使用Plane实现翻书效果

然后再复制一个改名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)

来源:https://blog.csdn.net/qq_39741605/article/details/80678229

标签:UnityShader,Plane,翻书
0
投稿

猜你喜欢

  • Mybatis日志参数快速替换占位符工具的详细步骤

    2023-09-30 21:29:36
  • Java 面向对象和封装全面梳理总结

    2023-10-16 08:20:27
  • 将应用程序进行Spring6迁移的最佳使用方式

    2021-08-28 12:03:58
  • 浅述int与string类型转换的两种方法

    2023-09-09 08:56:28
  • Spring mvc Json处理实现流程代码实例

    2023-07-14 21:31:06
  • Java设计模式之java装饰者模式详解

    2023-10-27 06:17:04
  • 3种C# 加载Word的方法

    2021-06-05 21:06:41
  • Java 批量文件压缩导出并下载到本地示例代码

    2023-04-15 07:29:30
  • spring boot 2.x html中引用css和js失效问题及解决方法

    2021-08-13 10:28:32
  • JAVA 格式化日期、时间的方法

    2023-10-17 07:53:22
  • Java中常用的设计模式之工厂模式详解

    2021-07-04 15:33:37
  • c#栈变化规则图解示例(栈的生长与消亡)

    2021-10-12 05:11:11
  • 解决SpringMvc中普通类注入Service为null的问题

    2023-10-29 01:23:25
  • 如何使用java修改文件所有者及其权限

    2023-11-16 09:35:53
  • 最值得Java开发者收藏的网站

    2022-03-09 15:57:08
  • unity实现贪吃蛇游戏

    2022-05-28 07:07:51
  • C#实现一键清空控件值的示例代码

    2021-11-12 12:10:15
  • Java Arrays工具类用法详解

    2023-12-19 13:08:00
  • SpringMVC请求参数的使用总结

    2022-11-30 22:23:18
  • IDEA安装详细步骤(多图预警)

    2022-02-28 14:38:39
  • asp之家 软件编程 m.aspxhome.com