UnityShader使用Plane实现翻书效果

 更新时间:2021年07月27日 14:15:09   作者:Cool-浩  
这篇文章主要为大家详细介绍了UnityShader使用Plane实现翻书效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

本文实例为大家分享了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)

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • C#实现ComboBox变色的示例代码

    C#实现ComboBox变色的示例代码

    这篇文章主要为大家详细介绍了C#如何实现ComboBox变色的效果,文中的示例代码讲解详细,对我们学习C#有一定的帮助,感兴趣的小伙伴可以跟随小编一起了解一下
    2023-01-01
  • C#实现图形路径变换的方法

    C#实现图形路径变换的方法

    这篇文章主要介绍了C#实现图形路径变换的方法,涉及C#针对图形路径的相关操作技巧,需要的朋友可以参考下
    2015-06-06
  • C# 操作符之二 算数操作符

    C# 操作符之二 算数操作符

    算数操作符+,-,*,/,%,的用法和大多程序设计语言是相同的,%号的作用是整数除法中产生余数,而整数法会直接去掉小数部分,而不是四舍五入。
    2011-02-02
  • C# datatable 不能通过已删除的行访问该行的信息处理方法

    C# datatable 不能通过已删除的行访问该行的信息处理方法

    采用datatable.Rows[i].Delete()删除行后再访问该表时出现出现“不能通过已删除的行访问该行的信息”的错误
    2012-11-11
  • C#对Word文档的创建、插入表格、设置样式等操作实例

    C#对Word文档的创建、插入表格、设置样式等操作实例

    今天小编就为大家分享一篇C#对Word文档的创建、插入表格、设置样式等操作实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-05-05
  • c#判断代码是否执行超时的几种方式总结

    c#判断代码是否执行超时的几种方式总结

    这篇文章主要介绍了c#判断代码是否执行超时的几种方式总结,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-01-01
  • C#设置文件权限的方法

    C#设置文件权限的方法

    这篇文章主要介绍了C#设置文件权限的方法,文中讲解非常细致,帮助大家更好的理解和学习c#,感兴趣的朋友可以了解下
    2020-08-08
  • 详解Unity日志打印工具功能

    详解Unity日志打印工具功能

    Unity是一个非常火的游戏引擎,我们再开发的时候有的时候要进行程序的调试,下面给大家介绍下Unity日志打印工具功能,感兴趣的朋友一起看看吧
    2022-01-01
  • Unity3D实现导航效果

    Unity3D实现导航效果

    这篇文章主要为大家详细介绍了Unity3D实现简单导航效果,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-02-02
  • Unity实现UI渐变效果

    Unity实现UI渐变效果

    这篇文章主要为大家详细介绍了Unity实现UI渐变效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-04-04

最新评论