三面翻广告牌(Trivision, Triangular Billboard,https://en.wikipedia.org/wiki/Trivision)
是由一组并排定位的三棱柱构成,通过旋转三棱柱,利用其三个侧面形成三幅画面的广告牌,在LED广告牌大规模出现之前是个很常见的东西。
在这篇文章里,我们就讲一下如何制作一个棱柱翻转切换图片的效果。
模拟棱柱翻转的基本,就在于将同时显示的两张贴图分割,之后按一定比例缩放。
先从基础的功能开始:
//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"
}
首先定义两章贴图,和一个propert,_progress作为控制三棱柱旋转的参数。
在frag 函数中,以progress 为依据判断绘制哪张贴图。
这样我们得到了一个使用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的数。
以左侧texB为例:
首先,让阴影强度随着progress 变化,在面所占的比例变大时,这个数逐渐接近1,比例变小的时候,逐渐接近0。
fixed shadowOnTexB=_ShadowStrength*abs(_Progress-1);
接着,让uv越接近progress位置时,阴影越淡。
shadowOnTexB *= (_Width*_Progress- posmod)/(_Width*_Progress);
这时,shadowOnTexB和我们所期待的正好相反,于是,
texB.rgb*=1-shadowOnTexB;
而针对在右侧texA区域的点,也是同样方法计算。
fixed shadowOnTexA=_ShadowStrength*_Progress;
shadowOnTexA *= (posmod-_Width*_Progress)/(_Width*(1-_Progress));
texA.rgb*=1-shadowOnTexA;
至此,一个所有三棱柱同时旋转以切换图片的模拟三棱柱广告牌就完成了。下一章会讲一下更多的三棱柱翻转方式。
这一章中所用到的内容在这里,真的很尴尬到现在才发现忘了加链接:
sakuraplus/make-terrain-with-google-elevationgithub.com其中上篇所讲到的内容为01,02,03
希望观看更多效果,去sakuraplus/make-terrain-with-google-elevation希望观看更多效果,去
Unity Web Player | SlideshowEffectsakuraplus.github.io作为摄像机特效也可以使用
Unity Web Player |SlideshowEffect CamEffectsakuraplus.github.ioBuy me a coffee: http://u3d.as/1jVq