[unity+shader] 模擬一個三稜柱廣告牌
阿新 • • 發佈:2018-12-18
三面翻廣告牌(Trivision, Triangular Billboard)是由一組並排定位的三稜柱構成,通過旋轉三稜柱,利用其三個側面形成三幅畫面的廣告牌,在LED廣告牌大規模出現之前是個很常見的東西。
在這篇文章裡,我們就講一下如何製作一個稜柱翻轉切換圖片的效果。
https://en.wikipedia.org/wiki/Trivision
模擬稜柱翻轉的基本,就在於將同時顯示的兩張貼圖按一定比例縮放。這個比例由一個property _Progress來控制。
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)' //AnimationEffects2D-->sakuraplus-->https://sakuraplus.github.io/make-terrain-with-google-elevation/index.html Shader "TUT/TriangularBillboard01" { Properties { _MainTex ("Texture A", 2D) = "white" {} _MainTexB ("Texture B", 2D) = "black" {} [Space(10)] _Progress("Progress", Range(0,1))=0 } SubShader { Tags {"Queue"="Transparent" } CGINCLUDE #include "UnityCG.cginc" sampler2D _MainTex; sampler2D _MainTexB; uniform half4 _MainTex_ST; uniform half4 _MainTexB_ST; fixed _Progress; struct v2f { float4 pos : SV_POSITION; half2 uvTA: TEXCOORD0; half2 uvTB: TEXCOORD1; half2 uvORI: TEXCOORD2;//original }; v2f vert(appdata_img v) { v2f o; o.pos = mul(UNITY_MATRIX_MVP, v.vertex); o.uvTA=(v.texcoord-_MainTex_ST.zw)*_MainTex_ST.xy ; o.uvTB=(v.texcoord-_MainTexB_ST.zw)*_MainTexB_ST.xy ; o.uvORI=v.texcoord; o.uvORI=v.texcoord; return o; } fixed4 frag(v2f i) : SV_Target { fixed4 texA; fixed4 texB ; fixed4 color; float posmod; texA = tex2D(_MainTex, i.uvTA).rgba ; texB = tex2D(_MainTexB, i.uvTB).rgba ; if(i.uvORI.x>_Progress){ color=texA; }else{ color=texB; } return color; } ENDCG Pass { //ZWrite Off Blend SrcAlpha OneMinusSrcAlpha CGPROGRAM #pragma vertex vert #pragma fragment frag #pragma target 3.0 ENDCG } } FallBack "Diffuse" }
這樣我們得到了一個使用progress控制切換兩張貼圖的效果。
但是一個三稜柱廣告牌不應該只有一個稜柱,於是加上一個width的property,來設定每個稜柱的寬度。
_Width("Width",Float )=0.5
雖然可能用不到,但是這個寬度其實是可以超過uv的範圍的,所以不需要限定成Range(0,1)。
修改一下這個部分,計算當前uv與width屬性的餘數:
float posmod= fmod(i.uvORI.x,_Width); if(posmod/_Width>_Progress){ color=texA; }else{ color=texB; }
這樣,就實現了一個簡單的百葉窗效果,把這裡的uvORI.x換成y,百葉窗就可以變成橫向開啟的啦。
作為一個模擬稜柱,圖片旋轉造成的壓縮效果必不可少,接下來我們來計算壓縮部分。
兩張貼圖uv的y座標不變,x根據自身的位置和progress計算。
fixed2 uvA=fixed2(i.uvTA.x+(posmod-_Width)* _Progress/(1-_Progress), i.uvTA.y); fixed2 uvB=fixed2(i.uvTB.x+(1-_Progress)*posmod /_Progress, i.uvTB.y); texA = tex2D(_MainTex, uvA).rgba ; texB = tex2D(_MainTexB, uvB).rgba ;
這個公式實在不記得是怎麼匯出來的了,也懶得再想一遍,反正只是平面幾何,有興趣的自己算一下吧……
接下來給它新增一個假的陰影。先新增一個表示陰影基礎強度的property。
_ShadowStrength("Shadow", Range(0,2)) = 1.0
之後,讓稜柱的兩個面都有顯示的時候,加上一個從內側向外逐步減淡的陰影,即讓最終的顏色乘以一個小於1的數。在面所佔的比例變大時,這個數逐漸接近1,比例變小的時候,逐漸接近0。
fixed shadowOn=1;
fixed strengtnWithProgress=_Progress/(1-_Progress);
fixed ratioInOneSide=(_Width*_Progress-posmod)/_Width;
if(posmod/_Width>_Progress){
shadowOn=1+_ShadowStrength*ratioInOneSide*strengtnWithProgress;
}else{
shadowOn=1-_ShadowStrength*ratioInOneSide/strengtnWithProgress;
}
color.rgb*=shadowOn;
至此,一個所有三稜柱同時旋轉以切換圖片的模擬三稜柱廣告牌就完成了。
希望觀看更多效果,去
作為攝像機特效也可以使用