UnityShader使用Plane實(shí)現(xiàn)翻書效果
本文實(shí)例為大家分享了UnityShader使用Plane實(shí)現(xiàn)翻書效果的具體代碼,供大家參考,具體內(nèi)容如下
之前在網(wǎng)上看到一個(gè)Shadr可以實(shí)現(xiàn)旋轉(zhuǎn)效果,就拿來實(shí)現(xiàn)一個(gè)翻書效果。解決辦法是用不同模型的顯示與隱藏,像序列幀一樣,為了實(shí)現(xiàn)效果感覺實(shí)現(xiàn)起來很繁瑣且占用資源,后期優(yōu)化可考慮用對(duì)象池解決。今天就試著用vertex shader來實(shí)現(xiàn)一下,互相交流學(xué)習(xí),大神勿噴。
實(shí)現(xiàn)簡單的翻書效果大概需要三步:
1.Plane的扭曲
2.Plane的旋轉(zhuǎn)
3.正反面的采樣
Plane的扭曲:
翻書的效果大概是,中間向外突出,X軸方向的正方向會(huì)向后偏移。
X軸負(fù)方向邊沿是保持不動(dòng)的,且扭曲程度跟隨旋轉(zhuǎn)角度增加又減小,90度為最大值。
Plane的旋轉(zhuǎn):
根據(jù)Plane的頂點(diǎn)X的范圍(-5,5)
Plane的貼圖采樣:
用了兩個(gè)Pass通道來實(shí)現(xiàn),一個(gè)是后面剔除,一個(gè)是前面剔除。分別對(duì)兩個(gè)圖片采樣。
下面是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 } } }
動(dòng)態(tài)修改這個(gè)值就可以達(dá)到Plan的翻轉(zhuǎn)
下面我們實(shí)現(xiàn)翻書效果
我們接下來要用DOTween,不明白DOTween可百度下來了解使用這里就不詳解;
創(chuàng)建Resources文件夾 在內(nèi)創(chuàng)建子文件夾FrontTextur(正面)和VersoTextur(反面)用來存放一本書的正反面圖片 把自己準(zhǔn)備的圖片導(dǎo)入 為了方面動(dòng)態(tài)加載我都用數(shù)字代替第幾頁
接下來我們創(chuàng)建一個(gè)Plan位置歸零
創(chuàng)建材質(zhì)球PageTurning2
然后再復(fù)制一個(gè)改名PageTurning3
把剛才創(chuàng)建的Plan添加材質(zhì)球PageTurning3
然后將Plan作為預(yù)設(shè)拖入Resources。
刪除Plan,然后重新創(chuàng)建一個(gè)Plan添加材質(zhì)球PageTurning2。
接下來用下面代碼實(shí)現(xiàn)翻書
using UnityEngine; using DG.Tweening; public class PageTurning : MonoBehaviour { private Material m_Material; private int nowPage = 1; //最下面頁碼 private int lastPage; //已經(jīng)翻過的 private int allPage = 10; //所有的頁數(shù) 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) //設(shè)置閾值 { nowPage = 1; } lastPage = nowPage - 1; if (lastPage < 1) { lastPage = allPage; } #region 翻動(dòng)的頁面 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做旋轉(zhuǎn)動(dòng)畫 m_Material2.DOFloat(180, "_Angle", 2); //m_Material2.name = "當(dāng)前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); //更改材質(zhì)的正面 m_Material2.SetTexture("_SecTex", ShowVersoLast); //更改材質(zhì)球的反面 #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); //更改材質(zhì)求的正面 m_Material.SetTexture("_SecTex", ShowVerso); //更改材質(zhì)球的反面 //m_Material.name = "當(dāng)前Material"+nowPage.ToString(); } }
把這個(gè)代碼掛載到剛創(chuàng)建的Plan上
創(chuàng)建一個(gè) UI的Button綁定腳本PageTurning上的 Turning方法。這樣就實(shí)現(xiàn)了翻書的效果。
現(xiàn)在只做了往后翻書效果,如果想做往前翻的效果可把每次創(chuàng)建的Plan加載到集合中然后從集合中修改他們的材質(zhì)球
m_Material.SetFloat("_Angle", value)
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
C#實(shí)現(xiàn)ComboBox變色的示例代碼
這篇文章主要為大家詳細(xì)介紹了C#如何實(shí)現(xiàn)ComboBox變色的效果,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)C#有一定的幫助,感興趣的小伙伴可以跟隨小編一起了解一下2023-01-01C# datatable 不能通過已刪除的行訪問該行的信息處理方法
采用datatable.Rows[i].Delete()刪除行后再訪問該表時(shí)出現(xiàn)出現(xiàn)“不能通過已刪除的行訪問該行的信息”的錯(cuò)誤2012-11-11C#對(duì)Word文檔的創(chuàng)建、插入表格、設(shè)置樣式等操作實(shí)例
今天小編就為大家分享一篇C#對(duì)Word文檔的創(chuàng)建、插入表格、設(shè)置樣式等操作實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-05-05c#判斷代碼是否執(zhí)行超時(shí)的幾種方式總結(jié)
這篇文章主要介紹了c#判斷代碼是否執(zhí)行超時(shí)的幾種方式總結(jié),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-01-01